Skip to content

Maintainer automation roadmap: self-managed releases, triage, and PR flow #161

@thomasttvo

Description

@thomasttvo

Why

Maintainer-time is the bottleneck. Today's friction points: hand-merging master into every open PR, manual release notes, unacknowledged issues, Claude review acting as a blocking oracle, and no changeset discipline. This issue scopes a phased rollout so each piece lands independently and delivers value on its own.

Invariant (target state)

Maintainer's active work reduces to three things:

  1. Triage decisions on accepted issues
  2. Yes/no on PR changesets (content review, not mechanical merging)
  3. Promoting canary → stable (a label flip, not a publish ceremony)

Everything else — versioning, release notes, npm publishes, branch updates, dependency PRs, stale issue cleanup — runs automatically.


Phase 1 — Stop the bleeding (days)

Foundation: protect the branch, standardize contributions, make issue reports actionable.

  • Branch protection on master: required typecheck + lint + unit tests + example-app build; dismiss stale approvals on push; enforce linear history; add CODEOWNERS on src/
  • Conventional Commits PR-title linter + squash-merge only policy — every merge produces a single, parseable commit
  • PR template with required sections: repro steps / before / after / changeset entry / breaking-change flag
  • Issue forms with required fields: library version, React Native version, platform (iOS/Android/both), Expo or bare workflow, Reanimated version, Snack or repro link
  • Auto-label from issue form metadata + PR title prefix (e.g., fix:bug, feat:enhancement)

Phase 2 — Releases run themselves (week)

Goal: merging a PR is the only manual step; everything downstream is automated.

  • Adopt changesets (or release-please) — every PR must include a .changeset/*.md entry; missing changeset = red CI check
  • Version Packages PR accumulates unreleased changes; merging it triggers: version bump → npm publish → git tag → GitHub Release with auto-generated notes
  • Continuous prereleases: every merge to master publishes x.y.z-next.N under the next npm dist-tag
  • Canary per-PR: publish 0.0.0-pr-<n>-<sha> on PR CI so reviewers can yarn add the exact change for drop-in testing
  • Stable release = label promotion on the Version Packages PR (no manual npm publish invocations)
  • SUPPORT.md: declared support window — latest minor + one minor back
  • DEPRECATED.md: breaking changes require a one-minor-release deprecation warning before removal

Phase 3 — PR flow runs itself (week)

Goal: eliminate merge toil and review bottlenecks.

  • GitHub merge queue enabled — queue-rebases safely, runs checks against the merge result, kills the "merge master into every PR" toil
  • automerge label → auto-merge when CI is green + required approvals met
  • Renovate or Dependabot with auto-merge on patch/minor bumps; major version bumps require human review
  • Review SLA bot: 5 days of silence → ping CODEOWNERS; 10 days → @-mention the PR submitter asking if still relevant
  • AI reviewers (Claude, Cursor, CodeRabbit) as advisory (non-blocking) checks — deterministic CI gates control merge eligibility, AI review informs but never blocks
  • Draft vs. ready-for-review enforced: draft PRs skip CI, reviewer assignment, and SLA timers

Phase 4 — Issue flow runs itself

Intake

  • Issue Forms (.github/ISSUE_TEMPLATE/*.yml) — bug, feature, question. Required fields: lib version, RN version, platform, Expo/bare, Reanimated version, Snack/repro link. Free-text only for "what happened"
  • Blank issues disabled
  • Auto-label on open from form fields: platform:ios|android, rn:<version>, area:zoom|pan|pinch|static-pin, reanimated:yes|no

Triage

  • needs-triage auto-applied on open; removed when any action label lands
  • Projects v2 board: needs-triage → needs-repro → accepted → in-progress → shipped
  • Bot comment on open: form summary + "maintainer triages within 48h"
  • Duplicate detector posts ranked possibly-related issues; maintainer closes with /duplicate #N
  • Triage SLA: within 48h every issue gets needs-repro / accepted (+size) / wontfix / duplicate

Repro enforcement

  • needs-repro auto-applied if repro-link field is empty or non-URL
  • Stale bot: needs-repro → comment at 7d, close at 14d; accepted exempt
  • cant-repro workflow: boilerplate ask for minimal Snack, 7d close

Categorization

  • Size labeler (size:XS/S/M/L/XL) from linked PR diff / discussion length
  • /severity <level> slash command from CODEOWNERS applies severity:*
  • Label changes sync to Projects custom fields (priority, area)

Communication

  • Status comments auto-posted on label transitions ("Moved to accepted — sized M, milestone v2.1")
  • PR ↔ issue linkage enforced; missing Closes #N / Fixes #N on non-chore PRs = red check
  • Release-closed notify: bot comments "Fixed in vX.Y.Z" on every issue closed by a release

Contributor funnel

  • good-first-issue + help-wanted surfaced in README (badge + live count)
  • First-time contributor welcome comment + CONTRIBUTING.md + DCO/CLA check
  • type:question issues auto-converted (or redirected) to GitHub Discussions

Anti-patterns (explicit non-goals)

  • Don't lock inactive threads (users need to say "still repros in v2.3"); only lock confirmed-fixed + released issues after 90d
  • Don't auto-close on inactivity alone — only when bot asked and got no answer
  • AI triage is advisory only (suggests labels/dupes as bot comments); humans decide

Metrics surfaced

  • Median open → accepted/closed time (triage SLA)
  • Open issues heatmap by area/severity
  • Stale accepted count (backlog rot)
  • Repro-rate % (drives form-field tightening)

Implementation

  • Tools: actions/stale, actions/labeler, dessant/label-actions, peter-evans/create-or-update-comment, actions/github-script, Projects v2 automation
  • Optional Claude/LLM advisory bot: suggest labels, summarize repro, flag dupes — bot comment, never auto-action

Target maintainer session

  1. Open Projects board → needs-triage column
  2. Per issue (~30s): accept (size+area) / ask repro / close-as-dup
  3. Done — bots handle chase, stale, notify, label

Phase 5 — Codebase enables the above (ongoing, tracked separately)

These are larger efforts that will each get their own tracking issue, linked back here:

  • Finish TypeScript migration (eliminate JSDoc @param types, complete ReactNativeZoomableViewProps interface)
  • Reanimated 3 + React Native Gesture Handler v2 conversion
  • Extract pan/zoom math into a pure, unit-tested core module
  • Example app as integration-test harness (Maestro or Detox on golden-path scenarios)
  • Stacked-PR workflow for the Reanimated conversion (vs. N parallel long-lived branches)

Out of scope (for this issue)

  • Specific library API changes — those get their own issues, linked from Phase 5 items
  • Migration of existing open PRs to the new flow — handled opportunistically as authors rebase

Order of operations

1 → 2 → 3 → 4 in series — each phase unblocks the next. Phase 5 runs in parallel starting whenever bandwidth allows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions