Skip to content

[build] unlock trunk once the release finishes writing to it - #17938

Merged
titusfortner merged 5 commits into
trunkfrom
release-pipeline-ordering
Aug 22, 2026
Merged

[build] unlock trunk once the release finishes writing to it#17938
titusfortner merged 5 commits into
trunkfrom
release-pipeline-ordering

Conversation

@titusfortner

@titusfortner titusfortner commented Aug 22, 2026

Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

  • Allows the required post-release commits to happen while trunk is still locked
  • Rearranges the order of execution to unlock trunk more quickly
  • Slack message reports the outcome whether the release succeeded or failed

🔧 Implementation Notes

Trunk lock

  • The tag for a new Selenium version is essentially "finalized" as soon as we release something. Everything after that is us making sure we've got the bits from that commit published in all the right places. We want to bump the versions to nightly after the release and do the mirror commit as the first two commits after the tagged release commit, but there's no reason to keep trunk locked until everything else is settled and verified
  • Uses a new Selenium team selenium-bot as a bypass actor on the release rulesets.
  • mirror no longer waits on nightly; that ordering was specified but isn't required
  • nightly doesn't need trunk to be locked; the version bumps to trunk to set nightly have already run, the nightly job is doing the publishing not committing anything to trunk.
  • docs no longer gates the version reset or the unlock, so a documentation failure can't leave trunk locked with release versions still set
  • If either trunk write fails, trunk stays locked and the summary reports it; re-running the failed job works under the lock (the bypass covers it) and resumes the chain through the unlock
  • Handles unlikely scenario for rerunning a job with commit-changes.yml so an already-applied patch doesn't error

