Skip to main content

Automate Barbara deployments with GitHub Actions

This article refers to Platform v3.2.0. The current Platform version is v3.2.0.

Overview

The barbara_github_actions_sample repository is a minimal Python application wired to a single GitHub Actions workflow that automates the full Barbara application lifecycle: build the image, register the application in Barbara, upload a new version, deploy it to selected devices, verify health on-device, and roll back automatically if verification fails.

The app itself is intentionally trivial — an HTTP server with a /health probe — so you can focus on the CI/CD plumbing and reuse it as a template for your own apps.

In this article you will:

  • Clone the sample and connect it to your own Barbara organization.
  • Configure the GitHub variables and secrets the workflow needs.
  • Declare the devices and groups where the app should be deployed.
  • Trigger a release by pushing a v* tag and follow the pipeline end-to-end.

Pipeline at a glance

When you push a tag matching v* (for example v0.1.0), the workflow at .github/workflows/cicd.yml runs nine jobs in sequence:

#JobWhat it does
1TestRuns the app's unit tests inside a Python container.
2Validate deployment targetsResolves deployment-targets.json against the Barbara API and fails fast if any declared device or group does not exist.
3Build imageBuilds and pushes a multi-platform Docker image tagged with the short commit SHA, the semver version, and latest.
4Package artifactGenerates a release .zip containing a single docker-compose.yaml that pins the immutable <sha>-tagged image.
5Register Barbara applicationCreates the application in Barbara if it does not already exist.
6Upload Barbara versionUploads the .zip as a new app version under the registered application.
7Deploy to devicesTriggers the deployment of that version to the resolved targets.
8Verify deploymentPolls device health and triggers a rollback if it fails within the configured timeout.
9Create GitHub releasePublishes a GitHub release with the .zip attached — only after successful verification.

The deployment targets are validated before the image is built. A typo in a device or group name fails the pipeline early, with no wasted build.

Get the sample repository

Clone or fork the repo so you can push your own tags and trigger the workflow:

git clone https://github.com/Barbaraedge/barbara_github_actions_sample.git
cd barbara_github_actions_sample

The repository layout is:

.
├── app/main.py # HTTP app (port 8080)
├── scripts/
│ ├── barbara_api.py # Barbara and Keycloak request helpers
│ ├── resolve_deployment_targets.py # Validates deployment-targets.json against Barbara
│ ├── package_docker_compose.py # Generates the deployable docker-compose.yaml
│ ├── ensure_barbara_application.py # Creates the Barbara app if missing
│ ├── upload_barbara_app_version.py # Uploads the .zip as a Barbara app version
│ ├── deploy_barbara_app_version.py # Triggers deployment on target devices
│ ├── verify_deployment.py # Polls health and rolls back if needed
│ └── get_container_info.py # Retrieves container runtime info from Barbara
├── tests/test_app.py
├── .github/workflows/cicd.yml
├── deployment-targets.json
├── Dockerfile
└── docker-compose.yaml

Every script under scripts/ is invoked by a job in the workflow. They use the standard library only — no extra runtime dependencies.

Run the app locally first

Before wiring CI/CD, smoke-test the app on your machine:

python app/main.py
curl http://localhost:8080/health # → OK

This is the same /health endpoint the verification job polls on the edge node.

Configure GitHub variables and secrets

The workflow reads two layers of configuration: repository-level (build and registry) and environment-level (Barbara and Keycloak). The repo ships with a production environment defined in the workflow; you typically configure both development and production.

Repository variables

Set these under Settings → Secrets and variables → Actions → Variables:

VariableDescriptionExample
APP_NAMELogical application name in Barbara.Github_Actions_Sample
IMAGE_NAMEImage name in the registry.github-actions-sample
REGISTRY_HOSTContainer registry host.bdr.barbara.tech
REGISTRY_NAMESPACENamespace within the registry.public
APP_DEVELOPERDeveloper name shown in Barbara for the app (defaults to Barbara).My Team
APP_SHORT_DESCRIPTIONShort description used when the app is first registered.
APP_LONG_DESCRIPTIONLong description used when the app is first registered.
APP_VERSION_ARCHITECTURESComma-separated target architectures.x86_64,arm64,armv7

Supported architecture values map to Docker platforms as follows: x86_64linux/amd64, arm64linux/arm64, armv7linux/arm/v7. Unrecognized values are ignored; if none remain, the workflow falls back to x86_64.

Repository secrets

Set these under Settings → Secrets and variables → Actions → Secrets:

SecretDescription
REGISTRY_USERNAMERegistry login username.
REGISTRY_PASSWORDRegistry login password or token.

