Files
missions/_docs/02_document/deployment/ci_cd_pipeline.md
T
Oleksandr Bezdieniezhnykh 7025f4d075 refactor: enhance JWT authentication and CORS configuration
Updated JWT authentication to use configuration values instead of hardcoded secrets, improving security and flexibility. Enhanced CORS policy to conditionally allow origins based on configuration settings, with logging for permissive defaults. Updated README to reflect project renaming and clarify service context.
2026-05-14 19:48:25 +03:00

5.4 KiB
Raw Blame History

CI / CD Pipeline

NOTE (forward-looking): image registry path reflects the post-rename state. Today's pipeline pushes azaion/flights:${BRANCH}-arm. Rename tracked under Jira AZ-EPIC child B10 (Dockerfile + Woodpecker + suite compose).

Source

./.woodpecker/build-arm.yml (single CI file). One job: build + push the container image.

when:
  event: [push, manual]
  branch: [dev, stage, main]

labels:
  platform: arm64

steps:
  - name: build-push
    image: docker
    environment:
      REGISTRY_HOST:  { from_secret: registry_host }
      REGISTRY_USER:  { from_secret: registry_user }
      REGISTRY_TOKEN: { from_secret: registry_token }
    commands:
      - echo "$REGISTRY_TOKEN" | docker login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin
      - export TAG=${CI_COMMIT_BRANCH}-arm
      - export BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
      - |
        docker build -f Dockerfile \
          --build-arg CI_COMMIT_SHA=$CI_COMMIT_SHA \
          --label org.opencontainers.image.revision=$CI_COMMIT_SHA \
          --label org.opencontainers.image.created=$BUILD_DATE \
          --label org.opencontainers.image.source=$CI_REPO_URL \
          -t $REGISTRY_HOST/azaion/missions:$TAG .                  # post-B10
      - docker push $REGISTRY_HOST/azaion/missions:$TAG             # post-B10
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Triggers

Trigger Branch filter Outcome
push dev, stage, main Build + push the corresponding ${BRANCH}-arm image tag
manual any of dev, stage, main Same as push — used for rebuilding without a code change (e.g., after a base-image security patch)
pull_request, other branches Not built today. Feature branches do not produce images

Runner / platform

  • labels: platform: arm64 — the pipeline runs on an ARM64-labeled Woodpecker runner. The build is therefore native for the ARM64 image variant (no QEMU). The Dockerfile's --platform=$BUILDPLATFORM for the build stage ensures the SDK image matches the runner's architecture.
  • For the (currently absent) AMD64 variant a second pipeline file (build-amd.yml) on an AMD64-labeled runner would be the natural pattern.

Secrets

Secret Source Purpose
registry_host Woodpecker secret store Hostname of the suite's container registry (Caddy-fronted Gitea Container Registry per ../../../suite/_docs/00_top_level_architecture.md)
registry_user Woodpecker secret store Service account that has push rights to azaion/missions
registry_token Woodpecker secret store Personal access token for the service account

docker login is piped via stdin (--password-stdin) — token never lands on the command line or in process listings.

OCI labels emitted

Three standard OCI labels are baked into every published image:

Label Value Source
org.opencontainers.image.revision $CI_COMMIT_SHA Git commit driving this build
org.opencontainers.image.created $BUILD_DATE (ISO 8601 UTC) date -u +%Y-%m-%dT%H:%M:%SZ at build time
org.opencontainers.image.source $CI_REPO_URL Suite Gitea repo URL

These let docker inspect answer "which commit and when?" without consulting the registry's metadata.

What the pipeline does NOT do (carry-forward improvements)

  • No dotnet test step — there is no test project in the repo today. Tracked in ../../../suite/_docs/_process_leftovers/2026-04-22_ci-unit-test-lane-missing-projects.md. When a tests/Azaion.Missions.Tests/ sibling lands (autodev existing-code Steps 57), the natural insert is a name: test step that runs dotnet test --collect "XPlat Code Coverage" against the build before the docker step.
  • No security scan — neither container scanning (Trivy / Grype on the published image) nor source scanning (CodeQL / Semgrep) is wired. Suite-level concern; out of this Epic.
  • No migration check — the migrator runs at app startup (Flow F6). A CI-time "does the migrator's DDL parse cleanly against an empty PG" smoke test is the next-cheapest safety net once tests exist.
  • No SBOMdocker buildx --sbom would surface base-image CVEs at registry-push time. Carry-forward.
  • No image-signing — Notary v2 / cosign is not wired. Carry-forward; suite-wide concern.
  • No multi-arch matrix — only arm64 builds today (see containerization.md § Multi-arch limitation).

Pipeline run-time characteristics

  • Single step, single image. Typical wall-clock time: 25 minutes on the suite's ARM64 runner (most of it dotnet publish + the runtime image layer pull).
  • No caching layer between builds today. dotnet restore re-downloads NuGet packages on every run. A persistent ~/.nuget volume on the runner would shave ~30 seconds per build.

Failure modes

Failure Symptom in Woodpecker Recovery
dotnet publish fails Build step fails with compilation errors Standard — fix source, push again
Registry login fails (rotated token) docker login exits non-zero Rotate registry_token in Woodpecker secrets
Registry push rate-limited docker push 429 Retry the manual run; rare in practice with Gitea-hosted registry
ARM64 runner offline Pipeline waits in queue Bring the runner back online; pipeline auto-resumes