Video Thumbnail for Lesson
10.3: Build and Deploy Workflows

Building and Deploy Workflows

Building and Pushing Container images

The build-push workflow mirrors the structure of the test workflow:

  • Perform the same filtering step to determine which services need new images.
  • Use full-depth checkouts (fetch-depth: 0) so git describe can compute semantic versions.
  • Authenticate to Docker Hub (skipped when running locally) and configure Buildx/QEMU for multi-arch builds.
  • Invoke docker/build-push-action with cache directives and tags supplied by helper Task targets.

Version tags come from task utils:generate-version and task utils:generate-version-tag, which inspect release tags to produce either compact (production) or extended (staging/dev) identifiers like 1.2.3+0047-<sha>. The workflow supports three trigger modes:

  • Push to main: builds staging images for any changed services.
  • Semantic tags (services/node/api-node@1.2.3): treated as production releases for a single service.
  • Manual dispatch: accepts service and version inputs to rebuild ad hoc images (e.g., hotfix tags).

Guard clauses ensure the job short-circuits when no services change, preventing “empty matrix” failures.

Updating GitOps manifests

After images are built, each matrix job triggers update-gitops-manifests.yaml via gh workflow run. That workflow:

  1. Accepts service, version, and environment inputs.
  2. Installs Task through a reusable composite action.
  3. Runs task utils:update-image-tags to search deploy/kubernetes/ for files containing # staging_services/node/api-node (or similar markers) and updates their image tags.
  4. Generates descriptive commit messages (chore: update staging services/node/api-node to 1.2.3 [skip ci]).
  5. Uses a custom task utils:git-commit-push helper that retries on conflicts, ensuring concurrent runs eventually merge back to main.
  6. Applies concurrency controls (concurrency.group = <workflow>-<env>-<service>) so only one deployment per service runs at a time.

Because the workflow mutates the default branch, we skip Act during local testing for these steps and rely on remote runs for validation.