Skip to content

ADR: Enforce changeset presence on dependency PRs touching published packages #824

@SnowboardTechie

Description

@SnowboardTechie

Summary

Today, a PR can bump a runtime dep under dependencies (or peerDependencies) in any of the four published packages (lib/core, lib/cli, lib/ts-sdk, lib/python-sdk) and merge to main without a corresponding .changeset/*.md entry. The lockfile and package.json move, but no version bump is produced, so the change ships in main without being recorded as a release of the published package.

This is a real drift gap, not a hypothetical one. Recent example: #821 bumped express 4.22.1 → 4.22.2 under dependencies in lib/cli/package.json. All CI checks passed green; there was no signal that a changeset was missing. Without intervention the bump would have merged and @common-grants/cli would have continued shipping the older transitive dep tree relative to its declared manifest.

We need to decide how to close this gap.

Options

Option A — Hard CI block via changeset status check on PRs.

Add a required check (the changesets-bot or changesets/action in status-check mode) that fails any PR touching lib/{core,cli,ts-sdk,python-sdk}/package.json (or pyproject.toml) without a corresponding .changeset/*.md in the PR's file list.

  • Pros: simple to configure, uses upstream tooling, applies uniformly to humans and bots.
  • Cons: every qualifying Dependabot PR needs a human to push a changeset onto the branch before merge. With Dependabot's grouped runtime PRs landing on a regular cadence, this adds non-trivial friction.

Option B — Auto-generate changesets for Dependabot PRs via a workflow.

A workflow triggered on pull_request from dependabot[bot] inspects the diff, detects published-package runtime/peer dep changes, and commits a patch-level changeset back onto the PR branch.

  • Pros: no merge-time friction; the gate is satisfied automatically; human PRs unaffected.
  • Cons: requires building and maintaining the workflow; needs careful permission handling (token with contents: write to push back); has to correctly classify dependencies vs devDependencies per file.

Option C — Hybrid.

Combine A and B: the hard block exists, but the auto-generation workflow runs first on Dependabot PRs so they satisfy the block without human intervention. Human-authored PRs still hit the block.

  • Pros: catches drift from any source while keeping the Dependabot flow ergonomic.
  • Cons: most setup work; two interacting pieces.

Decision Criteria

  • Prevents silent merges of published-package runtime dep changes without a recorded release.
  • Doesn't add merge-time friction for Dependabot PRs beyond what the maintainers are willing to absorb.
  • Setup and ongoing maintenance burden is proportionate to how often the gap actually triggers (today: sporadically, only when Dependabot touches dependencies in one of the four published packages).
  • Treats human-authored PRs and bot-authored PRs consistently from a drift-prevention standpoint.

Approvers

  • TBD

Acceptance criteria

  • The approvers for this decision have been identified (ideally before work on the ADR starts)
  • The ADR has been added to the list of ADRs in website/src/content/docs/decisions/adr/ with a number prefix like 0002-decision-summary.md
  • The ADR has been reviewed and approved by the approvers listed above
  • The ADR satisfies requirements that are outlined in the ADR template

Metadata

Metadata

Assignees

No one assigned

    Labels

    adrAn architectural decision to recordciIssue or PR related to CI/CD workflowsdependenciesPull requests that update a dependency filestewardshipCommunity stewardship transition tasks

    Type

    No fields configured for Task.

    Projects

    Status

    Todo

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions