Files
gstack/.github/workflows/version-gate.yml
T
Garry Tanandcapy-ai[bot] c03f185d15 v1.92.21.0 ci: blobless clones on the PR and train path, fail-loud history reads (GSTA-203 PR 5) (#3713)
* ci: blobless clones on the PR and train path, fail-loud history reads (GSTA-203 PR 5)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* changelog: GSTA-203 PR 5 fragment

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: tree-only merge-base diff in the Version Gate; ls-tree --full-tree in both history readers

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ci: keep the route and backstop policy reads inline (git and jq only); docs follow

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: base CHANGELOG read in readFragments fails loudly; history readers try git show first

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: HISTORY_READ_FAILED from gstack-restamp and ship-queue land

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-01 09:19:25 +00:00

103 lines
4.3 KiB
YAML

name: Version Gate
# Every PR: under changelog_fragments a PR that touches no release file must
# still prove it carries a fragment (docs/ship-policy.md#changelog-fragments).
on:
pull_request:
branches: [main]
concurrency:
group: version-gate-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
check:
name: Check VERSION is not stale vs queue
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
pull-requests: read
steps:
- name: Checkout PR head
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
# Blobless: full history with file contents fetched on demand; the
# reads below fail loudly when a fetch fails (.github/scripts/history-read.sh).
filter: blob:none
ref: ${{ github.event.pull_request.head.sha }}
# The head's release_tool runs inside the gate (lib/version-gate-train.ts);
# no token may sit in the checkout it stages. The base fetch below is public.
persist-credentials: false
# The gate's own code comes from the PR's merge commit (github.sha): a PR
# that edits the gate runs its edit, and an open PR picks up a gate fix
# on main at its next pull_request event (reopen or push), not on a re-run.
- name: Checkout gate code (merge commit)
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.sha }}
path: .version-gate
persist-credentials: false
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
- name: Read versions
id: versions
run: |
set -euo pipefail
PR_VERSION=$(cat VERSION | tr -d '[:space:]')
BASE_REF="${{ github.event.pull_request.base.ref }}"
for try in 1 2 3; do
git fetch origin "$BASE_REF" --quiet && break
if [ "$try" = 3 ]; then echo "::error::git fetch origin $BASE_REF failed 3 times ($(git --version)). Fix: see docs/troubleshooting.md#history-read-failed (HISTORY_READ_FAILED)"; exit 1; fi
sleep $((try * 2))
done
BASE_VERSION=$(bash .version-gate/.github/scripts/history-read.sh "origin/$BASE_REF" VERSION --absent 0.0.0.0 | tr -d '[:space:]')
{
echo "pr_version=$PR_VERSION"
echo "base_version=$BASE_VERSION"
echo "base_ref=$BASE_REF"
} >> "$GITHUB_OUTPUT"
- name: Detect bump level
id: bump
run: |
LEVEL=$(bun run scripts/detect-bump.ts "${{ steps.versions.outputs.base_version }}" "${{ steps.versions.outputs.pr_version }}")
echo "level=$LEVEL" >> "$GITHUB_OUTPUT"
- name: Query queue (util) — fail-open on error
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set +e
bun run bin/gstack-next-version \
--base "${{ steps.versions.outputs.base_ref }}" \
--bump "${{ steps.bump.outputs.level }}" \
--current-version "${{ steps.versions.outputs.base_version }}" \
--workspace-root null \
--exclude-pr "${{ github.event.pull_request.number }}" \
> next.json 2> next.err
RC=$?
if [ "$RC" != "0" ] || [ ! -s next.json ]; then
echo '{"offline":true}' > next.json
echo "::warning::util exit=$RC — failing open. stderr:"
cat next.err || true
fi
- name: Compare PR VERSION to next free slot
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_VERSION: ${{ steps.versions.outputs.pr_version }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
BASE_REF: ${{ steps.versions.outputs.base_ref }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if ! PR_CHANGED_FILES=$(gh api --paginate "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" --jq '.[].filename'); then PR_CHANGED_FILES=""; fi
export PR_CHANGED_FILES
bun --no-env-file --config=/dev/null run .version-gate/scripts/compare-pr-version.ts next.json "${{ github.event.pull_request.number }}"