ci: fix preview release baseline after stable

This commit is contained in:
Ogulcan Celik 2026-06-15 20:59:52 +03:00
parent 41d1c14e07
commit 517ca8163f
3 changed files with 123 additions and 5 deletions

View File

@ -272,13 +272,18 @@ jobs:
if [ -z "$previous" ]; then
previous="$(git describe --tags --match 'v[0-9]*' --abbrev=0)"
fi
range_base="$(python3 scripts/preview.py range-base \
--previous "$previous" \
--commit '${{ needs.preflight.outputs.commit }}')"
echo "commit=$previous" >> "$GITHUB_OUTPUT"
echo "range_base=$range_base" >> "$GITHUB_OUTPUT"
- name: Generate notes and checksums
shell: bash
run: |
set -euo pipefail
python3 scripts/preview.py notes \
--previous '${{ steps.previous-preview.outputs.range_base }}' \
--commit '${{ needs.preflight.outputs.commit }}' \
--build-id '${{ needs.preflight.outputs.build_id }}' \
--base-version '${{ needs.preflight.outputs.base_version }}' \
@ -349,10 +354,12 @@ jobs:
PREVIEW_TAG='${{ needs.preflight.outputs.tag }}'
PREVIEW_BUILD_ID='${{ needs.preflight.outputs.build_id }}'
PREVIOUS_PREVIEW_COMMIT='${{ steps.previous-preview.outputs.commit }}'
PREVIEW_RANGE_BASE='${{ steps.previous-preview.outputs.range_base }}'
echo "Scanning preview commits in $PREVIOUS_PREVIEW_COMMIT..$PREVIEW_COMMIT for refs #<issue> mentions."
echo "Previous preview commit: $PREVIOUS_PREVIEW_COMMIT"
echo "Scanning preview commits in $PREVIEW_RANGE_BASE..$PREVIEW_COMMIT for refs #<issue> mentions."
mapfile -t ISSUES < <(
git log --format='%s%n%b' "$PREVIOUS_PREVIEW_COMMIT..$PREVIEW_COMMIT" \
git log --format='%s%n%b' "$PREVIEW_RANGE_BASE..$PREVIEW_COMMIT" \
| perl -ne 'print "$1\n" if /\brefs\s+#([0-9]+)\b/i' \
| sort -nu
)

View File

@ -20,7 +20,6 @@ EXPECTED_ASSET_NAMES = {
"windows-x86_64": "herdr-windows-x86_64.exe",
}
HIDDEN_SUBJECTS = (
"release:",
"docs: update website manifest",
"docs: update preview manifest",
"chore: approve contributor",
@ -48,8 +47,21 @@ def normalize_version(version: str) -> str:
return version.strip().removeprefix("v")
def latest_stable_tag() -> str:
return run_git(["describe", "--tags", "--match", "v[0-9]*", "--abbrev=0"])
def latest_stable_tag(ref: str | None = None) -> str:
args = ["describe", "--tags", "--match", "v[0-9]*", "--abbrev=0"]
if ref:
args.append(ref)
return run_git(args)
def git_is_ancestor(ancestor: str, descendant: str) -> bool:
result = subprocess.run(
["git", "merge-base", "--is-ancestor", ancestor, descendant],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=False,
)
return result.returncode == 0
def read_json(path: Path) -> dict[str, Any] | None:
@ -95,6 +107,16 @@ def commit_subjects(previous: str, commit: str) -> list[str]:
return subjects
def preview_range_base(previous: str, commit: str) -> str:
try:
stable = latest_stable_tag(commit)
except subprocess.CalledProcessError:
return previous
if git_is_ancestor(previous, stable) and git_is_ancestor(stable, commit):
return stable
return previous
def humanize_subject(subject: str) -> tuple[str, str]:
match = COMMIT_RE.match(subject)
if not match:
@ -258,6 +280,11 @@ def cmd_select_commit(args: argparse.Namespace) -> int:
return 0
def cmd_range_base(args: argparse.Namespace) -> int:
print(preview_range_base(args.previous, args.commit))
return 0
def main() -> int:
parser = argparse.ArgumentParser(description="Preview channel release helpers")
sub = parser.add_subparsers(required=True)
@ -294,6 +321,11 @@ def main() -> int:
select.add_argument("--ref", default="origin/master")
select.set_defaults(func=cmd_select_commit)
range_base = sub.add_parser("range-base")
range_base.add_argument("--previous", required=True)
range_base.add_argument("--commit", required=True)
range_base.set_defaults(func=cmd_range_base)
args = parser.parse_args()
return args.func(args)

View File

@ -1,7 +1,9 @@
import json
import os
import subprocess
import tempfile
import unittest
from unittest import mock
from pathlib import Path
import scripts.conventional_commits as conventional_commits
@ -55,8 +57,85 @@ class PreviewNotesTests(unittest.TestCase):
def test_hidden_subjects_include_preview_manifest_commits(self):
self.assertTrue(preview.hidden_subject("docs: update preview manifest"))
self.assertTrue(preview.hidden_subject("docs: update website manifest"))
self.assertFalse(preview.hidden_subject("release: v0.7.0"))
self.assertFalse(preview.hidden_subject("fix: repair preview manifest"))
def test_latest_publishable_commit_keeps_release_commits(self):
output = "\n".join(
[
"manifest\x00docs: update website manifest for v0.7.0",
"release\x00release: v0.7.0",
"feature\x00feat: add plugin v1 system",
]
)
with mock.patch.object(preview, "run_git", return_value=output):
self.assertEqual(preview.latest_publishable_commit("origin/master"), "release")
def test_preview_range_base_advances_to_stable_tag(self):
with (
mock.patch.object(preview, "latest_stable_tag", return_value="v0.7.0"),
mock.patch.object(preview, "git_is_ancestor", return_value=True),
):
self.assertEqual(
preview.preview_range_base("previous-preview", "release"),
"v0.7.0",
)
def test_preview_range_base_keeps_previous_preview_for_unreleased_work(self):
def is_ancestor(ancestor: str, descendant: str) -> bool:
return (ancestor, descendant) == ("v0.7.0", "new-feature")
with (
mock.patch.object(preview, "latest_stable_tag", return_value="v0.7.0"),
mock.patch.object(preview, "git_is_ancestor", side_effect=is_ancestor),
):
self.assertEqual(
preview.preview_range_base("previous-preview", "new-feature"),
"previous-preview",
)
def test_post_stable_history_selects_release_and_bases_range_on_stable_tag(self):
with tempfile.TemporaryDirectory() as tmp:
repo = Path(tmp)
def git(*args: str) -> str:
return subprocess.check_output(
["git", *args],
cwd=repo,
text=True,
stderr=subprocess.DEVNULL,
).strip()
git("init")
git("config", "user.email", "test@example.com")
git("config", "user.name", "Test User")
marker = repo / "marker.txt"
marker.write_text("preview\n", encoding="utf-8")
git("add", "marker.txt")
git("commit", "-m", "feat: previous preview")
previous_preview = git("rev-parse", "HEAD")
marker.write_text("release\n", encoding="utf-8")
git("commit", "-am", "release: v0.7.0")
release = git("rev-parse", "HEAD")
git("tag", "v0.7.0")
marker.write_text("manifest\n", encoding="utf-8")
git("commit", "-am", "docs: update website manifest for v0.7.0")
original_cwd = os.getcwd()
try:
os.chdir(repo)
self.assertEqual(preview.latest_publishable_commit("HEAD"), release)
self.assertEqual(
preview.preview_range_base(previous_preview, release),
"v0.7.0",
)
finally:
os.chdir(original_cwd)
def test_preview_docs_rewrite_links_to_preview_namespace(self):
source = """---
title: Install Herdr