From 3834e45b665e7811104db32a3a4f585d90370fe8 Mon Sep 17 00:00:00 2001 From: "groombook-engineer[bot]" <269742240+groombook-engineer[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 23:19:29 +0000 Subject: [PATCH] feat: add cd job to update groombook/infra image tags on main merge (GRO-178) (#147) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add cd job to update groombook/infra image tags on main merge (GRO-178) - Adds `cd` job that runs after `docker` on main branch pushes only - Uses tibdex/github-app-token to get infra repo push token - Updates image tags in apps/groombook/base/{api,web,migrate-job,seed-job}.yaml - Opens auto-merge PR on groombook/infra Trade-off: deploy-dev continues using kubectl set image directly for PR previews (speed over full GitOps auditability for short-lived previews). Co-Authored-By: Paperclip * fix: correct --head branch format and use --enable-auto-merge (GRO-178) CTO review fixes: - Remove bogus "groombook-engineer[bot]:" prefix from --head — gh pr create does not use owner:branch syntax when pushing from a cloned repo; just the branch name is needed - Replace invalid --auto-merges-branch=main flag with --enable-auto-merge (valid gh flag that activates repo auto-merge) Co-Authored-By: Paperclip * fix: broaden annotation sed pattern, fix PR body link, remove error swallowing (GRO-178) CTO review remaining fixes: - Annotation sed pattern: broaden [a-f0-9]* to [a-zA-Z0-9-]* since migrate-job and seed-job use "groXXX" suffixes (e.g. "2026.03.28-gro177") which contain non-hex letters - PR body link: fix /d50d9792/issues/GRO-178 → /GRO/issues/GRO-178 - Remove error swallowing: "|| echo" was hiding PR creation failures; let the step fail naturally so CI catches it Co-Authored-By: Paperclip * fix(cd): split --enable-auto-merge into separate merge command CTO review fix: gh pr create does not support --enable-auto-merge flag. Split into two commands: create PR, then gh pr merge with --auto --merge. Co-Authored-By: Paperclip --------- Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com> Co-authored-by: Paperclip Co-authored-by: Flea Flicker Co-authored-by: groombook-engineer[bot] <269742240+groombook-engineer[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 935ab67..6064d9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,6 +111,8 @@ jobs: name: Build & Push Docker Images runs-on: ubuntu-latest needs: [build, e2e] + outputs: + tag: ${{ steps.version.outputs.tag }} permissions: contents: read packages: write @@ -268,3 +270,79 @@ jobs: 'Ready for UAT validation.' ].join('\n') }); + + cd: + name: Update Infra Image Tags + runs-on: ubuntu-latest + needs: [docker] + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + permissions: + contents: write + pull-requests: write + steps: + - name: Generate infra repo token + id: infra-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ vars.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - name: Clone groombook/infra + run: | + git clone https://x-access-token:${{ steps.infra-token.outputs.token }}@github.com/groombook/infra.git /tmp/infra + + - name: Update image tags + env: + TAG: ${{ needs.docker.outputs.tag }} + run: | + if [ -z "$TAG" ]; then + TAG="$(date -u +%Y.%m.%d)-${GITHUB_SHA::7}" + fi + echo "Updating image tags to: $TAG" + + cd /tmp/infra + + # Update api.yaml + sed -i "s|ghcr.io/groombook/api:[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*|ghcr.io/groombook/api:${TAG}|g" apps/groombook/base/api.yaml + sed -i "s|groombook.dev/image-version: \"[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*\"|groombook.dev/image-version: \"${TAG}\"|g" apps/groombook/base/api.yaml + + # Update web.yaml + sed -i "s|ghcr.io/groombook/web:[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*|ghcr.io/groombook/web:${TAG}|g" apps/groombook/base/web.yaml + sed -i "s|groombook.dev/image-version: \"[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*\"|groombook.dev/image-version: \"${TAG}\"|g" apps/groombook/base/web.yaml + + # Update migrate-job.yaml + sed -i "s|ghcr.io/groombook/migrate:[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*|ghcr.io/groombook/migrate:${TAG}|g" apps/groombook/base/migrate-job.yaml + sed -i "s|groombook.app/deploy-version: \"[a-zA-Z0-9-]*\"|groombook.app/deploy-version: \"${TAG}\"|g" apps/groombook/base/migrate-job.yaml + + # Update seed-job.yaml + sed -i "s|ghcr.io/groombook/seed:[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-[a-f0-9]*|ghcr.io/groombook/seed:${TAG}|g" apps/groombook/base/seed-job.yaml + sed -i "s|groombook.app/deploy-version: \"[a-zA-Z0-9-]*\"|groombook.app/deploy-version: \"${TAG}\"|g" apps/groombook/base/seed-job.yaml + + git -C /tmp/infra diff --stat + + - name: Create PR on groombook/infra + env: + TAG: ${{ needs.docker.outputs.tag }} + GH_TOKEN: ${{ steps.infra-token.outputs.token }} + run: | + if [ -z "$TAG" ]; then + TAG="$(date -u +%Y.%m.%d)-${GITHUB_SHA::7}" + fi + + cd /tmp/infra + git config user.name "groombook-engineer[bot]" + git config user.email "3141748+groombook-engineer[bot]@users.noreply.github.com" + git checkout -b "chore/update-image-tags-${TAG}" + git add apps/groombook/base/ + git commit -m "chore: update image tags to ${TAG}" + + git push -u origin "chore/update-image-tags-${TAG}" + + # Create PR with auto-merge + PR_URL=$(gh pr create \ + --repo groombook/infra \ + --base main \ + --head "chore/update-image-tags-${TAG}" \ + --title "chore: update image tags to ${TAG}" \ + --body "[GRO-178](/GRO/issues/GRO-178) — automated image tag update from main merge") + gh pr merge "$PR_URL" --auto --merge