From a24d373b24057fc81dfce1eea0185f345095c451 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sun, 26 Apr 2026 01:22:28 +0200 Subject: [PATCH] fix: apply dependabot config via PR (branch protection blocks direct push) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Root cause After PR #19 added `required_pull_request_reviews` to the default branch, direct pushes to `main` from the bot are blocked. The deployed scheduler (now actually running, post-#21) immediately revealed this: every `generate-dependabot` task across the org failed with: > Could not create file: Changes must be made through a pull request ## Fix Set `change_strategy.use_pull_requests: true` in `config.yml`. The code path already exists in `src/dependabot.js:25-30` and `src/github-api.js:42-83` — it was just never enabled in config. Schema validation added for the new section. ## Cleanup needed after deploy Three rows in the deployed task store are stuck at `status=failed, attempts=3`. Their dedup keys block re-enqueue. Run on netcup to clear: ``` node -e 'import("./src/task-store.js").then(m => { const s = m.initTaskStore("./data/tasks.db"); s._db.prepare("DELETE FROM tasks WHERE status = ?").run("failed"); s.close(); })' ``` A `/retry-failed-tasks` ChatOps command is a sensible follow-up. ## Test plan - [x] All 698 tests pass - [x] eslint clean - [ ] After merge + deploy + manual cleanup: next time a non-bot PR opens in any org repo, the bot enqueues `generate-dependabot`, the scheduler claims it on the next tick, and the bot opens a `[temper] Configuration update` PR adding `.github/dependabot.yml`. ## Risk & rollout - Risk: low. Pure config flip. PR-creation path is well-tested (`__tests__/integration/github-api.test.js`). - Rollout: self-update on merge, then manual one-shot to clear the 3 permanently-failed rows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- config.yml | 14 ++++++++++++++ src/schema.js | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/config.yml b/config.yml index f843192..43937cf 100644 --- a/config.yml +++ b/config.yml @@ -63,6 +63,20 @@ controller_repo: # Reaction approvers must add to authorise provisioning. approval_reaction: "+1" +# Configuration changes (dependabot.yml, templates, CODEOWNERS) are applied via +# pull request rather than direct push. Required because branch protection +# (PR #19) blocks direct commits to default branches. +change_strategy: + use_pull_requests: true + pr_title: "[temper] Configuration update" + pr_body: | + Automated configuration update from the Temper bot. + + Review the changes and merge if they match the org standard. + pr_labels: + - automation + - dependencies + auto_merge: enabled: true on_dependabot: true diff --git a/src/schema.js b/src/schema.js index 1df4b08..880d532 100644 --- a/src/schema.js +++ b/src/schema.js @@ -140,6 +140,20 @@ export function validateConfig(config) { } } + if (config.change_strategy !== undefined) { + const cs = config.change_strategy; + if (typeof cs !== 'object' || cs === null) { + errors.push('change_strategy must be an object'); + } else { + if (cs.use_pull_requests !== undefined && typeof cs.use_pull_requests !== 'boolean') { + errors.push('change_strategy.use_pull_requests must be a boolean'); + } + if (cs.pr_labels !== undefined && !Array.isArray(cs.pr_labels)) { + errors.push('change_strategy.pr_labels must be an array'); + } + } + } + if (config.controller_repo !== undefined) { const cr = config.controller_repo; if (typeof cr !== 'object' || cr === null) {