Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Description
<!-- Briefly describe what this PR does and why. -->

## Checklist
- [ ] Tests pass locally
- [ ] CHANGELOG.md updated (if user-facing)
- [ ] TypeScript builds cleanly

## Feature-removal sweep
**Skip this section if this PR doesn't remove a route, handler, endpoint, model, or toggle.**

When removing a feature, ensure no orphan code is left behind:
- [ ] Orphan Prisma models removed (or depended-upon by other models)
- [ ] Broken or stale test files removed
- [ ] Unused type aliases removed
- [ ] Imports/exports cleaned up
- [ ] ADRs and CONTEXT.md cross-references updated
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Internal
- fix(ci): group $GITHUB_STEP_SUMMARY redirects in madge workflow to satisfy shellcheck SC2129 (#905)
- test(shared): add `coverageThreshold` gate to `packages/shared/jest.config.cjs` (no-regression floor at current baseline -2%, statements=19/branches=16/functions=15/lines=18) (#909)
- chore(process): add Feature-removal sweep checklist to PR template + advisory dangerfile guard that flags PRs with removal-pattern commits missing the sweep (#908)

## [2.11.0] - 2026-05-15

Expand Down
25 changes: 25 additions & 0 deletions dangerfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,31 @@ if (!validPrefixes.test(headRef) && !headRef.startsWith('worktree-')) {
)
}


// --- 9. Feature-removal sweep guard -----------------------------------------
// When a commit message indicates feature/route/model removal,
// flag if the PR body doesn't mention the sweep checklist.
const removalVerb = /\b(remove|delete|retire|drop|deprecate)\b/i
const removalTarget = /\b(route|handler|endpoint|model|toggle|feature)\b/i
const prBody = pr.body || ''
const hasSweepChecklistInBody = /feature-removal sweep/i.test(prBody)
const hasRemovalCommit = danger.git.commits.some(
(c) => removalVerb.test(c.message) && removalTarget.test(c.message),
)

if (hasRemovalCommit && !hasSweepChecklistInBody) {
const baseRepo = pr.base.repo.full_name
const baseRef = pr.base.ref
const adrPath = 'docs/decisions/2026-05-19-retire-per-guild-feature-toggles.md'
const adrUrl = `https://github.com/${baseRepo}/blob/${baseRef}/${adrPath}`
warn(
`This PR appears to remove a feature or route (detected in commit message). ` +
`Please fill in the **Feature-removal sweep** checklist in the PR template ` +
`to ensure no orphan code (models, tests, types, imports) is left behind. ` +
`[See ${adrPath}](${adrUrl}) for context.`,
)
}

// --- 8. Big-file warning ----------------------------------------------------
// Files > 500 lines are review-hostile. Flag new ones.
async function checkLargeFiles(): Promise<void> {
Expand Down
Loading