Reporting

  • Fixed the logic for when a release was marked as a failure
  • Fixed bug where a scheduled nightly run reports a failure to Slack instead of just not running while trunk is locked (release-grid job wasn't blocked)

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code (Opus 5, Fable 5)
    • What was generated: the workflow reordering, the ruleset bypass, the failure-mode analysis, and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

  • CI Bot is limited to making PRs and not committing directly to trunk, except for in the release process. If that changed for some reason, then the CI Bot could update trunk during a release process. This shouldn't be an issue, but worth stating.

🔄 Types of changes

  • Bug fix (backwards compatible)

@selenium-ci selenium-ci added the B-build Includes scripting, bazel and CI integrations label Aug 22, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Release pipeline: unlock trunk earlier and improve nightly/release reporting

🐞 Bug fix ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Unlock trunk after post-release commits, without waiting for docs or nightly publishing.
• Add selenium-bot ruleset bypass and make patch commit workflow idempotent.
• Fix nightly grid gating and always send Slack outcome for release success/failure.
Diagram

graph TD
  RS{{"Release rulesets"}} --> REL["release.yml"] --> PUB(["Publish artifacts"]) --> POST(["Post-release commits"]) --> UNL(["Unlock trunk"]) --> NGT["nightly.yml"] --> SLK["Slack notification"]
  PUB --> DV(["Docs / verify"]) --> SLK

  subgraph Legend
    direction LR
    _rs{{"Ruleset"}} ~~~ _job(["Job"]) ~~~ _wf["Workflow file"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Temporarily disable rulesets via API during release
  • ➕ Avoids maintaining persistent bypass actors/teams
  • ➕ Makes bypass explicitly scoped to a single workflow run
  • ➖ Requires elevated/admin token scopes and more brittle API handling
  • ➖ Higher risk if re-enable step fails; could leave protections off
2. Use a dedicated “cleanup/finally” composite job without dependency rewiring
  • ➕ Less reshaping of job graph; smaller change surface
  • ➕ Centralizes unlock + Slack logic in one place
  • ➖ Still needs careful needs/if wiring to ensure cleanup runs at the right time
  • ➖ Doesn’t address ordering constraints (e.g., mirror vs nightly) as directly

Recommendation: Current approach is the best tradeoff: it shortens trunk lock duration by aligning unlock with the last required trunk write (version reset/mirror), keeps docs/verify from blocking unlock, and improves observability via always-on Slack summary. The ruleset bypass via a dedicated selenium-bot team is pragmatic and easier to reason about than dynamically toggling rulesets via API.

Files changed (5) +52 / -24

Bug fix (2) +5 / -1
commit-changes.ymlMake commit-changes idempotent when patch already applied +4/-0

Make commit-changes idempotent when patch already applied

• Adds a pre-check that detects when changes.patch has already been applied (via reverse-apply check) and exits successfully. This prevents reruns from failing on an already-updated branch.

.github/workflows/commit-changes.yml

nightly.ymlSkip grid nightly release when nightly build was skipped +1/-1

Skip grid nightly release when nightly build was skipped

• Updates the release-grid job condition to not run when the nightly-release matrix was skipped (e.g., trunk locked during a release). This avoids false failures/notifications when nightly publishing correctly did not run.

.github/workflows/nightly.yml

Other (3) +47 / -23
release-require-passing.jsonAllow selenium-bot to bypass required checks during release +7/-1

Allow selenium-bot to bypass required checks during release

• Adds the Selenium team bot as an always-bypass actor on the 'Require Passing' release ruleset. This lets release automation proceed with necessary post-release commits while trunk protections are active.

.github/rulesets/release-require-passing.json

release-restrict-trunk.jsonAllow selenium-bot to bypass trunk update restrictions +5/-0

Allow selenium-bot to bypass trunk update restrictions

• Adds selenium-bot as a bypass actor on the 'Restrict Trunk' ruleset. This enables release automation to write required commits even while trunk is locked for normal contributors.

.github/rulesets/release-restrict-trunk.json

release.ymlReorder release jobs to unlock trunk sooner and always report outcome +35/-22

Reorder release jobs to unlock trunk sooner and always report outcome

• Rewires job dependencies so verify/reset-version depend on publish results rather than docs, and moves trunk unlock to occur after post-release commits (update-version/mirror) instead of after all downstream tasks. Also adjusts nightly and mirror ordering, and replaces failure-only Slack reporting with an always-on summary whose title/color/icon reflect success, failure, or skipped release, including trunk unlock status.

.github/workflows/release.yml

@qodo-code-review

qodo-code-review Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Premature trunk unlock ✓ Resolved 🐞 Bug ≡ Correctness
Description
In .github/workflows/release.yml, unrestrict-trunk runs with always() but only gates on
publish / publish-python, so it can unlock trunk even if update-version or mirror failed or
were skipped. This can leave trunk unlocked before the nightly version reset and/or mirror update is
applied, allowing normal merges while trunk is still in a release state.
Code

.github/workflows/release.yml[R321-324]

+    if: >-
+      always() && !cancelled() &&
+      needs.publish.result == 'success' &&
+      (needs.publish-python.result == 'success' || needs.publish-python.result == 'skipped')
Evidence
unrestrict-trunk is explicitly responsible for unlocking trunk by deleting the release rulesets,
but its if: condition does not check the success of the jobs that actually push the post-release
commits to trunk (update-version and mirror). Since it uses always(), it can still run even
when those needed jobs fail/skip, causing an unlock before the nightly reset/mirror commit is
applied.

.github/workflows/release.yml[274-299]
.github/workflows/release.yml[311-325]
.github/workflows/restrict-trunk.yml[78-90]
.github/workflows/mirror-selenium-releases.yml[41-58]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`unrestrict-trunk` currently unlocks trunk (deletes the active release rulesets) as long as publishing succeeded, even if the jobs that write the required post-release commits to trunk (`update-version`, and `mirror` when applicable) failed or were skipped. This can unlock trunk while it still contains release versions (or without the mirror commit), which is exactly the unsafe state the lock is meant to prevent.

## Issue Context
- `update-version` pushes the nightly version reset commit to `trunk`.
- `mirror` (when `language == 'all'`) also pushes a commit to `trunk`.
- `unrestrict-trunk` calls `restrict-trunk.yml` with `restrict: false`, which deletes the release rulesets (unlocking trunk).

## Fix Focus Areas
- .github/workflows/release.yml[287-331]

### Suggested change
Update the `unrestrict-trunk` job `if:` condition to also require the trunk-writing steps to have completed successfully:
- Require `needs.update-version.result == 'success'`.
- Require `needs.mirror.result == 'success' || needs.mirror.result == 'skipped'` (since `mirror` is intentionally skipped for non-`all` releases).

Optionally, if you want trunk to *always* be unlockable even when these steps fail, introduce a separate explicitly-approved/manual unlock path (or a dedicated failure-recovery job) rather than unlocking automatically on partial completion.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/workflows/release.yml Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit b85fbce

@titusfortner
titusfortner merged commit ef7f722 into trunk Aug 22, 2026
28 checks passed
@titusfortner
titusfortner deleted the release-pipeline-ordering branch August 22, 2026 03:34
This was referenced Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants