#!/usr/bin/env bash # notify-chart-bump.sh — bump appVersion on tnd-zddc-chart and push. # # Replaces the inline shell that previously lived in # .forgejo/workflows/notify-chart-dev.yml and the notify-chart-prod # job in deploy-release.yml. Extracting the logic to a real script # means we can: # 1. test it locally without going through the runner # (CHART_FORGEJO_TOKEN=$FORGEJO_TOKEN ./.forgejo/scripts/notify-chart-bump.sh beta) # 2. invoke manually as an escape hatch when CI is broken # 3. avoid runner-version shell-wrapper quirks (e.g. Forgejo # runner v12.9.0 reporting phantom SIGPIPE on bare echo + set -eu) # # Usage: # notify-chart-bump.sh beta # Bump chart's develop branch with appVersion = -beta- # (next-stable = max(zddc-server-v* tag) + 1). # Self-skips if HEAD has a zddc-server-v* tag (the stable workflow # owns the bump in that case). # # notify-chart-bump.sh stable VERSION # Bump chart's main + develop branches with appVersion = VERSION. # Called from deploy-release.yml's notify-chart-prod job, where # VERSION = "${GITHUB_REF#refs/tags/zddc-server-v}". # # Requires: # - run from the ZDDC repo root, with full git history (all tags) # - $CHART_FORGEJO_TOKEN with repo:write on BMCD/tnd-zddc-chart set -eu CHANNEL="${1:?usage: $(basename "$0") [VERSION]}" EXPLICIT_VERSION="${2:-}" if [ -z "${CHART_FORGEJO_TOKEN:-}" ]; then echo "::error::CHART_FORGEJO_TOKEN env not set" >&2 exit 1 fi CHART_REPO="git.varasys.io/BMCD/tnd-zddc-chart.git" CHART_URL="https://oauth2:${CHART_FORGEJO_TOKEN}@${CHART_REPO}" case "$CHANNEL" in beta) # Self-skip if HEAD has a stable tag — prod workflow owns the # bump in that case (avoids both workflows racing on develop). STABLE_TAGS=$(git tag --points-at HEAD --list 'zddc-server-v*') if [ -n "$STABLE_TAGS" ]; then echo "HEAD has stable tag ($STABLE_TAGS) — stable workflow handles chart bump; skipping" exit 0 fi LATEST_STABLE=$(git tag --list 'zddc-server-v*' --sort=-v:refname | head -1) if [ -z "$LATEST_STABLE" ]; then echo "::error::no zddc-server-v* tags exist; cannot derive next-stable target" >&2 exit 1 fi MAJ=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f1) MIN=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f2) PAT=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f3) NEXT_STABLE="$MAJ.$MIN.$((PAT + 1))" # Use the SHA baked into the embedded files (third field of # versions.txt: "= · · "), NOT # `git rev-parse HEAD`. This matters because `./build beta` # runs locally at HEAD=N, then the operator commits the # generated embed files as N+1; the embed label encodes N # while git HEAD on push is N+1. If we used N+1 here, the # chart's appVersion (N+1) wouldn't match the build label # users see in the served website (N) — confusing on its # face when triaging "is this image current?". Reading from # versions.txt guarantees they line up. VERSIONS_FILE="zddc/internal/apps/embedded/versions.txt" SHORT_SHA=$(awk -F' · ' '/^[a-z]+=/ { print $NF; exit }' "$VERSIONS_FILE" \ | tr -d '[:space:]') if [ -z "$SHORT_SHA" ]; then echo "::error::could not parse SHA from $VERSIONS_FILE" >&2 cat "$VERSIONS_FILE" >&2 exit 1 fi TARGET_VERSION="${NEXT_STABLE}-beta-${SHORT_SHA}" BRANCHES="develop" TRIGGER_DESC="ZDDC beta cut" TRAILER="Triggered by push to git.varasys.io/VARASYS/ZDDC main with embedded/* changes (a ./build beta cut). Bumps appVersion so the dev Docker image is tagged zddc:$TARGET_VERSION, ensuring kubelet pulls a fresh image on the next helm upgrade." ;; stable) if [ -z "$EXPLICIT_VERSION" ]; then echo "::error::stable channel requires an explicit VERSION arg" >&2 exit 1 fi TARGET_VERSION="$EXPLICIT_VERSION" # Bump both branches: main fires BMCD pipeline-prod (prod image # rebuild), develop fires pipeline-dev so dev follows stable # whenever no beta is active. BRANCHES="main develop" TRIGGER_DESC="ZDDC stable cut" TRAILER="Triggered by zddc-server-v$TARGET_VERSION tag push on git.varasys.io/VARASYS/ZDDC. Bumps appVersion so prod (and dev tracking stable) rebuild against the new ZDDC stable." ;; *) echo "::error::unknown channel '$CHANNEL' (expected: beta | stable)" >&2 exit 1 ;; esac echo "Bumping tnd-zddc-chart appVersion → $TARGET_VERSION" echo "Branches: $BRANCHES (HEAD=$(git rev-parse HEAD))" TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT cd "$TMP" for BRANCH in $BRANCHES; do echo "" echo "=== bumping $BRANCH ===" rm -rf tnd-zddc-chart git clone --depth=20 --branch="$BRANCH" "$CHART_URL" cd tnd-zddc-chart CURRENT=$(grep '^appVersion:' chart/Chart.yaml \ | sed -E 's/^appVersion: *"?([^"]*)"?.*/\1/') if [ "$CURRENT" = "$TARGET_VERSION" ]; then echo " $BRANCH already at $TARGET_VERSION; skipping" cd .. continue fi sed -i "s/^appVersion: .*/appVersion: \"$TARGET_VERSION\"/" chart/Chart.yaml OLD_CHART_VER=$(grep '^version:' chart/Chart.yaml | awk '{print $2}') MAJC=$(echo "$OLD_CHART_VER" | cut -d. -f1) MINC=$(echo "$OLD_CHART_VER" | cut -d. -f2) PATC=$(echo "$OLD_CHART_VER" | cut -d. -f3) # Chart-version bump strategy: # stable cut → MINOR++, PATCH=0 (e.g. 0.2.7 → 0.3.0) # beta cut → PATCH++ (e.g. 0.3.0 → 0.3.1) # This keeps the patch number bounded (≈ #betas-per-stable, not # all-time), while staying monotonically increasing — JFrog chart # repos reject duplicate chart-version numbers, so a literal # "reset to 0.2.0" cycle would break uploads after the first # stable cut. The actual zddc-server version lives in appVersion; # chart version is just JFrog packaging metadata. if [ "$CHANNEL" = "stable" ]; then NEW_CHART_VER="$MAJC.$((MINC + 1)).0" else NEW_CHART_VER="$MAJC.$MINC.$((PATC + 1))" fi sed -i "s/^version: .*/version: $NEW_CHART_VER/" chart/Chart.yaml echo " appVersion: $CURRENT → $TARGET_VERSION" echo " version: $OLD_CHART_VER → $NEW_CHART_VER" git config user.name "ZDDC Release Bot" git config user.email "noreply@zddc.varasys.io" git add chart/Chart.yaml git commit \ -m "chore(chart): auto-bump appVersion to $TARGET_VERSION ($TRIGGER_DESC)" \ -m "$TRAILER" \ -m "Auto-generated by .forgejo/scripts/notify-chart-bump.sh. The next ZDDC beta or stable cut will overwrite this." git push origin "$BRANCH" echo " pushed $BRANCH" cd .. done echo "" echo "Done."