Skip to content

Commit a764cfc

Browse files
castrojoCopilot
andauthored
fix(ci): use tree-hash anchor for accurate promotion commit list (ublue-os#1197)
... and of course I messed it up, one more. :) ## Solution Find the most-recent commit on `main` whose tree hash matches the current `lts` tree. Since squash-merges preserve content exactly, this is always the `main` commit that was squash-merged into `lts`. `git log` is anchored from that point, showing only genuinely new commits regardless of squash-merge history. If no match is found within 500 commits (first-ever promotion), falls back to `git diff --name-status`. ## Also fixed - Removed `|| true` from `gh pr edit` — failures now surface visibly instead of silently leaving the PR body stale - Added guard: if `git diff` detects a difference but `origin/lts..origin/main` is empty (lts is ahead/diverged), skip rather than open a misleading empty PR Addresses Copilot review comments from ublue-os#1195. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude Sonnet 4.6 via GitHub Copilot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 6462f99 commit a764cfc

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

.github/workflows/create-lts-pr.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ jobs:
3232
if git diff --quiet origin/lts origin/main; then
3333
echo "No content difference between lts and main. Nothing to promote."
3434
echo "has_diff=false" >> "$GITHUB_OUTPUT"
35+
elif [ -z "$(git log origin/lts..origin/main --oneline)" ]; then
36+
echo "lts is ahead of or diverged from main with no commits to promote. Nothing to promote."
37+
echo "has_diff=false" >> "$GITHUB_OUTPUT"
3538
else
3639
echo "has_diff=true" >> "$GITHUB_OUTPUT"
3740
fi
@@ -40,7 +43,20 @@ jobs:
4043
if: steps.diff.outputs.has_diff == 'true'
4144
id: commits
4245
run: |
43-
LIST=$(git log origin/lts..origin/main --oneline)
46+
# Find the most-recent commit on main whose tree hash matches the current lts tree.
47+
# This is the anchor point from which we show only genuinely new commits, even after
48+
# squash-merge promotions (which lose individual commit provenance in lts history).
49+
LTS_TREE=$(git rev-parse origin/lts^{tree})
50+
ANCHOR=$(git log origin/main --format="%H %T" --max-count=500 \
51+
| awk -v t="$LTS_TREE" '$2==t{print $1; exit}')
52+
53+
if [ -n "$ANCHOR" ]; then
54+
LIST=$(git log "${ANCHOR}..origin/main" --oneline)
55+
else
56+
# Fallback when the tree match isn't in recent history (e.g., first ever promotion).
57+
LIST=$(git diff --name-status origin/lts origin/main)
58+
fi
59+
4460
{
4561
echo "list<<EOF"
4662
echo "$LIST"
@@ -66,7 +82,7 @@ jobs:
6682
6783
if [ -n "$EXISTING" ]; then
6884
echo "Updating existing promote PR #${EXISTING}"
69-
printf '%s\n' "${BODY}" | gh pr edit "$EXISTING" --body-file - || true
85+
printf '%s\n' "${BODY}" | gh pr edit "$EXISTING" --body-file -
7086
else
7187
echo "Creating new draft promote PR"
7288
printf '%s\n' "${BODY}" | gh pr create \

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Promotion and production release are **intentionally decoupled**. There are two
140140
**Phase 1 — Promotion (human-gated via PR):**
141141
1. Every push to `main` triggers `create-lts-pr.yml`
142142
2. The workflow checks `git diff --quiet origin/lts origin/main` (content diff, not commit graph — survives squash-merges)
143-
3. If content differs: a draft PR from `main``lts` is created (or the existing one is updated with the latest commit list)
143+
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.
144144
4. A maintainer reviews and **squash-merges** the PR — this is the human approval gate
145145
5. The squash-merge triggers a `push` event on `lts` — all 5 build workflows run as **validation builds** (`publish=false`). No images are published.
146146

0 commit comments

Comments
 (0)