|
| 1 | +name: Helm appVersion |
| 2 | + |
| 3 | +# Pre-merge half of the appVersion gate. The post-merge half lives in the |
| 4 | +# publish job of helm.yml, which refuses to publish a chart whose appVersion |
| 5 | +# lags the latest release -- but it runs only on a push to main, so it can only |
| 6 | +# ever report the mistake after the release is already merged, with the chart |
| 7 | +# for that release left unpublished until someone bumps by hand. |
| 8 | +# |
| 9 | +# A release PR knows the version it is cutting before the merge: the main-branch |
| 10 | +# merge commit message is the PR title, and `vX.Y.Z:` in that message is exactly |
| 11 | +# what detect-version in ci.yml turns into the release tag. So on a release PR |
| 12 | +# the target is knowable up front and the check is an equality, not the |
| 13 | +# lags-behind comparison the publish job is stuck with. |
| 14 | +# |
| 15 | +# Deliberately its own workflow rather than a job in helm.yml: paths filters |
| 16 | +# apply per workflow, and helm.yml only runs when chart files change. A release |
| 17 | +# PR that forgets appVersion is very often a release PR that touches no chart |
| 18 | +# file at all, which is precisely the case that must not slip through. |
| 19 | + |
| 20 | +on: |
| 21 | + pull_request: |
| 22 | + # `edited` matters as much as `synchronize`: the version being cut lives in |
| 23 | + # the PR title, so retitling a PR changes what this check asserts. |
| 24 | + types: [opened, edited, reopened, synchronize] |
| 25 | + branches: [main] |
| 26 | + |
| 27 | +concurrency: |
| 28 | + group: helm-release-appversion-${{ github.event.pull_request.number }} |
| 29 | + cancel-in-progress: true |
| 30 | + |
| 31 | +permissions: |
| 32 | + contents: read |
| 33 | + |
| 34 | +jobs: |
| 35 | + appversion: |
| 36 | + name: Chart appVersion matches the release |
| 37 | + runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} |
| 38 | + timeout-minutes: 5 |
| 39 | + steps: |
| 40 | + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 |
| 41 | + with: |
| 42 | + # Reads two files out of the merge commit; no history, no pushes. |
| 43 | + persist-credentials: false |
| 44 | + |
| 45 | + - name: appVersion names the release this PR cuts |
| 46 | + env: |
| 47 | + # Never interpolated into the script body: a PR title is attacker-controlled text. |
| 48 | + PR_TITLE: ${{ github.event.pull_request.title }} |
| 49 | + run: | |
| 50 | + set -euo pipefail |
| 51 | +
|
| 52 | + # Same shape detect-version (ci.yml) matches on the merge commit. A PR |
| 53 | + # to main that is not a release -- a hotfix, a revert, a docs fix -- |
| 54 | + # cuts no tag, so there is nothing for appVersion to name. |
| 55 | + if ! [[ "$PR_TITLE" =~ ^(v[0-9]+\.[0-9]+\.[0-9]+): ]]; then |
| 56 | + echo "::notice::\"${PR_TITLE}\" is not a release title (vX.Y.Z: ...); nothing to check." |
| 57 | + exit 0 |
| 58 | + fi |
| 59 | + release="${BASH_REMATCH[1]}" |
| 60 | +
|
| 61 | + app_version=$(awk '/^appVersion:/ {print $2}' helm/sim/Chart.yaml | tr -d '"') |
| 62 | + chart_version=$(awk '/^version:/ {print $2}' helm/sim/Chart.yaml) |
| 63 | +
|
| 64 | + if [ "$app_version" = "$release" ]; then |
| 65 | + echo "::notice::Chart ${chart_version} ships appVersion ${app_version}, matching release ${release}." |
| 66 | + exit 0 |
| 67 | + fi |
| 68 | +
|
| 69 | + # Equality, not "not behind". An appVersion ahead of the release being |
| 70 | + # cut names an image tag that this merge will not create either, so |
| 71 | + # the chart would install into ImagePullBackOff. |
| 72 | + echo "::error::helm/sim/Chart.yaml appVersion is ${app_version}, but this PR cuts ${release}. The chart defaults its image tags to appVersion, and published chart versions are immutable, so a stale value freezes an old Sim into the chart for ${release} forever." |
| 73 | + { |
| 74 | + echo "### Chart appVersion does not match this release" |
| 75 | + echo |
| 76 | + echo "| | |" |
| 77 | + echo "| --- | --- |" |
| 78 | + echo "| Release being cut | \`${release}\` |" |
| 79 | + echo "| \`Chart.yaml\` appVersion | \`${app_version}\` |" |
| 80 | + echo "| \`Chart.yaml\` version | \`${chart_version}\` |" |
| 81 | + echo |
| 82 | + echo "Fix it on this PR's head branch:" |
| 83 | + echo |
| 84 | + echo '```bash' |
| 85 | + echo "# 1. appVersion: \"${release}\" and a SemVer bump to version: in helm/sim/Chart.yaml" |
| 86 | + echo "# 2. the image inventory embeds appVersion, so regenerate it" |
| 87 | + echo "bun run images:generate" |
| 88 | + echo '```' |
| 89 | + } >> "$GITHUB_STEP_SUMMARY" |
| 90 | + exit 1 |
0 commit comments