Auto-Merge Renovate PRs #277
Closed
opened 2026-05-27 05:31:45 +00:00 by guettli
·
4 comments
No Branch/Tag Specified
main
issue-563-agentloop-validation
dummy-pr-test
issue-560-fix-firebase-run-url
issue-539-stable-imap-uid
issue-533-shared-email-list
plan-issue-555
drop-nix
plan-issue-484
plan-issue-539
plan-issue-535
plan-issue-474
plan-issue-533
fix-dagger-engineless-precommit
issue-521-fix-deploy-yml-wait-time-api
issue-502-fix-email-id-collision-mailbox
issue-492-eliminate-duplicate-build-runner
issue-494-website-change-detection
issue-491-parallelize-check
issue-478-fix-stalwart-dual-stack-bind
issue-475-allowed-addresses-glob
issue-473-search-result-reorder
issue-453-update-agentloop-defaults
issue-466-structured-search
issue-505-exclude-chaos-monkey-from-regular-ci
issue-509-fix-search-result-sorting
fix-ink-sparkle-remaining-tests
issue-506-fix-search-emails-tests
issue-504-runner-wait-time
issue-488-search-notes
issue-472-changelog-issue-links
issue-501-folder-search-local-sqlite
issue-486-fix-stale-test-shader-mismatch
fix/prevent-settled-search-rerun-473
issue-467-fix-search-stale-results
issue-446-installed-versions-in-changelog
issue-462-fix-pr
issue-448-chaos-monkey-test
issue-436-notes-on-emails
issue-429-unify-mail-display
issue-422-move-to-folder-create-new
issue-414-ensure-not-run-as-root
issue-424-unify-email-list-views
issue-419-trusted-senders-page
issue-425-fix-prs
test-foo
issue-421-bug-report
issue-383-fix-ci
issue-394-fix-deploy-flutter-version
issue-391-fix-ci-double-trigger
issue-376-combined-inbox-v2
issue-376-combined-inbox
issue-384-fix-open-prs
sops-migrate
issue-339-safe-first-on-imap-fetch
issue-340-try-catch-measure-height
issue-342-pin-intl-version
issue-341-guard-threademails-last
issue-335-agentloop-code-test
issue-329-fix
issue-315-fix
issue-320-fix
issue-325-fix
issue-312-fix
issue-311-fix
issue-305-fix
issue-304-fix
issue-299-fix
issue-300-fix
issue-298-fix
issue-296-fix
issue-294-fix
issue-289-fix
issue-288-fix
issue-287-fix
issue-286-fix
issue-277-fix
issue-282-fix
issue-280-fix
issue-272-fix
issue-268-fix
issue-267-fix
issue-266-fix
issue-258-fix
issue-260-fix
issue-257-fix
issue-253-fix
issue-216-fix
issue-251-fix
issue-249-fix
issue-question-fixes
issue-235-fix
issue-236-fix-v2
issue-237-fix
issue-236-fix
issue-228-fix
issue-217-fix
issue-214-fix
issue-213-fix
issue-208-fix
issue-205-fix
issue-204-fix
issue-203-fix
issue-202-fix
issue-129-fix
issue-161-fix
issue-160-fix
issue-201-fix
issue-210-fix
issue-198-fix
issue-200-fix
issue-144-fix
issue-199-fix
fix/playstore-upload-use-requests
issue-193-fix
issue-186-fix
issue-185-fix
issue-192-fix
issue-183-fix
issue-175-fix
issue-172-fix
issue-171-fix
issue-167-fix
issue-136-fix
issue-162-fix
issue-179-fix
issue-155-fix
issue-154-fix
issue-152-fix
issue-151-fix
issue-141-fix
issue-150-fix
issue-164-fix
migrate-to-dagger
task/d1-ci-matrix
task/a4-typeconverter-json
task/u7-onboarding-walkthrough
task/d3-sync-doc
task/a5-layer-boundary-lint
task/t5-golden-tests
task/p5-date-cache
task/s4-link-handling
task/p3-html-parse-isolate
task/u8-mark-all-read
task/u3-recent-searches
task/a3-jmap-injectable-http-client
task/r5-tls-error-handling
fix/playstore-redirect-retry
task/t3-repository-contract-tests
task/p2-email-list-pagination
task/p1-fts5-search
fix/playstore-upload-timeout
task/a1-email-detail-notifier
fix/upgrade-workmanager-0.9
fix/android-core-library-desugaring
task/p4-db-indexes
task/r3-html-error-boundary
task/d2-check-coverage
task/a2-email-tile
task/t4-migration-tests
task/t2-widget-tests
task/t1-email-repo-coverage
task/u6-connection-status
task/u4-push-notifications
task/u2-draft-sync
task/u1-list-unsubscribe
task/s2-hostname-validation
task/r6-reliability-fuzz-tests
task/r4-sync-error-banner
task/r2-force-resync
task/r1-undo-history-persistence
No results found.
Labels
Clear labels
NeedSupervisor
State/InProgress
State/Later
State/Planned
automerge
ci-failure
do-not-merge
loop/code
loop/code-ci-pending
loop/code-done
loop/code-in-process
loop/merge
loop/merge-done
loop/merge-in-process
loop/plan
loop/plan-done
loop/plan-in-process
Issue escalated to a human supervisor; agentloop will skip it until cleared.
Eligible for automatic merge by CI
Issue opened by agentloop to track a failing CI workflow; used for deduplication.
Plan PR — review only, do not merge.
Add to run the built-in "code" prompt; override at prompts/code.md.
Prompt "code" finished; waiting for the PR's CI to pass before advancing.
Prompt "code" finished successfully.
Agent for the "code" prompt is currently running on this issue.
Managed by agentloop
Managed by agentloop
Managed by agentloop
Add to run the built-in "plan" prompt; override at prompts/plan.md.
Prompt "plan" finished successfully.
Agent for the "plan" prompt is currently running on this issue.
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: guettli/sharedinbox#277
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
We use Renovate, which creates PRs like this:
https://codeberg.org/guettli/sharedinbox/pulls/275
Update plan.
do automerge via ci.yaml.
But Renovate should only do updates which are considered "safe".
Implementation Plan: Auto-Merge Renovate PRs
Background
Renovate PRs (e.g. #275) are currently created by
guettlibotwith branches namedrenovate/.... Automerge is shown as "Disabled by config" in PR descriptions becauserenovate.jsondoes not setautomerge: true.The codebase already has sophisticated merge tooling (
scripts/agent_loop.pyusesfgj pr merge), so the plumbing exists — it just needs to be wired up for Renovate PRs.Recommended Approach: Add an
automergejob toci.ymlAdd a new dependent job at the end of
.forgejo/workflows/ci.ymlthat runs only when the existing CI job succeeds and the PR originates from Renovate.Why this over alternatives:
needs:)Step 1 — Modify
.forgejo/workflows/ci.ymlAdd a job like this after the existing CI job (replace
ciwith the actual job name in the file):The
if:condition ensures this job only runs for Renovate branches, not normal feature branches or pushes tomain.Step 2 (optional fallback) — Enable Renovate's native automerge in
renovate.jsonThis provides a fallback: if the workflow-based merge ever fails, Renovate will attempt the merge itself during its next daily run (06:00 UTC).
Files to Change
.forgejo/workflows/ci.ymlautomerge-renovatejob (primary implementation)renovate.jsonautomerge: true+ strategy (optional fallback)Risks & Open Questions
Token permissions — The job needs a token with merge rights.
RENOVATE_FORGEJO_TOKEN(already used inrenovate.yml) is the natural candidate since it belongs toguettlibot. Confirm it has thewrite:repository(or equivalent) scope to merge PRs.fgjavailability on runner — Theautomerge-renovatejob needsfgjinstalled. The self-hosted runner Dockerfile installstaskanddaggerbutfgjmay not be present. If not, either install it in the step or use the Forgejo REST API directly (curl -X POST .../pulls/{id}/merge).CI path filters —
ci.ymlcurrently only triggers on changes tolib/,test/,android/,linux/, etc. A Renovate PR that only touchespubspec.yamlorandroid/app/build.gradlemay or may not match those filters depending on exact paths. Verify thatci.ymlactually runs for the kinds of PRs Renovate creates (e.g. #275 updatesdesugar_jdk_libsin an Android Gradle file).Major version bumps — Should major dependency upgrades be auto-merged too, or only
patchandminor? Renovate supportsautomergescoped to update types viapackageRules. If you want to be conservative, restrict automerge to patch/minor only:The workflow-based approach should mirror the same logic (e.g. via PR title prefix
fix(deps)vsfeat(deps)!).Minimum stabilisation delay — Renovate supports a
minimumReleaseAgesetting (e.g."3 days") so brand-new versions aren't merged before potential security advisories surface. Worth considering for production dependencies.Branch protection — If
mainhas branch protection rules requiring a minimum number of approvals, the merge will fail unless the token is a repository admin or the rule exempts bots. Check repo settings.Summary
The cleanest path is a single new job in
ci.ymlplus optionally enabling automerge inrenovate.jsonas a fallback. The main prerequisite to confirm before coding is whetherRENOVATE_FORGEJO_TOKENhas merge permissions and whetherfgjis available on the CI runner.Planning complete. To resume this session:
Implementation Plan: Auto-Merge Renovate PRs
Overview
The goal is to automatically merge Renovate PRs that are considered "safe" once CI passes. The approach uses two layers:
renovate.json— classify which update types are safe viapackageRulesand add anautomergelabel to those PRs..forgejo/workflows/ci.yml— add a newautomergejob that runs after thecheckjob succeeds and merges the PR when it has theautomergelabel and was opened by Renovate.What counts as "safe"?
For this Flutter/Dart project, safe means low-probability-of-breaking-changes:
patch(1.2.3 → 1.2.4)minorfordev_dependenciesminorfor appdependenciesmajorlockFileMaintenancepin/digest(CI action SHA pins)File 1:
renovate.jsonAdd a
packageRulessection to label safe PRs withautomerge. Renovate's ownautomergeflag is intentionally not set — the merge is delegated to CI so that CI is the single gate.The
addLabelsfield is additive; the base"labels": ["dependencies"]already applies to all PRs.File 2:
.forgejo/workflows/ci.ymlAdd a new
automergejob at the end of the file. It:pull_requestevents (not pushes to main)checkjob to have succeededrenovate[bot]and the PR carries theautomergelabelWhy a dedicated
AUTOMERGE_TOKENsecret? The existingRENOVATE_FORGEJO_TOKENis scoped to Renovate's own operations. The merge step needs a token withrepository write(merge PRs) permission. Using a separate token limits blast radius.Required secret
AUTOMERGE_TOKENrepository write(merge) onguettli/sharedinboxThis can be the same Forgejo account as
RENOVATE_FORGEJO_TOKENbut stored as a separate secret, or a dedicated bot account.How the flow works end-to-end
packageRules→ adds theautomergelabel to the PR if it matches a safe rule.pull_requestevent), executestask check-dagger.checkpasses, theautomergejob runs, detects theautomergelabel, and squash-merges the PR.checkfails,automergeis skipped (needs: checkprevents it from running).Risks and open questions
Does
github.actorequal'renovate[bot]'on Codeberg/Forgejo?On GitHub this is
renovate[bot]; on Forgejo it may berenovate(without brackets). Check the actor name in an existing Renovate PR's workflow run logs before finalising theif:condition. Worst case, usecontains(github.actor, 'renovate').Label sync timing
The
automergelabel must be set before CI starts. Renovate sets labels when it creates or updates the PR, so the label should be present by the time the CIpull_requestevent fires. However, if Renovate fails to set labels (e.g., API timeout), CI will safely skip the merge.Minor app-dependency updates deliberately excluded
The plan excludes minor bumps for runtime
dependencies(only patch is safe). If experience shows that minor updates rarely break things in practice, the rule can be relaxed later.Squash vs. merge commit
Squash keeps the main branch history clean (one commit per Renovate PR). If a merge commit is preferred, change
"Do":"squash"to"Do":"merge".ci.ymlpath filterCurrently
ci.ymlonly triggers on PRs that touchpubspec.yaml,pubspec.lock,lib/**, etc. Renovate PRs that only updatepubspec.yaml/pubspec.lockwill match the path filter — but pure.forgejo/workflows/action-version updates will also match because.forgejo/workflows/ci.ymlis in the path list. This seems intentional and correct.Re-entrancy
If the merged Renovate commit triggers the
pushCI run onmain, that is a normal post-merge check and is not a problem.Planning complete. To resume this session: