The docs site is served by Cloudflare Pages now, so the AWS deployment path is redundant.
- Drop the AWS CLI installation step.
- Drop the `configure-aws-credentials` step and the `aws s3 sync` + CloudFront invalidation step.
- Keep only the Cloudflare Pages deploy, and simplify the `_headers` / `_redirects` comment since it no longer needs to explain S3 ordering.
The AWS_* secrets are no longer used by this workflow and can be removed from the repository settings.
Reviewed-on: https://gitea.com/gitea/docs/pulls/518
Reviewed-by: silverwind <[email protected]>
The `checks` workflow deploys a Cloudflare Pages preview to the `pr-<number>` branch of the `docs-gitea-com` project for every pull request, but nothing ever removed it. Closed and merged pull requests therefore keep an alias and a growing list of deployments around.
This adds a `cleanup preview` workflow that runs when a pull request is closed (merged or not), lists the deployments of the project through the Cloudflare API and deletes the ones whose trigger branch is `pr-<number>`. `force=true` is used so the deployment the branch alias points at is removed as well.
Pull requests from forks do not receive the secrets, so the cleanup is skipped there, exactly like the preview deployment itself.
---------
Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/517
Reviewed-by: bircni <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
Closes#37.
Gitea generates an OpenAPI 3.0 document since 1.27 (`templates/swagger/v1_openapi3_json.tmpl`, renamed to `templates/swagger/v1-openapi3.generated.json` on main, served by an instance at `/openapi3.v1.json`), but this site never picked it up and still published Swagger 2.0 only. That is what the issue is about: code generators such as `openapi-python-client` reject the document with "You may be trying to use a Swagger document; this is not supported by this project".
**What this does**
- `update_api_docs.sh` downloads the OpenAPI 3.0 document next to the Swagger 2.0 one, rewrites the same placeholders (they sit in `servers` instead of `basePath`) and writes `static/openapi3-latest.json` and `static/openapi3-<minor>.json`. Versions that do not have one (1.26 and older) are skipped with a message and keep their Swagger 2.0 document.
- The OpenAPI 3.0 document is rendered where it exists (`/api/` and `/api/next/`), the older versions keep rendering Swagger 2.0. Both documents describe the same api and carry the same operation ids, so no url of an operation page changes; the `basePath` normalization is now only applied to the Swagger 2.0 documents, since a full url in `servers` is valid.
- The overview page of each version links both documents for download, which is what the issue actually needs: `https://docs.gitea.com/openapi3-27.json` for the current release, `https://docs.gitea.com/openapi3-latest.json` for gitea main.
- The scheduled workflow now refreshes and proposes both documents of gitea main.
**Verification**
- `pnpm dlx @redocly/cli lint static/openapi3-latest.json`: valid, only content warnings that come from upstream (missing 4xx responses, ambiguous paths).
- `openapi-python-client generate --path static/openapi3-latest.json`, the tool from the issue, generates a client. The only warning left is `POST /markdown/raw`, whose request body is `text/plain`.
- Operation ids of `static/swagger-27.json` and `static/openapi3-27.json` are identical (481 on both sides), so the operation pages keep their urls.
- Built the api product and compared a rendered operation page against the Swagger 2.0 one: same sections, the request body is now marked required where the document says so.
The released Swagger 2.0 documents are kept: they are the only description 1.26 and older ever produced, and some tooling still expects them.
<!-- cloudflare-preview --> Preview: https://pr-514.docs-gitea-com.pages.dev
Reviewed-on: https://gitea.com/gitea/docs/pulls/514
Reviewed-by: bircni <[email protected]>
Replace [#307](https://gitea.com/gitea/docs/issues/307)
Closes [#237](https://gitea.com/gitea/docs/issues/237)
## Summary
Rebuilds docs.gitea.com with [Astro](https://astro.build) and [Starlight](https://starlight.astro.build), replacing Docusaurus. Every
published url keeps working and no content file was moved: the site is a new rendering layer over the existing `docs/`, `versioned_docs/`, `i18n/`, `runner-docs/` and `static/swagger-*.json` trees.
For the first time the API reference is part of the site rather than a Redoc
bundle: all seven swagger documents are rendered into real pages, one per
operation, so they are linkable, crawlable and searchable.
## Why
- the Docusaurus build needs an 8 GB heap and about 2 minutes for 2478 pages;
the Astro build produces 5751 pages, API reference included, in about 100
seconds
- the API reference was a single client rendered Redoc page per version, absent
from the site search and from search engines
- sidebars, version lists and language lists were configured in three different
places and drifted apart
## What is in here
- **`packages/content-loader`** — the product × version × language matrix
(`products.ts`) and an Astro content loader that reads the existing markdown
trees directly. The matrix is the single source of truth: content loading,
sidebars, the version and language pickers, the version banner, the search
facets and the API schemas are all derived from it.
- **Content compatibility** — frontmatter `slug`, `sidebar_position` and
`sidebar_label` keep working, `_category_.json` still drives sidebar labels,
order and the generated category pages, `@version@` style release variables are
still substituted, `:::note` admonitions become Starlight asides and the 2778
relative `*.md` links are rewritten to urls while the site is built.
- **API reference** — `starlight-openapi` renders the seven swagger documents.
Operation urls are hyphenated (`/api/operations/list-admin-workflow-jobs/`),
the sidebar shows the operations of the version being read with a coloured
HTTP method badge, and the overview page links to one page per tag instead of
repeating all 484 operations.
- **Navigation** — a version picker that follows the reader to the same page in
another version, a language picker that only offers the languages the current
product is published in, and product links for Docs, API, Runner and
Enterprise.
- **Theme** — the light and dark palettes of about.gitea.com, mapped onto the
Starlight variables.
- **Search** — Pagefind by default; Algolia DocSearch takes over when
`PUBLIC_DOCSEARCH_APP_ID` and `PUBLIC_DOCSEARCH_API_KEY` are set. Every page
carries `docsearch:product`, `docsearch:version` and `docsearch:language` meta
tags, so a search stays inside what is being read.
`cloudflare/docsearch-crawler.json` holds the crawler configuration.
## Bugs fixed along the way
- `GET /user/applications/oauth2` and `GET /user/applications/oauth2/{id}` have
operation ids that only differ in case, so they collapsed onto the same url
and one of the two pages was silently dropped. They are now
`user-get-oauth2-application` and `user-get-oauth2-application-by-id`.
- The API overview and every tag page were all titled "Overview".
## Url compatibility
The routes of both builds were compared page by page during the migration with
`scripts/url-diff.mjs`:
```
identical: 2368, missing: 0, accepted: 110, added: 3292
```
The 110 accepted ones are all redirected in `cloudflare/_redirects`: the
localized copies of the English-only API and Runner docs, the Docusaurus search
page, and `/1.27/`, `/runner/3/`, `/api/1.27/` which are aliases of the versions
served at the product root. The added ones are the API operation and tag pages
plus the routes the Starlight language fallback serves in English when a
translation is missing — Docusaurus answered those with a 404.
## Workflows
- `checks` builds the site and type checks it on every pull request
- `Build and Publish Docs site` publishes `sites/docs/dist` to S3/CloudFront and
to Cloudflare Pages, and copies `cloudflare/_headers` and
`cloudflare/_redirects` into the deployment
- `update swagger files` and `update runner reference` are unchanged, they only
touch content
- `make cut-version PRODUCT=docs VERSION=1.28` replaces
`docusaurus docs:version`
## Removed
`docusaurus.config.js`, the swizzled theme under `src/`, and the Docusaurus UI
translations (`i18n/*/code.json`, `i18n/*/docusaurus-theme-classic/`). The
strings those carried — the product names, the footer column titles and the
outdated translation notice — were ported to
`sites/docs/src/config/strings.ts`; Starlight ships the rest of its interface in
both Chinese locales. The documentation content itself is untouched.
## Follow ups
- nine relative links are broken in the sources and reported by every build, the
same ones Docusaurus warned about; `GITEA_DOCS_STRICT_LINKS=true` turns them
into an error once they are fixed
- `cloudflare/worker.js` has to be deployed for `/enterprise/` to keep resolving
- the Algolia index has to be created and crawled before the search credentials
are set
## Testing
```shell
make install
make serve-fast # english, the version served at the root
make serve # the whole matrix
make build # 5751 pages
make check # 0 errors
make serve-built # build and serve, the only way to try the search locally
```
## Screenshots
<img width="1371" alt="image.png" src="attachments/69acdd77-cc89-4635-a8bd-1163a34afa86">
<img width="1810" alt="image.png" src="attachments/76212416-4825-4b4d-bf59-3e549900c96f">
<img width="1789" alt="image.png" src="attachments/7be84cda-5abe-48bd-8839-7ae1ee7806e7">
---------
Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/496
Reviewed-by: bircni <[email protected]>
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | Pending |
|---|---|---|---|---|---|---|
| [@easyops-cn/docusaurus-search-local](https://github.com/easyops-cn/docusaurus-search-local) ([source](https://github.com/easyops-cn/docusaurus-search-local/tree/HEAD/packages/docusaurus-search-local)) | [`0.55.2` → `0.55.3`](https://renovatebot.com/diffs/npm/@easyops-cn%2fdocusaurus-search-local/0.55.2/0.55.3) |  |  | dependencies | patch | |
| [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm11/pnpm)) | [`11.17.0` → `11.20.0`](https://renovatebot.com/diffs/npm/pnpm/11.17.0/11.20.0) |  |  | packageManager | minor | `11.21.0` |
| [pnpm/action-setup](https://github.com/pnpm/action-setup) ([changelog](https://github.com/pnpm/action-setup/compare/0ebf47130e4866e96fce0953f49152a61190b271..0977fd99725f1db4007ccb2928dbb4e90d06cc86)) | `0ebf471` → `0977fd9` | | | action | digest | |
---
### Release Notes
<details>
<summary>easyops-cn/docusaurus-search-local (@​easyops-cn/docusaurus-search-local)</summary>
### [`v0.55.3`](https://github.com/easyops-cn/docusaurus-search-local/releases/tag/v0.55.3)
[Compare Source](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.55.2...v0.55.3)
##### Bug Fixes
- trigger a release for refining search icon for [#​577](https://github.com/easyops-cn/docusaurus-search-local/issues/577) ([9a7eb91](https://github.com/easyops-cn/docusaurus-search-local/commit/9a7eb91393f389838cc31f45e4f4737dc4bb325e))
</details>
<details>
<summary>pnpm/pnpm (pnpm)</summary>
### [`v11.20.0`](https://github.com/pnpm/pnpm/releases/tag/v11.20.0): pnpm 11.20
[Compare Source](https://github.com/pnpm/pnpm/compare/v11.19.0...v11.20.0)
#### Minor Changes
- **Security fix.** Affects projects using `namedRegistries` on pnpm 11.1.0–11.19.x. It is **semi-breaking** for those projects — see "If you use named registries" below.
The lockfile recorded no marker for which registry a package came from. Packages were keyed by `name@version` alone, and entry lookup went through `refToRelative(ref, name)`, so a dependency you declared against one registry could be satisfied by an entry that was actually resolved from another. When two registries served the same name and version, both collapsed onto a single `packages:` entry and whichever resolved first decided the tarball every consumer got.
That is a package-substitution risk: a package you expect from your private registry could be installed from a different registry that publishes the same name and version, and the lockfile recorded nothing that would let you tell.
Packages resolved from a named registry are now recorded under registry-qualified keys (`<name>@​<registryName>:<version>`, e.g. `foo@work:1.0.0`), so each registry gets its own entry and the lockfile pins which one a dependency came from.
The lockfile format version is unchanged. Registry-qualified keys appear only for packages resolved from a named registry, so a project that does not use `namedRegistries` sees no difference, and older pnpm versions keep reading the file.
##### If you use named registries
Your next non-frozen install re-keys those entries, which shows up as a lockfile diff. Commit it — that diff is the fix being applied. Review it: an entry that moves to a registry you did not expect is worth investigating.
Everyone working on the project should be on this version or newer before you do. An older pnpm reads the re-keyed lockfile fine — frozen installs are unaffected — but it does not produce registry-qualified keys itself, so any install that updates the lockfile writes those entries back to the old shape, and the next install on a current pnpm re-qualifies them. The result is a lockfile that flips back and forth, and while it is in the old shape the project is exposed again. Because the lockfile format version is deliberately unchanged, pnpm cannot detect this and warn you about it.
There is no setting to keep the old behavior: the old shape is the vulnerability.
Tarball URLs that follow the standard registry layout are no longer written to the lockfile for named-registry packages; they are recomputed from the `namedRegistries` setting on demand.
To use named registries, map your aliases in `pnpm-workspace.yaml`:
```yaml
namedRegistries:
work: https://npm.enterprise.example.com/
```
##### New built-in `npmjs:` alias
`npmjs:` now resolves to `https://registry.npmjs.org/` with no configuration, alongside the existing `gh:` alias for GitHub Packages. It pins a dependency to the public registry even when `registry` points elsewhere, such as an internal proxy:
```json
{ "dependencies": { "left-pad": "npmjs:^1.3.0" } }
```
`npm:` cannot do this — it is the alias protocol (`npm:<name>@​<range>`) and resolves through whatever `registry` points at.
**If you mirror or proxy npmjs, point the alias at your mirror:**
```yaml
namedRegistries:
npmjs: https://npm.internal.example.com/
```
Built-in registry URLs are also the prefixes a lockfile's recorded tarball URL is matched against when pnpm verifies a package. Without the override, an entry whose tarball URL is on `registry.npmjs.org` is verified against the public registry rather than your mirror. This only affects lockfiles that record such URLs — a canonical URL for your configured registry is omitted from the lockfile and unaffected — and only when a tarball-URL, `minimumReleaseAge`, or `trustPolicy` check runs. Overriding the alias is the same escape hatch GHES users already have for `gh`.
Every alias the lockfile references must stay in `namedRegistries`: reading an entry whose alias is gone fails with `ERR_PNPM_MISSING_NAMED_REGISTRY` rather than silently falling back to the default registry, since that would fetch a different package. Renaming an alias re-resolves the packages that used it.
Named registry aliases that shadow a reserved dependency specifier prefix (`file`, `link`, `workspace`, `runtime`, `npm`, `jsr`, ...) are now rejected with `ERR_PNPM_RESERVED_NAMED_REGISTRY_NAME` instead of being silently shadowed by the corresponding resolver.
`pnpm licenses` and `pnpm sbom` now keep the two artifacts apart as well: license records carry the registry alias, and SBOM components carry the purl `repository_url` qualifier.
#### Patch Changes
- An empty `http-proxy`, `https-proxy`, `proxy`, or `no-proxy` value — from the `.npmrc`, `pnpm-workspace.yaml`, the CLI, or the `HTTP_PROXY` / `HTTPS_PROXY` / `PROXY` / `NO_PROXY` environment variables — no longer fails the install with `ERR_PNPM_INVALID_PROXY`. Empty settings read as unset, so a shell exporting `HTTP_PROXY=` disables the proxy, and an empty `proxy=` in the `.npmrc` no longer suppresses `HTTPS_PROXY` [#​13533](https://github.com/pnpm/pnpm/issues/13533).
`proxy=false` in the `.npmrc` or `proxy: false` in `pnpm-workspace.yaml` now turns proxying off instead of being read as a proxy host named `false`. `false` and `null` on `https-proxy` / `http-proxy` / `no-proxy` read as unset, and on the command line they are ordinary host names, since a flag carries its value verbatim.
- The env lockfile no longer pins `@pnpm/exe` alongside `pnpm` when the wanted pnpm version is 12 or newer. From v12 the unscoped `pnpm` package is itself the native executable, so `@pnpm/exe` is not published for it and resolving it would fail. The engine identity check now verifies the native binary through whichever package ships it.
- `lexCompare` and `nerfDart` are now published as `@pnpm/text.ordinal-comparator` and `@pnpm/config.registry-auth-key`. Use these instead of `@pnpm/util.lex-comparator` and `@pnpm/config.nerf-dart`.
- Fixed the order in which pnpm matches a lockfile's recorded tarball URL against known registry URLs. Two registry URLs of equal length were previously ordered arbitrarily, so which one a tarball URL matched could differ between runs.
- Dependency resolution is faster: package metadata is now filtered once per packument instead of once per dependency edge when `minimumReleaseAge` is active, and parsed semver versions and ranges are reused instead of re-parsed on every comparison.
- Security: `pnpm rebuild` now refuses a lockfile whose `packages` key carries a path traversal in the package name (e.g. `../../../[email protected]`), instead of running that package's lifecycle scripts and linking its bins in a directory outside the virtual store. Such a name is rejected with `ERR_PNPM_INVALID_DEPENDENCY_NAME`.
<!-- sponsors -->
#### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
#### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
### [`v11.19.0`](https://github.com/pnpm/pnpm/releases/tag/v11.19.0): pnpm 11.19
[Compare Source](https://github.com/pnpm/pnpm/compare/v11.18.0...v11.19.0)
#### Minor Changes
- `pnpm login` no longer requires an interactive terminal when the registry supports web-based login: without a TTY it prints the authentication URL (skipping the QR code and the "Press ENTER to open the URL in your browser" prompt) and polls the registry until the browser approval completes. Only the classic username/password login still fails with `ERR_PNPM_LOGIN_NON_INTERACTIVE` in a non-interactive terminal.
- The `save-prefix` setting now accepts `=`: newly added dependencies are saved with an explicit `=` operator (`=1.2.3`) instead of the setting being silently treated as the default `^`.
#### Patch Changes
- `allowBuilds` entries can now approve git-hosted packages that pnpm downloads as a tarball, such as `github:` dependencies (which are fetched from `codeload.github.com` rather than cloned), by their repository URL without the resolved commit hash. This matches the hashless `git+` matching already supported for cloned git dependencies. For example:
```yaml
allowBuilds:
"foo@git+https://github.com/org/foo.git": true
```
This approves the package whether pnpm clones it or downloads a tarball, so the entry no longer has to be updated every time the pinned commit changes. GitLab and Bitbucket tarball downloads are matched the same way. Approving or denying a specific resolved commit by its full tarball dep path continues to work.
- `pnpm outdated --include-github-actions` no longer blocks on an interactive git credential prompt when a workflow uses a private action repo.
- Prevented `minimumReleaseAge` from replacing `latest` with a SemVer-greater version than the registry tag target [#​13034](https://github.com/pnpm/pnpm/issues/13034).
- Fixed empty `bundledDependencies` and `bundleDependencies` arrays causing nondeterministic lockfile changes. See [#​13123](https://github.com/pnpm/pnpm/issues/13123).
- The install summary no longer prints `(X is available)` when the registry's `dist-tags.latest` is still held back by the active `minimumReleaseAge` policy. The hint only ever names the actual latest tag, so an immature latest suppresses the hint instead of advertising the version pnpm just refused to install [#​11698](https://github.com/pnpm/pnpm/issues/11698).
- `pnpm update` keeps the explicit `=` operator of an exact version pin: a dependency saved as `=3.5.1` now updates to `=3.5.2` instead of the bare `3.5.2`. See [#​13168](https://github.com/pnpm/pnpm/issues/13168).
- Preserve a workspace dependency's `link:` entry when a run does not target it — e.g. `pnpm update <other-pkg>` (with or without `--recursive`), or a plain install after a root/catalog dependency change — with `injectWorkspacePackages`, instead of spuriously rewriting it to a peer-suffixed `file:` protocol. See [#​10433](https://github.com/pnpm/pnpm/issues/10433).
- Workspace dependencies declared with a relative path (e.g. `"foo": "workspace:../foo"`) are no longer silently dropped from the workspace projects graph, so `--filter` selection and the topological order of recursive commands take them into account.
<!-- sponsors -->
#### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
#### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
### [`v11.18.0`](https://github.com/pnpm/pnpm/releases/tag/v11.18.0): pnpm 11.18
[Compare Source](https://github.com/pnpm/pnpm/compare/v11.17.0...v11.18.0)
#### Minor Changes
- Fixed an installed optional dependency being left without one of its own required dependencies. When a package reached through `optionalDependencies` is installable on the current system but one of its regular `dependencies` is not, a lockfile-based install skipped that dependency and installed the parent anyway, so importing the parent failed with `MODULE_NOT_FOUND`. The dependency is now installed, and an install-check warning reports the incompatibility. A dependency is still only skipped when every path to it is optional, or when the package that pulls it in was itself skipped [#​13286](https://github.com/pnpm/pnpm/issues/13286).
- `pnpm setup` now appends `PNPM_HOME` and the global bin directory to the GitHub Actions environment files (`GITHUB_ENV` and `GITHUB_PATH`), so later steps in the same job can run `pnpm add --global` and other global commands [#​9191](https://github.com/pnpm/pnpm/issues/9191).
- Added support for `publishConfig.name`, which publishes a package under a different name than the one its manifest carries in the workspace. It is for a project whose published name is already taken by a sibling project, which otherwise has to be renamed by a build step just before publishing. Only the published artifact is renamed — dependents, `pnpm-lock.yaml`, and release tooling keep addressing the project by its manifest name — and the new name reaches the packed manifest, the tarball filename, and everything that addresses the package at the registry: the already-published check of `pnpm publish -r`, its registry selection, and the release-planning probes of `pnpm change status` and `pnpm version -r` [#​13345](https://github.com/pnpm/pnpm/issues/13345).
- `pnpm self-update` no longer takes any instruction from the project it is run in:
- pnpm is fetched through the same trusted registry and auth configuration used when switching pnpm versions, so a project `.npmrc` or `pnpm-workspace.yaml` can no longer redirect the download or attach credentials to it, and the project's default `.pnpmfile.(c|m)js` is no longer loaded. Pnpmfiles from trusted sources (the `pnpmfile` setting, the global pnpmfile, config dependencies) still apply.
- The `minimumReleaseAge` settings in `pnpm-workspace.yaml` no longer affect `self-update`. They still govern the project's own dependencies; for `self-update` the cooldown now comes from the built-in default, your global config, a `PNPM_CONFIG_*` environment variable, or a command-line flag. This fixes `self-update` failing inside a workspace that raises the cutoff while succeeding everywhere else, and stops a repository from either waiving the cooldown or keeping you on an outdated pnpm by raising it.
- The same applies to the `trustPolicy` settings and to `ci`: a project can no longer weaken the trust check that guards the pnpm download, nor re-enable the confirmation prompt that a CI run suppresses.
When `self-update` refuses a version that is younger than the cutoff, an interactive run now offers to update anyway; non-interactive runs still fail. CI never prompts, even on a runner that attaches a TTY.
#### Patch Changes
- Fixed `pnpm licenses list` to report every version when the same package is installed under multiple aliases [pnpm/pnpm#13438](https://github.com/pnpm/pnpm/issues/13438).
- Sort `pnpm dedupe --check` snapshot changes for stable output across pnpm implementations.
- Strip Unicode formatting characters from registry- and manifest-derived terminal output.
- Speed up installs after compatible catalog or direct dependency range changes by retaining the locked version without resolving the dependency graph again.
- Speed up installs after safe override changes by reusing unambiguous compatible dependency resolutions, pruning obsolete dependencies, applying independent replacements and removals together, and handling parent-scoped `"-"` overrides without full lockfile resolution.
- Installing a local `file:` directory dependency with the global virtual store enabled no longer fails with `TypeError: Cannot read properties of undefined (reading 'split')` [#​13335](https://github.com/pnpm/pnpm/issues/13335).
Local directory dependencies — `file:` directories and injected workspace packages — now get a global-virtual-store slot of their own per project. They used to share one slot across every project that depended on a directory of the same name, so a project could end up linked to another project's copy of the dependency.
- The `Workspace` column of `pnpm update --interactive` now falls back to the project's path when its `name` is only whitespace, as it already did for a missing or empty one — all three render an equally blank label otherwise.
- Checking GitHub Actions dependencies for updates is now opt-in for every command. Neither `pnpm outdated` nor `pnpm update` reads the workflow files unless `--include-github-actions` is passed or `update.githubActions` is set to `true` in `pnpm-workspace.yaml`. Reading them runs `git ls-remote` against every referenced repository, which fails in environments where GitHub is not reachable the way pnpm assumes (a GitHub Enterprise Server, a custom certificate authority, or an offline network) [#​13254](https://github.com/pnpm/pnpm/issues/13254).
`pnpm outdated` accepts the `--include-github-actions` option too.
- `pnpm update --interactive` now measures its table in terminal columns rather than in characters. A package name, workspace name, or version containing wide characters (CJK, most emoji) no longer knocks its row's columns out of line with the rest of the group, and a wide character in a version no longer aborts the command with `Subject parameter value width cannot be greater than the container width` [#​13357](https://github.com/pnpm/pnpm/issues/13357).
- The `Workspace` column of `pnpm update --interactive` is more informative in two cases. A dependency outdated at the same version in several workspace projects is offered as one choice, since selecting it updates every project — that choice now names all of them instead of only the first. And a workspace project without a `name` is now labelled with its path rather than left blank, so several unnamed projects can be told apart.
- An auto-installed *optional* peer is no longer hoisted at a version the workspace root's own dependency on that package excludes. `resolvePeersFromWorkspaceRoot` already made the workspace root's specifier decide which version a missing *required* peer is installed at; the optional-peer picker ignored it and always took the highest version present anywhere in the graph. In a workspace whose root pins `postcss: 8.5.10`, an importer that depends on `webpack` and declares no `postcss` of its own got `[email protected]` hoisted for `terser-webpack-plugin`'s optional `postcss` peer, leaving two `[email protected]` instances in the graph [#​13320](https://github.com/pnpm/pnpm/issues/13320).
- `overrides` now also govern peers that pnpm auto-installs. Previously an override only rewrote dependencies declared in a manifest, so a peer nobody declares — installed because `autoInstallPeers` is on — resolved against its declared peer range and could bring in a second copy of the very package the override pinned. For example, with `overrides: { react: npm:[email protected] }` and a lone `lucide-react` dependency, pnpm installed `[email protected]`; it now installs the pinned `[email protected]` [#​13320](https://github.com/pnpm/pnpm/issues/13320).
- Under `resolvePeersFromWorkspaceRoot`, a workspace root dependency declared with `link:` or `file:` (or the path form of `workspace:`, such as `workspace:../pkg`) now satisfies another project's missing peer dependency at the linked package's own version, instead of being hoisted as a path. Those specifiers are relative to the project that declares them, so the same specifier reached a different directory — or none — from the project the peer was hoisted into, leaving a broken link. The root now has the same authority over the peer as it has when it declares the package with a version range [#​13373](https://github.com/pnpm/pnpm/issues/13373).
- Installs through a pnpr server now apply the project's whole verification policy. `minimumReleaseAgeExclude`, `minimumReleaseAgeIgnoreMissingTime`, `trustPolicy`, `trustPolicyExclude`, `trustPolicyIgnoreAfter`, and `trustLockfile` were ignored, so excluded packages were still held back and a lockfile containing them could be rejected.
`trustPolicy: no-downgrade` no longer fails with `TRUST_POLICY_INCOMPATIBLE_WITH_PNPR` when a pnpr server is configured.
`--frozen-lockfile` and `--no-prefer-frozen-lockfile` are now honored on the pnpr path, instead of resolving and rewriting the lockfile anyway. Since `frozenLockfile` defaults to `true` on CI, a CI install through a pnpr server now fails on an out-of-date lockfile rather than updating it.
- Workspace installs through a pnpr server no longer crash with `Cannot read properties of undefined (reading 'filter')` after linking, when `minimumReleaseAge` is active [#​13275](https://github.com/pnpm/pnpm/issues/13275).
- Fixed `pnpm dedupe` updating valid catalog resolutions when another matching version exists in the lockfile.
- `pnpm -r run "/pattern/" --no-bail` no longer exits zero when one of a project's matched scripts fails and a later one passes. The run summary carries a single status per project, and the passing script overwrote the recorded failure.
- Restored the store block a first install prints, naming how packages were materialized and where the stores live [#​13315](https://github.com/pnpm/pnpm/issues/13315):
```text
Packages are hard linked from the content-addressable store to the virtual store.
Content-addressable store is at: ~/.local/share/pnpm/store/v11
Virtual store is at: node_modules/.pnpm
```
- The root project's `pnpm:devPreinstall` script now runs before resolution and linking, as it does in pnpm 11. It is skipped under `--ignore-scripts`, `--lockfile-only` and `--dry-run`, by `pnpm fetch` and `pnpm rebuild`, and by a repeat install that is already up to date. Workspaces that use the hook to prepare state the install depends on — such as [next.js](https://github.com/vercel/next.js), which generates a placeholder `next` bin with it — were left with dependents linked against files that were never created [#​13313](https://github.com/pnpm/pnpm/issues/13313).
- Prevented `pnpm dedupe --check` from removing an incompatible `node_modules` directory.
- `pnpm update --workspace` no longer links dependencies the user never named:
- Running it with `updateConfig.ignoreDependencies` configured no longer fails with `ERR_PNPM_WORKSPACE_PACKAGE_NOT_FOUND` for a dependency that is only published to the registry. Such dependencies keep their specifiers, as they already did when no dependencies were ignored.
- Passing package selectors that match no direct dependency no longer falls back to linking every workspace dependency.
<!-- sponsors -->
#### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
#### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTEuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE5MS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
<!-- cloudflare-preview --> Preview: https://pr-500.docs-gitea-com.pages.dev
---------
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/500
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
Pull requests now get a Cloudflare Pages preview deployment after the site build succeeds, and the preview URL is written back as the last line of the pull request description.
- `concurrency` cancels the previous preview build when a pull request is pushed again.
- After `make build`, the workflow copies `cloudflare/_headers` into `build/` (same as the production deployment, so the file is never published to S3/CloudFront) and runs `wrangler pages deploy build --project-name docs-gitea-com --branch pr-<number>`, then extracts the `*.pages.dev` URL from the wrangler output.
Notes:
- Pull requests from forks do not receive the secrets, in that case the preview steps are skipped with a log message and the build check still runs.
- Requires `CLOUDFLARE_ACCOUNT_ID` / `CLOUDFLARE_API_TOKEN` (Pages edit permission) and `DEPLOY_TOKEN` (pull request write permission).
<!-- cloudflare-preview --> Preview: https://pr-498.docs-gitea-com.pages.dev
Reviewed-on: https://gitea.com/gitea/docs/pulls/498
Reviewed-by: Zettat123 <[email protected]>
The scheduled `update swagger files` job has failed on **every** run since it was added (I checked the run list on gitea.com, ~250 consecutive failures). Two reasons:
1. Upstream moved the file: `go-gitea/gitea` main no longer has `templates/swagger/v1_json.tmpl`, it is now `templates/swagger/v1-swagger.generated.json`, and the placeholders changed from `{{.SwaggerAppVer}}` / `{{.SwaggerAppSubUrl}}` to `0.0.0+GITEA-API-APP-VERSION` / `/GITEA-API-APP-SUBURL/api/v1`. Because the script used `curl --silent` without `--fail`, the 404 body was written into `static/swagger-latest.json`.
2. `main` is protected (`required_approvals=1`), so the job's `git push` to main could never succeed.
Changes:
- `update_api_docs.sh`: `set -euo pipefail`, download with `--fail` (a broken download now aborts instead of committing garbage), try the new generated json first and fall back to the old template for released tags, handle the 1.28+/1.24+/<1.24 placeholder variants, and add a `--latest-only` flag.
- `Makefile`: new `update-api-docs-latest` target for the cron job; `clean` no longer deletes the committed `static/swagger-*.json` files (deleting them breaks `make build`).
- `.gitea/workflows/update_swagger.yaml`: every 12h (plus `workflow_dispatch`) it regenerates only `static/swagger-latest.json`, verifies no placeholder is left and the file is valid JSON, force pushes to `bot/update-swagger-latest` and opens a pull request via the API (HTTP 409 = a PR is already open, it just now points at the new commit). It skips entirely when the bot branch already carries the same file, so no PR churn.
- `README.md`: document the two make targets and the automation.
`secrets.DEPLOY_TOKEN` must belong to a real user with `write:repository` so the PR checks are triggered; the job fails with a clear message if it is empty.
Tested locally in a scratch clone: `make update-api-docs-latest` produces a valid `dev` spec with no placeholders left, `make update-api-docs` still regenerates all released versions, and the workflow shell logic was simulated against a local bare repo for all three paths (open PR / bot branch already up to date / main already up to date), including a shallow clone to confirm `fetch-depth: 1` force pushes work.
Fixes#454
Reviewed-on: https://gitea.com/gitea/docs/pulls/481
Reviewed-by: techknowlogick <[email protected]>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [pnpm/action-setup](https://github.com/pnpm/action-setup) | action | major | `v4` → `v5` |
---
### Release Notes
<details>
<summary>pnpm/action-setup (pnpm/action-setup)</summary>
### [`v5`](https://github.com/pnpm/action-setup/compare/v4...v5)
[Compare Source](https://github.com/pnpm/action-setup/compare/v4...v5)
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My43Ni41IiwidXBkYXRlZEluVmVyIjoiNDMuNzYuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
---------
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/365
Reviewed-by: silverwind <[email protected]>
Reviewed-by: Nicolas <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
Co-committed-by: Renovate Bot <[email protected]>