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
31 changes: 26 additions & 5 deletions cli/release-automation/internal/automation/release_pr_body.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,47 @@ func clarifyReleasePRCheckComponentHeadingBlock(block string) (string, bool) {
return block, false
}

displayName, found := releasePRCheckComponentDisplayName(matches[1])
component := matches[1]
version := matches[2]
changed := false

if summarySlug, found := releasePRCheckComponentSummarySlug(component); found {
clarifiedSummary := "<details><summary>" + summarySlug + ": " + version + "</summary>"
block = strings.Replace(block, matches[0], clarifiedSummary, 1)
changed = true
}

displayName, found := releasePRCheckComponentDisplayName(component)
if !found {
return block, false
return block, changed
}

version := matches[2]
heading := "## [" + version + "]("
if !strings.Contains(block, heading) {
return block, false
return block, changed
}

clarifiedHeading := "## [" + displayName + " " + version + "]("
return strings.Replace(block, heading, clarifiedHeading, 1), true
}

// releasePRCheckComponentSummarySlug renames component summary labels whose
// release-please component id lacks the uloop prefix. The release tag keeps
// the bare component id, so consumers that resolve tags from summaries must
// also accept the renamed slug (see release_tag_from_body in
// scripts/sync-published-release-pr-labels.sh).
func releasePRCheckComponentSummarySlug(component string) (string, bool) {
if component == "dispatcher" {
return "uloop-dispatcher", true
}
return "", false
}

func releasePRCheckComponentDisplayName(component string) (string, bool) {
switch component {
case "unity-package":
return "Unity Package", true
case "dispatcher":
case "dispatcher", "uloop-dispatcher":
return "uloop Dispatcher", true
case "uloop-project-runner":
return "uloop Project Runner", true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,25 @@ func TestReleasePRCheckComponentHeadingsAreClarified(t *testing.T) {
assertReleasePRCheckLogContains(t, clarifiedBody, "## [Unity Package 3.0.0-beta.48](https://example.test/compare/v3.0.0-beta.47...v3.0.0-beta.48) (2026-07-01)")
assertReleasePRCheckLogContains(t, clarifiedBody, "## [uloop Dispatcher 3.0.1-beta.13](https://example.test/compare/dispatcher-v3.0.1-beta.12...dispatcher-v3.0.1-beta.13) (2026-07-11)")
assertReleasePRCheckLogContains(t, clarifiedBody, "## [uloop Project Runner 3.0.0-beta.45](https://example.test/compare/uloop-project-runner-v3.0.0-beta.44...uloop-project-runner-v3.0.0-beta.45) (2026-07-01)")
assertReleasePRCheckLogContains(t, clarifiedBody, "<details><summary>uloop-dispatcher: 3.0.1-beta.13</summary>")
assertReleasePRCheckLogContains(t, clarifiedBody, "<details><summary>unity-package: 3.0.0-beta.48</summary>")
assertReleasePRCheckLogContains(t, clarifiedBody, "<details><summary>uloop-project-runner: 3.0.0-beta.45</summary>")
}

// Verifies an already clarified dispatcher block stays unchanged on a second clarification pass.
func TestReleasePRCheckClarifiedDispatcherBlockIsStable(t *testing.T) {
body := "<details><summary>uloop-dispatcher: 3.0.1-beta.13</summary>\n\n" +
"## [uloop Dispatcher 3.0.1-beta.13](https://example.test/compare/dispatcher-v3.0.1-beta.12...dispatcher-v3.0.1-beta.13) (2026-07-11)\n" +
"</details>\n"

clarifiedBody, changed := clarifyReleasePRCheckComponentLabels(body)

if changed {
t.Fatal("expected clarified dispatcher block to stay unchanged")
}
if clarifiedBody != body {
t.Fatalf("expected body to stay unchanged, got:\n%s", clarifiedBody)
}
}

// Verifies that missing release PRs skip without dispatching checks.
Expand Down
2 changes: 1 addition & 1 deletion scripts/sync-published-release-pr-labels.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ release_tag_from_body() {
"v" + $version
elif $component == "uloop-project-runner" then
"uloop-project-runner-v" + $version
elif $component == "dispatcher" then
elif $component == "dispatcher" or $component == "uloop-dispatcher" then
"dispatcher-v" + $version
else
""
Expand Down
12 changes: 12 additions & 0 deletions scripts/test-sync-published-release-pr-labels.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ test_marks_dispatcher_component_summary_release_pr_from_body() {
assert_contains "$TMP_DIR/dispatcher-component-summary/output.txt" "Marked release PR #1470 as tagged for dispatcher-v3.0.1-beta.12."
}

# Verifies uloop-prefixed dispatcher summaries written by the release PR clarifier still resolve the dispatcher release tag.
test_marks_uloop_dispatcher_component_summary_release_pr_from_body() {
run_case uloop-dispatcher-component-summary \
'[{"number":1696,"title":"chore: release v3-beta","body":"<details><summary>uloop-dispatcher: 3.0.1-beta.13</summary></details>","mergeCommit":{"oid":"abc123"}}]' \
'{"dispatcher-v3.0.1-beta.13":{"isDraft":false,"targetCommitish":"abc123"}}'

assert_file_equals "$TMP_DIR/uloop-dispatcher-component-summary/status.txt" "0"
assert_contains "$TMP_DIR/uloop-dispatcher-component-summary/gh.log" "release view dispatcher-v3.0.1-beta.13 --repo hatayama/unity-cli-loop --json isDraft,targetCommitish"
assert_contains "$TMP_DIR/uloop-dispatcher-component-summary/output.txt" "Marked release PR #1696 as tagged for dispatcher-v3.0.1-beta.13."
}

# Verifies component summaries take precedence over legacy numeric release titles.
test_marks_project_runner_component_summary_release_pr_before_numeric_title() {
run_case project-runner-component-before-title \
Expand Down Expand Up @@ -234,6 +245,7 @@ test_marks_stale_pending_release_pr
test_marks_branch_title_release_pr_from_body
test_marks_component_summary_release_pr_from_body
test_marks_dispatcher_component_summary_release_pr_from_body
test_marks_uloop_dispatcher_component_summary_release_pr_from_body
test_marks_project_runner_component_summary_release_pr_from_body
test_marks_project_runner_component_summary_release_pr_before_numeric_title
test_keeps_draft_release_pending
Expand Down
Loading