Skip to content

Commit ee9f620

Browse files
authored
feat(deploy): align Flux HelmReleases with build path + add image-tag PR bridge (#1097)
The build job in `deploy-azd.yml` already pushes images to the root-prefix ACR path (`<acr>/<svc>:<sha>`) but every HelmRelease was still pinned to the legacy `<acr>/holiday-peak-hub/<svc>-dev:azd-deploy-<ts>` path that predates the Pattern A Flux migration (PR #1089). Flux therefore never saw new images and the cluster kept running the April 4 build, even after the direct-model migration merged. Closes the gap: * Re-points all 27 HelmReleases (26 agents + crud-service) at the real build path, pinned to `808d48227b08` — the current `main` SHA — so Flux reconciles the freshly tested images on merge. * Adds an `open-image-tag-bump-pr` job that consumes the `tested-image-*` artifacts the build stage already produces, edits `.kubernetes/releases/{agents,crud}/<svc>.yaml` via `scripts/ci/update_helmrelease_image.py` (a surgical line-level edit, 10/10 pylint, byte-identical idempotent), and opens (or refreshes) a `chore/image-bump-<env>-<sha12>` PR against the default branch. The bridge respects the GH013 main-branch ruleset because it never pushes to main itself — it just files a normal PR that the operator merges. * Replaces the stale `ImageUpdateAutomation` follow-up comment with the actual implementation notes. Refs ADR-017 (Pattern A Flux GitOps), PR #1089, PR #1093 (#990 direct-model migration whose images are the ones being rolled out by this change).
1 parent 808d482 commit ee9f620

29 files changed

Lines changed: 272 additions & 62 deletions

.github/workflows/deploy-azd.yml

Lines changed: 124 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,14 +2717,130 @@ jobs:
27172717
path: .kubernetes/rendered/${{ matrix.service }}/all.yaml
27182718
retention-days: 1
27192719

2720-
# NOTE (ADR-017 amendment, Pattern A): the previous `commit-rendered-manifests`
2721-
# job was deleted because it pushed bot-generated manifests directly to
2722-
# `refs/heads/main`, which is rejected by the `main-governance-baseline`
2723-
# ruleset (GH013). Flux now reconciles HelmRelease CRDs from
2724-
# `.kubernetes/releases/{crud,agents}` and the helm-controller renders the
2725-
# chart in-cluster on every reconciliation, so no workflow push to main is
2726-
# ever required. Image tag updates remain a follow-up (planned: Flux
2727-
# ImageUpdateAutomation with PR bridge).
2720+
# ADR-017 amendment, Pattern A — image-tag PR bridge.
2721+
#
2722+
# The previous ``commit-rendered-manifests`` job pushed bot-generated YAML
2723+
# straight at ``refs/heads/main``, which the ``main-governance-baseline``
2724+
# ruleset (GH013) rejects. Flux now reconciles HelmRelease CRDs from
2725+
# ``.kubernetes/releases/{crud,agents}`` and the helm-controller renders the
2726+
# chart in-cluster on every reconciliation. To close the loop without
2727+
# pushing to ``main``, the build emits ``tested-image-*`` artifacts holding
2728+
# the immutable ACR reference for each service. The job below consumes those
2729+
# artifacts and opens a single image-bump PR per deploy, so Flux picks up
2730+
# the new images on the next reconcile after the PR is merged.
2731+
open-image-tag-bump-pr:
2732+
runs-on: ubuntu-latest
2733+
# Run only when at least one of the deploy matrices actually produced new
2734+
# tested images and the run was not cancelled. The bridge intentionally
2735+
# does NOT depend on ``success()`` of every deploy slot — partial deploys
2736+
# (e.g., a single matrix entry flaked) should still surface the bumps for
2737+
# the services that did succeed.
2738+
if: ${{ always() && !cancelled() && !inputs.uiOnly && (needs.deploy-crud.result == 'success' || needs.deploy-agents.result == 'success') }}
2739+
needs:
2740+
- deploy-crud
2741+
- deploy-agents
2742+
- detect-changes
2743+
permissions:
2744+
contents: write
2745+
pull-requests: write
2746+
env:
2747+
DEPLOY_ENV: ${{ inputs.environment }}
2748+
# ``env.DEPLOY_SOURCE_SHA`` is not visible inside job-level ``env:`` so
2749+
# we re-derive the same expression used at the workflow level.
2750+
DEPLOY_SHA: ${{ inputs.sourceSha != '' && inputs.sourceSha || github.sha }}
2751+
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
2752+
steps:
2753+
- name: Checkout default branch
2754+
uses: actions/checkout@v4
2755+
with:
2756+
# The bridge edits Flux source-of-truth files on the default branch
2757+
# so the PR diff reflects only the image bumps from this deploy.
2758+
ref: ${{ github.event.repository.default_branch }}
2759+
fetch-depth: 0
2760+
persist-credentials: true
2761+
2762+
- name: Download tested-image artifacts
2763+
uses: actions/download-artifact@v4
2764+
with:
2765+
path: ${{ runner.temp }}/tested-images
2766+
pattern: tested-image-*
2767+
2768+
- name: Apply HelmRelease image bumps
2769+
id: update
2770+
shell: bash
2771+
env:
2772+
RUNNER_TEMP: ${{ runner.temp }}
2773+
run: |
2774+
set -euo pipefail
2775+
changed=0
2776+
declare -a updated_services=()
2777+
for dir in "${RUNNER_TEMP}/tested-images"/tested-image-*; do
2778+
[ -d "$dir" ] || continue
2779+
svc=$(basename "$dir" | sed 's/^tested-image-//')
2780+
ref_file="$dir/image-ref.txt"
2781+
if [ ! -f "$ref_file" ]; then
2782+
echo "::warning::no image-ref.txt for ${svc} — skipping"
2783+
continue
2784+
fi
2785+
image_ref=$(tr -d '\r\n' < "$ref_file")
2786+
# image_ref shape: ``<registry>/<svc>@sha256:<digest>``. The
2787+
# registry path is the durable identifier; the tag is the SHA we
2788+
# already pushed alongside the digest in ``build-aks-images``.
2789+
repo="${image_ref%@*}"
2790+
tag="${DEPLOY_SHA}"
2791+
if [ "$svc" = "crud-service" ]; then
2792+
target=".kubernetes/releases/crud/${svc}.yaml"
2793+
else
2794+
target=".kubernetes/releases/agents/${svc}.yaml"
2795+
fi
2796+
if [ ! -f "$target" ]; then
2797+
echo "::warning::no HelmRelease found for ${svc} at ${target}"
2798+
continue
2799+
fi
2800+
python3 scripts/ci/update_helmrelease_image.py "$target" "$repo" "$tag"
2801+
if ! git diff --quiet -- "$target"; then
2802+
updated_services+=("$svc")
2803+
changed=$((changed + 1))
2804+
fi
2805+
done
2806+
echo "changed_count=${changed}" >> "$GITHUB_OUTPUT"
2807+
if [ "${changed}" -gt 0 ]; then
2808+
printf 'updated_services=%s\n' "${updated_services[*]}" >> "$GITHUB_OUTPUT"
2809+
fi
2810+
2811+
- name: Open or refresh PR
2812+
if: ${{ steps.update.outputs.changed_count != '0' }}
2813+
shell: bash
2814+
env:
2815+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2816+
UPDATED_SERVICES: ${{ steps.update.outputs.updated_services }}
2817+
run: |
2818+
set -euo pipefail
2819+
short="${DEPLOY_SHA:0:12}"
2820+
branch="chore/image-bump-${DEPLOY_ENV}-${short}"
2821+
git config user.name "github-actions[bot]"
2822+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
2823+
git switch -c "$branch"
2824+
git add .kubernetes/releases
2825+
git commit -m "chore(deploy): bump ${DEPLOY_ENV} HelmRelease image tags to ${short}" \
2826+
-m "Triggered by deploy-azd run ${{ github.run_id }}. Services: ${UPDATED_SERVICES}. Merge to roll new images via Flux reconciliation."
2827+
git push -f origin "$branch"
2828+
existing=$(gh pr list --state open --head "$branch" --base "${DEFAULT_BRANCH:-main}" --json number --jq '.[0].number // ""' 2>/dev/null || echo '')
2829+
if [ -z "${existing}" ]; then
2830+
gh pr create \
2831+
--base "${DEFAULT_BRANCH:-main}" \
2832+
--head "$branch" \
2833+
--title "chore(deploy): bump ${DEPLOY_ENV} HelmRelease image tags to ${short}" \
2834+
--body "Auto-generated by [deploy-azd run ${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
2835+
2836+
Updates HelmRelease \`image.repository\` and \`image.tag\` to the freshly built & tested images at SHA \`${DEPLOY_SHA}\` for environment **${DEPLOY_ENV}**.
2837+
2838+
**Services updated (${{ steps.update.outputs.changed_count }}):** ${UPDATED_SERVICES}
2839+
2840+
Merging this PR triggers Flux reconciliation, which rolls the new images. No additional action required after merge."
2841+
else
2842+
echo "PR #${existing} already open against ${branch}; force-pushed branch HEAD."
2843+
fi
27282844
27292845
wait-flux-reconciliation:
27302846
runs-on: ubuntu-latest

.kubernetes/releases/agents/crm-campaign-intelligence.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/crm-campaign-intelligence-dev
33-
tag: azd-deploy-1775344528
32+
repository: holidaypeakhub405devacr.azurecr.io/crm-campaign-intelligence
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/crm-profile-aggregation.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/crm-profile-aggregation-dev
33-
tag: azd-deploy-1775344626
32+
repository: holidaypeakhub405devacr.azurecr.io/crm-profile-aggregation
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/crm-segmentation-personalization.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/crm-segmentation-personalization-dev
33-
tag: azd-deploy-1775344793
32+
repository: holidaypeakhub405devacr.azurecr.io/crm-segmentation-personalization
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/crm-support-assistance.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/crm-support-assistance-dev
33-
tag: azd-deploy-1775345018
32+
repository: holidaypeakhub405devacr.azurecr.io/crm-support-assistance
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/ecommerce-cart-intelligence.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/ecommerce-cart-intelligence-dev
33-
tag: azd-deploy-1775345183
32+
repository: holidaypeakhub405devacr.azurecr.io/ecommerce-cart-intelligence
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/ecommerce-catalog-search.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ spec:
3232
clientId: "036f4fd2-9093-4948-b0dd-beb5c87aa6dc"
3333

3434
image:
35-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/ecommerce-catalog-search-dev
36-
tag: deterministic-fanout-20260420-190823
35+
repository: holidaypeakhub405devacr.azurecr.io/ecommerce-catalog-search
36+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3737

3838
replicaCount: 1
3939

.kubernetes/releases/agents/ecommerce-checkout-support.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/ecommerce-checkout-support-dev
33-
tag: azd-deploy-1775345620
32+
repository: holidaypeakhub405devacr.azurecr.io/ecommerce-checkout-support
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/ecommerce-order-status.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/ecommerce-order-status-dev
33-
tag: azd-deploy-1775345850
32+
repository: holidaypeakhub405devacr.azurecr.io/ecommerce-order-status
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

.kubernetes/releases/agents/ecommerce-product-detail-enrichment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ spec:
2929
create: true
3030
clientId: 036f4fd2-9093-4948-b0dd-beb5c87aa6dc
3131
image:
32-
repository: holidaypeakhub405devacr.azurecr.io/holiday-peak-hub/ecommerce-product-detail-enrichment-dev
33-
tag: azd-deploy-1775346091
32+
repository: holidaypeakhub405devacr.azurecr.io/ecommerce-product-detail-enrichment
33+
tag: 808d48227b08ceaf9f2d820010e02edf5250b57f
3434
replicaCount: 2
3535
resources:
3636
limits:

0 commit comments

Comments
 (0)