A collection of reusable GitHub Actions workflows (on: workflow_call) shared across WeMoveEU projects. Caller repositories reference these by path and version tag from their own .github/workflows.
Always pin to a version tag — the current latest is @v12:
uses: WemoveEU/ci-workflows/.github/workflows/docker-build.yml@v12A new vN tag is pushed on each release. Pin to a tag (not a branch) so callers opt
in to changes deliberately.
The workflows available:
docker-build.yml— build and push a Docker image to GitHub Container Registry.deploy-strapi.yml— build and deploy a Strapi backend + frontend.notify.yml— post a Slack notification.python-build.yml— build a Python package withuv.
Builds a Docker image and pushes it to GitHub Container Registry
(ghcr.io/<name>). This is the foundational workflow that the others build on. It
supports staging and production environments via its tagging strategy.
-
dockerfile: Path to the Dockerfile used for building the image. Default
Dockerfile. -
name: Name of the image in the registry (pushed to
ghcr.io/<name>). Default${{github.repository}}. -
dir: The root of app sources / build context. Use if your app is in a subdirectory, e.g.
frontend. Default.. -
overlay: Name of an artifact to unpack over the checked-out source before building (e.g. env files). Use a unique name based on
${{github.run_id}}to avoid races between concurrent runs. The artifact is deleted after it is unpacked. -
prepare: Shell commands run (via
bash) after unpacking the overlay, before building the image. -
args: Docker build args (one variable, or multiline format), passed to the
build-argsinput of docker/build-push-action. -
production_branch: The name of the production branch. Default
main.
- personal_token: Optional personal access token used to check out private repositories and submodules. Falls back to
github.tokenwhen not provided.
Tags are generated by docker/metadata-action from the git context:
feature/*branches →featuretag + the branch ref- Semver tags (
v1.2.3) →version/major.minor/majortags - Push to
production_branch→latest - Push to the default branch when it is not the production branch →
staging
If the ref matches none of these rules (e.g. a release/* or otherwise
unrecognised branch), no tag is produced. In that case the image is built but
not pushed — the run still validates the Dockerfile, and a warning is emitted —
rather than failing with tag is needed when pushing to registry.
The release job runs on ubuntu-latest with contents: read, packages: write,
and actions: write permissions (the last is needed because the overlay artifact is
deleted via the Actions API). Its steps:
-
Checkout Code:
actions/checkout@v7clones the repository and its submodules (fetch-depth: 20). -
Apply Overlay: If
overlayis set,actions/download-artifact@v8downloads it andgeekyeggo/delete-artifact@v6removes it. Create the overlay in the caller withactions/upload-artifact@v4; its files are unpacked into the project directory. See this example. -
Run Prepare Script: Executes the
prepareshell commands if provided. -
Generate Image Tag:
docker/metadata-action@v6produces tags per the strategy above. -
Set up Docker Buildx:
docker/setup-buildx-action@v4. -
Login to GitHub Container Registry:
docker/login-action@v4(authenticates toghcr.iowithGITHUB_TOKEN). -
Build and Push:
docker/build-push-action@v7builds fromdirusingdockerfileand pushes the generated tags.
name: Deploy
on:
push:
branches:
- main
- "release/*"
jobs:
release:
uses: WemoveEU/ci-workflows/.github/workflows/docker-build.yml@v12
with:
production_branch: ${{vars.CI_PRODUCTION_BRANCH}}
dockerfile: server/Dockerfile
dir: server
name: crm/serverOrchestrates a Strapi deploy by calling docker-build.yml twice — backend first
(backend/Dockerfile, image <repo>/backend), then frontend
(frontend/Dockerfile, image <repo>/frontend). Between them, a wait-for-backend
job polls the live backend until it is ready.
- backend_args: Docker build args for the backend image. Default
''. - frontend_args: Docker build args for the frontend image. Default
''. - production_branch: The name of the production branch. Default
main. - deploy_marker: Filename in the Strapi
publicfolder whose presence means the backend is deployed. The health check pollshttps://strapi.${{vars.DOMAIN}}/<deploy_marker>and only runs when this input is provided.
- personal_token: Optional personal access token, forwarded to
docker-build.ymlfor private repositories and submodules.
- The
wait-for-backendjob selects its GitHub Environment dynamically: production when on thevars.CI_PRODUCTION_BRANCHbranch or a tag starting withv; otherwise staging. - Overlay names are made run-unique with
${{github.run_id}}(backend_env_<run_id>,frontend_env_<run_id>) to avoid collisions between concurrent runs. - Calling repositories must define the repository variables
vars.CI_PRODUCTION_BRANCHandvars.DOMAIN.
Posts a Slack notification (green on success, red on failure) via
slackapi/slack-github-action@v3. Call it as a final step from a caller workflow.
- slack_webhook_url: Slack channel incoming-webhook URL (required).
Builds a Python package with uv: checks out the repo (actions/checkout@v7),
installs uv (astral-sh/[email protected]), and runs uv build. Takes no inputs.
- v12 —
docker-build.yml: when no tag rule matches the ref, the image is now built without pushing (with a warning) instead of failing withtag is needed when pushing to registry. Registry login is skipped in that case. - v11 — README rewritten as a repo overview covering all four workflows; action versions corrected.