GitHub Actions CI/CD
GitHub Actions handles continuous integration and deployment.
Each service repository contains branch-specific workflows that call reusable workflows from the parent POM repository (christhonie/event).
Reusable Workflows
Reusable workflows live in christhonie/event/.github/workflows/ and are called from service repositories using uses: christhonie/event/.github/workflows/<name>.yml@main.
maven-package.yml
Builds and packages the Maven project.
| Input | Description |
|---|---|
|
Maven profiles to activate (default: |
|
JDK version (default: |
|
Whether to set up Node.js and npm (default: |
|
Node.js version when npm is required (default: |
Key behaviour:
-
Caches Maven dependencies with
run_idto refresh SNAPSHOTs each build -
Removes cached SNAPSHOT directories before build
-
Caches the
target/directory for downstream jobs (docker-build, helm-build)
docker-build.yml
Builds a Docker image using Jib and pushes it to Docker Hub.
| Input | Description |
|---|---|
|
Maven profiles to activate (default: |
|
JDK version (default: |
| Output | Description |
|---|---|
|
The Docker image tag (Maven project version, e.g. |
The image tag is the Maven project version, extracted via mvn help:evaluate.
This output is consumed by the argocd-update job.
helm-build.yml
Packages the Helm chart and pushes it to Docker Hub as an OCI artifact. See Helm Configuration for chart structure details.
| Output | Description |
|---|---|
|
The Helm chart version that was packaged (e.g. |
Key details:
-
Restores the cached
target/directory frommaven-package -
Creates a placeholder
settings-security.xml(required by helm-maven-plugin 6.17.0) -
Uses Helm CLI for registry login (not the Maven
helm:registry-logingoal, which stores credentials under the wrong registry key) -
Uses
continue-on-error: trueto tolerate duplicate OCI tag pushes on SNAPSHOT rebuilds -
Runs Helm goals in a single Maven invocation:
mvn helm:init helm:package helm:push
The helm:registry-login goal is intentionally omitted.
It stores credentials under registry-1.docker.io/christhonie instead of registry-1.docker.io, causing 401 errors on push.
The workflow uses helm registry login CLI command before the Maven invocation instead.
|
argocd-update.yml
Updates the ArgoCD manifest in the GitOps repository to trigger a deployment.
| Input | Description |
|---|---|
|
Target environment ( |
|
Service name matching the ArgoCD manifest filename (e.g. |
|
Helm chart version to deploy — updates |
|
Docker image tag override (optional — chart |
|
Git commit SHA for forcing SNAPSHOT rollouts (optional) |
|
ArgoCD repository (default: |
This workflow:
-
Checks out the ArgoCD repository using
ARGOCD_REPO_TOKEN -
If
chart-versionis provided, updates.spec.source.targetRevisionso ArgoCD pulls the correct chart from the OCI registry -
If
image-tagis provided, updates.spec.source.helm.valuesObject.image.tag— typically omitted because the chart’sappVersiondefaults to the correct Docker image tag -
If
build-shais provided, sets apodAnnotations."app.kubernetes.io/build-sha"value to force pod recreation even when the image tag is unchanged (important for SNAPSHOT rebuilds) -
Commits and pushes with retry logic (pull --rebase on conflict)
Branch Workflows
Each service has two main workflow files.
push-dev.yml (develop branch)
Triggered on push to develop.
Runs the full CI pipeline including tests.
paths-filter ──► test-fe ──► package ──► docker-build ──► helm-build ──► update-argocd-dev
└ test-be ──┘ ├── publish
└── dependencygraph
Key features:
-
Path filtering: Uses
dorny/paths-filterto skip unnecessary jobs (e.g. skip backend tests if only frontend changed) -
Conditional execution: Test jobs only run when relevant files change; downstream jobs use
always()with result checks to handle skipped dependencies -
Helm chart built on every push: Ensures chart and Docker image are always in lock-step
-
ArgoCD update: Passes
chart-versionandbuild-sha: ${{ github.sha }}— the chart version setstargetRevision, and the build SHA forces SNAPSHOT rollouts
Example workflow call:
helm-build:
name: Helm
needs: [docker-build]
if: always() && needs.docker-build.result == 'success'
uses: christhonie/event/.github/workflows/helm-build.yml@main
with:
maven-profiles: dev,webapp
jdk-version: 17
secrets:
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
update-argocd-dev:
name: Deploy Dev
needs: [helm-build]
if: always() && needs.helm-build.result == 'success'
uses: christhonie/event/.github/workflows/argocd-update.yml@main
with:
environment: dev
service-name: membership-ui
chart-version: ${{ needs.helm-build.outputs.chart-version }}
build-sha: ${{ github.sha }}
secrets:
ARGOCD_REPO_TOKEN: ${{ secrets.ARGOCD_REPO_TOKEN }}
push-main.yml (main branch)
Triggered on push to main (typically via Gitflow release finish).
No tests — assumes code was tested on develop.
package ──► docker-build ──► helm-build ──► update-argocd-stage
├── publish
└── gitflow-release-finish
Key differences from develop:
-
Uses
prod,webappMaven profiles -
Helm build depends on
docker-build(same as develop) -
Updates ArgoCD stage environment with
chart-versiononly (nobuild-shasince image tag changes on release) -
Triggers Gitflow release finish workflow