diff --git a/.github/workflows/desktop-release.yml b/.github/workflows/desktop-release.yml index 81e86a56b..2f255ee72 100644 --- a/.github/workflows/desktop-release.yml +++ b/.github/workflows/desktop-release.yml @@ -150,8 +150,10 @@ jobs: subject="${GITHUB_SHA}" else # A dispatch builds the tip; its checks are those of the newest - # commit that changed Desktop, whose tree the tip must equal. - subject="$(git log -1 --format=%H "${GITHUB_SHA}" -- .)" + # commit on main's own history (first parent) that changed + # Desktop, whose tree the tip must equal. A commit from inside a + # merged branch never had a Packages push run on main. + subject="$(git log -1 --first-parent --format=%H "${GITHUB_SHA}" -- .)" fi echo "Release checks follow ${subject}." echo "sha=${subject}" >> "${GITHUB_OUTPUT}" diff --git a/tests/test_desktop_release_subject.py b/tests/test_desktop_release_subject.py new file mode 100644 index 000000000..cf98b4d9a --- /dev/null +++ b/tests/test_desktop_release_subject.py @@ -0,0 +1,23 @@ +"""A dispatched Desktop release waits on a commit that has its own checks. + +Only commits on main's first-parent history get a Packages push run. A commit +from inside a merged branch never does, so choosing it made the release gate +wait 60 minutes for a run that cannot exist, then refuse (2026-10-20, 0.21.1). +""" + +from __future__ import annotations + +from pathlib import Path + +WORKFLOW = Path(__file__).resolve().parents[1] / ".github/workflows/desktop-release.yml" + + +def test_dispatch_subject_follows_first_parent_history() -> None: + lines = [ + line.strip() + for line in WORKFLOW.read_text(encoding="utf-8").splitlines() + if line.strip().startswith('subject="$(git log') + ] + assert lines, "the release gate no longer chooses a subject commit with git log" + for line in lines: + assert "--first-parent" in line, line