Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/workflows/create-lts-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
if git diff --quiet origin/lts origin/main; then
echo "No content difference between lts and main. Nothing to promote."
echo "has_diff=false" >> "$GITHUB_OUTPUT"
elif [ -z "$(git log origin/lts..origin/main --oneline)" ]; then
echo "lts is ahead of or diverged from main with no commits to promote. Nothing to promote."
echo "has_diff=false" >> "$GITHUB_OUTPUT"
else
echo "has_diff=true" >> "$GITHUB_OUTPUT"
Comment on lines 32 to 39
fi
Expand All @@ -40,7 +43,20 @@ jobs:
if: steps.diff.outputs.has_diff == 'true'
id: commits
run: |
LIST=$(git log origin/lts..origin/main --oneline)
# Find the most-recent commit on main whose tree hash matches the current lts tree.
# This is the anchor point from which we show only genuinely new commits, even after
# squash-merge promotions (which lose individual commit provenance in lts history).
LTS_TREE=$(git rev-parse origin/lts^{tree})
ANCHOR=$(git log origin/main --format="%H %T" --max-count=500 \
| awk -v t="$LTS_TREE" '$2==t{print $1; exit}')

if [ -n "$ANCHOR" ]; then
LIST=$(git log "${ANCHOR}..origin/main" --oneline)
else
# Fallback when the tree match isn't in recent history (e.g., first ever promotion).
LIST=$(git diff --name-status origin/lts origin/main)
Comment on lines +50 to +57
fi

{
echo "list<<EOF"
echo "$LIST"
Expand All @@ -66,7 +82,7 @@ jobs:

if [ -n "$EXISTING" ]; then
echo "Updating existing promote PR #${EXISTING}"
printf '%s\n' "${BODY}" | gh pr edit "$EXISTING" --body-file - || true
printf '%s\n' "${BODY}" | gh pr edit "$EXISTING" --body-file -
else
echo "Creating new draft promote PR"
printf '%s\n' "${BODY}" | gh pr create \
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Promotion and production release are **intentionally decoupled**. There are two
**Phase 1 — Promotion (human-gated via PR):**
1. Every push to `main` triggers `create-lts-pr.yml`
2. The workflow checks `git diff --quiet origin/lts origin/main` (content diff, not commit graph — survives squash-merges)
3. If content differs: a draft PR from `main``lts` is created (or the existing one is updated with the latest commit list)
3. If content differs: a draft PR from `main``lts` is created (or the existing one is updated). The PR body lists only the commits since the last promotion by anchoring to the `main` commit whose tree hash matches the current `lts` tree — this survives squash-merge history and prevents the list from bloating.
4. A maintainer reviews and **squash-merges** the PR — this is the human approval gate
5. The squash-merge triggers a `push` event on `lts` — all 5 build workflows run as **validation builds** (`publish=false`). No images are published.

Expand Down
Loading