ci: harden and document the release procedure#268
Conversation
🦋 Changeset detectedLatest commit: 97d82b7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
I understand that there are no changesets, but there should be one, or at least there should be a recommendation about the version impact. In a perfect world, we would at least see the next version calculated based on conventional commits and semantic release conventions. So in this case, there are two commits that contain the prefix fix. And for those, that should trigger a patch increase. Now obviously when the PR lands, it would be a single patch level increase, not multiple patch level increases. I also wonder what happens if we don't have a change set and instead we decide to roll together n number of changes in a specific build. In that case, I suppose the next time we went to go do a change set, it would calculate and find the highest version bump that was available. The problem with that is that now we have a batching problem. In lean software engineering, you'd want to be releasing more often. So the fact that there is a PR without a changeset to me feels like a smell or as possibly an anti pattern. I'm willing to have the conversation and there are no right answers here. There are just a bunch of potentially wrong ones. So please take this as more of a, let's think about this – this is feedback v "sosmething here is wrong." I think this is suboptimal right now, and I think that we can probably improve it. Those of us who are handling releases have the confidence that we're doing the right thing for each individual PR and that we're shipping improvements to the community as fast as humanly possible and as responsibly as our mission demands. For things like patch releases that may address small issues (and don't necessarily rise to the level of a point increase), most consumers will allow patch level increases for things like security fixes, or small bugs. But even we shouldn't wholesale be adopting point level increases, especially when we consider things like supply chain attacks. Small PRs that are patch fixes and bug fixes tend to get approved as long as the change set is relatively small. The size of a change and its "reviewability" are a signal about a given change's impact, and smaller changes should receive careful-enough scrutiny to avoid loosening security or introducing other subtle bugs, especially since so many of us allow these patch-level increases automatically (like Dependabot, e.g.) Things like point increases should trigger much more diligence. Our downstream dependencies and their transitive dependencies may have wider wider version ranges that they accept. But generally speaking, in this day and age, we should be pinning specific versions and maybe allowing for patch increases. And we should probably be telling our consumers and partners to do the same. |
jhampton
left a comment
There was a problem hiding this comment.
Please take the feedback and make sure it's captured in this repo as learning (agents, skills, etc). Some of these need @davidfedor consulted if not deciding. We can (and should) defer landing this until we have clear decisions, then pin those behaviors with both deterministic (code/config) guardrails and semi-deterministic (Greptile, AGENTS.md) rules.
jhampton
left a comment
There was a problem hiding this comment.
Resolved the two questions. Lookin' good.
578c2b4 to
7f7ece4
Compare
…ardening # Conflicts: # pnpm-lock.yaml
Ports the release-hardening work from YPE-2486 to the React SDK.
What's here
origin/maintip, huskycommit-msghook, and config (allows theYPE-####prefix, ignores the release commit). Ported from the Kotlin SDK.Greptile Summary
This PR hardens the React SDK release procedure by porting CI guardrails from the Kotlin SDK and documenting 10 failure modes for npm/Changesets workflows. It adds four new GitHub Actions workflows (commitlint, PR title lint, changeset gate, and workflow comments), corepack-aware Husky hooks implementing Decision 2, and companion documentation (
RELEASE-RUNBOOK.md,docs/release-hardening-plan.md).amannn/action-semantic-pull-request@v6), per-commit commitlint anchored togit merge-base origin/main, and a hard-fail changeset-per-PR check that exemptschangeset-release/main.commit-msgandpre-commitprefercorepack pnpmand fall back to barepnpmwhere corepack isn't available, enforcing the repo-pinned pnpm version.RELEASE-RUNBOOK.mdcovers 10 failure modes using correct per-package tags (@youversion/platform-core@$VERSION);docs/release-hardening-plan.mdrecords the keep-Changesets decision and AC status — though its AC6 section still describes aheaderPatternforYPE-####ticket prefixes that was removed per Decision 1 and is absent fromcommitlint.config.js.Confidence Score: 4/5
Safe to merge once the stale ticket-prefix documentation in docs/release-hardening-plan.md is corrected or removed.
The code changes are correct and well-reasoned throughout — workflows, hooks, and the commitlint config all implement the documented decisions faithfully. The one concrete defect is in docs/release-hardening-plan.md: the 'Ticket prefix allowed' paragraph in the AC6 section describes a headerPattern for YPE-#### prefixes that was explicitly removed per Decision 1 and does not exist in commitlint.config.js. A contributor following that documentation would try the described format and hit an unexpected commitlint failure on every commit.
docs/release-hardening-plan.md — the AC6 'Ticket prefix allowed' section contradicts both Decision 1 and the actual commitlint.config.js.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD PR([Pull Request opened / updated]) --> PT[pr-title.yml\namannn/action-semantic-pull-request\nLints PR title as Conventional Commit] PR --> CL[commitlint.yml\npnpm exec commitlint\nLints individual commits in range] PR --> CS[changeset.yml\nDetects added .changeset/*.md\nExempts changeset-release/main] PR --> CI[ci.yml\nBuild · Test · Lint · Typecheck\nNode 24 LTS] PT -->|Pass| MERGE{Merge to main\nsquash-merge} CL -->|Pass| MERGE CS -->|Pass| MERGE CI -->|Pass| MERGE MERGE --> RA[release.yml\nchangesets/action\nOpens Version Packages PR] RA --> VPR([Version Packages PR\nmanual approval gate\nfor major bumps]) VPR -->|Merge| PUB[Trusted Publishing\n+ NPM_TOKEN fallback\npnpm publish per package] PUB --> TAG[Per-package git tags\n@youversion/platform-core@V\n@youversion/platform-react-hooks@V\n@youversion/platform-react-ui@V] CS -->|No changeset| FAIL1([PR blocked\npnpm changeset or\npnpm changeset --empty]) PT -->|Not conventional| FAIL2([PR blocked\nfix PR title]) CL -->|Bad commit msg| FAIL3([PR blocked\nfix commit messages])Reviews (12): Last reviewed commit: "Merge branch 'main' into ks/YPE-2486-rel..." | Re-trigger Greptile