Skip to content

ci(changelog): re-run the check when PR labels change - #6916

Closed
FarhanAliRaza wants to merge 3 commits into
mainfrom
farhan/changelog-label-trigger
Closed

ci(changelog): re-run the check when PR labels change#6916
FarhanAliRaza wants to merge 3 commits into
mainfrom
farhan/changelog-label-trigger

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

The `changelog` workflow gates on the `skip-changelog` / `changelog-version-edit` labels, but it only ran on the default `pull_request` types (`opened`, `synchronize`, `reopened`). Adding a label after the last push never starts a new run, and re-running the failed run replays the original event payload where the label does not exist yet, so the check keeps failing until someone pushes again (see run 32273787477 on #6866).

Add `labeled` and `unlabeled` to the trigger types so toggling a label re-evaluates the check with the current label set.

Review in cubic

@FarhanAliRaza
FarhanAliRaza requested a review from a team as a code owner August 19, 2026 16:51
@FarhanAliRaza FarhanAliRaza added the skip-changelog For doc/internal changes label Aug 19, 2026
@greptile-apps

greptile-apps Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The changelog workflow now reruns when pull-request labels change and reads the current labels through the GitHub API, ensuring changelog waivers are reevaluated rather than relying on stale event payloads.

  • Adds labeled and unlabeled pull-request event triggers.
  • Grants read access to pull-request metadata.
  • Uses API-derived label outputs for changelog and version-heading checks.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
.github/workflows/changelog.yml The workflow consistently fetches current PR labels and applies those outputs across all label-dependent checks; no eligible follow-up defect was identified.

Reviews (3): Last reviewed commit: "ci(changelog): restore the label trigger..." | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Aug 19, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

βœ… 27 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing farhan/changelog-label-trigger (105cefe) with main (d86f167)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 1 file

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread .github/workflows/changelog.yml
@masenf

masenf commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Reviewbot comment seems legit. Can you also apply this change to the template CI workflow that's part of reflex-release

The skip-changelog and changelog-version-edit gates read
github.event.pull_request.labels, which is a snapshot taken when the run
was queued. A label applied after the last push is invisible to the run,
and "Re-run failed jobs" replays that same stale payload, so the check
keeps failing until someone pushes again.

Read the labels from the API at job time instead, so a re-run picks up
the current label set. This removes the need for the labeled/unlabeled
trigger types added earlier on this branch, which fired for every label
on every PR and cancelled in-progress runs for no change in outcome.

Same approach aiohttp uses for its CHANGES-fragment check.
@FarhanAliRaza FarhanAliRaza removed the skip-changelog For doc/internal changes label Aug 21, 2026
Dropping labeled/unlabeled left the opposite bug: removing skip-changelog
produced no run at all, so the green computed while the label was applied
stayed as the check's verdict and the gate silently stayed open.

The verdict is only valid for the label set it was computed under, so a
label change has to start a run. Keep the API read too: it is what makes
"Re-run failed jobs" pick up the current labels instead of replaying the
queued payload.
masenf pushed a commit that referenced this pull request Aug 27, 2026
Ports #6916 into the reflex-release changelog template, so the fix applies
to every repository the tool scaffolds rather than to this one's copy of a
workflow that is now generated.

skip-changelog and changelog-version-edit waive parts of the check, so a
verdict is only valid for the label set it was computed under. Three ways
that broke: applying a label after the last push started no run at all,
removing one left the green run that label produced standing with the gate
silently open, and re-running a failed run replayed the original event
payload β€” where the label does not exist yet β€” so the check kept failing
until someone pushed again.

So: labeled/unlabeled join the trigger types, and the labels are read back
from the API into a step output the two guarded steps test, in a step that
runs before the checkout because it needs nothing but `gh`. The job itself
stays ungated: a job skipped by `if` reports its check as skipped, which
branch protection counts as passing, so a cheap no-op on an unrelated label
would overwrite a real failure with a green.

Regenerated reflex's own changelog.yml from the template. The jq program was
checked against the label sets it has to distinguish, running the generated
step itself against a stubbed `gh`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX
@masenf

masenf commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

ported into #6941

@masenf masenf closed this Aug 27, 2026
masenf added a commit that referenced this pull request Aug 27, 2026
…package (#6941)

* Replace the release workflows with the bundled reflex-release

The publish pipeline was a hand-maintained set of workflows over
scripts/release.py and .github/scripts/*. reflex-release, which lives in
this repository at packages/reflex-release, is that same pipeline packaged
and generalized, so the workflows now come from its templates instead.

Every reflex-specific behavior moves into [tool.reflex-release] in the
repo-root pyproject.toml: the reflex/reflex-base lockstep pair (one
version, exact pin rewritten at build time, reflex uploaded last), the
internal packages that patch-release on every push, the America/Los_Angeles
release timezone, and the packages exempt from the news-fragment check. The
.pyi check on the reflex wheel becomes the pipeline's post_build.sh hook,
and the dev-pin gate is now reflex-release's own check-dev-pins, which
reports identically to scripts/check_min_deps.py --check-dev-pins.

cli-command runs the copy in this repository straight from uv.lock rather
than a version published to PyPI:

    uv run --frozen --package reflex-release reflex-release

That pins the pipeline to one commit. The workflows are rendered from the
templates of the commit that contains them, so `sync --check` β€” which
changelog.yml now runs on every pull request β€” fails both on a workflow
edited by hand and on a template change that was never regenerated. The
two can no longer drift apart.

What changes in behavior, beyond the move:

- publish.yml splits validation, build and verification into separate
  unprivileged jobs and puts the SHA-256 manifest in front of the approver;
  the manifest is also attached to the GitHub release.
- changelog.yml also runs on pull requests targeting the publishing
  branches, and its release-branch exemption for version headings now
  requires the pull request to be authored by github-actions[bot].
- Dispatch release takes a comma-separated package list instead of one
  checkbox per package, which no longer fits GitHub's workflow_dispatch
  input limit.
- auto_release_internal.yml triggers on an internal package's src/ rather
  than its whole directory, matching what detection counts as its source,
  and diffs the whole pushed range instead of the last commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX

* Pin the release toolchain in reflex-release, restore the checkboxes

Four changes to the tool, and the regenerated workflows that follow from
them.

Pinned toolchain. New uv-version and python-version keys write the uv and
Python the generated workflows install verbatim into every setup-uv step,
in place of whatever that action resolves at run time. Both default to a
version reflex-release itself pins, so upgrading the tool moves the release
toolchain with it and `sync --check` reports that as drift until the
workflows are regenerated β€” the same signal a template change already
gives. A repository that wants its own cadence sets either key; "" leaves
that version to the setup action. Both are interpolated into a quoted YAML
scalar, so they are validated against a version-or-specifier pattern rather
than trusted.

The pins live in one rendered block instead of in each template, and a test
asserts every setup-uv step in every template carries the placeholder that
receives it: render() only fails on a placeholder it cannot substitute, so
a step added without one would otherwise silently install an unpinned uv.

Pinned build backend. reflex-release pins hatchling and
uv-dynamic-versioning exactly. Build requirements are resolved fresh rather
than locked, so a repository that vendors the tool β€” as this one now does,
running it out of uv.lock β€” no longer has the backend that builds its
release tooling move underneath it.

Checkbox limit. Ten was wrong: workflow_dispatch takes twenty inputs, and
this repository's own dispatch form has been running eighteen checkboxes.
Raised to nineteen packages plus the release action, which brings the
checkboxes back here β€” the comma-separated fallback was a regression, not a
fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX

* Regenerate the release workflows after merging main

Merge brings in two reflex-release changes that alter the templates:
dependency-pin lifting during materialize (#6889) and the skip-propagation
fix in publish.yml and release_from_changelog.yml (#6950). `sync --check`
flagged all three affected workflows as drifted, which is the mechanism
working β€” a template change on main that never reached this repository's own
workflows is exactly what it is there to catch. Regenerated; the uv and
Python pins and the dispatch checkboxes are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX

* Add never-publish-packages; append new Config fields

Both from cubic's review of #6941.

never-publish-packages, for the packages a repository builds but never
releases. changelog-exempt-packages was the closest thing, and it only
waives the news-fragment requirement β€” it left integrations-docs with a
release checkbox and publishable by hand, which the checkbox form made
visible. A listed package now gets no checkbox, is never auto-selected, is
skipped by changelog detection even when it has a CHANGELOG.md, needs no
fragment, and is refused by prepare-publish, so the one remaining way to
reach it β€” typing it into the publish workflow β€” fails in the first
unprivileged job rather than at verify-dist after a build. Being
unreleasable it cannot also be a lockstep member, a custom-build package,
latest-release-package or internal; each is rejected when the configuration
loads. integrations-docs moves to the new key, which drops it from the
Dispatch release form.

Config's new fields move to the end of the dataclass. It is exported, so
the generated __init__ has a positional contract: uv_version and
python_version sat after cli_command, shifting every later argument for a
caller that does not pass everything by keyword. A test pins the historical
field order as a prefix so the next field added lands in the right place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX

* Re-run the changelog check when pull request labels change

Ports #6916 into the reflex-release changelog template, so the fix applies
to every repository the tool scaffolds rather than to this one's copy of a
workflow that is now generated.

skip-changelog and changelog-version-edit waive parts of the check, so a
verdict is only valid for the label set it was computed under. Three ways
that broke: applying a label after the last push started no run at all,
removing one left the green run that label produced standing with the gate
silently open, and re-running a failed run replayed the original event
payload β€” where the label does not exist yet β€” so the check kept failing
until someone pushed again.

So: labeled/unlabeled join the trigger types, and the labels are read back
from the API into a step output the two guarded steps test, in a step that
runs before the checkout because it needs nothing but `gh`. The job itself
stays ungated: a job skipped by `if` reports its check as skipped, which
branch protection counts as passing, so a cheap no-op on an unrelated label
would overwrite a real failure with a green.

Regenerated reflex's own changelog.yml from the template. The jq program was
checked against the label sets it has to distinguish, running the generated
step itself against a stubbed `gh`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX

---------

Co-authored-by: Claude <noreply@anthropic.com>
@FarhanAliRaza
FarhanAliRaza deleted the farhan/changelog-label-trigger branch August 28, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants