* feat(gitlab): merge MRs through merge trains via the platform merge queue API
* feat(gitlab): report MRs waiting on a merge train through isPrInMergeQueue
* test(gitlab): drop targetBranch from mergePr calls
* Apply suggestion from @secustor
* refactor(gitlab): validate the merge train car response with a Zod schema
* test: replace manual process.env mutation with vi.stubEnv
Enable Vitest's `unstubEnvs` so env stubs are reverted automatically
before every test, and convert the manual `process.env.X = ...` /
`delete process.env.X` pairs in specs to `vi.stubEnv()`.
This removes the hand-written `afterEach` cleanup blocks and the
`const OLD_ENV = process.env` / `process.env = { ...OLD_ENV }`
save-restore dance, which silently leaked state between tests when a
test set a variable without a matching delete.
Left as-is (incompatible with `unstubEnvs`, which unstubs before each
test, not after):
- module top-level env writes (cocoapods, gomod, post-update, pip-compile
and bundler artifacts specs)
- `beforeAll` env writes -- the two in `util/http` moved to `beforeEach`
* test: stop asserting on ambient environment variables
Three specs asserted on values that the surrounding environment can
override, so they only passed on a machine that happened not to set them:
- `util/exec/env`: `getChildProcessEnv()` forwards every entry of
`basicEnvVars`, but the spec only seeded a subset. Any other forwarded
variable that was set ambiently (e.g. a lowercase `http_proxy`) leaked
into the `toEqual` assertion. Clear all of them first.
- `util/git/index`: `process.env.GIT_SSH_COMMAND` deliberately overrides
the default that the two env-inheritance tests assert on. Clear it.
- `logger/pretty-stdout`: the colorized level strings are built at import
time, so the `beforeEach` setting `FORCE_COLOR` could never affect them
-- it was dead code, and the test silently assumed a terminal without
colour support. Derive the expectation the same way the module does.
* test(datasource/nuget): use a throwaway cache dir for nupkg downloads
The `determine source URL from nupkg` tests do not mock the filesystem,
so they really wrote downloaded packages into a fixed `/tmp/cache` path.
That fails wherever the system tmpdir is not writable, and two checkouts
running the suite at once would share the same directory.
Use `tmp.dir({ unsafeCleanup: true })` and clean it up afterwards, which
is the pattern the other specs that touch disk already use.
* feat(lint): add renovate/prefer-stub-env rule
Enforces in specs what the migration to `vi.stubEnv` established:
- assigning to or deleting `process.env.X` inside `beforeEach`, `afterEach`,
`it` or `test` is reported, with a fixer that rewrites it to `vi.stubEnv()`
- module scope, `describe` bodies and `beforeAll` / `afterAll` are left alone:
`unstubEnvs` reverts stubs *before* each test, so a stub created there is
gone by the time the first test runs, and those must keep assigning directly
- replacing the `process.env` object is reported everywhere and never fixed.
`vi.stubEnv()` captures the original object when the worker starts, so after
a reassignment its deletes silently target the old object
The rule found 28 further violations in specs the earlier sweep missed, since
that one was anchored on `delete process.env`. Twelve were auto-fixed; the
rest replaced `process.env` wholesale and are now `clearEnv()` from test/util.
`util/exec/index.spec.ts` opts out with a comment: it asserts on the whole
child env, and `vi.stubEnv()` cannot express that because it maps `PROD`,
`DEV` and `SSR` onto '' instead of deleting them.
* feat(gitlab): add gitlab codeowners role support
* chore: use named group in roleRegex
* Update lib/config/options/index.ts
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* Update lib/modules/platform/gitlab/roles.ts
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* chore: rename getMembers to getGroupMembers
* chore: refactor getRoleMemberUsernames
* chore: adjust test chaining
---------
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* test: add linter for `as LongCommitSha` in test files
Adds a custom oxlint rule `renovate/prefer-fake-sha-in-specs` that flags
`as LongCommitSha` casts in spec files and suggests the deterministic
`fakeSha()` helper from `test/util` instead. Enabled at error level for
`**/*.spec.ts` and `test/**`; all 131 pre-existing casts across 22 spec
files replaced.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update lib/modules/platform/bitbucket-server/index.spec.ts
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): add renovate/no-host-rules-mock rule
Flags vi.mock()/vi.doMock() calls whose module specifier contains
"host-rules" in spec files. Tests should configure real rules via
hostRules.add() instead of mocking the host-rules module.
Enabled at "warn" severity instead of "error": the repo currently has
35 pre-existing violations across 34 spec files, which exceeds the
agreed fix threshold of 12 files. No violation fixes are included;
migrating each spec to real hostRules.add()/clear() setup is a
semantic test rewrite that should be done incrementally, after which
the rule can be promoted to "error".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): enforce renovate/no-host-rules-mock at error
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(datasource): use real host-rules instead of mocking
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(manager): use real host-rules instead of mocking
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(platform): use real host-rules instead of mocking
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(util,workers): use real host-rules instead of mocking
Also narrow renovate/no-host-rules-mock to the host-rules module itself so that mocking e.g. host-rules-from-env is not flagged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): mention '~test/host-rules.ts' util in no-host-rules-mock message
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): add prefer-partial-in-specs oxlint rule
Flags object literals cast to `any` (`{...} as any`) in spec/test files and steers toward `partial<T>()` from `test/util`. Enabled at error in the spec-files override so CI blocks new occurrences.
Closes#44646
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: drop unnecessary object-literal `as any` casts
The casts masked values already assignable to the expected type (migration configs accepted as Record<string, unknown>, all-optional param types, etc.); removing them restores real type checking.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: replace object-literal `as any` casts with partial<T>()
Uses partial<T>() from test/util so incomplete mock/config objects keep proper typing. Azure API mocks switch to mockResolvedValue(partial<T>()) and their inner method mocks to mockResolvedValue(), matching the sibling-file idiom.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: suppress prefer-partial-in-specs for intentionally-invalid inputs
Some tests deliberately pass malformed or legacy data to exercise validation/error paths, where no real type fits; keep the cast with a reasoned oxlint-disable-next-line.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* refactor(platform/gitlab): changed merge_request to detailed_merge_request.
* refactor(platform/gitlab): changed merge_request to detailed_merge_request in scehma.ts and in pr-cache-tests
* refactor(platform/gitlab): enums added for detailed_merge_requests #44114
* refactor(platform/gitlab): added enums for detailed_merge_status and unit tests modified #44114
* refactor(platform/gitlab): detailed_merge_status field added in pr-cache unit tests
* refactor(platform/gitlab): made detailed_merge_status optional and catch statement to handle newer status for future #44114
GitLab can return a non-string `message` in error bodies (e.g. validation errors as an object), which crashed `message.startsWith` with "err.body?.message?.startsWith is not a function". Guard with an `isString` check.
* feat(git): validate length commit shas
* test: adapt test mocks
* chore: update import paths
* feat(git): make the validation more strict and support repositories using sha256
* test: add fakeSha function for deterministic git commit shas in tests
When a GitLab project has merge trains enabled, automerged MRs are now added to the merge train via POST /projects/:id/merge_trains/merge_requests/:iid with auto_merge:true (GitLab 17.11+). Non-merge-train projects keep using the existing /merge endpoint, preserving Renovate's pipeline-success guarantee for free-tier users.
* fix(gitlab): skip branch status when no pipeline found, retry after PR creation
On GitLab with MR pipelines, posting a commit status without a
pipeline_id causes GitLab to create an unwanted branch pipeline.
Skip posting the status in setBranchStatus() when no pipeline is found
after retries. Retry setting branch statuses after ensurePr() in the
with-pr block so that the MR pipeline created by GitLab can be found.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(gitlab): gate skip-status-without-pipeline behind experimental flag
Move the behavior that skips setting a branch status check when no
pipeline is found behind the RENOVATE_X_GITLAB_SKIP_STATUS_WITHOUT_PIPELINE
experimental environment variable. Without the flag, the original
behavior of always posting the status is preserved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(gitlab): restore original 'sets branch status' test case
Keep the original test that verifies branch status is set without
the experimental flag alongside the new skip-behavior test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(docs): sort experimental env var headers alphabetically
Move RENOVATE_X_GITLAB_SKIP_STATUS_WITHOUT_PIPELINE after
RENOVATE_X_GITLAB_MERGE_REQUEST_DELAY to satisfy alphabetical
ordering requirement in self-hosted-experimental.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(gitlab): address PR review comments for skip-status-without-pipeline
Use strict `=== 'true'` check for env var, update docs wording, and
add test coverage for the new experimental flag behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Avoid unnecessary retry loops when merge_when_pipeline_succeeds is already
enabled on a merge request. This prevents wasting ~15 seconds per MR when
reattempting platform automerge on MRs with failed pipelines.
Co-authored-by: Ona <no-reply@ona.com>
* use getJson
* fix schema and tests
* make updated_at & target_branch non-optional
* convert head_pipeline[sha] to LongCommitSha type
* make assignee object nullable
* make head_pipleline nullable
* fix: revert some changes
* fix schema definition
* Apply Suggestions
* fix test
---------
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>