fix(ci): stop publishing on paths that cannot reach a consumer - #3098
Merged
Merged
Conversation
This was referenced Sep 2, 2026
mfal
force-pushed
the
claude/title-driven-release-gate
branch
from
September 2, 2026 12:06
cb6e273 to
b529f13
Compare
Contributor
Coverage Report for ./packages/components/
File CoverageNo changed files found. |
Contributor
🚀 Preview DeploymentPreview environments are ready:
Images:
|
mfal
marked this pull request as ready for review
September 2, 2026 14:16
mfal
marked this pull request as draft
September 4, 2026 06:43
The release denylist knew only repo-ROOT prefixes, matched with `startsWith`, so everything under `packages/**` counted as publish-relevant wholesale. 1.0.14 came from `packages/components/.storybook/preview.tsx` alone (#3010); 1.0.12 from a `scripts`-only package manifest, a package-local `CONTRIBUTE.md`, `dev/cross-version/**` and `src/tests/visual/**` (#3006). Neither reaches a consumer. Package-local denylist entries, segment-exact under `packages/<name>/` — `e2e-helpers/` is not `e2e/`: - `.storybook/**`, `e2e/**`, `src/tests/**`, `dev/cross-version/**`, `dev/vitest/**` - `Dockerfile` and `.dockerignore` — the Storybook preview image (#3008) - `*.stories.tsx` and `*.test.*` anywhere: `.test.` is not always the last extension (`*.browser.test.remote.tsx`) A package's root-level Markdown is judged against that package's `files` instead of by path — nothing builds one, so it reaches a consumer exactly if it is published. `flow-react-components` lists `AGENTS.md`, `MIGRATION.md` and `USAGE.md`; `remote-react-components` lists only `USAGE.md`, so ITS `AGENTS.md` reaches nobody. Markdown deeper in a package keeps its path-level relevance — `codemods/src/migrations/*/entry.md` is a generator input, not documentation. `packages/*/dev/**` is deliberately NOT denylisted wholesale: in `components` and `codemods` that directory IS the build. `dev/vite/*` holds the plugins `vite.build.config.ts` imports, `dev/createDocPropertiesJson.ts` writes the shipped `dist/assets/doc-properties.json`, `dev/remote-components-generator/**` generates `view.ts` and `src/auto-generated/**`, and `codemods`' build script is `tsx dev/generateCli.ts && …`. The key-diff refinement now applies to every `packages/*/package.json`, not just the root one: a `scripts`-only diff cannot reach a consumer. `publish.yml` therefore snapshots each changed manifest into `MANIFEST_SNAPSHOT_DIR` rather than the two `ROOT_MANIFEST_*` files. A failed fetch leaves the snapshot missing, which the classifier still reads as "relevant" — the behaviour before, and what an added or deleted manifest gets. The criterion is NO CONSUMER EFFECT, not "not in the tarball": a tarball carries the package's `scripts`, yet nothing a consumer installs reads them. `isPublishRelevant` is now a wrapper around `classifyPath`, which also returns the RULE that decided — that is what the skip notice prints. Verified: 35 classifier tests, run by the `decide` job before it classifies. Replayed every non-release commit on `main` since #2933 through the changed classifier — #3010 and #3008 flip to no-publish, and no commit that produced a legitimate release flips with them. `next` stays symmetric: docs-only `chore(sync):` merges produce no `-next.N` bump. Part of #3023 — the path half; the type half is a sibling PR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mfal
force-pushed
the
claude/title-driven-release-gate
branch
from
September 8, 2026 14:05
9ab9101 to
bd2307d
Compare
mfal
marked this pull request as ready for review
September 8, 2026 14:06
This was referenced Sep 8, 2026
mfal
enabled auto-merge (squash)
September 8, 2026 14:13
Member
Author
|
@copilot resolve the merge conflicts in this pull request |
…elease-gate # Conflicts: # docs/release-workflow.md Co-authored-by: mfal <4696750+mfal@users.noreply.github.com>
auto-merge was automatically disabled
September 15, 2026 08:01
Head branch was pushed to by a user without write access
Contributor
mfal
enabled auto-merge (squash)
September 15, 2026 08:45
ins0
approved these changes
Sep 15, 2026
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.
The release denylist knew only repo-root prefixes, matched with
startsWith, so everything underpackages/**counted as publish-relevant wholesale:packages/components/.storybook/preview.tsxalonescripts-only package manifest, a package-localCONTRIBUTE.md,dev/cross-version/**,src/tests/visual/**Package-local denylist entries, segment-exact under
packages/<name>/—e2e-helpers/is note2e/:.storybook/**,e2e/**,src/tests/**,dev/cross-version/**,dev/vitest/**CONTRIBUTE.md(no package lists it infiles)Dockerfileand.dockerignore— the Storybook preview image, built by CI fromdev/and.github/. ci: build the preview apps in CI and let the image only package them #3008 pushed both and nothing else underpackages/*.stories.tsxand*.test.*anywhere —.test.is not always the last extension (*.browser.test.remote.tsx)A package's root-level Markdown is judged against that package's
files, not by path — nothing builds one, so it reaches a consumer exactly if it is published.flow-react-componentslistsAGENTS.md,MIGRATION.mdandUSAGE.md;remote-react-componentslists onlyUSAGE.md, so ITSAGENTS.mdreaches nobody. Markdown deeper in a package keeps its path-level relevance:codemods/src/migrations/*/entry.mdis a generator input, not documentation.packages/*/dev/**is deliberately not denylisted wholesale: incomponentsandcodemodsthat directory is the build —dev/vite/*holds the pluginsvite.build.config.tsimports,dev/createDocPropertiesJson.tswrites the shippeddist/assets/doc-properties.json,dev/remote-components-generator/**generatesview.tsandsrc/auto-generated/**, andcodemods' build script istsx dev/generateCli.ts && ….The criterion is no consumer effect, not "not in the tarball": a tarball carries the package's
scripts, yet nothing a consumer installs reads them.The key-diff refinement applies to every
packages/*/package.json, not just the root one — ascripts-only diff cannot reach a consumer.publish.ymltherefore snapshots each changed manifest intoMANIFEST_SNAPSHOT_DIRinstead of the twoROOT_MANIFEST_*files. A failed fetch leaves the snapshot missing, which the classifier still reads as "relevant" — the behaviour before, and what an added or deleted manifest gets.isPublishRelevantis now a wrapper aroundclassifyPath, which also returns the rule that decided — that is what the skip notice prints.Verified
decidejob before it classifies.mainsince ci: skip the release for docs- and CI-only merges #2933 through the changed classifier: build(components): use the next-themes client entry in Storybook #3010 and ci: build the preview apps in CI and let the image only package them #3008 flip to no-publish, and no commit that produced a legitimate release flips with them.nextstays symmetric — docs-onlychore(sync):merges produce no-next.Nbump.docs/release-workflow.mdis cut back to the mechanics: what the classifier excludes and what it judges by content.Split out of this PR
This PR was three changes; each now has its own line, all rebased onto current
main.dist/types. Changes what the packages publish, not when.changelogPresetrendering every commit type. Relevance is decided by path, the changelog by type; two axes, two PRs.main. It is now standalone, and it depends on this PR: without the package-Markdown andDockerfilerules above it would fire on test(remote-react-components): extract the scenario-focus wait into a documented lib #3009 and ci: build the preview apps in CI and let the image only package them #3008, which reach nobody, and itsMANIFEST_SNAPSHOT_DIRwiring needs the classifier below. Merge this one first.A title-driven variant of the release gate (
[release]/[no-release]tags in the PR title) was built and withdrawn — the tag puts the decision in a hand-written token while the paths answer the question directly. The branch name still carries that withdrawn approach; the PR number is kept for its review history.Part of #3023 — the path half.
🤖 Generated with Claude Code