Skip to content

ci(infra): wrap release-please PR titles in code fences - #5599

Closed
Mason Daugherty (mdrxy) wants to merge 1 commit into
mainfrom
mdrxy/infra/code-fences-in-pr-titles
Closed

ci(infra): wrap release-please PR titles in code fences#5599
Mason Daugherty (mdrxy) wants to merge 1 commit into
mainfrom
mdrxy/infra/code-fences-in-pr-titles

Conversation

@mdrxy

Copy link
Copy Markdown
Member

Release-please PR titles now wrap the component and version in code fences, so they render as release(`deepagents-code`): `0.5.0` instead of release(deepagents-code): 0.5.0.


Before / after

Before release(deepagents-code): 0.5.0
After release(`deepagents-code`): `0.5.0`

On GitHub, backticks in a PR title render as inline code, so the package and version now show in monospace.

Why the title is load-bearing here

A release-please title is not just a label in this repo — it is a machine-readable contract, and the exact byte format is matched across the release pipeline. This PR changes the producer and every exact-match consumer in one commit so none of the correlations silently always-miss (most of these guards are deliberately fail-open, so a drift would not error — it would just stop catching failures):

  • Producerrelease-please-config.json's pull-request-title-pattern.
  • Run-title correlationrelease.yml's run-name, release-please.yml's find_run_url and the pending-release guard's displayTitle == title equality, and release_comment_update.yml's run re-discovery all key on the same rendered string; all four are updated together.
  • Version extractionrelease-please.yml pulls the version out of the squash-merge commit subject with a sed capture. That capture now strips the surrounding backticks, so the bare version (0.5.0) still flows to release.yml for the pyproject version check and the git tag. This was the highest-risk capture-shift: without the change, the tag and version check would have picked up a leading backtick.
  • Per-package dispatch — all ten commit matchers in release-please.yml.
  • PR lookup — both in:title searches in release.yml.
  • Curated notesrelease-notes.js's parseReleaseTitle expects the new form.

Lint and scope-gate interplay

Two checks treat the title as input rather than a fixed string:

  • pr_lint.yml validates titles against a scope allowlist, and a backticked component (`deepagents-code`) is not in that list, so release titles are now exempted from the scope check — the release pipeline validates them itself.
  • check_pr_scope_files.py gates the scope-file bypass on a release(...) title. That gate intentionally still matches both title forms: an author-typed release(cli): anything must keep failing the scope check, so the gate cannot become a bypass vector. parse_title_scopes now strips the backticks so the real release title maps to the correct package label.

The outcome comment on the release PR wraps the title in double backticks so the embedded code fences render as a single code span.

Verification

  • All 54 workflow files parse as valid YAML.
  • The helper-script suite (python -m pytest .github/scripts/tests, which also runs the node --test release-notes tests) passes: 1046 passed.
Test plan
  • python -m pytest .github/scripts/tests -q — 1046 passed.
  • YAML parse check across all of .github/workflows/*.yml.
  • The sed extraction was exercised against both release(`deepagents-code`): `0.5.0` (#1234) and the legacy release(deepagents): 0.5.0 form and returns the bare version for each.

Release-please PR titles and the matching release.yml run names now
render as release(`<component>`): `<version>` (e.g.
release(`deepagents-code`): `0.5.0`) so the package and version show as
inline code on GitHub.

The title is a machine-readable contract across the release pipeline, so
the byte-format change is applied in lock-step to every producer and
exact-match consumer:

- Producer: release-please-config.json pull-request-title-pattern
- Correlation keys: release.yml run-name, release-please.yml
  find_run_url and the pending-release guard's displayTitle match,
  release_comment_update.yml run-title re-discovery
- Parsers: the sed version extraction strips backticks so the bare
  version still reaches release.yml for the pyproject check and git tag;
  all ten per-component commit matchers; the curated-notes title filters
- Search: both in:title PR lookups in release.yml
- release-notes.js parseReleaseTitle expects the backticked form
- pr_lint.yml exempts release titles from the scope allowlist (a
  backticked scope is not in the allowlist and would otherwise fail)

The scope-bypass gate in check_pr_scope_files.py keeps matching both
title forms so an author-typed fake release title cannot escape the
scope check, and parse_title_scopes strips backticks so the new form
maps to the right package label. The outcome comment in
release_comment_update.yml wraps titles in double backticks so the
embedded code fences render as one code span.
@github-actions github-actions Bot added github_actions PR touching `.github` infra Repo meta changes internal User is a member of the `langchain-ai` GitHub organization size: S 50-199 LOC labels Aug 18, 2026

@open-swe open-swe Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open SWE Review found 2 potential issues.

Approval score: 0/100 · Decision: commented · Blocked by: team auto approve disabled, repo auto approve disabled, open blocking findings, score below threshold

Open in WebView Open SWE trace

# (release(`deepagents-code`): `0.5.0`), which is not one of the
# allowlisted scopes below; the release pipeline validates those titles
# itself, so skip the scope check for them.
if: "!startsWith(github.event.pull_request.title, 'release(`')"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Prefix bypass disables all title validation

This condition skips the entire semantic-title check for any author-controlled title beginning with release(\``, not just the exact release-please shape. For example, a PR titled release(`not-a-package` with only release artifacts also passes the deliberately broad scope-file bypass, so no check validates its type, scope, separator, or version; after squash merge, the release workflow treats the subject as release-like and fails post-merge. Gate the exemption on an exact validated release title (and managed component), rather than this prefix alone.

(Refers to line 98)


Your feedback helps Open SWE learn. React with 👍 or 👎 to tell us if this review comment was useful.

ANY_PACKAGE=false

if echo "$CHANGED" | grep -q "^libs/cli/CHANGELOG.md$" && echo "$COMMIT_MSG" | grep -qE "^release\(deepagents-cli\):"; then
if echo "$CHANGED" | grep -q "^libs/cli/CHANGELOG.md$" && echo "$COMMIT_MSG" | grep -qE "^release\(`deepagents-cli`\):"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Legacy release merges no longer dispatch

The version extractor immediately above deliberately accepts both legacy and backticked release subjects, but this and every other package guard now accept only the new form. There is currently an open old-format release PR (#5591, release(deepagents-code): 0.1.58); if it merges after this workflow lands but before release-please rewrites its title, RELEASE_VERSION is nonempty, none of these guards sets ANY_PACKAGE, and the workflow exits at the unmatched-package check without dispatching the release. Keep the optional-backtick compatibility consistent in the per-package matchers until old-format release PRs can no longer merge.

(Refers to line 192)


Your feedback helps Open SWE learn. React with 👍 or 👎 to tell us if this review comment was useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions PR touching `.github` infra Repo meta changes internal User is a member of the `langchain-ai` GitHub organization size: S 50-199 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant