* fix(github): use base_tree in pushFiles to avoid org ruleset file-path restrictions (#42554)
pushFiles sent the entire repo tree to POST /git/trees without base_tree.
GitHub validates all file paths against org rulesets, rejecting the tree
when it contains protected files (e.g. semgrep.yaml) — even if Renovate
only changed unrelated paths.
Use base_tree (parent commit's tree) with only the changed files from
git diff-tree, so unchanged protected files are inherited without
validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(git): add coverage for getCommitTreeSha and diffCommitTree
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(test): assert specific files instead of hardcoding diff count
The test fixture creates 2 known files between develop and
defaultBranch (master_file, file_to_delete), but CI produces 3
changed files — likely a .gitattributes from the CI environment.
Assert on the known files rather than the total count.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(git): handle renames, copies, and submodules in diffCommitTree
- Regex now matches multi-char status codes (R100, C100) and
tab-separated source/target paths for renames and copies.
- Renames emit a deletion for the source path + addition for target.
- Derive tree item type from mode: 160000→commit, 040000→tree,
otherwise blob.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(git): address review comments in diffCommitTree
Keep git utility types centralized and make diff status handling easier to follow.
Made-with: Cursor
* test(git): cover rename handling in diffCommitTree
Verify that renamed files are emitted as a deletion for the old path and an addition for the new path, matching the tree delta expected by GitHub.
Made-with: Cursor
* fix(git): validate parsed tree SHA
Fail fast when commit output cannot be parsed into a tree SHA so pushFiles does not propagate an invalid base_tree, and cover the failure path in tests.
Made-with: Cursor
* fix(git): enable rename detection and cover remaining diffCommitTree branches
Add -M to diff-tree so Git emits R status for renames, exercising the
existing case 'R' handler. Add focused tests for rename parsing,
submodule mode (160000), and tree mode (040000).
Made-with: Cursor
* fix(git): clarify copy vs rename comment in diffCommitTree
R uses both tab-separated paths (delete old + add new), while C falls
through to default where only the target path matters.
Made-with: Cursor
* refactor(git): remove dead listCommitTree and TreeItem
Nothing imports listCommitTree after the switch to diffCommitTree with
base_tree. Remove the function, its regex, its test, and the TreeItem
interface.
Made-with: Cursor
* refactor(git): tighten DiffTreeItem.type to GitObjectType union
Define GitObjectType = 'blob' | 'tree' | 'commit' and use it in
DiffTreeItem and treeTypeFromMode instead of plain string.
Made-with: Cursor
* fix(git): remove unreachable nullish coalescing in getCommitTreeSha
split()[0] on a non-empty string is always defined, so the ?? ''
fallback was unreachable and caused an uncovered branch in Codecov.
Made-with: Cursor
* fix(git): add v8 ignore for partial branch on throw template literal
v8 reports template literal interpolations inside throw as partial
branch coverage even when the line is tested. Use the established
v8 ignore pattern to suppress the false positive.
Made-with: Cursor
* fix(github): guard pushFiles against empty diff from diffCommitTree
GitHub's POST /git/trees rejects an empty tree array with 422
"Invalid tree info". While prepareCommit already prevents no-op
commits from reaching pushFiles, add a defensive early return so
the failure mode is a clear log message instead of a swallowed 422.
Made-with: Cursor
* docs(github): document hybrid git/REST commit strategy in pushFiles
Restore architectural knowledge from PRs #13824 and #14271 that was
lost when the old "for reasons unknown" comments were replaced. The
push-then-recreate pattern exists because custom refs avoid CI triggers,
REST-created commits get GitHub signing, and GraphQL lacks force-push
and file mode support.
Made-with: Cursor
* fix(git): wrap bare regex literals in regEx() in tests
Use the project's regEx() helper instead of bare /pattern/ in
toMatch and stringMatching calls, consistent with repo conventions.
Made-with: Cursor
* fix(git): revert regEx() in expect.stringMatching (only accepts bare RegExp)
expect.stringMatching() is a Vitest/Jest API that requires a native
RegExp, not the wrapped object from Renovate's regEx() helper.
Made-with: Cursor
* fix(git): drop line count from v8 ignore next
Vitest uses ast-v8-to-istanbul which is AST-aware: it ignores the
entire next AST node (here the whole throw statement), making the
line count unnecessary.
Made-with: Cursor
* refactor(git): replace magic mode strings with GitTreeMode enum
Introduce a documented GitTreeMode enum in types.ts and use it in
treeTypeFromMode, replacing raw '160000'/'040000' literals with named
members linked to the git data model documentation.
Made-with: Cursor
* fix(git): use const object instead of enum for GitTreeMode
Node's TypeScript strip-only mode does not support enum syntax.
Use `as const` object pattern consistent with the rest of the codebase.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(config): add github to gitUrl supportedPlatforms
Declare GitHub as a supported platform for the gitUrl option so users
can configure ssh/endpoint URL resolution on github.com and GHES.
Wiring in the github platform module follows in subsequent commits.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(platform/github): fetch sshUrl from repoInfoQuery
Add sshUrl to the GraphQL repository query and to the GhRepo type so
the platform can resolve SSH-based git remotes. Typed as nullable
to match the gitlab pattern and to allow a missing-field error path.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(platform/github): add getRepoUrl helper
Introduce a getRepoUrl helper that returns the repository git URL based
on the gitUrl option:
- 'ssh' uses the sshUrl from the GraphQL repo response; throws
CONFIG_GIT_URL_UNAVAILABLE if not available
- 'default' and 'endpoint' build an https URL from the configured
endpoint with credentials embedded (current behavior)
The helper is unused in this commit; initRepo wiring follows.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(platform/github): support gitUrl in initRepo
Destructure gitUrl from RepoParams and replace the inline URL
construction with getRepoUrl calls. The working URL uses the fork's
ssh_url when running in fork mode, otherwise the GraphQL repo.sshUrl.
The upstream URL (used when forkCreation and a parentRepo is set)
uses repo.sshUrl, which is the parent's URL because the GraphQL
query runs before the fork swap.
GhRestRepo gains an ssh_url field so findFork/createFork responses
can carry the fork's SSH URL forward.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* test(platform/github): cover gitUrl branches
Add unit tests for getRepoUrl in utils.spec.ts and three integration
tests in index.spec.ts that exercise initRepo with gitUrl=ssh:
- ssh URL is forwarded to git.initRepo
- missing sshUrl with gitUrl=ssh throws CONFIG_GIT_URL_UNAVAILABLE
- fork mode uses the fork's ssh_url for url and the parent's sshUrl
for upstreamUrl
initRepoMock and forkInitRepoMock now include sshUrl in the GraphQL
response so existing tests continue to populate the field that the
new code path reads.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: note github-specific gitUrl behavior
Document that 'default' and 'endpoint' produce the same URL on GitHub,
that 'ssh' uses the repository's sshUrl, and that fork mode propagates
SSH selection to both the working URL and the upstream URL.
Refs: renovatebot/renovate#43086
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor(platform/github): pass parsed URL to getRepoUrl
Accept a pre-parsed URL in getRepoUrl instead of re-parsing the
endpoint string inside the helper. The endpoint is validated during
initPlatform so the helper no longer needs its own null check. The
caller now parses once and passes the URL to both initRepo call
sites; the helper clones it before mutating.
Also assert config.repository as non-null at the initRepo call site,
fixing the TS2345 error reported by the lint-other job.
* Update docs/usage/self-hosted-configuration.md
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* chore: migrate from zod/v3 to zod/v4
This commit contains the logic changes
* chore: migrate imports from zod/v3 to zod/v4
This contains import updates and adds explicit record keys as zod/v4 requires these now
* ci: enforce usage of zod/v4
* ci: add local mkdocs-admonitions plugin for prettier to allow admonition preservation
* docs: remove uses of `prettier-ignore` for admonitions
* test: rather use await expect
* chore: use named group exclusively
* docs: ensure 2 spaces used for generated admonitions
As a follow-up to 4b0146ab7b and
1844916259b6dc17f532e491eb93f6116327c324., this correctly renders
admonitions with 2 spaces (1 indent).
* fixup! docs: use 2-space indentation for Markdown (#43537)
Plus using 3-space for mixed-style `<ul>` and `<ol>`s.
* fixup! docs: use 2-space indentation for Markdown (#43537)
As otherwise it breaks the rendering of the table.
* fix(config/global): return default values for `GlobalConfig.get`
As noted in #39949, it can be awkward working with in `GlobalConfig.get`, where
we would previously need to specify the default value when calling `.get`,
which could lead to drift with the defaults for a given config option.
To reduce this risk, we can rely on a given `default` for a configuration
option, providing that as a default.
Because this now definitely returns a value that matches the config option, it
now allows us to remove `!` assertions.
* fixup! fix(config/global): return default values for `GlobalConfig.get`
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* fixup! fix(config/global): return default values for `GlobalConfig.get`
* test(presets): remove impossible test
As it's now not possible to set a value as `undefined` (as
`GlobalConfig` will then use the default), this test no longer validates
anything.
* test(workers/repository): add mock
Now `platform` defaults to `github`, we need to mock out the call to
fetch config.
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
* test: coverage
* test: coverage
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
* test(noNewURL): add new rule enforcing parseUrl() from 'lib/util/url.ts'
* replace newURL with parseUrl
* remove non-null assertions marks if appropiate
* test: add additional tests
* test: add additional tests and ignore where it makes sense
* implement suggestions
* test: further improve coverage
* apply suggestion
* fix(github): set commit message explicitly for platform automerge
When GitHub's "Use PR title and body as commit message" setting is
enabled, the verbose Renovate PR description gets used as the squash
commit body. Pass `commitHeadline` and `commitBody` to the
`enablePullRequestAutoMerge` GraphQL mutation so the actual commit
message is used instead.
* add REBASE test
* pr feedback
* fix: Add `github-digest` to `GITHUB_API_USING_HOST_TYPES` list
* fix(http): detect x-access-token prefix before hostType-based auth branching
Moves GitHub App installation token detection (`x-access-token:` prefix)
before the hostType-based authorization chain in `applyAuthorization`.
This ensures correct `token` scheme auth for any GitHub-related hostType,
not only those listed in `GITHUB_API_USING_HOST_TYPES`.
* test(http/auth): add regression test for GitHub App token with non-listed hostType
* Fixes
* Fix tests
* feat(vulnerabilities): add support for github-actions vulnerability alerts
* fix failed merge from main
* now for real
* review comments
* remove no longer needed assertion
As part of efforts to improve the performance of the `getPrCache`
function, we can add additional instrumentation to understand the time
taken.
This adds additional insight through our instrumentation functions, for
those using OpenTelemetry, as well as a `durationMs` for our logs.
* fix(github): prevent PR cache sync from exhausting all pages
* refactor(github): derive cutoff from cached items, simplify reconcile
- When lastModified is missing but items exist (via updateItem()),
derive cutoff from max(item.updated_at) instead of falling back
to reconcile's return value. Eliminates the fallback branch.
- reconcile() now called purely for side effects; return value ignored.
- MAX_SYNC_PAGES guard checks needNextPageSync (not needNextPageFetch)
to avoid spurious warning when cutoff already stopped the loop.
- Add test for mixed pages (Renovate + non-Renovate PRs interleaved).
- Update derived-cutoff test for caches without lastModified.
* fix(github): advance PR cache watermark from unfiltered page
* fix(github): add comment clarifying MAX_SYNC_PAGES is a safety net
As part of #39309 we enabled "Vigilant Mode" for the `@renovate-bot`
author.
To give an indication to folks who are self-hosting (on GitHub.com) and
using this Git commit author, we can provide a log message to let them
know.
This does not at all stop usage of this default committer email address,
but does provide a "nudge" to folks that they may see `Unverified`
commits pop up.
* use branchPrefix if multiple base branches expected
* fix test
* fix coverage
* apply suggestions
* apply suggestions
* use utility fn
* refactor tests
* fix test
* major overhaul: use baseBranches field internally
suggested by @secustor
* refactor: cleanup
* test: use better descriptions
* add tests
* fix logic
* fix test
* exclude unlisted versions when finding latestStable
---------
Co-authored-by: Rhys Arkins <rhys@arkins.net>
* fix: Use SHA of fresh branches when reopening PR
* Revert
* Add force push for differing local and PR commit SHAs
* Update GitHub PR reopening with local SHA
* Update GitHub platform PR reopening logic
* Fix
* Remove title-related changes, keep only force-push logic
According to the [GitHub Docs](https://docs.github.com/en/rest/repos/rules?apiVersion=2022-11-28#get-rules-for-a-branch), the definition of the non_fast_forward ruleset is: “Prevent users with push access from force pushing to refs.”
Even if this ruleset is applied, a head branch that lags behind the base branch can still be merged normally. In other words, this ruleset has nothing to do with whether a rebase is required.