Skip to content

[ci] fix: accept stacked-PR title prefixes and gate on the PR author - #294

Merged
JoyboyBrian merged 9 commits into
mainfrom
brian/osm-1713-fix-pr-title-check-stack-prefix
Aug 7, 2026
Merged

[ci] fix: accept stacked-PR title prefixes and gate on the PR author#294
JoyboyBrian merged 9 commits into
mainfrom
brian/osm-1713-fix-pr-title-check-stack-prefix

Conversation

@JoyboyBrian

@JoyboyBrian JoyboyBrian commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What

  • Accept an optional leading [N/M] in PR titles, before [BREAKING], and validate that 1 <= N <= M, M >= 2, with no leading zeroes.
  • Gate title validation and auto-labeling on the PR author rather than the actor that triggered the workflow run.
  • Reconcile title-derived labels whenever a PR is opened, reopened, or its title changes: remove stale type/module/breaking/stack labels, add the labels implied by the latest title, and preserve priority, triage, and other manually managed labels.
  • Add the stacked-pr label for [N/M] titles and recognize [BREAKING] after an optional stack prefix.
  • Parse only leading module brackets so bracketed text in the description cannot create accidental module labels.
  • Document the stacked title format, labels, and gh stack link/submit workflow in CONTRIBUTING.md, the PR template, and the create-PR skill.

Why

The [N/M] prefix used by this repository's stacked PRs did not match the title check, so every stack needed to ignore or work around a failing gate. The convention was also absent from the contributor docs and PR template.

The title check used github.actor, which identifies whoever triggered the current run rather than who opened the PR. A bot touching a human-authored PR could therefore skip validation and make an invalid title appear green.

Auto-labeling previously only added labels. After a title changed, labels derived from the old title remained indefinitely. It also scanned bracketed text anywhere in the title, so description text such as [server] could be mistaken for a module. Reconciliation makes the latest title the source of truth for title-managed labels while leaving unrelated labels untouched.

How to Test

  • Parse both workflows, syntax-check the title validator's Bash, and syntax-check the auto-labeler's JavaScript in the async wrapper used by actions/github-script:
    uv run python -c "import yaml; yaml.safe_load(open('.github/workflows/check-pr-title.yml')); yaml.safe_load(open('.github/workflows/auto-label-pr.yml'))"
    uv run python -c "import yaml; print(yaml.safe_load(open('.github/workflows/check-pr-title.yml'))['jobs']['check-title']['steps'][0]['run'])" | bash -n
    uv run python -c "import yaml; s=yaml.safe_load(open('.github/workflows/auto-label-pr.yml'))['jobs']['label']['steps'][0]['with']['script']; print('(async()=>{\\n'+s+'\\n})()')" | node --check
  • Execute the title workflow's exact Bash block against standard, stacked, stacked-breaking, zero, leading-zero, reversed, missing-module, and values beyond Bash's fixed-width integer range. Valid cases pass; [0/2], [1/1], [3/2], [01/02], [1/0], [9223372036854775808/2], and [1/2] fix: x fail, while [1/9223372036854775808] passes without overflow.
  • Execute the auto-label workflow's exact JavaScript with mocked github, context, and core objects:
    • changing a stacked breaking rollout refactor into a CLI fix removes breaking, refactor, rollout, and stacked-pr, then adds bug and cli;
    • priority: high remains untouched;
    • [ci] fix: document [server] labels adds only bug and ci;
    • invalid stack positions fail without label writes;
    • an already-correct label set performs no writes.
  • git diff --check
  • gh pr checks 294 --repo Osmosis-AI/osmosis-sdk-python

Checklist

  • PR title follows [module] type: description format
  • Appropriate labels added
  • Workflow YAML, Bash, and JavaScript parse successfully
  • Title and label reconciliation cases exercised directly
  • Full GitHub CI passes
  • Public contributor documentation updated
  • No secrets or credentials included

Two defects in the PR title check, both surfaced while opening the
OSM-1713 stack.

The `[N/M]` prefix this repo uses for stacked PRs has never matched the
pattern, which anchors on an optional `[BREAKING]` followed by module
brackets. Every stacked PR merged so far failed this check — #277, #279,
#280, #281, #283 through #288. The convention and the gate disagreed, and
the convention won by being ignored. The pattern now accepts an optional
leading `[N/M]`; nothing else about it changes, so malformed titles still
fail.

