Repository navigation
Collapse the looping end-to-end scenarios to one Run per behavior - #217
Merged
Merged
Conversation
Each looping test in spec_run, run_notification and release keeps one case end to end and moves the rest to unit tests where the cases differ: the interrupt's signals, the Spec run's Unready labels, the Resend key lookup, and the release scripts' version, summary and bump-PR steps, which the tests now call by sourcing the scripts. The Repair and upstream-move budget tests keep their real rounds, say so, and gain unit tests of the counting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Each looping end-to-end test in the four slowest binaries now keeps one case end to end. The other cases moved to unit tests at the level where they actually differ.
Other code changes:
release.shandrelease-notes.shcallmainonly when run directly, so tests can source them. The version pattern moved intois_plain_version.resend_key.rs: the empty-RESEND_API_KEYrule moved intoenvironment_key(value), so it can be tested without touching the process environment.help/version/update.Evidence
Full suite:
cargo testpasses, 24 of 24 binaries, including 76 unit tests (was 65).How timings were taken: each test executable ran directly with libtest
--report-time, base first, then this branch. The base wasorigin/issue-174at dbbe8de, which already includes #205 and #204. The machine is shared, 4 cores. Load averages are noted; single-test times vary by about ±1s between runs.Totals per binary. CPU is user+sys. "Σ tests" is the sum of the per-test times.
spec_runmerge_runreleaserun_notificationWhat moved and what didn't:
merge_runhad no multi-Run loops; its changes are comments and unit tests only.spec_run's wall time is set by its long single-Run scenarios, so fewer Runs barely move its total.Each test changed
spec_run
each_unready_label_keeps_a_ticket_from_running→an_unready_label_keeps_a_ticket_from_runningsigterm_while_a_ticket_runs_…→a_signal_to_the_spec_run_alone_fails_the_ticket_run_then_ends_the_spec_run_as_interruptedsighup_while_a_ticket_runs_…(removed)sigint_to_the_spec_run_alone_is_passed_on_to_the_ticket_run(removed)parallel_1_runs_the_tickets_one_at_a_timerepairs_exhausted_on_the_spec_pr_send_it_back_to_draft_and_exit_1(comment only)rerunning_a_failed_spec_run_…(comment only)merge_run (comments only)
foreign_commits_that_keep_coming_spend_the_upstream_move_budgeta_review_repair_counts_against_the_repair_capmerge_failures_that_keep_moving_the_base_branch_spend_the_base_move_budgeta_repair_needed_after_a_failed_merge_counts_against_the_repair_capa_merge_run_gives_the_agent_the_same_implement_prompt_as_a_runrelease
when_the_agent_fails_or_prints_nothing_…→when_the_agent_fails_the_summary_is_the_generated_notesthe_summary_is_the_agents_unless_it_fails_or_prints_only_blank_space(new)without_a_bump_pr_summary_the_release_body_is_…the_summary_is_only_that_of_a_pr_merged_as_the_tagged_commit(new)a_version_that_is_not_plain_semver_is_refusedonly_plain_x_y_z_versions_with_no_leading_zeros_pass(new)a_version_not_higher_than_the_one_on_main_is_refuseda_version_is_higher_only_by_its_parts_as_numbers(new)the_release_body_is_the_bump_prs_summary_…(comment only)when_the_bump_pr_cannot_be_read_…(comment only)run_notification
an_interrupted_run_sends_one_notification_that_it_was_interruptedwithout_resend_api_key_the_run_stops_before_any_work_and_sends_nothinga_failed_send_is_a_warning_that_changes_neither_the_exit_code_nor_stdoutno_email_skips_the_notification_email_always_asks_forwithout_resend_api_key_a_run_sends_with_the_key_in_the_credentialsbroken_credentials_stop_a_run_that_asks_for_a_notification_before_any_workhelp_version_and_update_never_read_the_credentials(comment only)email_always_without_an_address_or_a_key_…→email_always_without_an_address_stops_the_run_before_any_workwithout_email_always_a_run_without_the_flag_sends_nothing→email_always_false_makes_a_run_without_the_flag_send_nothingNew unit tests:
interrupt::testsraises SIGINT, SIGTERM and SIGHUP in turn and checks each is recorded.run::testscovers the shared Repair cap and upstream-move budget.spec_run::testschecks each Unready label.resend_key::testscovers an emptyRESEND_API_KEYand each way the Credentials can be broken.args::testscovers both spellings ofno-emailandparallel.config::testscoversemail.towithoutemail.always.Merge Danger
Door: two-way
Tests only, apart from two small refactors made for testability. The scripts'
mainguard changes nothing when they are run as before (scripts/release.sh, andrelease-notes.shfrom the workflow).Blast Radius: tests
If a moved case was mis-covered, a regression in that case would only show in unit tests rather than end to end.
Unaddressed findings
Standards
tests/release.rs(sourcing the scripts, overridingsummary_input): skipped. The codebase-design skill allows internal seams used by a module's own tests, and bash offers no other level at which the cases differ.from_environmentdelegating toenvironment_key: skipped. It is the seam that keeps unit tests from touching the process environment."stderr: {}"vs"{}"): skipped. Each file keeps its existing style.Spec
mainsettles the exit code and prints stdout beforeRunNotification::send, which returns(), so no seam exists without restructuringmain. The reply shapes are covered byemail::error_text's unit test.email.alwaysplus Credentials key case: skipped.email.alwaysonly picksNotificationAsk::Send(None), whichconfig::testscovers. The key is then found by the sameResend::newcall as with the flag, which stays end to end.no-emailandparallelloops were argument-parsing work left to Unit tests for argument parsing; one Run per --email end-to-end test #205: kept. Unit tests for argument parsing; one Run per --email end-to-end test #205 merged without them and added theargsseam, so two small unit tests were enough to meet this issue's one-Run-per-behavior criterion.FailedRun.interrupted = interrupt::requested(), which doesn't depend on the signal. The remaining end-to-end tests show the flag reaching the outcome.Closes #206
🤖 Generated with Claude Code