Skip to content

Commit e7abf09

Browse files
authored
fix: release with authenticated github app (#57)
* feat: analyze current setup and define frictionless renovate requirements - Analyzed existing renovate.json with basic config:recommended - Identified CI/CD setup with GitHub Actions and automated testing - Defined comprehensive requirements for frictionless dependency management - Designed configuration approach with auto-merge and grouping strategies - Ready for implementation phase * docs: research comprehensive GitHub PR configuration options for Renovate - Documented 30+ PR-related configuration options from Renovate docs - Covered PR creation, timing, content, behavior, labels, assignment - Identified GitHub-specific features like milestone, platformCommit - Documented security/vulnerability PR handling and branch management - Ready to implement frictionless configuration with informed choices * fix: use GitHub App token to bypass branch protection in release workflow - Add GitHub App token generation using VERSION_BUMPER_APPID and VERSION_BUMPER_SECRET - Update checkout to use app token for git operations - Set GITHUB_TOKEN env var to app token for git push - Allows version bump commits to bypass branch protection rules Fixes release workflow failure after enabling branch protection for Renovate automerge setup.
1 parent 7935928 commit e7abf09

2 files changed

Lines changed: 339 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,18 @@ jobs:
3939
runs-on: ubuntu-latest
4040
steps:
4141

42+
- name: Generate GitHub App Token
43+
id: generate_token
44+
uses: tibdex/github-app-token@v1
45+
with:
46+
app_id: ${{ vars.VERSION_BUMPER_APPID }}
47+
private_key: ${{ secrets.VERSION_BUMPER_SECRET }}
48+
4249
- name: Checkout
4350
uses: actions/checkout@v4
4451
with:
4552
fetch-depth: 0
53+
token: ${{ steps.generate_token.outputs.token }}
4654

4755
- name: Setup Node.js
4856
uses: actions/setup-node@v4
@@ -85,6 +93,8 @@ jobs:
8593
git add package.json package-lock.json
8694
git commit -m "chore: bump version to $NEW_VERSION [skip ci]" || exit 0
8795
git push
96+
env:
97+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
8898

8999
- name: Create GitHub Release
90100
if: steps.version.outputs.new_tag
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
# Development Plan: responsible-vibe (configure-renovate branch)
2+
3+
*Generated on 2025-08-21 by Vibe Feature MCP*
4+
*Workflow: [minor](https://mrsimpson.github.io/responsible-vibe-mcp/workflows/minor)*
5+
6+
## Goal
7+
Configure Renovate to provide a frictionless dependency update experience with minimal manual intervention while maintaining code quality and stability.
8+
9+
## Explore
10+
### Tasks
11+
- [x] Analyze current project structure and dependencies
12+
- [x] Identify existing Renovate configuration (if any)
13+
- [x] Research frictionless Renovate best practices
14+
- [x] Define requirements for automated dependency management
15+
- [x] Design configuration approach for minimal friction
16+
- [x] Research GitHub PR configuration options
17+
- [x] Analyze and fix branch protection workflow issue
18+
19+
### Completed
20+
- [x] Created development plan file
21+
- [x] Analyzed project: Node.js/TypeScript project with npm, has basic renovate.json with config:recommended
22+
- [x] Found existing CI/CD: GitHub Actions with PR validation (Node 18, 20, latest) and automated tests
23+
- [x] Researched best practices for frictionless dependency management
24+
- [x] Defined comprehensive requirements for automated updates
25+
- [x] Designed configuration approach with auto-merge and grouping strategies
26+
- [x] Documented 30+ GitHub PR configuration options from Renovate docs
27+
- [x] Fixed release workflow to use GitHub App token for bypassing branch protection
28+
29+
## Implement
30+
31+
### Phase Entrance Criteria:
32+
- [ ] Current project structure and dependencies are analyzed
33+
- [ ] Frictionless Renovate requirements are clearly defined
34+
- [ ] Configuration approach is designed and documented
35+
- [ ] Best practices for automated updates are identified
36+
37+
### Tasks
38+
- [ ] *To be added when this phase becomes active*
39+
40+
### Completed
41+
*None yet*
42+
43+
## Finalize
44+
45+
### Phase Entrance Criteria:
46+
- [ ] Renovate configuration is implemented and tested
47+
- [ ] Automated dependency updates are working as expected
48+
- [ ] Configuration provides the desired frictionless experience
49+
- [ ] Documentation is complete and accurate
50+
51+
### Tasks
52+
- [ ] *To be added when this phase becomes active*
53+
54+
### Completed
55+
*None yet*
56+
57+
## Key Decisions
58+
59+
### Current State Analysis
60+
- **Project Type**: Node.js/TypeScript MCP server with npm package management
61+
- **Dependencies**: Mix of production deps (@modelcontextprotocol/sdk, js-yaml, sqlite3, zod) and dev deps (vitest, typescript, etc.)
62+
- **Current Renovate Config**: Basic setup with `config:recommended` preset only
63+
- **CI/CD**: GitHub Actions with PR validation across Node 18, 20, and latest versions
64+
- **Testing**: Automated test suite with `npm run test:run`
65+
66+
### Updated Frictionless Requirements (Automerge with CI)
67+
- **Automerge when CI checks pass** (user has good test coverage)
68+
- **Automatic PR creation** but silent merging when tests pass
69+
- **Grouped updates** to reduce PR noise for related dependencies
70+
- **Semantic commit messages** (project uses conventional commits)
71+
- **Respect CI/CD pipeline** - only merge when all checks succeed
72+
- **Different strategies** for patch vs minor vs major updates
73+
- **Security updates** get immediate priority
74+
75+
### Optimal Automerge Configuration Strategy
76+
**Patch & Dev Dependencies**: Auto-merge immediately when CI passes
77+
**Minor Updates**: Auto-merge for well-maintained packages
78+
**Major Updates**: Create PR for manual review
79+
**Security Updates**: Immediate auto-merge when CI passes
80+
**Lock File Maintenance**: Weekly auto-merge
81+
82+
### Configuration Design Approach - FINAL
83+
- **Base**: Extend `config:recommended` (current setup)
84+
- **Automerge**: Enable with `platformAutomerge=true` for GitHub native merging
85+
- **Grouping**: Group dev dependencies and related packages
86+
- **Schedule**: Allow updates during off-hours to avoid CI conflicts
87+
- **Safety**: Require all status checks to pass before merging
88+
89+
### Frictionless Requirements Identified
90+
- **Auto-merge capability** for low-risk updates (patch versions, dev dependencies)
91+
- **Grouped updates** to reduce PR noise
92+
- **Semantic commit messages** (project uses conventional commits)
93+
- **Respect CI/CD pipeline** and only merge when tests pass
94+
- **Schedule optimization** to avoid overwhelming maintainers
95+
96+
### Detailed Frictionless Requirements
97+
1. **Auto-merge Strategy**:
98+
- Patch updates for production dependencies (auto-merge when CI passes)
99+
- All dev dependency updates (auto-merge when CI passes)
100+
- Minor updates for well-maintained packages (with approval)
101+
102+
2. **Grouping Strategy**:
103+
- Group dev dependencies together
104+
- Group patch updates together
105+
- Separate major updates for individual review
106+
107+
3. **Scheduling**:
108+
- Non-office hours to avoid interrupting development
109+
- Limit concurrent PRs to avoid overwhelming CI
110+
111+
4. **Safety Measures**:
112+
- Require status checks (CI must pass)
113+
- Respect package.json constraints
114+
- Use semantic commit messages for changelog generation
115+
116+
### GitHub PR Configuration Options Available
117+
118+
Based on the comprehensive Renovate documentation, here are the key configuration options specifically for GitHub PRs:
119+
120+
**PR Creation & Timing:**
121+
- `prCreation`: When to create PRs (`immediate`, `not-pending`, `status-success`, `approval`)
122+
- `prConcurrentLimit`: Limit concurrent PRs (default: 10)
123+
- `prHourlyLimit`: Rate limit PR creation per hour (default: 2)
124+
- `prNotPendingHours`: Timeout for `prCreation=not-pending` (default: 25 hours)
125+
126+
**PR Content & Appearance:**
127+
- `prTitle`: PR title template (inherits from `commitMessage`)
128+
- `prTitleStrict`: Bypass appending extra context to PR title
129+
- `prHeader`: Text at the beginning of PR body
130+
- `prFooter`: Text at the end of PR body (default: Renovate Bot attribution)
131+
- `prBodyTemplate`: Controls which sections appear in PR body
132+
- `prBodyColumns`: Columns to include in PR tables
133+
- `prBodyDefinitions`: Custom column definitions for PR tables
134+
- `prBodyNotes`: Extra notes/templates in PR body
135+
136+
**PR Behavior:**
137+
- `draftPR`: Create draft PRs instead of normal PRs
138+
- `platformAutomerge`: Use GitHub's native auto-merge (default: true)
139+
- `automerge`: Enable Renovate's automerge functionality
140+
- `automergeType`: How to automerge (`pr`, `branch`, `pr-comment`)
141+
- `automergeStrategy`: Merge strategy (`auto`, `squash`, `merge-commit`, `rebase`, etc.)
142+
- `automergeSchedule`: Limit automerge to specific times
143+
144+
**PR Labels & Assignment:**
145+
- `labels`: Labels to set on PRs
146+
- `addLabels`: Additional labels (mergeable with existing)
147+
- `assignees`: PR assignees
148+
- `reviewers`: PR reviewers (supports `team:` prefix for GitHub teams)
149+
- `assigneesFromCodeOwners`: Auto-assign based on CODEOWNERS
150+
- `reviewersFromCodeOwners`: Auto-assign reviewers from CODEOWNERS
151+
- `assignAutomerge`: Assign reviewers/assignees even for automerge PRs
152+
153+
**PR Lifecycle Management:**
154+
- `rebaseLabel`: Label to trigger manual rebase (default: "rebase")
155+
- `stopUpdatingLabel`: Label to stop Renovate updates (default: "stop-updating")
156+
- `keepUpdatedLabel`: Label to keep PR updated with base branch
157+
- `rebaseWhen`: When to rebase PRs (`auto`, `never`, `conflicted`, `behind-base-branch`)
158+
- `recreateWhen`: When to recreate closed PRs (`auto`, `always`, `never`)
159+
160+
### Automerge Configuration Options
161+
162+
**Perfect! Here's the optimal "frictionless" automerge setup:**
163+
164+
#### Core Automerge Settings
165+
```json
166+
{
167+
"extends": ["config:recommended"],
168+
"platformAutomerge": true,
169+
"automerge": true,
170+
"automergeType": "pr",
171+
"automergeStrategy": "squash"
172+
}
173+
```
174+
175+
#### Selective Automerge by Update Type
176+
```json
177+
{
178+
"packageRules": [
179+
{
180+
"description": "Automerge patch updates and dev dependencies",
181+
"matchUpdateTypes": ["patch"],
182+
"matchDepTypes": ["devDependencies"],
183+
"automerge": true
184+
},
185+
{
186+
"description": "Automerge minor updates for trusted packages",
187+
"matchUpdateTypes": ["minor"],
188+
"matchPackageNames": ["@types/**", "eslint**", "prettier"],
189+
"automerge": true
190+
},
191+
{
192+
"description": "Manual review for major updates",
193+
"matchUpdateTypes": ["major"],
194+
"automerge": false
195+
}
196+
]
197+
}
198+
```
199+
200+
#### Security & Lock File Maintenance
201+
```json
202+
{
203+
"vulnerabilityAlerts": {
204+
"automerge": true
205+
},
206+
"lockFileMaintenance": {
207+
"enabled": true,
208+
"automerge": true,
209+
"schedule": ["before 4am on monday"]
210+
}
211+
}
212+
```
213+
214+
#### Grouping to Reduce PR Noise
215+
```json
216+
{
217+
"packageRules": [
218+
{
219+
"description": "Group dev dependencies",
220+
"matchDepTypes": ["devDependencies"],
221+
"matchUpdateTypes": ["patch", "minor"],
222+
"groupName": "dev dependencies"
223+
},
224+
{
225+
"description": "Group TypeScript ecosystem",
226+
"matchPackageNames": ["typescript", "@types/**"],
227+
"groupName": "TypeScript"
228+
}
229+
]
230+
}
231+
```
232+
233+
### CI Check Requirements for Automerge
234+
235+
**Important: The CI check condition is handled by GitHub + Renovate automatically:**
236+
237+
#### Default Behavior (Automatic)
238+
- **Renovate default**: Only automerges when ALL status checks pass
239+
- **GitHub branch protection**: Should be configured to require status checks
240+
- **No explicit config needed** - this is built-in safety
241+
242+
#### Explicit Configuration (Recommended)
243+
```json
244+
{
245+
"automerge": true,
246+
"platformAutomerge": true,
247+
"ignoreTests": false,
248+
"prCreation": "not-pending"
249+
}
250+
```
251+
252+
#### GitHub Branch Protection Setup Required
253+
You need to configure GitHub branch protection rules:
254+
1. Go to Settings → Branches → Add rule for `main`
255+
2. Enable "Require status checks to pass before merging"
256+
3. Select your CI workflow (e.g., "Pull Request Validation")
257+
4. Enable "Require branches to be up to date before merging"
258+
259+
#### Alternative: Explicit Status Check Names
260+
```json
261+
{
262+
"requiredStatusChecks": ["ci/github-actions"],
263+
"automerge": true
264+
}
265+
```
266+
267+
#### Safety Override (NOT recommended)
268+
```json
269+
{
270+
"ignoreTests": true,
271+
"automerge": true
272+
}
273+
```
274+
**⚠️ This would automerge WITHOUT waiting for CI - dangerous!**
275+
276+
### Branch Protection Issue Analysis
277+
278+
**Problem Identified**: Release workflow fails because version bump commits don't trigger CI checks, but branch protection requires them.
279+
280+
#### Current Workflow Issues
281+
1. **Version bump commit** uses `[skip ci]` - intentionally skips CI
282+
2. **Branch protection** now requires 3 status checks to pass
283+
3. **GitHub Actions token** can't bypass branch protection rules
284+
4. **Chicken-and-egg problem**: Need CI to pass, but CI is skipped
285+
286+
#### Current vs Suggested GitHub App Approach
287+
288+
**Current Workflow (Failing)**:
289+
```yaml
290+
- name: Update package.json version
291+
run: |
292+
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
293+
git push # Uses GITHUB_TOKEN - subject to branch protection
294+
```
295+
296+
**Suggested GitHub App Approach**:
297+
```yaml
298+
- name: Generate GitHub App Token
299+
id: generate_token
300+
uses: tibdex/github-app-token@v1
301+
with:
302+
app_id: ${{ secrets.APP_ID }}
303+
private_key: ${{ secrets.PRIVATE_KEY }}
304+
305+
- name: Update package.json version
306+
run: |
307+
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
308+
git push
309+
env:
310+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
311+
```
312+
313+
#### Key Differences
314+
1. **GitHub App token** can bypass branch protection (if configured)
315+
2. **App permissions** need "Contents: Write" and "Metadata: Read"
316+
3. **Repository settings** must allow app to bypass protection
317+
4. **Secrets needed**: `APP_ID` and `PRIVATE_KEY` for your created app
318+
319+
#### Alternative Solutions
320+
1. **Remove [skip ci]** and let version bump trigger CI (cleaner)
321+
2. **Use GitHub App** to bypass protection (your current approach)
322+
3. **Exclude version bump commits** from branch protection rules
323+
4. **Use semantic-release** which handles this automatically
324+
325+
## Notes
326+
*Additional context and observations*
327+
328+
---
329+
*This plan is maintained by the LLM. Tool responses provide guidance on which section to focus on and what tasks to work on.*

0 commit comments

Comments
 (0)