Environment variables

Defined per GitHub environment (typically development and production). The shipped workflow targets the production environment.

VariableDescriptionExample (production)
BARBARA_API_URLBarbara API base URL.https://prod.bap.barbara.tech
BARBARA_AUTH_URLKeycloak base URL.https://prod.auth.barbara.tech
BARBARA_KEYCLOAK_REALMKeycloak realm.bbr_prod
BARBARA_KEYCLOAK_CLIENT_IDKeycloak client ID.
BARBARA_KEYCLOAK_USER_EMAILUser email used for token requests.
VERIFY_TIMEOUT_SECONDSMax seconds to wait for deployment health.300
VERIFY_INTERVAL_SECONDSPoll interval during verification.15

Environment secrets

SecretDescription
BARBARA_KEYCLOAK_CLIENT_SECRETKeycloak client secret.
BARBARA_KEYCLOAK_USER_PASSWORDKeycloak user password.
Barbara API credentials

The Keycloak client ID and secret are issued by Barbara as part of an Enterprise license. Contact the Barbara support team if you do not have them yet.

Declare your deployment targets

deployment-targets.json at the repo root tells the workflow which devices and groups should receive each new version:

{
"devices": ["device-a", "device-b"],
"groups": ["group-a"]
}

Resolution rules:

  • devices entries are matched against deviceName in Barbara.
  • groups entries are matched against name in Barbara; every device in a matched group is resolved.
  • Devices from both lists are deduplicated by id.
  • If any declared device or group does not exist, the pipeline fails before building the Docker image.
  • After successful validation, the job uploads dist/resolved-deployment-targets.json as a workflow artifact for diagnostics.
warning

Empty devices and groups arrays are accepted but the deploy and verify steps will skip with "status": "skipped" — no version will reach a device. Always declare at least one target before tagging a release.

Trigger a release

Pushing a v* tag is the only event the workflow listens for. The version published to Barbara and the image tag are both derived from the tag name (v0.2.0 → version 0.2.0):

git tag v0.2.0
git push --tags

At runtime, the app combines the semver version with the short commit SHA injected at build time:

0.2.0+17a0484

Hit any running instance to confirm:

curl http://<device-ip>:8080/
# → Everything works fine, version 0.2.0+17a0484

This makes every container traceable to an exact source commit and CI build.

The release artifact

The .zip uploaded to Barbara contains a single file — a docker-compose.yaml that pins the immutable <sha>-tagged image built by CI:

services:
sample-barbara-app:
container_name: sample-barbara-app
image: bdr.barbara.tech/public/github-actions-sample:17a0484
warning

Do not substitute a locally rebuilt image for the CI-built one. Only the image built by the workflow carries the embedded build metadata (semver version + short SHA) that powers traceability and rollback.

Verify and roll back

After deployment, scripts/verify_deployment.py polls each target device for up to VERIFY_TIMEOUT_SECONDS (default in the example: 300), at VERIFY_INTERVAL_SECONDS intervals (default: 15). For each device it:

  1. Waits until the new image reference is reported as running.
  2. Polls the workload's health status until it reports healthy.

If any device fails verification within the timeout window, the script performs a rollback:

  • If a previous version exists in Barbara, it is redeployed to every target device.
  • If no previous version exists, the workload is removed from every target device.
  • The failed version is then deleted from the Barbara application's version list (retried for up to 5 minutes to absorb transient API errors).

The GitHub release is only created if verification succeeds — a failed deployment never produces a release artifact on GitHub.

Adapt the sample to your own app

The sample is structured so that almost everything app-specific is contained in app/, Dockerfile, and docker-compose.yaml. To turn it into a pipeline for your own application:

  1. Replace app/ with your codebase and update the Dockerfile accordingly.
  2. Update docker-compose.yaml with your service name and any volumes, devices, or App Config / Secrets your workload needs.
  3. Bump the APP_NAME and IMAGE_NAME repository variables to match your app and registry image.
  4. Edit deployment-targets.json to point at the real device or group names in your Barbara organization.
  5. Push a v* tag and watch the workflow run.

Keep the scripts/ folder and the workflow as-is — they are designed to be reusable across apps and to remain valid as the Barbara API evolves.

Summary

The barbara_github_actions_sample repository is a working blueprint for a GitOps-style release pipeline against Barbara: tag a commit, and a single workflow tests, builds, registers, deploys, verifies, and rolls back if needed. Replace the demo app with your own and you have a reusable CI/CD layer for any Barbara-deployable Docker workload.