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:
| # | Job | What it does |
|---|---|---|
| 1 | Test | Runs the app's unit tests inside a Python container. |
| 2 | Validate deployment targets | Resolves deployment-targets.json against the Barbara API and fails fast if any declared device or group does not exist. |
| 3 | Build image | Builds and pushes a multi-platform Docker image tagged with the short commit SHA, the semver version, and latest. |
| 4 | Package artifact | Generates a release .zip containing a single docker-compose.yaml that pins the immutable <sha>-tagged image. |
| 5 | Register Barbara application | Creates the application in Barbara if it does not already exist. |
| 6 | Upload Barbara version | Uploads the .zip as a new app version under the registered application. |
| 7 | Deploy to devices | Triggers the deployment of that version to the resolved targets. |
| 8 | Verify deployment | Polls device health and triggers a rollback if it fails within the configured timeout. |
| 9 | Create GitHub release | Publishes 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.
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:
| Variable | Description | Example |
|---|---|---|
APP_NAME | Logical application name in Barbara. | Github_Actions_Sample |
IMAGE_NAME | Image name in the registry. | github-actions-sample |
REGISTRY_HOST | Container registry host. | bdr.barbara.tech |
REGISTRY_NAMESPACE | Namespace within the registry. | public |
APP_DEVELOPER | Developer name shown in Barbara for the app (defaults to Barbara). | My Team |
APP_SHORT_DESCRIPTION | Short description used when the app is first registered. | |
APP_LONG_DESCRIPTION | Long description used when the app is first registered. | |
APP_VERSION_ARCHITECTURES | Comma-separated target architectures. | x86_64,arm64,armv7 |
Supported architecture values map to Docker platforms as follows: x86_64 → linux/amd64, arm64 → linux/arm64, armv7 → linux/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:
| Secret | Description |
|---|---|
REGISTRY_USERNAME | Registry login username. |
REGISTRY_PASSWORD | Registry login password or token. |
Environment variables
Defined per GitHub environment (typically development and production). The shipped workflow targets the production environment.
| Variable | Description | Example (production) |
|---|---|---|
BARBARA_API_URL | Barbara API base URL. | https://prod.bap.barbara.tech |
BARBARA_AUTH_URL | Keycloak base URL. | https://prod.auth.barbara.tech |
BARBARA_KEYCLOAK_REALM | Keycloak realm. | bbr_prod |
BARBARA_KEYCLOAK_CLIENT_ID | Keycloak client ID. | |
BARBARA_KEYCLOAK_USER_EMAIL | User email used for token requests. | |
VERIFY_TIMEOUT_SECONDS | Max seconds to wait for deployment health. | 300 |
VERIFY_INTERVAL_SECONDS | Poll interval during verification. | 15 |
Environment secrets
| Secret | Description |
|---|---|
BARBARA_KEYCLOAK_CLIENT_SECRET | Keycloak client secret. |
BARBARA_KEYCLOAK_USER_PASSWORD | Keycloak user password. |
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:
devicesentries are matched againstdeviceNamein Barbara.groupsentries are matched againstnamein 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.jsonas a workflow artifact for diagnostics.
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
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:
- Waits until the new image reference is reported as running.
- 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:
- Replace
app/with your codebase and update theDockerfileaccordingly. - Update
docker-compose.yamlwith your service name and any volumes, devices, or App Config / Secrets your workload needs. - Bump the
APP_NAMEandIMAGE_NAMErepository variables to match your app and registry image. - Edit
deployment-targets.jsonto point at the real device or group names in your Barbara organization. - 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.