Merge pull request #236 from open-gsd/fix/critical-release-flow-next-aware

fix(critical): make hotfix + auto-branch next-aware (Phase 3)
This commit is contained in:
Tom Boucher
2026-05-24 17:35:12 -04:00
committed by GitHub
2 changed files with 40 additions and 15 deletions

View File

@@ -67,18 +67,31 @@ jobs:
if (e.status !== 404) throw e;
}
// Create branch from main HEAD
const mainRef = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/main',
});
// Create branch from next HEAD (the integration branch under the
// next-branch model). Fall back to main if next doesn't exist —
// covers the brief transition window when this workflow was first
// deployed and any legacy single-branch state.
let baseRef;
try {
baseRef = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/next',
});
} catch (e) {
if (e.status !== 404) throw e;
baseRef = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/main',
});
}
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `refs/heads/${branch}`,
sha: mainRef.data.object.sha,
sha: baseRef.data.object.sha,
});
await github.rest.issues.createComment({

View File

@@ -37,7 +37,7 @@ on:
required: true
type: string
auto_cherry_pick:
description: 'Auto-cherry-pick fix:/chore: commits from origin/main since base tag (create only)'
description: 'Auto-cherry-pick fix:/chore: commits from origin/next (fallback origin/main) since base tag (create only)'
required: false
type: boolean
default: true
@@ -141,7 +141,7 @@ jobs:
git push -u origin "$BRANCH"
fi
- name: Cherry-pick fix/chore commits from origin/main since base tag
- name: Cherry-pick fix/chore commits from origin/next since base tag
if: ${{ inputs.auto_cherry_pick }}
env:
BRANCH: ${{ needs.validate-version.outputs.branch }}
@@ -149,23 +149,35 @@ jobs:
DRY_RUN: ${{ inputs.dry_run }}
run: |
set -euo pipefail
git fetch origin main:refs/remotes/origin/main
# `git cherry $BASE_TAG origin/main` lists every commit on main not
# Under the next-branch model, day-to-day fixes land on `next` first
# and only reach `main` via release back-merge. So `next` is the
# canonical cherry-pick source. Fall back to `main` if `next` doesn't
# exist yet (legacy single-branch repos) or as a transition guard.
if git ls-remote --exit-code origin next >/dev/null 2>&1; then
git fetch origin next:refs/remotes/origin/next
SOURCE="origin/next"
else
git fetch origin main:refs/remotes/origin/main
SOURCE="origin/main"
fi
echo "Cherry-pick source: $SOURCE"
# `git cherry $BASE_TAG $SOURCE` lists every commit on the source not
# patch-equivalent in BASE_TAG. + means needs picking, - means
# already applied (skipped silently).
CANDIDATES=$(git cherry "$BASE_TAG" origin/main | awk '/^\+ / {print $2}')
CANDIDATES=$(git cherry "$BASE_TAG" "$SOURCE" | awk '/^\+ / {print $2}')
if [ -z "$CANDIDATES" ]; then
echo "No commits on origin/main beyond $BASE_TAG."
echo "No commits on $SOURCE beyond $BASE_TAG."
echo "## Cherry-pick summary" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Base: \`$BASE_TAG\` — no commits to consider." >> "$GITHUB_STEP_SUMMARY"
echo "Base: \`$BASE_TAG\` (source: \`$SOURCE\`) — no commits to consider." >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
# Re-order chronologically (oldest first) for predictable application.
ORDERED=$(git log --reverse --format='%H' "$BASE_TAG..origin/main" \
ORDERED=$(git log --reverse --format='%H' "$BASE_TAG..$SOURCE" \
| grep -F -f <(echo "$CANDIDATES") || true)
INCLUDED=""