* refactor(util): one "read repo file at ref" helper per host The "fetch a single file from a repository at a ref" logic was implemented separately in the platform, preset and changelog layers for every host, and `lib/config/presets` reached into `lib/modules/platform` to reuse the Gitea client and its contents helper. Add per-host util modules that own the URL shape, the response schema and the decoding, taking the caller's own `Http` instance so the host type stays with the calling layer: - `lib/util/gitea/contents.ts` (shared by Gitea and Forgejo): the `RepoContents` and `ContentsListResponse` schemas, `getRepoFile()` and `listRepoDir()` - `lib/util/github/contents.ts`, `lib/util/gitlab/files.ts`, `lib/util/bitbucket/files.ts`: `getRepoFile()` Callers rewired: `getRawFile` for github/gitlab/bitbucket and the shared Gitea/Forgejo platform, `fetchJSONFile` for the github/gitlab presets and the shared Gitea/Forgejo preset source, and `getReleaseNotesMd` for the bitbucket changelog source and the shared Gitea/Forgejo changelog source. `getRepoContents` is gone from `gitea-helper.ts`, the contents schemas move out of `platform/gitea/schema.ts`, and the Gitea and Forgejo preset sources build their own `Http` instance instead of importing the platform's. Behaviour changes: - GitLab presets no longer look up the project's default branch before fetching; they request `?ref=HEAD` like the platform already does, and they use the JSON contents endpoint instead of `/raw`. This removes one HTTP request per preset lookup. - A GitHub contents response without a `content` field now surfaces as `PRESET_DEP_NOT_FOUND` instead of an uncaught `TypeError`, because the base64 decode moved inside the try block. - GitLab `getRawFile` escapes the file name with `encodeURIComponent` instead of only escaping `/`. - Gitea/Forgejo contents URLs escape each path segment on its own, so a nested path keeps its slashes: the platform `getRawFile` and the preset source now request `contents/path/custom.json` where they used to request `contents/path%2Fcustom.json`. Both spellings work; the unescaped one is the documented form and the one the changelog source already used. - The Gitea/Forgejo changelog source now escapes the segments of the source directory and of the changelog file path, as the platform and preset callers already did. - The `Preset URL` trace log in the GitHub and GitLab presets is gone; the URL is built inside the util helper. Not covered here: Bitbucket Server (platform reads `browse`, changelog reads `raw` - genuinely different endpoints) and the GitHub/GitLab changelog sources, which use the git tree/blob APIs rather than a path lookup. * refactor(platform): keep the repo-file helpers in the platform folders The helpers landed under `lib/util/<host>/`, which added a second home for host API code next to the platform modules that already own it. Move them into the platform folder of their host instead, so there is one place per host rather than two: - `lib/util/github/contents.ts` -> `lib/modules/platform/github/contents.ts` - `lib/util/gitlab/files.ts` -> `lib/modules/platform/gitlab/files.ts` - `lib/util/bitbucket/files.ts` -> `lib/modules/platform/bitbucket/files.ts` - `lib/util/gitea/contents.ts` -> `lib/modules/platform/gitea/contents.ts` The preset and changelog layers import them from there, which is the direction they already had: the preset sources read `gitea-helper.ts` and the changelog sources read `platform/*/schema.ts`. `RepoContents` and `ContentsListResponse` go back to `platform/gitea/schema.ts` with their tests, because `renovate/zod-schema-location` keeps zod schemas under `lib/modules/**` in a `schema.ts`. That is also where the changelog sources read them from today. The functions keep taking the caller's `Http` instance, so the host type and its host rules still belong to the calling layer; only the file location changes. * refactor(presets): keep using the platform's Gitea and Forgejo clients The preset sources were switched to `new GiteaHttp()` / `new ForgejoHttp()` to keep `lib/config/presets` from importing `lib/modules/platform`. That boundary is gone now that the contents helpers live in the platform folder, and the second instance never bought anything: `giteaHttp` and `forgejoHttp` are themselves plain `new GiteaHttp()` / `new ForgejoHttp()`, an `HttpBase` holds only its host type and its merged default options, and `baseUrl` is module state shared by every instance of the class rather than per-instance. Both files are back to what they were, so the preset sources no longer appear in this change at all. * refactor(platform): resolve repo-file URLs against the client base url `getRepoFile()` and `listRepoDir()` took an `apiBaseUrl` positional argument that meant three different things depending on the caller: an empty string or a slash for "use the client's own base", a path prefix for Gitea, and a full API base URL for the preset and changelog layers. `Http` already owns this: `resolveUrl()` reads `options.baseUrl ?? this.baseUrl`. The helpers now build a URL relative to the API root and take no base of their own, so callers reading the host their client is configured for pass nothing, and callers reading a foreign host pass `baseUrl` in the options they already pass. The GitHub, GitLab and Bitbucket platform clients are based at the API root, so those three call sites lose their placeholder argument outright. The Gitea client is based at the web root and the rest of that folder prefixes every URL with `API_PATH`, so the Gitea callers pass that same constant instead of the duplicate `API_BASE_PATH` this stack had added next to it. * test(platform): cover the client base url fallback for repo files The GitHub and GitLab `getRepoFile()` specs always passed a `baseUrl` option, so the fallback to the client's own base url - the path the platform callers take now that they pass no base at all - was never exercised. Both specs get a case that sets a self-hosted base url on the client and reads a file without passing one, which also pins that a configured endpoint reaches the request. The Bitbucket and Gitea specs already covered it. * refactor(platform): name the repo-file helper files.ts on every platform The helper was named after each vendor's own word for the endpoint: GitHub and Gitea call it "contents", GitLab calls it "files" and Bitbucket calls it "src", so the same helper sat under two different names and neither matched Bitbucket. Use files.ts everywhere, so a reader looking for "read a file from a repo" finds the same filename in every platform folder. The vendor's noun still appears where it belongs: in the request paths, the doc links and the Gitea schema names.
Gitea
Renovate supports Gitea.
!!! note
Use forgejo as the platform if you are using Forgejo.
Forgejo support will be removed from gitea platform in a future release.
Authentication
First, create a Personal Access Token (PAT) for the Renovate account. The Renovate account should have full name and email address configured. Then let Renovate use your PAT by doing one of the following:
- Set your PAT as a
tokenin yourconfig.jsfile - Set your PAT as an environment variable
RENOVATE_TOKEN - Set your PAT when you run Renovate in the CLI with
--token=
You must set platform=gitea in your Renovate config file.
The PAT should have these permissions:
| Scope | Permission | Valid for Gitea versions | Notes |
|---|---|---|---|
repo |
Read and Write |
all | |
user |
Read |
all | |
issue |
Read and Write |
>= 1.20.0 |
|
organization |
Read |
>= 1.20.0 |
Required to read org labels and teams |
email |
Read |
<= 1.19.3 |
|
misc |
Read |
Only for 1.20.0 and 1.20.1 |
If you use Gitea packages, add the read:packages scope.
Unsupported platform features/concepts
- Adding reviewers to PRs not supported: Gitea versions older than
v1.14.0do not have the required API. platformAutomerge(trueby default) for platform-native automerge not supported: Gitea versions older than v1.24.0 don't support required branch autodelete for automerge.- Git upload filters: If you're using a Gitea version older than
v1.16.0then you must enable clone filters.
Features awaiting implementation
- none
Repo autodiscover
Renovate can discover repositories on Gitea using the autodiscover feature.
Repositories are ignored when one of the following conditions is met:
- The repository is a
mirror - We do not have push or pull permissions to that repository
- Pull requests are disabled for that repository
You can change the default server-side sort method and order for autodiscover API.
Set those via autodiscoverRepoSort and autodiscoverRepoOrder.
Read the Gitea swagger docs for more details.
Merge style
Renovate uses the repository's default merge style if allowed; if the default merge style is not an allowed merge style, renovate falls back to an allowed merge style as per an order chosen to minimize commits. If no merge style is allowed, the repository is blocked.