name: Build & push images # Build the SERVER (API + SPA) and VISION (ANPR) container images and push them to the # house Gitea registry, tagged by BRANCH + short SHA (branch-aware: dev→:dev, stage→:stage, # main→:main). Separate from ci.yml (checks-only) and release.yml (tag-only desktop bundle). # Mirrors the house pattern (cf. trm/processor build.yml). See # wiki/decisions/container-deployment.md and fleet-deployment-komodo.md (dev→stage→main tiers). on: push: branches: [dev, stage, main] paths: - 'apps/server/**' - 'apps/web/**' - 'apps/vision/**' - 'packages/**' - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - 'turbo.json' - 'docker-compose*.yml' - '.dockerignore' - '.gitea/workflows/build-images.yml' workflow_dispatch: env: REGISTRY: git.infra.msai.al/mca/parking_solution jobs: images: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Node 22 uses: actions/setup-node@v4 with: node-version: 22 - name: Enable pnpm run: corepack enable && corepack prepare pnpm@10.24.0 --activate - name: Install dependencies run: pnpm install --frozen-lockfile - name: Set up uv (for @parking/vision checks) # Install uv via its official standalone script rather than a third-party action — # the Gitea runner can't reliably resolve astral-sh/setup-uv. uv provisions the # pinned Python (apps/vision/.python-version) itself. Add it to PATH for later steps. run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.local/bin" >> "$GITHUB_PATH" - name: Sync vision deps working-directory: apps/vision run: uv sync --frozen # Don't publish a broken image — run the same checks as ci.yml first. - name: Build + lint + test (Turbo) run: pnpm turbo run build lint test - name: Compute tags id: meta # BRANCH = the pushed branch (dev|main); SHA = short commit. Two tags per image: # the moving branch tag + an immutable branch-SHA tag. run: | BRANCH="${GITHUB_REF_NAME}" SHA="$(echo "${GITHUB_SHA}" | cut -c1-7)" echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT" echo "sha=${SHA}" >> "$GITHUB_OUTPUT" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: driver: docker-container - name: Login to Gitea Registry uses: docker/login-action@v3 with: registry: git.infra.msai.al username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Build & push SERVER (API + SPA) uses: docker/build-push-action@v5 with: context: . file: apps/server/Dockerfile push: true tags: | ${{ env.REGISTRY }}/parking-server:${{ steps.meta.outputs.branch }} ${{ env.REGISTRY }}/parking-server:${{ steps.meta.outputs.branch }}-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.REGISTRY }}/parking-server:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/parking-server:buildcache,mode=max - name: Build & push VISION (ANPR) uses: docker/build-push-action@v5 with: context: apps/vision file: apps/vision/Dockerfile push: true tags: | ${{ env.REGISTRY }}/parking-vision:${{ steps.meta.outputs.branch }} ${{ env.REGISTRY }}/parking-vision:${{ steps.meta.outputs.branch }}-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.REGISTRY }}/parking-vision:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/parking-vision:buildcache,mode=max # Optional: trigger a Komodo stack redeploy (cf. trm/processor). Enable by setting the # KOMODO_* secrets; left guarded so it no-ops until the parking stack is wired. - name: Trigger Komodo redeploy if: success() && vars.KOMODO_ENABLED == 'true' env: URL: ${{ secrets.KOMODO_STACK_WEBHOOK_URL }} SECRET: ${{ secrets.KOMODO_WEBHOOK_SECRET }} run: | body="{\"ref\":\"refs/heads/${GITHUB_REF_NAME}\"}" sig=$(printf '%s' "$body" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}') curl -fsS -X POST \ -H 'Content-Type: application/json' \ -H "X-Hub-Signature-256: sha256=$sig" \ -d "$body" \ "$URL"