CI/CD
Continuous Integration and Deployment for PATH DRC EMR.
Overview
PATH DRC EMR uses GitHub Actions for automated builds, testing, and releases. The CI/CD pipeline:
- Validates configuration on pull requests
- Builds and publishes Docker images on merge
- Creates releases with air-gapped bundles on tags
Workflows
build-test.yml
Trigger: Pull requests to main
Purpose: Validate changes before merge
name: Build and Validate Configuration
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '8'
- name: Build and Test
run: mvn --batch-mode --activate-profiles distro,validator clean verify
What it checks:
- Maven build succeeds
- Configuration validation passes
- No syntax errors in Initializer files
build-and-release.yml
Trigger: Push to main, tags, manual dispatch
Purpose: Build and publish Docker images
Jobs:
- get-changed-distributions - Detect what changed
- build-and-release-base - Build base distribution
- build-and-release-sites - Build site-specific distributions
Change Detection
The workflow uses paths-filter to only build what changed:
filters: |
common: &common
- ./.github/workflows/build-and-release.yml
- ./distro/**
- ./frontend/**
- ./gateway/**
- pom.xml
- Dockerfile
base:
- *common
akram:
- *common
- ./sites/akram/**
libikisi:
- *common
- ./sites/libikisi/**
This means:
- Changes to
distro/trigger base and all site builds - Changes to
sites/akram/only trigger akram build - Workflow changes trigger all builds
Build Process
Base Distribution Build
steps:
- name: Build and push gateway image
uses: docker/build-push-action@v6
with:
context: ./gateway
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/.../gateway:$
ghcr.io/.../gateway:latest
ghcr.io/.../gateway:$
- name: Build and push frontend image
# Similar to gateway
- name: Build and push backend image
uses: docker/build-push-action@v6
with:
context: .
secret-files: |
m2settings=/home/runner/.m2/settings.xml
build-args: |
MVN_ARGS=deploy
tags: |
ghcr.io/.../backend:latest
Site-Specific Build
- name: Build and push backend image
uses: docker/build-push-action@v6
with:
build-args: |
BUILD_TYPE=site
MVN_PROJECT=$
MVN_ARGS=deploy
tags: |
ghcr.io/.../backend:latest-$
Air-Gapped Bundle Creation
Process
- Pull all required images
- Use docker-compose-air-gapper to create bundle
- Upload as artifact
- Attach to release (for tags)
- name: Build senzing/docker-compose-air-gapper
run: |
docker build -t senzing/docker-compose-air-gapper \
https://github.com/senzing-garage/docker-compose-air-gapper.git#1.0.7
- name: Generate save-images.sh
run: |
docker run --rm \
-v $:/data \
-e SENZING_DOCKER_COMPOSE_FILE=/data/docker-compose-normalized.yaml \
-e SENZING_OUTPUT_FILE=/data/save-images.sh \
senzing/docker-compose-air-gapper:latest
- name: Save images as tars
run: ./save-images.sh
- name: Package bundle
run: |
mv /home/runner/docker-compose-air-gapper-*.tgz \
path-drc-emr-images-bundle.tgz
Releases
Creating a Release
- Create and push a tag:
git tag v1.0.0 git push origin v1.0.0 - Workflow automatically:
- Builds all images with version tag
- Creates air-gapped bundles
- Creates GitHub release with bundles attached
Release Artifacts
path-drc-emr-images-bundle.tgz- Base imagespath-drc-emr-images-bundle-akram.tgz- Akram site imagespath-drc-emr-images-bundle-libikisi.tgz- Libikisi site imagespath-drc-docker-compose.tgz- Docker Compose files
Secrets and Permissions
Required Permissions
permissions:
contents: write # For creating releases
packages: write # For pushing images
Secrets Used
| Secret | Purpose |
|---|---|
GITHUB_TOKEN |
Auto-provided, used for registry auth and releases |
Maven Authentication
Maven settings are configured for GitHub Packages:
- uses: s4u/maven-settings-action@v3.1.0
with:
servers: |
[{
"id": "path-drc",
"username": "$",
"password": "$"
}]
Caching
Docker Layer Cache
Images use registry-based caching:
cache-to: |
type=registry,ref=ghcr.io/.../backend:latest-cache
cache-from: |
type=registry,ref=ghcr.io/.../backend:latest-cache
Maven Cache
- uses: actions/setup-java@v4
with:
cache: 'maven'
Multi-Platform Builds
All images are built for both AMD64 and ARM64:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
Manual Dispatch
Trigger builds manually from GitHub UI:
- Go to Actions tab
- Select “Build and Publish Docker Images”
- Click “Run workflow”
- Select branch
Manual dispatch builds all distributions regardless of changes.
Troubleshooting
Build Fails
Check logs in GitHub Actions:
- Go to Actions tab
- Click on failed run
- Expand failed step
Common issues:
- Maven dependency not found - Check GitHub Packages availability
- Docker push fails - Check permissions
- Out of disk space - Check runner resources
Images Not Updated
Check if workflow ran:
- Verify push triggered workflow
- Check paths-filter detected changes
Force rebuild:
- Use manual dispatch to rebuild all
Release Not Created
Check tag format:
- Tags should match expected format
- Workflow must be configured for tag triggers
Documentation Workflow
docs.yml
Builds and deploys documentation to GitHub Pages:
name: Deploy Documentation
on:
push:
branches: [main]
paths:
- 'docs/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
working-directory: docs
- name: Build with Jekyll
run: bundle exec jekyll build
working-directory: docs
Related
- Building Images - Image build details
- Local Development - Development setup
- Contributing - Contribution guidelines