feat(merge-deps): extend to the GitLab forge - #219
Conversation
merge-deps was GitHub-only because its select-by-author guarantee rested on app/dependabot being a constant. GitLab has no constant — Renovate is always self-run there — so the identity comes from mergeDeps.gitlab.bot instead, and the guarantee is reproduced rather than traded away: exactly one identity, not a list, matched on the immutable id, with no way to say *how* authorship is decided. No identity configured under forge:gitlab stops the run rather than reporting an empty queue. Answers the three places GitLab does not mirror GitHub: the hand-back is Renovate's rebase checkbox and never GitLab's native /rebase, which rebases without regenerating a lockfile; security advisories are an Ultimate-only tier statement, never a silent zero; and the bump level is read from Renovate's own artifacts, with the highest bump in a request setting its tier. The merge method still comes from the forge — a branch ruleset on GitHub, the project's merge_method/squash_option on GitLab. Refs #187
ADR-0028 deferred merge-deps and release as GitHub-only. That clause held for release and no longer does for merge-deps, so ADR-0029 records what made the difference — a key that can only narrow — and ADR-0028 gains a dated addendum rather than being edited or superseded. Refs #187
|
AI review — changes requested (round 1 of 3, head TL;DR — the argument lands and the schema half is genuinely test-driven, but three of the new Checked: the issue's requirements against the diff, the 1.
|
Three recipes were wrong against the CLI they name, and all three are executed verbatim by an agent rather than read for sense. - `glab mr list --all` is a state widener, not a paging one: the list already defaults to open, so `--all` pulled closed and merged requests into assessment, the report and eventually `glab mr merge`. Dropped, with a note that a branch-pruning recipe passes it correctly for the opposite reason and so is not copy-pasteable here. - `glab api /graphql` resolves to `/api/v4/graphql` and 404s; the bare `graphql` keyword is what reaches `/api/graphql`. The 404 was indistinguishable from the Ultimate-tier answer, so a paying project would have been told its tier does not expose advisories. Also stated as a bullet where the tier rule itself is written. - `$tmp` was never defined in the hand-back recipe, so the redirect went to an empty path and the command failed outright. The substitution now stays in the pipeline, so there is no path to get wrong. Verified against glab 1.111.0 rather than from memory. Refs #187
…hold
`mergeDeps.gitlab.bot.id` carried no `minimum` and no `minLength` while
its sibling `login` required a non-empty string, so `{"id": "", "login":
"renovate-bot"}` validated and then compared an empty string against
`.author.id`.
It fails closed — nothing matches, nothing is touched — so it is not a
safety hole, but a run reads that as a healthy empty queue rather than
as a broken config, and the surrounding suite is otherwise careful that
half an identity is not an identity. An empty id is half an identity.
GitLab mints user ids from 1, so `minimum: 1` and `minLength: 1` reject
the empty string, zero and a negative without touching the string form
the key deliberately allows.
Refs #187
|
Re-work for round 1 — all four findings addressed, head TL;DR — the three defects were real; every 1.
|
|
AI review — accepted (round 2 of 3, head TL;DR — all three round-1 defects are genuinely fixed, and I re-probed each against Checked: the issue's requirements against the current diff; the three prior findings re-verified from the CLI's own help output; anchors, the The three findings — verified fixed, not just claimed
RequirementsEvery item the issue asked for is present and argued: one configured identity matched on the numeric id, no identity under Residuals — recorded, not blocking
RoundRound 2 of |
Summary
Docks GitLab on
merge-deps, with the skill's select-by-author guarantee reproduced rather than ported.The guarantee rested on a fact that holds only on GitHub:
app/dependabotis a constant the forge itself runs. GitLab has no constant — Mend's hosted app is offline indefinitely, so Renovate there is always self-run and its author is a per-repo, per-instance account. The identity therefore comes from the config, via a newmergeDeps.gitlab.bot({id, login}), and three properties are what keep that strictly narrower than a constant rather than a weakening:loginthere only for readability and forglab mr list --author; an id/login disagreement is the rename signal and the MR is left alone.No identity under
forge: gitlabstops the run, rather than reporting an empty queue — an empty queue reads as a healthy run, which is the one wrong way to fail here. The stop is a runtime rule, not a schema constraint, so a profile fragment stays valid on its own.The three places GitLab does not mirror GitHub, all answered:
<!-- rebase-check -->checkbox in the MR description. GitLab's native/rebaseis explicitly not the counterpart: it rebases and regenerates nothing, which is the lockfile hand-editing this skill forbids itself, reached through a button. Renovate is self-run, so the hand-back is reported and never waited on.Also settled, per the issue's open question: the merge method still comes from the forge, at whatever level the forge binds it — a branch ruleset on GitHub, the project's
merge_method/squash_optionon GitLab, whereffrequires a rebase andsquash_option: "never"makes--squasha rejection rather than a preference.merge-depsjoins the<skills-forge>roster (six carriers, not five), pinned bytest/isolation.test.ts.Type of change
Checklist
pnpm verifypasses locallySKILL.mdupdated (description, examples)Test discipline
The change is part prose and part schema. The schema half was test-driven: the seams are the issue body's own acceptance criteria — "matched on the numeric id", "names exactly one identity, never a selector type", "no identity configured → the skill stops" — written as
test/schema.test.ts's newmerge-deps' GitLab bot identitysuite and confirmed red beforemergeDeps.gitlab.botexisted. Every rejection in it is a way of widening the key: a bare login, a list, aselector, a branch prefix, half an identity. The<skills-forge>roster change intest/isolation.test.tswas driven the same way, red first. The prose half (SKILL.md,REFERENCE.md, the ADRs) drives no test discipline, as a prose-only change does not.Gate:
pnpm verifygreen in a fresh worktree afterpnpm install --frozen-lockfile— 204 tests, 0 failures.Related issues
Refs #187