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
10 changes: 8 additions & 2 deletions .github/scripts/publish_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

REPOSITORY = "krav01/usage-billing"
TAG = "v0.3.0"
BRANCH = "release/v0.3.0-publisher-fix"
BRANCH = "release/v0.3.0-final"


def github(method, path, data=None, optional=False):
Expand Down Expand Up @@ -68,13 +68,19 @@ def publish(event, notes, api=github):
return "Skipped: not the unique release branch merge"
# List responses may omit merge metadata. Fetch the authoritative PR detail.
pr = api("GET", f"pulls/{prs[0]['number']}")
if not pr["merged"] or pr["merge_commit_sha"] != sha:
if not pr["merged"]:
return "Skipped: not the unique release branch merge"
if (
pr["head"]["ref"] != BRANCH or pr["head"]["repo"]["full_name"] != REPOSITORY
or pr["base"]["ref"] != "main" or pr["base"]["repo"]["full_name"] != REPOSITORY
):
return "Skipped: unexpected release PR source"
# Bind the release to the actual Git merge object. PR responses can omit
# merge_commit_sha; the second parent must still be the exact reviewed head.
commit = api("GET", f"git/commits/{sha}")
parents = commit["parents"]
if commit["sha"] != sha or len(parents) != 2 or parents[1]["sha"] != pr["head"]["sha"]:
return "Skipped: commit does not merge the reviewed release head"
query = urlencode({"head_sha": sha, "event": "push", "per_page": 100})
runs = api("GET", f"actions/runs?{query}")["workflow_runs"]
verified = []
Expand Down
11 changes: 8 additions & 3 deletions .github/scripts/test_publish_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ def check(path, sha=SHA, event="push", number=1):
class FakeAPI:
def __init__(self):
self.main = SHA
self.parents = ["c" * 40, HEAD]
self.prs = [{
"number": 15, "merged": True,
"merged_at": "2026-09-03T00:00:00Z", "merge_commit_sha": SHA,
"merged_at": "2026-09-03T00:00:00Z",
"head": {"sha": HEAD, "ref": BRANCH, "repo": {"full_name": REPOSITORY}},
"base": {"ref": "main", "repo": {"full_name": REPOSITORY}},
"html_url": "https://example.test/pr",
Expand Down Expand Up @@ -62,6 +63,8 @@ def __call__(self, method, path, data=None, optional=False):
return [{"number": pr["number"]} for pr in self.prs]
if path == "pulls/15":
return self.prs[0]
if path == f"git/commits/{SHA}":
return {"sha": SHA, "parents": [{"sha": parent} for parent in self.parents]}
if path.startswith("actions/runs?"):
query = parse_qs(urlsplit(path).query)
return {"workflow_runs": self.runs if query["head_sha"] == [SHA] else self.dependencies}
Expand Down Expand Up @@ -97,13 +100,15 @@ def forbidden(*args, **kwargs):
publish(event, "", forbidden)

def test_current_main_and_unique_release_merge_are_required(self):
for field in ("main", "merge", "unmerged", "multiple", "fork"):
for field in ("main", "merge", "nonmerge", "unmerged", "multiple", "fork"):
with self.subTest(field=field):
api = FakeAPI()
if field == "main":
api.main = "c" * 40
elif field == "merge":
api.prs[0]["merge_commit_sha"] = "c" * 40
api.parents[1] = "c" * 40
elif field == "nonmerge":
api.parents.pop()
elif field == "unmerged":
api.prs[0]["merged"] = False
elif field == "multiple":
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-v0.3.0.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_repository.full_name == github.repository &&
github.event.workflow_run.head_branch == 'main' &&
contains(github.event.workflow_run.head_commit.message, 'from krav01/release/v0.3.0-publisher-fix') &&
contains(github.event.workflow_run.head_commit.message, 'from krav01/release/v0.3.0-final') &&
github.event.workflow_run.head_sha == github.sha &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
Expand Down