The step also gated on `github.actor`, which is whoever triggered *this
run* rather than who opened the PR. When a bot touched a human's PR — a
review app pushing a commit, say — the step was skipped, and a job whose
only step is skipped reports success. A failing title silently turned
green, depending on who happened to trigger the most recent run. Observed
on #291: the run triggered by `cubic-dev-ai[bot]` reported `check-title
pass` with an empty log, while the run triggered by the author on the same
title failed. Gating on `github.event.pull_request.user.login` keeps the
intended bot-PR exemption without letting bot activity mask a real
failure.

Also documents the `[N/M]` form in CONTRIBUTING.md and the PR template,
which likewise never mentioned it.
@JoyboyBrian JoyboyBrian added the bug Something isn't working label Aug 6, 2026
@JoyboyBrian
JoyboyBrian requested a review from BaiqingL as a code owner August 6, 2026 23:54
@JoyboyBrian JoyboyBrian added ci CI/CD related bug Something isn't working labels Aug 6, 2026
…pr skill

The skill drove the title this PR's regex change now accepts, and it said
nothing about stacked PRs — so following it produced titles the repo's own
convention contradicts. Adds the `[N/M]` form, its ordering relative to
`[BREAKING]`, and two bad examples covering the orderings that look
plausible but fail.

Also records how the stack itself gets created. Base pointers alone leave
the PRs unlinked on GitHub, which owns a separate stack object driving the
navigation UI and base rebasing on merge. `gh stack submit` is
interactive; `gh stack link` is the path that works non-interactively and
against PRs that already exist.
@JoyboyBrian JoyboyBrian added the documentation Improvements or additions to documentation label Aug 7, 2026
JoyboyBrian added a commit that referenced this pull request Aug 7, 2026
## What

- Reformat `tests/unit/rollout/test_harbor_backend_v2.py` so it
satisfies `ruff format --check`.
- Annotate `HarborBackendV2.native_agent_kwargs` as `dict[str, Any] |
None`.

## Why

`main` is currently red. Its most recent Tests run fails on two
independent checks, and every branch cut from it inherits both —
including #294, whose two failures are entirely this, not anything that
PR changed.

`lint` fails because `tests/unit/rollout/test_harbor_backend_v2.py` does
not satisfy `ruff format --check` under the pinned ruff 0.16.0.
Reproducible locally with the same version: `git show
main:tests/unit/rollout/test_harbor_backend_v2.py > /tmp/t.py && ruff
format --check /tmp/t.py` reports one file would be reformatted. The fix
is the formatter's own output; no behavior changes.

`typecheck-pyright` fails on the `--verifytypes` step, which reports
`native_agent_kwargs` as "missing type annotation and could be inferred
differently by type checkers". The attribute is assigned a conditional
expression, and pyright will not commit to a type other checkers are
guaranteed to agree on. Annotating it explicitly restores a clean run
and does not change the value.

Both fixes are also present in #291, which is part of a larger stack
that is not merging yet. Pulling them out lets `main` go green now
rather than waiting on that review.

## How to Test

- `uv run ruff check . && uv run ruff format --check .`
- `uv run pyright osmosis_ai/` — 0 errors.
- `uv run --no-editable pyright --verifytypes osmosis_ai
--ignoreexternal`, filtered the way `.github/workflows/tests.yml`
filters it (skipping the `agent_adapter`,
`convert_sample_to_trajectory`, and `harness_agent` baselines), reports
no remaining errors.
- `uv run pytest` — 2019 passed.

## Checklist

- [x] PR title follows `[module] type: description` format
- [x] Appropriate labels added (e.g. `enhancement`, `bug`, `breaking`)
- [x] `ruff check .` and `ruff format --check .` pass
- [x] `pyright osmosis_ai/` passes
- [x] `pytest` passes (new tests added if applicable)
- [x] Public API changes are documented
- [x] No secrets or credentials included

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Restore CI by fixing `ruff` formatting and `pyright --verifytypes`
failures on main. Reformats
`tests/unit/rollout/test_harbor_backend_v2.py` and annotates
`HarborBackendV2.native_agent_kwargs` as `dict[str, Any] | None`, with
no behavior changes.

<sup>Written for commit fa2dc94.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/Osmosis-AI/osmosis-sdk-python/pull/295?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->
Follow-up on three defects found reviewing the previous commit, plus a wip
label. The reconcile step moves from inline Bash to actions/github-script,
which is what makes the first two tractable.

Reconciliation removed any label in its managed list that the current title
did not imply, with no notion of who applied it. A `documentation` label a
human added to a `[ci] fix:` PR that also touches the docs was deleted on the
next title edit. The timeline API attributes every `labeled` event to an
actor, so the job now removes only labels carrying `github-actions[bot]`
attribution; anything a person applied is a deliberate override and survives.
A label with no timeline entry yet is treated as human, so the conservative
outcome of a race is to keep it. Attribution is required *in addition to* the
managed list rather than replacing it: `github-actions[bot]` is a shared
identity, and without the list a future labeling workflow's labels would
become fair game for this one.

That change only holds if nothing else applies those labels as a human. The
create-pr skill did exactly that, via `--label` on create, so its labels were
pinned to whatever the title said on day one and never tracked an edit. The
skill now applies none of them and says why.

A title that did not parse produced an empty derived set and wiped every
managed label. It now fails the job and writes nothing.

Reading the current labels via `gh pr view` inside a process substitution
discarded the exit status, so an API failure silently degraded to the old
add-only behaviour. The payload already carries the labels, so the call is
gone rather than hardened.

Also derives `wip` from GitHub's own draft state — no third optional title
prefix for contributors to order against `[N/M]` and `[BREAKING]` — and
writes the final set with a single setLabels PUT instead of separate remove
and add calls.

pull-requests: write covers both endpoints; GitHub lists the timeline read
and the label write under either Issues or Pull requests.
@JoyboyBrian
JoyboyBrian merged commit cae8d03 into main Aug 7, 2026
8 checks passed
@JoyboyBrian
JoyboyBrian deleted the brian/osm-1713-fix-pr-title-check-stack-prefix branch August 7, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ci CI/CD related documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant