Author SHA1 Message Date
Gitea BotandLunny Xiao b0b0c5090e Update the runner reference pages (#555)
Automated update of the generated runner reference pages from gitea/runner (main for the develop docs, the newest stable tag for every documented series), opened by the "update runner reference" scheduled workflow.

---------

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/555
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Gitea Bot <[email protected]>
2026-09-21 19:51:28 +00:00
Renovate Bot f95a334777 chore(deps): update dependencies (#554)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.42.0` → `0.42.1`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.42.0/0.42.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight/0.42.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight/0.42.0/0.42.1?slim=true) |
| [pnpm](https://github.com/pnpm/pnpm/tree/main/pnpm) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.4.0` → `12.4.2`](https://renovatebot.com/diffs/npm/pnpm/12.4.0/12.4.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/12.4.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/12.4.0/12.4.2?slim=true) |
| [yaml](https://eemeli.org/yaml/) ([source](https://github.com/eemeli/yaml)) | [`2.9.0` → `2.9.1`](https://renovatebot.com/diffs/npm/yaml/2.9.0/2.9.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/yaml/2.9.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/yaml/2.9.0/2.9.1?slim=true) |

---

### Release Notes

<details>
<summary>withastro/starlight (@&#8203;astrojs/starlight)</summary>

### [`v0.42.1`](https://github.com/withastro/starlight/blob/HEAD/packages/starlight/CHANGELOG.md#0421)

[Compare Source](https://github.com/withastro/starlight/compare/@astrojs/[email protected]...@astrojs/[email protected])

##### Patch Changes

- [#&#8203;4198](https://github.com/withastro/starlight/pull/4198) [`96a44d4`](https://github.com/withastro/starlight/commit/96a44d4f296b512febc6e631a587103ec5297872) Thanks [@&#8203;mayank99](https://github.com/mayank99)! - Removes the `popover` attribute from the sidebar pane on desktop viewports. This ensures the desktop sidebar doesn't stay in a "hidden" popover visibility state.

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

### [`v12.4.2`](https://github.com/pnpm/pnpm/releases/tag/v12.4.2): pnpm 12.4.2

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.4.1...v12.4.2)

pnpm 12.4.2 includes security fixes for executable shims and GitHub Actions links, more reliable installs, faster peer dependency checks in workspaces, and Python lockfiles that work across compatible targets.

#### Patch Changes

##### Security

- Dependency executables can no longer take over another package's POSIX bin shim through its shell helpers. Reinstall dependencies to replace existing shims [#&#8203;14837](https://github.com/pnpm/pnpm/issues/14837).

  On Cygwin, MSYS2, and WSL, shims still use `PATH` for Windows path conversion, so dependency executables can still redirect them there.

- GitHub Actions homepage links no longer expose server credentials. GitHub server URLs now require HTTPS, with HTTP allowed only for loopback hosts.

##### Installing packages

- pnpm no longer crashes at startup on FreeBSD and other Unix-like platforms. Platforms other than Windows and macOS use `~/.local/share/pnpm/store` by default [#&#8203;14859](https://github.com/pnpm/pnpm/issues/14859).

- `pnpm install` on Windows no longer fails with `ERR_PNPM_PACKAGE_MANAGER_REMOVE_MODULES_DIR` when clearing `node_modules` containing linked dependencies, such as when changing `nodeLinker` [#&#8203;14790](https://github.com/pnpm/pnpm/issues/14790).

- `pnpm install <pkg>` now accepts `--prod` and `--dev`, including `--prod=false` [#&#8203;14868](https://github.com/pnpm/pnpm/issues/14868).

- `pnpm install` and `pnpm update` now honor `--ignore-workspace` in nested projects excluded from the surrounding workspace. The flag also skips that workspace's settings during the `packageManager` check [#&#8203;14809](https://github.com/pnpm/pnpm/issues/14809).

- `pnpm install` on macOS no longer reuses stale files for `file:` tarball or git-hosted tarball dependencies.

- `pnpm install` in a single-project directory now detects `package.json` edits made while the previous install was finishing [#&#8203;14890](https://github.com/pnpm/pnpm/issues/14890).

- `pnpm install --frozen-lockfile` now removes packages no longer reachable from any project in `pnpm-lock.yaml`. This also prevents repeated lifecycle script execution and unnecessary installs before `pnpm run` and `pnpm exec` with `verifyDepsBeforeRun` [#&#8203;14891](https://github.com/pnpm/pnpm/issues/14891).

##### Resolving and updating dependencies

- Node.js runtime resolution now reports network failures from unofficial-builds.nodejs.org. These failures previously omitted musl builds from `pnpm-lock.yaml`, making its contents depend on network access [#&#8203;14813](https://github.com/pnpm/pnpm/issues/14813).

- `pnpm install` now rejects invalid `peerDependencies` specifiers with `ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION`. A value such as `"foo": "[email protected]"` previously created a broken directory link [#&#8203;14791](https://github.com/pnpm/pnpm/issues/14791).

- `pnpm deploy` now writes plain registry versions in the deployed `package.json`, without peer dependency suffixes. The lockfile retains peer bindings, and npm aliases retain their target package names [#&#8203;14873](https://github.com/pnpm/pnpm/issues/14873).

- `pnpm add <git repository>` now names repositories without a `package.json` as `@owner/repo`, allowing dependencies on equally named repositories from different owners [#&#8203;14870](https://github.com/pnpm/pnpm/issues/14870).

- Peer dependency resolution now deduplicates packages whose child dependency resolves an optional peer in only some workspace projects, such as `next` with `styled-jsx`'s optional `babel-plugin-macros` peer [#&#8203;14800](https://github.com/pnpm/pnpm/issues/14800).

- `pnpm update` now settles the lockfile in one run when an upgrade removes the package providing an optional peer dependency [#&#8203;14895](https://github.com/pnpm/pnpm/issues/14895).

- `pnpm update --no-save` now preserves override-applied specifiers for dependencies it is not updating, preventing subsequent frozen installs from failing with `ERR_PNPM_OUTDATED_LOCKFILE` [#&#8203;14836](https://github.com/pnpm/pnpm/issues/14836).

- `pnpm update --no-save` now succeeds under `minimumReleaseAgeStrict` when every resolved version is old enough [#&#8203;14835](https://github.com/pnpm/pnpm/issues/14835).

##### Performance

- Workspace installs and `pnpm peers check` are faster when projects depend on each other, fixing a slowdown introduced in 12.3.0. Unmet peer dependencies of workspace packages are now reported only under projects that link them directly [#&#8203;14906](https://github.com/pnpm/pnpm/issues/14906).

- Hoisted installs use less memory when packages are cached. Frozen-lockfile hoisted installs on macOS are also faster when reusable package directories are cached.

##### Python projects

- `pnpm install --frozen-lockfile` now reuses `pylock.toml` across compatible Python targets, including after kernel updates. Reuse requires unchanged requirements, index, and `requires-python`, compatible wheels, and a locked dependency graph matching the target's markers [#&#8203;14843](https://github.com/pnpm/pnpm/issues/14843).

  The lockfile's `environments` marker now includes only the interpreter version and marker variables used by the dependency graph. Without `--frozen-lockfile`, pnpm warns and resolves again when the locked graph no longer matches the target.

- Python resolution no longer fails on malformed `Requires-Python` values, such as the trailing comma in `openpyxl` 3.0.x. pnpm treats these releases as declaring no interpreter range [#&#8203;14910](https://github.com/pnpm/pnpm/issues/14910).

- `pnpm add pypi:...` now rejects unsupported `--save-prefix` values before editing the manifest or resolving dependencies.

##### Workspaces and scripts

- Scripts listed in `syncInjectedDepsAfterScripts` no longer fail with `ERR_PNPM_INJECTED_DEPS_SYNC_READ_DIR` when the lockfile contains an injected package copy that no project depends on.

- `shellEmulator` now expands `${VAR}`, `${VAR:-default}`, and `${VAR:+alternative}` in scripts [#&#8203;14814](https://github.com/pnpm/pnpm/issues/14814).

- Cargo and Python project discovery now honors `!` exclusions in `pnpm-workspace.yaml` `packages`, skipping both parsing and generated source configuration for excluded projects [#&#8203;14844](https://github.com/pnpm/pnpm/issues/14844).

- `pnpm --filter "./packages/{app,lib}"` now selects either alternative. Brace alternatives can nest, span path separators, and combine with other wildcards.

- GitHub Actions updates now stop if an action reference changes during version resolution, and preserve unrelated workflow edits.

##### CLI and output

- `pn`, `pnpx`, and `pnx` now run the pnpm installed alongside them, even when that directory is absent from `PATH` or another pnpm comes first [#&#8203;14803](https://github.com/pnpm/pnpm/issues/14803).

- `pnpm --version` now reports failures to install or record a project's pinned pnpm, then prints the running CLI's version. It also honors `--store-dir` and `--store` [#&#8203;14831](https://github.com/pnpm/pnpm/issues/14831).

- `pnpm self-update` no longer reinstalls the active version when it was installed by the standalone installation script [#&#8203;14823](https://github.com/pnpm/pnpm/issues/14823).

- `pnpm t` and `pnpm tst` work again as aliases for `pnpm test`.

- `pnpm sbom` now emits valid repository URLs in CycloneDX `externalReferences[].url` and SPDX `homepage`. Shorthands such as `vercel/ms` become `git+https` URLs, embedded credentials are removed, and invalid repository values are omitted [#&#8203;14773](https://github.com/pnpm/pnpm/issues/14773).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
      </td>
    </tr>
    <tr>
      <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>
    </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://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>
      <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>
    </tr>
    <tr>
      <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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.4.1`](https://github.com/pnpm/pnpm/releases/tag/v12.4.1): pnpm 12.4.1

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.4.0...v12.4.1)

pnpm 12.4.1 fixes installs that failed on filesystems refusing hard links or clones, on Android, and under `nodeLinker: hoisted`. Repeat installs are faster.

#### Patch Changes

##### Installing packages

- `pnpm install` no longer fails with `Operation not permitted` when the filesystem refuses a hard link or a copy-on-write clone [#&#8203;14722](https://github.com/pnpm/pnpm/issues/14722). Under `packageImportMethod: auto` and `clone-or-copy`, pnpm copies the file instead. EdenFS checkouts, which have no hard links, and rootless containers, which refuse the clone syscall, both hit this. An explicit `packageImportMethod: hardlink` or `clone` still reports the error.

  pnpm also copies a package file whose store entry has reached the filesystem's limit on names for one file, 1024 on NTFS and 65000 on ext4. Such a file failed the install under `packageImportMethod: hardlink`, and under `auto` it stopped pnpm hard linking for the rest of the install.

- `pnpm install` no longer writes a package file through a symlink left at the path it is importing to. Copying such a file overwrote whatever the link pointed at, and created that file when the link pointed nowhere. An executable package file also made the link's target executable.

- Fixed `pnpm install` and `pnpm dlx` on Android. Registry requests crashed because pnpm found no system CA certificates, so pnpm uses bundled ones there [#&#8203;14777](https://github.com/pnpm/pnpm/issues/14777). Imports also failed with "Permission denied" on filesystems that deny hard links and reflinks, and now fall back to copying [#&#8203;14780](https://github.com/pnpm/pnpm/issues/14780).

- `pnpm install` no longer fails with "Invalid cross-device link" while preserving a package's nested `node_modules` directory during a Docker build [#&#8203;14758](https://github.com/pnpm/pnpm/issues/14758).

- `pnpm install` no longer fails on a package tarball that carries a file at the archive root, such as the `._*` entries macOS `tar` adds [#&#8203;14701](https://github.com/pnpm/pnpm/issues/14701). The file is installed at the root of the package.

  A `file:` tarball packed without the usual `package/` directory is now recorded under the name and version from its own `package.json`. It was recorded under the alias the dependency was given, at version 0.0.0.

- Under `nodeLinker: hoisted`, `pnpm install` no longer re-imports packages that are already in place. A repeat install replaced the whole `node_modules` tree and reported `Packages: +N`. A package is still imported when its directory is missing, when its `package.json` no longer carries the installed version, when it is a `file:` dependency, and when it is patched. Lifecycle scripts no longer run again for a package left in place, and `pnpm rebuild` and a change to `allowBuilds` still reach it.

- `pnpm install` now runs a dependency's build scripts again when its side-effects cache entry has no files to restore [#&#8203;14717](https://github.com/pnpm/pnpm/issues/14717). Such builds were skipped and nothing was put in their place, so a script whose whole effect lands outside its own package directory, such as a git hook installer, never took effect. pnpm no longer publishes empty artifacts to the shared side-effects cache either.

##### Resolving and linking dependencies

- `pnpm install`, `pnpm add`, and `pnpm dedupe` now apply `ignoredOptionalDependencies` [#&#8203;14729](https://github.com/pnpm/pnpm/issues/14729). Matching optional dependencies are left out of the lockfile and are not installed. pnpm 12 installed them whenever it resolved dependencies from scratch.

- `pnpm install` no longer links a transitive dependency to a workspace package when `linkWorkspacePackages` is `true` and the dependency is declared with a plain version range [#&#8203;14781](https://github.com/pnpm/pnpm/issues/14781). Enabling `preferWorkspacePackages` does not change this. Set `linkWorkspacePackages: deep` to link them.

- `pnpm install` no longer leaves dangling dependency links in workspace packages located above the workspace root [#&#8203;14726](https://github.com/pnpm/pnpm/issues/14726).

- `pnpm install` and `pnpm add` no longer leave a dangling symlink in `node_modules` when a project starts depending directly on a package that the lockfile holds only as a transitive dependency with resolved peer dependencies [#&#8203;14714](https://github.com/pnpm/pnpm/issues/14714).

- `pnpm dedupe` now keeps a compatible auto-installed peer when another workspace project depends on a newer major [#&#8203;14697](https://github.com/pnpm/pnpm/issues/14697). Repeated runs alternated between compatible and incompatible peer versions.

- `pnpm peers check` no longer reports a peer dependency declared as `workspace:^`, `workspace:~`, or a bare `workspace:` as unmet [#&#8203;14770](https://github.com/pnpm/pnpm/issues/14770). pnpm reported these as unmet whatever version the linked workspace project supplied.

##### Performance

- Sped up repeat installs [#&#8203;14540](https://github.com/pnpm/pnpm/issues/14540). pnpm checks the store's files only for the packages it links into `node_modules`, instead of every package in the lockfile. Creating the command shims in `node_modules/.bin` makes about 1,500 fewer filesystem calls in a 76 project workspace. Installs that use the global virtual store read their slot paths from the cache directory instead of deriving them every time. Verifying a large lockfile also allocates less memory.

- Sped up `pnpm install` in Cargo workspaces with many member crates. Repeated installs reuse verified Cargo checksum metadata.

- Installing several packages from the same Git repository and commit now downloads the source once per install [#&#8203;14725](https://github.com/pnpm/pnpm/issues/14725). Each package still runs its prepare scripts in its own copy of the checkout.

##### Running scripts and tasks

- pnpm now passes Ctrl+C on to the script or command it started and waits for it to shut down [#&#8203;14723](https://github.com/pnpm/pnpm/issues/14723). pnpm exited first, so a script that was still writing landed on the shell prompt.

- `pnpm run "/pattern/" --no-bail` now lets every matched script finish after one of them fails [#&#8203;14718](https://github.com/pnpm/pnpm/issues/14718). The command exits with `ERR_PNPM_RUN_FAILED`, and its message lists the scripts that failed in the order they were selected.

- `pnpm pipeline` no longer fails on a project that tracks a symlink, such as a `CLAUDE.md` pointing at `AGENTS.md` [#&#8203;14692](https://github.com/pnpm/pnpm/issues/14692). Changing a symlinked input's target invalidates that task's cache, and `pnpm pipeline --no-cache` no longer hashes task inputs.

##### Commands

- `pnpm add -g`, `pnpm update -g`, and `pnpm remove -g` no longer change global bins or install directories after reading only part of an installed package group [#&#8203;13796](https://github.com/pnpm/pnpm/issues/13796). If any declared package manifest is missing, malformed, or unreadable, pnpm now fails before it activates or removes anything and leaves the existing global installation intact.

- `pnpm dedupe` now processes every workspace project by default, including workspaces that keep a separate lockfile per project [#&#8203;14732](https://github.com/pnpm/pnpm/issues/14732). Workspace filters select which projects it processes, and `--fail-if-no-match` exits with an error when no project matches.

- `pnpm update <name>@&#8203;<version>` now keeps the range operator the manifest declares [#&#8203;14745](https://github.com/pnpm/pnpm/issues/14745). Running `pnpm update [email protected]` on `"react": "^19.2.8"` writes `"react": "^19.3.0"`. A `jsr:` entry keeps its `jsr:` prefix, and a plain `pnpm update` now moves a `jsr:` range the way it moves an npm range.

- `pnpm --filter` directory selectors now support `?` wildcards and character classes such as `[ab]`. A `*` or `?` wildcard no longer selects a directory whose name starts with a dot, as on pnpm 11.

- `pnpm deploy --legacy` now prefers the dependency versions pinned in the source workspace lockfile when they still satisfy the deployed project's range [#&#8203;13857](https://github.com/pnpm/pnpm/issues/13857).

- `pnpm sbom` now leaves out a package's author field when the manifest author name is empty or contains only whitespace [#&#8203;14685](https://github.com/pnpm/pnpm/issues/14685). In a filtered or split workspace run, only a project with no `author` field inherits the workspace root's author.

  `pnpm sbom --sbom-format spdx` now writes `creationInfo.created` with whole seconds, such as `2026-09-08T10:38:21Z` [#&#8203;14684](https://github.com/pnpm/pnpm/issues/14684). The fractional seconds it carried were rejected by strict SPDX consumers.

##### Configuration

- The `updateConfig` pnpmfile hook now receives the resolved configuration, including settings that came from `.npmrc`, the command line, or a default [#&#8203;14676](https://github.com/pnpm/pnpm/issues/14676). Scoped registries are reported under `registriesByScope`, and a hook may rewrite that map to change where packages are fetched from. Registry credentials are reported under `configByUri`, as pnpm 11 reports them. An unset setting is left out rather than reported as `null`.

- `pnpm audit --fix` and the `minimumReleaseAgeStrict` approval prompt now keep the comments in `minimumReleaseAgeExclude` when they append an entry to it in `pnpm-workspace.yaml`. The rest of the list is left as written, and the `trustPolicyExcludePrune` and `minimumReleaseAgeExcludePrune` cleanups keep the comments of the entries they retain.

  `pnpm install` and `pnpm dedupe` now run those cleanups too [#&#8203;14759](https://github.com/pnpm/pnpm/issues/14759). Only `pnpm add`, `pnpm update`, and `pnpm remove` pruned the entries that the freshly written lockfile no longer resolves.

- `pnpm config set --global node-download-mirrors` no longer rejects the key [#&#8203;13611](https://github.com/pnpm/pnpm/issues/13611). The global config file already accepted `nodeDownloadMirrors`, but the command refused to write it.

- `NO_PROXY` entries that start with a dot, such as `.npmjs.org`, now bypass the proxy for the domain and its subdomains [#&#8203;14686](https://github.com/pnpm/pnpm/issues/14686).

- pnpm no longer creates a project `pnpm-lock.yaml` when `devEngines.packageManager.onFail` is `download` and lockfile writing is off through `lockfile: false` or `--no-lockfile` [#&#8203;14728](https://github.com/pnpm/pnpm/issues/14728). pnpm still switches to the pinned version.

- pnpm now writes `node_modules/.package-map.json` only when `nodeExperimentalPackageMap` is enabled. Nothing reads the file without that setting, and an install that stops writing the map removes the one a previous install left.

##### Windows

- `pnpm pipeline` no longer fails with intermittent access denied errors when concurrent tasks save their cache entries on Windows.

- Windows filesystem operations now retry permission errors for up to one second [#&#8203;14682](https://github.com/pnpm/pnpm/issues/14682). A permanent permission error delayed the failure by a minute. Sharing and lock violations keep their one minute retry budget.

##### Messages and output

- pnpm now warns when the root `package.json` declares a non-empty `workspaces` array and the project has no `pnpm-workspace.yaml` [#&#8203;2255](https://github.com/pnpm/pnpm/issues/2255). Such an install linked no project and said nothing about why.

- `ERR_PNPM_PACKAGE_MANAGER_REMOVE_MODULES_DIR` now names the file or directory in `node_modules` that pnpm could not clean up. It reported only the underlying OS error, such as "Access is denied (os error 5)".

- `pnpm --help` no longer describes pnpm as experimental.

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
      </td>
    </tr>
    <tr>
      <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>
    </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://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>
      <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>
    </tr>
    <tr>
      <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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

</details>

<details>
<summary>eemeli/yaml (yaml)</summary>

### [`v2.9.1`](https://github.com/eemeli/yaml/releases/tag/v2.9.1)

[Compare Source](https://github.com/eemeli/yaml/compare/v2.9.0...v2.9.1)

- Limit recursive merge aliases ([#&#8203;685](https://github.com/eemeli/yaml/issues/685), [#&#8203;713](https://github.com/eemeli/yaml/issues/713))
- Simplify line unfolding during quoted string parsing ([#&#8203;714](https://github.com/eemeli/yaml/issues/714))

</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-554.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/554
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
2026-09-21 17:20:52 +00:00
Lunny Xiaoandbircni c5fdf2eb18 docs: use the maintained main-nightly docker tags (#550)
Fixes https://github.com/go-gitea/gitea/issues/39310

The docker install pages tell readers to use `:nightly` / `:nightless-rootless` for the latest development version, but those tags are no longer published — the registry only carries `main-nightly` and `main-nightly-rootless` (plus the per-release-branch `1.x-nightly` tags):

```
$ curl -s https://docker.gitea.com/v2/gitea/tags/list?n=1000 | tr ',' '\n' | grep -E '"(main-)?nightly(-rootless)?"'
"main-nightly"
"main-nightly-rootless"
```

Anyone who followed the rootless page has been pinned to an image that has not been rebuilt since 2025-08-23.

Changes:

- point the docker and rootless docker install pages at `:main-nightly` / `:main-nightly-rootless`, in English and in the zh-cn/zh-tw translations
- use `1.27-nightly` instead of the long gone `1.16-nightly` as the release branch example (the oldest one still published is `1.19-nightly`)
- fix the zh-cn/zh-tw claim that `:latest` installs a development version, and mention the nightly tags there the way the English page does
- render `@dockerVersion@` as `main-nightly` for the next version, so the compose snippets on the unreleased docs no longer reference `gitea:nightly`

Not touched: the 1.22–1.26 versioned docs carry the same stale tag, but those versions are already out of maintenance — happy to include them if preferred.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- cloudflare-preview --> Preview: https://pr-550.docs-gitea-com.pages.dev

---------

Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/550
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
2026-09-20 16:46:22 +00:00
8404944fbb docs: Document audit logging (#544)
Co-authored-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/544
Reviewed-by: Lunny Xiao <[email protected]>
Reviewed-by: silverwind <[email protected]>
Co-authored-by: bircni <[email protected]>
2026-09-19 12:54:16 +00:00
Gitea Bot 9f58fd3d28 Update the latest api documents (#551)
Automated update of static/swagger-latest.json and static/openapi3-latest.json from the gitea main branch, opened by the "update api spec files" scheduled workflow.

<!-- cloudflare-preview --> Preview: https://pr-551.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/551
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Gitea Bot <[email protected]>
2026-09-19 00:12:35 +00:00
silverwind 779acd1cb9 docs: document NOTICE_ON_SUCCESS for every cron task (#552)
Several cron tasks in the cheat sheet listed `ENABLE_SUCCESS_NOTICE` or `NO_SUCCESS_NOTICE`. Gitea reads neither, only `NOTICE_ON_SUCCESS`. `NO_SUCCESS_NOTICE` was removed in https://github.com/go-gitea/gitea/pull/19221.

1. Replace both dead keys with `NOTICE_ON_SUCCESS` (default `false`).
2. Fix "Notice if not success" descriptions, which inverted the key's meaning.
3. List the key for `cleanup_hook_task_table`, `cleanup_actions`, `cleanup_action_runs` and `gc_lfs`, which honor it but omitted it.

Matches https://github.com/go-gitea/gitea/pull/39352.

Written by Claude.

Reviewed-on: https://gitea.com/gitea/docs/pulls/552
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-09-18 23:53:53 +00:00
5db4089ae6 chore(deps): update dependencies (#546)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.41.11` → `0.42.0`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.41.11/0.42.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight/0.42.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight/0.41.11/0.42.0?slim=true) |
| [@astrojs/starlight-docsearch](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/docsearch)) | [`0.7.0` → `0.8.0`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight-docsearch/0.7.0/0.8.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight-docsearch/0.8.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight-docsearch/0.7.0/0.8.0?slim=true) |
| [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`7.2.10` → `7.3.2`](https://renovatebot.com/diffs/npm/astro/7.2.10/7.3.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/astro/7.3.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/astro/7.2.10/7.3.2?slim=true) |
| [pnpm](https://github.com/pnpm/pnpm/tree/main/pnpm) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.2.1` → `12.4.0`](https://renovatebot.com/diffs/npm/pnpm/12.2.1/12.4.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/12.4.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/12.2.1/12.4.0?slim=true) |
| [starlight-openapi](https://github.com/HiDeoo/starlight-openapi) ([source](https://github.com/HiDeoo/starlight-openapi/tree/HEAD/packages/starlight-openapi)) | [`0.26.1` → `0.26.2`](https://renovatebot.com/diffs/npm/starlight-openapi/0.26.1/0.26.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/starlight-openapi/0.26.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/starlight-openapi/0.26.1/0.26.2?slim=true) |

---

### Release Notes

<details>
<summary>withastro/starlight (@&#8203;astrojs/starlight)</summary>

### [`v0.42.0`](https://github.com/withastro/starlight/blob/HEAD/packages/starlight/CHANGELOG.md#0420)

[Compare Source](https://github.com/withastro/starlight/compare/@astrojs/[email protected]...@astrojs/[email protected])

##### Minor Changes

- [#&#8203;3572](https://github.com/withastro/starlight/pull/3572) [`292fb17`](https://github.com/withastro/starlight/commit/292fb179cbf6e2cd970ced46359c520aa14a80b4) Thanks [@&#8203;HiDeoo](https://github.com/HiDeoo)! - Distributes package as JavaScript files with dedicated type declaration files instead of TypeScript source files.

- [#&#8203;4121](https://github.com/withastro/starlight/pull/4121) [`2623ae6`](https://github.com/withastro/starlight/commit/2623ae60af0fdafc71938f96153b0427fcc2b5aa) Thanks [@&#8203;delucis](https://github.com/delucis)! - Simplifies markup for Starlight’s mobile menu toggle

  **⚠️ Potentially breaking change:** If you use a theme plugin, custom styles, or component overrides targeting the `MobileMenuToggle` button or `PageFrame` components, you may need to adjust these for the new markup. The button is no longer wrapped in a `<starlight-menu-button>` custom element and no longer uses the `aria-expanded` attribute. Instead, you can use the `.sl-menu-button` class name to target the button and the `:popover-open` pseudo-class to style the menu open state specifically.

  In the following example, custom styles for the menu button are updated for the new approach:

  ```diff
  - starlight-menu-button button {
  + .sl-menu-button {
    color: var(--sl-color-text);
  }

  - starlight-menu-button[aria-expanded='true'] button {
  + .sl-menu-button:has(~ :popover-open) {
    color: var(--sl-color-text-accent-high);
  }
  ```

  See [`MobileMenuToggle.astro`](https://github.com/withastro/starlight/blob/main/packages/starlight/components/MobileMenuToggle.astro) and [`PageFrame.astro`](https://github.com/withastro/starlight/blob/main/packages/starlight/components/PageFrame.astro) on GitHub for the full source code of the updated components.

- [#&#8203;3572](https://github.com/withastro/starlight/pull/3572) [`292fb17`](https://github.com/withastro/starlight/commit/292fb179cbf6e2cd970ced46359c520aa14a80b4) Thanks [@&#8203;HiDeoo](https://github.com/HiDeoo)! - Removes the `tagline` configuration option, which was never used.

  If your configuration included a `tagline` option, you can safely remove it without any replacement.

- [#&#8203;4134](https://github.com/withastro/starlight/pull/4134) [`6135f01`](https://github.com/withastro/starlight/commit/6135f015b527453d7083ad01d2dc6c61d72fbefc) Thanks [@&#8203;HiDeoo](https://github.com/HiDeoo)! - Updates internal `@astrojs/mdx`, `@astrojs/markdown-satteri`, and `satteri` dependencies.

  ⚠️ **BREAKING CHANGE:** The following minimum versions are now required:

  - `astro` v7.2.10 or later
  - `@astrojs/markdown-satteri` 0.4.0 or later (if you use it)
  - `@astrojs/markdown-remark` 7.3.0 or later (if you use it)

  Please update Starlight and Astro together:

  ```sh
  npx @&#8203;astrojs/upgrade
  ```

- [#&#8203;4121](https://github.com/withastro/starlight/pull/4121) [`2623ae6`](https://github.com/withastro/starlight/commit/2623ae60af0fdafc71938f96153b0427fcc2b5aa) Thanks [@&#8203;delucis](https://github.com/delucis)! - Refactors Starlight’s mobile menu toggle to work when JavaScript fails or is disabled

  ⚠️ **BREAKING CHANGE:** This release drops official support for Chromium-based browsers prior to version 116 (released August 2023), Safari-based browsers prior to version 17.0 (released September 2023), and Firefox prior to version 125 (released April 2024). You can find a list of currently supported browsers and their versions using this [browserslist query](https://browsersl.ist/#q=%3E+0.5%25%2C+not+dead%2C+Chrome+%3E%3D+116%2C+Edge+%3E%3D+116%2C+Firefox+%3E%3D+125%2C+Safari+%3E%3D+17.0%2C+iOS+%3E%3D+17.0%2C+not+op_mini+all).

  This change also removes the `data-mobile-menu-expanded` attribute, which was previously added to `<body>` while the mobile menu is open. If you have custom code that was depending on this attribute, you will need to update it to use a new selector to check if the mobile menu is open.

  In the following example, a custom background colour for the site header while the menu is open is updated for the new approach:

  ```diff
  - [data-mobile-menu-expanded] header {
  + body:has(sl-sidebar-pane:popover-open) header {
    background-color: var(--sl-color-bg);
  }
  ```

</details>

<details>
<summary>withastro/starlight (@&#8203;astrojs/starlight-docsearch)</summary>

### [`v0.8.0`](https://github.com/withastro/starlight/blob/HEAD/packages/docsearch/CHANGELOG.md#080)

[Compare Source](https://github.com/withastro/starlight/compare/@astrojs/[email protected]...@astrojs/[email protected])

##### Minor Changes

- [#&#8203;3572](https://github.com/withastro/starlight/pull/3572) [`292fb17`](https://github.com/withastro/starlight/commit/292fb179cbf6e2cd970ced46359c520aa14a80b4) Thanks [@&#8203;HiDeoo](https://github.com/HiDeoo)! - Distributes package as JavaScript files with dedicated type declaration files instead of TypeScript source files.

</details>

<details>
<summary>withastro/astro (astro)</summary>

### [`v7.3.2`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#732)

[Compare Source](https://github.com/withastro/astro/compare/[email protected]@7.3.2)

##### Patch Changes

- [#&#8203;17896](https://github.com/withastro/astro/pull/17896) [`a548223`](https://github.com/withastro/astro/commit/a548223607b9bb146d5d90ddda495343f9a2a739) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes `<script>`/`<style>` rendering in MDX so that only literal content (including content injected by remark/rehype plugins) is treated as trusted markup. A dynamic value passed as a `<script>`/`<style>` child (e.g. `<script>{value}</script>`) is now escaped like any other element's content instead of being rendered raw. Use `set:html` to explicitly opt a dynamic value back into raw rendering.

- [#&#8203;17931](https://github.com/withastro/astro/pull/17931) [`c1a6a89`](https://github.com/withastro/astro/commit/c1a6a89efa577b8388f04c4b42d655913bb4b886) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes the dev toolbar returning a 504 "Outdated Optimize Dep" error when a workspace-linked package imports a dependency that Vite's initial scan did not discover

- [#&#8203;17908](https://github.com/withastro/astro/pull/17908) [`42e9188`](https://github.com/withastro/astro/commit/42e9188c4ba7360e5ab8ea4cd7f13d6abcf31879) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes i18n fallback routing replacing the first substring match instead of the actual locale segment, which mangled paths like `/energy/en/about` into `/esergy/en/about`

- [#&#8203;17936](https://github.com/withastro/astro/pull/17936) [`4b92ddc`](https://github.com/withastro/astro/commit/4b92ddc6ab0795ac78c30aedfe43b081dcf5b6b0) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes sessions breaking in dev mode with the Cloudflare adapter when middleware is present

- Updated dependencies \[[`a548223`](https://github.com/withastro/astro/commit/a548223607b9bb146d5d90ddda495343f9a2a739)]:
  - [@&#8203;astrojs/markdown-satteri](https://github.com/astrojs/markdown-satteri)@&#8203;0.4.1

### [`v7.3.1`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#731)

[Compare Source](https://github.com/withastro/astro/compare/[email protected]@7.3.1)

##### Patch Changes

- [#&#8203;17899](https://github.com/withastro/astro/pull/17899) [`0389640`](https://github.com/withastro/astro/commit/03896405717471f7d6ff54986ed6beaec0cac94f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixes an error that prevented projects using `astro:assets` from starting or building

### [`v7.3.0`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#730)

[Compare Source](https://github.com/withastro/astro/compare/[email protected]@7.3.0)

##### Minor Changes

- [#&#8203;17767](https://github.com/withastro/astro/pull/17767) [`ce7c91f`](https://github.com/withastro/astro/commit/ce7c91f77dbd7be03c04bc13f87af9d01fef6cef) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Adds `--ignore-lock` flag to `astro preview`, allowing multiple preview servers to run simultaneously on different ports. This is useful for E2E testing workflows (e.g., Playwright) that need to run several preview servers at once.

- [#&#8203;17818](https://github.com/withastro/astro/pull/17818) [`c0b6581`](https://github.com/withastro/astro/commit/c0b65811dfa0dafa1aa04b7d6d67fd09250ff8c1) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Adds a `logger` parameter to image services hooks

  Custom image services now receive Astro's runtime logger as an extra argument. Messages logged with it are routed through the destination configured in `logger` and respect your log level, instead of being written straight to the console:

  ```ts
  import type { LocalImageService } from 'astro';

  const service: LocalImageService = {
    // ...
    async transform(inputBuffer, transform, imageConfig, logger) {
      logger.warn(`Could not optimize "${transform.src}". Passing it through unchanged.`);
      return { data: inputBuffer, format: 'png' };
    },
  };
  ```

  Astro's built-in Sharp service now uses this logger for the warnings it emits when it encounters an unexpected or unsupported source format.

- [#&#8203;17818](https://github.com/withastro/astro/pull/17818) [`c0b6581`](https://github.com/withastro/astro/commit/c0b65811dfa0dafa1aa04b7d6d67fd09250ff8c1) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Adds `logger` to the context object passed to cache providers

  Custom cache providers now receive Astro's runtime logger on the context passed to `onRequest()`. Messages logged with it are routed through the destination configured in `logger` and respect your log level, instead of being written straight to the console:

  ```ts
  import type { CacheProvider } from 'astro';

  const provider: CacheProvider = {
    name: 'my-cache',
    async onRequest({ request, url, logger }, next) {
      logger.warn(`Skipping cache for ${url.pathname} because the response sets a cookie.`);
      return next();
    },
    // ...
  };
  ```

  Astro's built-in `memoryCache()` provider now uses this logger for the warnings it emits when it skips caching a response that sets cookies, and when a background revalidation fails.

##### Patch Changes

- [#&#8203;17818](https://github.com/withastro/astro/pull/17818) [`c0b6581`](https://github.com/withastro/astro/commit/c0b65811dfa0dafa1aa04b7d6d67fd09250ff8c1) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Updates Astro's remaining internal warnings and errors to be written through the configured logger instead of directly to the console, when possible

- [#&#8203;17886](https://github.com/withastro/astro/pull/17886) [`e747cba`](https://github.com/withastro/astro/commit/e747cba07fcd2b9e7fb03c02ed42abfe2079daa2) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes the memory cache provider to skip responses with `Vary: Cookie` or `Vary: *`

- [#&#8203;17885](https://github.com/withastro/astro/pull/17885) [`916b738`](https://github.com/withastro/astro/commit/916b738b0447728f1c274e32677c9bac09be78f6) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Improves build performance for sites with a large number of pages coming from a large amount of different modules.

- [#&#8203;17795](https://github.com/withastro/astro/pull/17795) [`15e2deb`](https://github.com/withastro/astro/commit/15e2debc7e81d353410ff76a76c3bf75b7fb3070) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Adds concurrent rendering support for `experimental.incrementalBuild`, including when using `@astrojs/cloudflare`

  Incremental builds no longer disable caching when `build.concurrency` is greater than `1`. Projects that set `build.concurrency: 1` to keep the cache enabled can remove that workaround. Cloudflare builds also reduce serialization overhead for large prerendered pages.

- [#&#8203;17879](https://github.com/withastro/astro/pull/17879) [`21c34a6`](https://github.com/withastro/astro/commit/21c34a6816372220157ff7e6b697275360d3e367) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes missing styles, links, and scripts from content collection entries rendered inside server islands

- [#&#8203;17861](https://github.com/withastro/astro/pull/17861) [`3193988`](https://github.com/withastro/astro/commit/3193988d0566f53ecd10b03cd18669dcf230c8d6) Thanks [@&#8203;ethanstoner](https://github.com/ethanstoner)! - Fixes i18n fallback routes being generated with a corrupted path when the locale code also appears at the start of a later path segment. A page such as `src/pages/en/enterprise.astro` with `fallback: { es: 'en' }` produced the route `/es/esterprise` instead of `/es/enterprise`, so the fallback never matched the intended URL. Only the leading locale segment is rewritten now.

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

### [`v12.4.0`](https://github.com/pnpm/pnpm/releases/tag/v12.4.0): pnpm 12.4

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.3.4...v12.4.0)

#### Minor Changes

- pnpm can now manage npm, Python, and Cargo dependencies in the same workspace. Enable `python.enabled` or `cargo.enabled` in `pnpm-workspace.yaml`, then use `pnpm install` to install them together.

  - Add Python packages with `pnpm add pypi:<package>`. pnpm uses `pyproject.toml`, `pylock.toml`, and a managed `.venv`. Frozen and offline installs are supported, and `pnpm run` and `pnpm exec` make the environment's executables available [#&#8203;14566](https://github.com/pnpm/pnpm/issues/14566).
  - Add Rust crates with `pnpm add crate:<package>`. pnpm supports crates.io and custom sparse registries configured with `cargo.indexUrl`. Registry authentication supports pnpm credentials and, for crates.io, `CARGO_REGISTRY_TOKEN` or `$CARGO_HOME/credentials.toml`.

  Both ecosystems support faster dependency resolution through `pnprServer`, with local resolution as a fallback when the server does not support it.

- Added `pnpm pipeline [name]` to install frozen dependencies and run workspace tasks declared in `pipelines`. It selects affected projects, runs their task graph, and continues running tasks after a task fails.

  Tasks support `inputs`, `outputs`, `env`, and `cache` settings. Cached results restore task outputs and replay logs. Cargo tasks can reuse local build state between worktrees with `tasks.<name>.cargoTargetDir`. Set `includeWorkspaceRoot: true` to include root tasks.

  Use `pnpm pipeline --dry-run` to preview the task graph without installing configuration dependencies or running workspace hooks.

- Added support for Android on arm64 and x64, FreeBSD on x64, and Linux on ppc64le, s390x, and RISC-V (riscv64 with glibc) [#&#8203;14431](https://github.com/pnpm/pnpm/issues/14431), [#&#8203;14597](https://github.com/pnpm/pnpm/issues/14597), [#&#8203;7582](https://github.com/pnpm/pnpm/issues/7582).

- Added `trustPolicyExcludePrune` to automatically remove unused versions and packages from `trustPolicyExclude` when running `pnpm add`, `pnpm update`, or `pnpm remove`. It is disabled by default. Package name patterns such as `@scope/*` are kept, and cleanup is skipped when `sharedWorkspaceLockfile` is `false`.

- Added `pnpm change check` for CI validation of package versions against the `versioning.epics` bands and `versioning.fixed` groups in `pnpm-workspace.yaml`. It reports all violations, including packages that are not part of the current release.

#### Patch Changes

- Registry metadata is now kept separate for registries with different URL paths or schemes. This prevents installs from using another registry's package versions or tarball URLs, and keeps metadata fetched over HTTP from being reused for HTTPS [#&#8203;13558](https://github.com/pnpm/pnpm/issues/13558).

  The first install after upgrading refetches registry metadata. The package store is unchanged. `pnpm cache view` now shows full registry URLs. Scripts that parse the directory names from `pnpm cache list-registries` or `pnpm cache list` need updating.

- Patches that add build scripts or a `binding.gyp` now trigger a build, subject to build approval. Unapproved builds appear under "Ignored build scripts" [#&#8203;14648](https://github.com/pnpm/pnpm/issues/14648).

- Build scripts can now be rejected before installing a package with `pnpm add --allow-build=!<pkg>`, including global installs. `pnpm approve-builds <pkg>` and `pnpm approve-builds !<pkg>` also save decisions when no packages are awaiting approval. They warn if the named package is not awaiting approval [#&#8203;14067](https://github.com/pnpm/pnpm/issues/14067).

- A registry configured in `.npmrc` now takes precedence over registry settings saved by `pnpm login` in the global `config.yaml`. This fixes installs using the wrong registry after login [#&#8203;14614](https://github.com/pnpm/pnpm/issues/14614).

- Large downloads over slow connections no longer time out while data is still arriving. `fetch-timeout` now limits how long a request can go without making progress [#&#8203;14604](https://github.com/pnpm/pnpm/issues/14604).

- Sped up installs in workspaces with many projects when reusing a warm global virtual store [#&#8203;14540](https://github.com/pnpm/pnpm/issues/14540).

- `pnpm deploy` is faster in large workspaces and no longer fails with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` when the project includes a `.pnpmfile.mjs` [#&#8203;14539](https://github.com/pnpm/pnpm/issues/14539), [#&#8203;14671](https://github.com/pnpm/pnpm/issues/14671).

- `pnpm add --workspace <pkg>` works again. It saves the dependency with the `workspace:` protocol and links it from the workspace. The command fails if no workspace project provides the package [#&#8203;14602](https://github.com/pnpm/pnpm/issues/14602).

- `pnpm add` and `pnpm install` now accept protocol-prefixed selectors such as `jsr:@&#8203;scope/pkg`, `npm:pkg@^1.0.0`, and `workspace:pkg@*` [#&#8203;14590](https://github.com/pnpm/pnpm/issues/14590). Installs with JSR dependencies in the lockfile also no longer fail with `ERR_PNPM_META_FETCH_FAIL` [#&#8203;14649](https://github.com/pnpm/pnpm/issues/14649).

- Boolean flags now accept explicit inline values. For example, `pnpm install --prod=false` installs devDependencies, while `--prod=true` skips them [#&#8203;14553](https://github.com/pnpm/pnpm/issues/14553).

- `pnpm install <pkg>` now accepts `--offline` and `--prefer-offline`, as `pnpm add <pkg>` already did [#&#8203;14194](https://github.com/pnpm/pnpm/pull/14194).

- Fixed `pnpm install --frozen-lockfile` rejecting a freshly generated lockfile when overrides use relative `file:` or `link:` paths in a workspace [#&#8203;14555](https://github.com/pnpm/pnpm/issues/14555).

- Fixed installs with config dependencies failing on symlinked lockfiles, such as those used by Bazel and Nix, when the config dependencies have not changed. Updates that would write through a symlink remain disallowed. Updating config dependencies also preserves lockfiles that start with a byte order mark [#&#8203;14372](https://github.com/pnpm/pnpm/issues/14372).

- Fixed package manager version pins being written to the wrong lockfile when `lockfileDir` is set. The pins also remain consistent across commands when version switching is disabled, avoiding unnecessary lockfile changes [#&#8203;14633](https://github.com/pnpm/pnpm/issues/14633), [#&#8203;14575](https://github.com/pnpm/pnpm/issues/14575).

- `pnpm import` now respects `lockfileDir` and branch lockfiles without modifying other lockfiles. Failed imports restore the destination lockfile [#&#8203;14563](https://github.com/pnpm/pnpm/issues/14563).

- `pnpm patch-commit` now produces valid patches when files are added or deleted. `pnpm install` also accepts patches that delete files without listing their contents, and patch files with CRLF line endings [#&#8203;14559](https://github.com/pnpm/pnpm/issues/14559), [#&#8203;14557](https://github.com/pnpm/pnpm/issues/14557).

- Fixed version ranges with partial upper bounds. For example, `<=16` now includes all 16.x versions, and `>=0.11 <=3` correctly accepts 3.0.1 [#&#8203;14419](https://github.com/pnpm/pnpm/issues/14419).

- Workspace package patterns now support `.` and `..` segments and repeated slashes. Patterns such as `./packages/*` and exclusions such as `!./packages/foo` now match correctly [#&#8203;14571](https://github.com/pnpm/pnpm/issues/14571).

- `packageConfigs` settings now apply to the specified projects when `sharedWorkspaceLockfile` is `false`, including `overrides`, `hoist`, `modulesDir`, `saveExact`, and `savePrefix`. Workspaces with a shared lockfile report which entries were ignored [#&#8203;14556](https://github.com/pnpm/pnpm/issues/14556).

- `pnpm run` and `pnpm exec` no longer report a changed workspace structure after a successful install when `sharedWorkspaceLockfile` is `false` and `verifyDepsBeforeRun` is enabled [#&#8203;14588](https://github.com/pnpm/pnpm/issues/14588).

- Commands run from a project's subdirectory now find the nearest ancestor with a manifest. This fixes commands such as `pnpm bin` returning paths under the wrong directory. `pnpm init` still creates its manifest in the current directory, and `pnpm exec` still runs there [#&#8203;14622](https://github.com/pnpm/pnpm/issues/14622).

- Relative `scriptShell` paths in `pnpm-workspace.yaml` now resolve from the workspace root, including when scripts run in nested packages. Bare command names such as `bash` still use `PATH` [#&#8203;14422](https://github.com/pnpm/pnpm/issues/14422).

- Fixed installing the pnpm version pinned in `packageManager` when `nodeLinker` is `hoisted`. Managed Node.js, Deno, and Bun installations also work when the global config uses `nodeLinker: hoisted` [#&#8203;14595](https://github.com/pnpm/pnpm/issues/14595).

- The JavaScript pnpm can again switch to a project's pinned pnpm version on platforms without a native binary for that version, such as Alpine Linux with pnpm 10 or Intel Macs with pnpm 11. If a native pnpm version does not support the platform, the error now names the missing target [#&#8203;13622](https://github.com/pnpm/pnpm/issues/13622).

- Provisioning Yarn 6 now uses `GH_TOKEN` or `GITHUB_TOKEN` when available to avoid GitHub's anonymous API rate limit in CI. Tokens are only sent when `strict-ssl` is enabled.

- Fixed concurrent installs sharing a global virtual store on macOS failing with "failed to import ... No such file or directory" [#&#8203;14560](https://github.com/pnpm/pnpm/issues/14560).

- Fixed `pnpm setup` failing with `ERR_PNPM_DIRECTORY_FETCHER_PATH_ESCAPE` on Windows. Local `file:` dependencies whose directories are symlinks or junctions are now packed correctly [#&#8203;14618](https://github.com/pnpm/pnpm/issues/14618).

- On Windows, installs now retry replacing command shims temporarily locked by another process [#&#8203;14549](https://github.com/pnpm/pnpm/issues/14549).

- Fixed argument forwarding on Windows with `shellEmulator` enabled. Paths ending in a backslash, line breaks, and literal shell expressions are preserved [#&#8203;14548](https://github.com/pnpm/pnpm/issues/14548).

- Windows store paths now consistently use backslashes in `pnpm store path` output and in the `storeDir` and `virtualStoreDir` fields of `node_modules/.modules.yaml`.

- Invalid certificates in `ca` or `cafile` no longer cause an `Invalid CA certificate` error. Valid certificates still apply, and blank `cert` or `key` values are treated as unset [#&#8203;14646](https://github.com/pnpm/pnpm/issues/14646).

- Installs now respect the archive extraction concurrency limit even after a download is abandoned [#&#8203;14585](https://github.com/pnpm/pnpm/issues/14585).

- `pnpm audit` summaries now exclude advisories ignored through `auditConfig.ignoreGhsas` and report them separately. When all advisories are ignored, the summary says so [#&#8203;14535](https://github.com/pnpm/pnpm/issues/14535).

- `pnpm pack --json` now reports errors as JSON. Lifecycle script output appears before the final JSON output.

- `pnpm outdated -r` now wraps the `Dependents` column, keeping the table readable when many workspace projects use the same dependency [#&#8203;14591](https://github.com/pnpm/pnpm/issues/14591).

- Shell completions now support the `pn` alias in bash, fish, pwsh, and zsh [#&#8203;11955](https://github.com/pnpm/pnpm/issues/11955).

- `pnpm version` now accepts `-m` as a short alias for `--message` [#&#8203;14567](https://github.com/pnpm/pnpm/issues/14567).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
      </td>
    </tr>
    <tr>
      <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>
    </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://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>
      <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>
    </tr>
    <tr>
      <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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.3.4`](https://github.com/pnpm/pnpm/releases/tag/v12.3.4): pnpm 12.3.4

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.3.3...v12.3.4)

#### Patch Changes

- Sped up dependency resolution in large workspaces [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- pnpm 12 now accepts the boolean settings as command-line flags on every command that takes them in pnpm 11, for example `pnpm install --unsafe-perm`, `pnpm add foo --offline`, and `pnpm install --dangerously-allow-all-builds`. pnpm 12 rejected them with `unexpected argument`, which failed every install on Vercel, whose build runs `pnpm install --unsafe-perm` [#&#8203;14346](https://github.com/pnpm/pnpm/issues/14346).

  `pnpm remove` now accepts `--unsafe-perm`, the same flag `pnpm install`, `pnpm add`, and `pnpm update` take.

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.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/notion.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/notion_light.svg" />
            <img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion" />
          </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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.3.3`](https://github.com/pnpm/pnpm/releases/tag/v12.3.3): pnpm 12.3.3

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.3.2...v12.3.3)

#### Patch Changes

- Fixed concurrent installs sharing a store occasionally failing with an ENOENT error while importing a package file [#&#8203;14353](https://github.com/pnpm/pnpm/issues/14353).

- Sped up writing the lockfile in large workspaces [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Sped up dependency resolution in large workspaces [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- pnpm now runs through Node.js when it was installed by a tool that skips build scripts, such as Vercel's `packageManager` provisioning, Bun, Deno, or `npm install --ignore-scripts`. Those installs previously failed with `syntax error near unexpected token ')'`. They still cannot run pnpm on Windows. On macOS only a shell can start it [#&#8203;14346](https://github.com/pnpm/pnpm/issues/14346).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.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/notion.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/notion_light.svg" />
            <img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion" />
          </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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.3.2`](https://github.com/pnpm/pnpm/releases/tag/v12.3.2): pnpm 12.3.2

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.3.1...v12.3.2)

#### Patch Changes

- `pnpm audit --fix update` no longer aborts when a vulnerable package has no safe version inside its declared range [#&#8203;14508](https://github.com/pnpm/pnpm/issues/14508). The run updates every package it can and lists the rest as remaining.

- `pnpm install` no longer reruns root lifecycle scripts when the global virtual store contains an unfinished-build marker in a package slot that the current lockfile does not use [pnpm/pnpm#14485](https://github.com/pnpm/pnpm/issues/14485).

- Sped up installs that have no lockfile. pnpm now links packages whose dependency subtree has no peer dependencies into the virtual store while resolution is still running.

- `pnpm run` and `pnpm exec` now start without reinstalling on filesystems that keep sub-millisecond mtimes, such as NTFS. Previously, every run on those filesystems reinstalled first [pnpm/pnpm#14486](https://github.com/pnpm/pnpm/issues/14486).

- `pnpm import` now keeps the versions recorded in `package-lock.json`, `npm-shrinkwrap.json`, or `yarn.lock` when it generates `pnpm-lock.yaml`. A range in `package.json`, a catalog, or an override still decides which versions are eligible, and the recorded version is preferred among them. The generated lockfile previously could pin newer versions than the source lockfile [#&#8203;14476](https://github.com/pnpm/pnpm/issues/14476).

  `pnpm import` in a workspace now imports every workspace project into the shared lockfile. It previously imported only the project in the current directory.

  `pnpm import` now fails with `ERR_PNPM_LOCKFILE_NOT_FOUND` when none of the three source lockfiles is present. It also fails with `ERR_PNPM_YARN_LOCKFILE_PARSE_FAILED` when it cannot parse `yarn.lock`. It previously generated a lockfile from scratch in both cases.

  `pnpm import` always resolves locally. It warns when `--pnpr-server` or the `pnpr-server` setting is given and does not use the server.

- Sped up installs in large workspaces. Discovering the workspace projects no longer enumerates every matched directory to learn which manifest files it holds [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Sped up installs in large workspaces. The resolver and the peer pass allocate less for every dependency edge [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- `pnpm self-update`, `pnpm with`, and automatic package-manager version switching no longer wait through registry retry delays when a configured registry has no signatures and `registry.npmjs.org` is unavailable [#&#8203;14483](https://github.com/pnpm/pnpm/issues/14483).

- Sped up installs in large workspaces. Saving the lockfile is faster, and the install finishes without waiting for memory cleanup [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- `pnpm install` now relinks workspace packages when `publishConfig.linkDirectory` changes. Frozen installs report an outdated lockfile until it is regenerated [pnpm/pnpm#14488](https://github.com/pnpm/pnpm/issues/14488).

- The pnpm npm wrapper keeps its placeholder shebang-less so pnpm 11 can install pnpm 12 through the version store. Wrapper installs must allow lifecycle scripts to install the native binary [#&#8203;14502](https://github.com/pnpm/pnpm/issues/14502).

- Sped up dependency resolution when there is no lockfile, and for the dependencies a lockfile does not cover.

- Sped up installs in large workspaces. Workspace `link:` targets and importer ids are now derived from the paths' suffixes under the workspace root [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- `pnpm install` now reports "Already up to date" when local tarball dependencies have not changed [#&#8203;14495](https://github.com/pnpm/pnpm/issues/14495).

- `pnpm update` now accepts `--ignore-scripts` and skips lifecycle scripts during the update [pnpm/pnpm#14512](https://github.com/pnpm/pnpm/issues/14512).

- Sped up installs that restore a deleted `node_modules` from a warm global virtual store. pnpm no longer re-links packages that are already fully present in the global virtual store [#&#8203;14510](https://github.com/pnpm/pnpm/issues/14510).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.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/notion.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/notion_light.svg" />
            <img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion" />
          </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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.3.1`](https://github.com/pnpm/pnpm/releases/tag/v12.3.1): pnpm 12.3.1

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.3.0...v12.3.1)

#### Patch Changes

- Sped up installs in large workspaces: the anchor for re-rendering workspace `link:` targets is now derived once per project instead of once per dependency edge, and project ordering hashes paths by their raw bytes [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- After a self-update from pnpm 12.2 to 12.3, global commands such as `node`, `npm`, and `yarn` failed with `unexpected argument '--shim' found`. Global commands now launch normally, and their first launch migrates the global bin directory to native shims. When self-update downgrades to pnpm 12.2 or older, it keeps the newer native shims so those commands continue to work.

- Sped up installs in large workspaces. The check that verifies each project against the lockfile now runs the projects in parallel [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.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/notion.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/notion_light.svg" />
            <img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion" />
          </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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

### [`v12.3.0`](https://github.com/pnpm/pnpm/releases/tag/v12.3.0): pnpm 12.3

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.2.1...v12.3.0)

#### Minor Changes

- Every context-aware global command (`node`, `deno`, `bun`, and the shims created with `pnpm shim add`) is now a native executable on every platform, so environment variables whose names are not valid shell identifiers reach these commands. On Windows, `<name>.exe` replaces the `.cmd` and `.ps1` shims for them. Shims written by earlier pnpm 12 releases are migrated on the next global install or self-update.

- `pnpm remove` and `pnpm update` now accept `--trust-lockfile`, `--no-trust-lockfile`, `--trust-policy`, `--trust-policy-exclude` and `--trust-policy-ignore-after`, the same flags `pnpm install` and `pnpm add` take, so the supply-chain settings can be overridden for a single run. `pnpm remove` verifies the lockfile against the active policies the way `pnpm install` does, and `--trust-lockfile` skips that pass for every entry, not only the package being removed.

  `pnpm` now also honors `--config.trust-lockfile=<value>`, and accepts the bare `--trust-lockfile` / `--no-trust-lockfile` spelling on the commands that previously took the setting from the config file alone.

#### Patch Changes

- `pnpm add <local directory>`, `pnpm add <local tarball>`, `pnpm add file:<path>` and `pnpm add <tarball URL>` work again. A specifier given without a `<name>@&#8203;` prefix is no longer read as a registry package name and rejected with `ERR_PNPM_PACKAGE_MANAGER_ADD_RESOLVE_LATEST` [#&#8203;14437](https://github.com/pnpm/pnpm/issues/14437).

- Fixed `pnpm deploy --legacy` ignoring `allowUnusedPatches` supplied through `--config.allow-unused-patches` or the `PNPM_CONFIG_ALLOW_UNUSED_PATCHES` environment variable [pnpm/pnpm#14450](https://github.com/pnpm/pnpm/issues/14450).

- Fixed `pnpm install --lockfile-only` writing a lockfile that referenced a missing peer-suffixed snapshot when an npm-aliased dependency took part in a cyclic peer dependency graph. The following `pnpm install --frozen-lockfile` failed with `ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY` [#&#8203;14449](https://github.com/pnpm/pnpm/issues/14449).

- `pnpm config` now accepts `-g`/`--global`, `--location`, and `--json` before its subcommand [pnpm/pnpm#14421](https://github.com/pnpm/pnpm/issues/14421).

- `pnpm dedupe` now converges in one pass when it re-resolves a lockfile created by pnpm 11, so a second run no longer changes the lockfile [#&#8203;14455](https://github.com/pnpm/pnpm/issues/14455).

- Fixed detached child processes being terminated on Windows when another program launches `pnpm` directly, without a shell, as `nr` from `@antfu/ni` does [#&#8203;14447](https://github.com/pnpm/pnpm/issues/14447).

- Fixed `pnpm docs <package>@&#8203;<version>` ignoring the requested version. It now opens the selected version's homepage and reports a missing version instead of opening the package-level homepage [pnpm/pnpm#14428](https://github.com/pnpm/pnpm/issues/14428).

- Sped up installs in large workspaces. `pnpm-lock.yaml` is now read while the workspace projects are being discovered [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Fixed filtered and recursive `pnpm run` and `pnpm exec` hanging when a script reads from the terminal. Interactive prompts work again in a script that pnpm never runs alongside another one, such as a single `--filter`ed project, `--workspace-concurrency=1`, a dependency chain, or a task declaring `concurrency: 1` [#&#8203;14397](https://github.com/pnpm/pnpm/issues/14397).

- Fixed false unmet peer errors for auto-installed peers in linked workspace packages.

- Fixed npm global installs on Windows so the PowerShell shims invoke `pnpm.exe`.

- Fixed `pnpm with current <command>` when global options precede it, such as `pnpm --workspace-root with current --version` [pnpm/pnpm#14413](https://github.com/pnpm/pnpm/issues/14413).

  A short-option cluster that mixes a global flag with an option owned by the command, such as `pnpm -ro dist pack-app`, is now parsed like the same options written after the command.

  An option written before the command name is now reported as an unknown option unless that command accepts it, instead of being taken for the command to run. `pnpm -P exec echo` and `pnpm -z exec echo` fail the way `pnpm --tag next exec echo` does.

- Apply pure insertions in zero-context patches at the correct line instead of one line early.

- Improved peer dependency resolution performance when many packages reuse the same peer ranges.

- `pnpm outdated` and `pnpm update` now follow local actions and reusable workflows referenced with GitHub's self-repository syntax (`uses: $/.github/actions/setup`) when looking for outdated GitHub Actions, the same way they follow `./` references.

- The `pnpm install --help` descriptions of `--prod` and `--dev` no longer claim that the flags take precedence over `NODE_ENV`. pnpm does not read `NODE_ENV` when selecting which dependency groups to install [#&#8203;14445](https://github.com/pnpm/pnpm/issues/14445).

- Sped up installs in large workspaces. The check that decides whether the lockfile needs updating no longer compares every project against every lockfile entry [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Sped up dependency resolution in large workspaces that use `link:` dependencies [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- On Linux, pnpm now resolves registry hostnames through the system resolver (`getaddrinfo`), as it already does on macOS and Windows and as pnpm 11 did. Previously, an `/etc/resolv.conf` containing an option the bundled pure-Rust resolver did not recognize, such as `options no_tld_query`, made pnpm ignore the configured nameservers and silently query Google's public DNS instead [#&#8203;14469](https://github.com/pnpm/pnpm/issues/14469).

- Sped up dependency resolution in large workspaces. The resolver builds fewer lookup keys for each dependency [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- `catalogMode` and `--save-catalog` no longer move a local path, tarball, or `workspace:<path>` specifier into a catalog. Such a specifier is resolved against the project that declares it, so one catalog entry cannot mean the same directory for every project that references it [#&#8203;14437](https://github.com/pnpm/pnpm/issues/14437).

- Sped up installs in large workspaces. The workspace dependency graph is now built once per run instead of twice [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Sped up writing `pnpm-lock.yaml` in large workspaces [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- Fixed non-frozen installs through a pnpr server failing instead of regenerating a conflicted lockfile.

- `pnpm update --interactive` renders its checklist the way pnpm 11 does. Group headings and column headers are separators the cursor skips instead of checkboxes that select nothing. The columns of one group line up with the next. `a` toggles all and `i` inverts the selection. The confirmed selection is echoed as a list of package names [#&#8203;14423](https://github.com/pnpm/pnpm/issues/14423).

- Fixed `pnpm config` commands targeting global configuration to skip project package manager version switching, allowing registry authentication to be configured before pnpm downloads a project-pinned version [pnpm/pnpm#14463](https://github.com/pnpm/pnpm/issues/14463).

- Fixed pnpm retaining the surrounding quotes in `.npmrc` values, including auth tokens expanded from environment variables. This restores authentication with registries configured using `:_authToken="${TOKEN}"` [pnpm/pnpm#14427](https://github.com/pnpm/pnpm/issues/14427).

- Fetch and tarball errors no longer print the secrets of the URL they name. Inline `user:pass@` credentials and the query string or fragment of a signed URL are hidden, so a failed install or `pnpm add <url>` cannot leak them into terminal scrollback or CI logs.

- When `dist-tags.latest` names a version whose manifest pnpm cannot read, the error now names that version and the field it could not decode, instead of reporting the tag as empty.

- Retry transient Windows file-lock errors, including sharing violations, while linking dependencies with the default (isolated) `nodeLinker`. This fixes [pnpm/pnpm#14407](https://github.com/pnpm/pnpm/issues/14407).

- `pnpm run`, `pnpm exec`, `pnpm rebuild`, and the script shortcuts such as `pnpm test` now load the pnpmfile, so `updateConfig` hook settings such as `extraEnv` and `extraBinPaths` reach the scripts they spawn [#&#8203;14433](https://github.com/pnpm/pnpm/issues/14433).

- The `pnpm` executable of the npm package now works when the package was installed without running its install scripts, as under `--ignore-scripts` or the default build-script block of pnpm and Bun [#&#8203;14346](https://github.com/pnpm/pnpm/issues/14346). In that case it runs through Node.js and, in a terminal, says how to switch to the native binary.

- Sped up installs in large workspaces. The resolver no longer copies the whole lockfile before resolving [#&#8203;14352](https://github.com/pnpm/pnpm/issues/14352).

- `minimumReleaseAgeStrict` now defaults to `true` when `minimumReleaseAge` is explicitly configured, whether in `pnpm-workspace.yaml`, the global `config.yaml`, a `PNPM_CONFIG_*` variable, or a CLI flag. The built-in 1440-minute default stays non-strict. Previously an explicit cutoff was treated as non-strict, so immature versions were silently added to `minimumReleaseAgeExclude` instead of being gated with a prompt [#&#8203;14409](https://github.com/pnpm/pnpm/issues/14409).

- Preserve environment variables whose names are not valid shell identifiers when launching Node.js installed by `pnpm runtime set node --global` on Unix [pnpm/pnpm#14417](https://github.com/pnpm/pnpm/issues/14417).

- Fixed `pnpm repo` and `pnpm docs` failing to open the Windows browser from WSL [pnpm/pnpm#14467](https://github.com/pnpm/pnpm/issues/14467).

- `pnpm link`, `pnpm outdated`, and `pnpm import` now apply pnpmfile `updateConfig` hooks before resolving dependencies.

- Fixed standalone installations to preserve the bundled `node-gyp` files used to build native dependencies.

- Fixed resolution against registries whose version manifests carry `_npmUser`, `dist.attestations`, `dist.unpackedSize`, `dist.fileCount`, or `peerDependenciesMeta` in a shape npm does not use. Such a version was skipped as though it had never been published, so `pnpm add` could fail with "no version found for the latest tag" even though the registry served it.

- `pnpm unpublish` now completes the two-factor authentication a registry asks for instead of failing with `ERR_PNPM_UNAUTHORIZED` while logged in. A 401 that is an OTP challenge starts the web-based authentication flow, or prompts for a classic one-time password. The obtained password is reused by every request of the run [#&#8203;14464](https://github.com/pnpm/pnpm/issues/14464).

- On Windows, pnpm now resolves host names through the system resolver instead of its own DNS client. The built-in client bound a UDP socket for every lookup, which made Windows Defender Firewall ask to allow `pnpm.exe` again after every `pnpm self-update` [#&#8203;14405](https://github.com/pnpm/pnpm/issues/14405).

<!-- 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>
      <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>
      <td align="center" valign="middle">
        <a href="https://notion.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/notion.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/notion_light.svg" />
            <img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion" />
          </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>
      <td align="center" valign="middle">
        <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

</details>

<details>
<summary>HiDeoo/starlight-openapi (starlight-openapi)</summary>

### [`v0.26.2`](https://github.com/HiDeoo/starlight-openapi/blob/HEAD/packages/starlight-openapi/CHANGELOG.md#0262)

[Compare Source](https://github.com/HiDeoo/starlight-openapi/compare/[email protected]@0.26.2)

##### Patch Changes

- [#&#8203;176](https://github.com/HiDeoo/starlight-openapi/pull/176) [`a4342e6`](https://github.com/HiDeoo/starlight-openapi/commit/a4342e6250ac0509b625e9b2569bff0603a94eec) Thanks [@&#8203;HiDeoo](https://github.com/HiDeoo)! - Fixes custom Expressive Code configuration being overwritten.

</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-546.docs-gitea-com.pages.dev

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/546
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
2026-09-18 00:22:46 +00:00
f1553bed2f docs(installation): adding podman quadlet instructions (#536)
I was reading the instructions from Docker, trying to adapt to my podman setup (with Quadlet) and through I could share it, some people might find it useful.

Signed-off-by: axel7083 <[email protected]>
Co-authored-by: silverwind <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
Co-authored-by: axel7083 <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/536
Reviewed-by: Lunny Xiao <[email protected]>
Reviewed-by: silverwind <[email protected]>
Co-authored-by: axel7083 <[email protected]>
2026-09-17 23:10:02 +00:00
Gitea Bot 77e495f772 Update the latest api documents (#549)
Automated update of static/swagger-latest.json and static/openapi3-latest.json from the gitea main branch, opened by the "update api spec files" scheduled workflow.

<!-- cloudflare-preview --> Preview: https://pr-549.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/549
Co-authored-by: Gitea Bot <[email protected]>
2026-09-17 00:21:50 +00:00
Talya 3d302e72e2 Add commits in other repos documentation (#548)
Added in [go-gitea/gitea#22645](https://github.com/go-gitea/gitea/pull/22645) but not properly documented.

Reviewed-on: https://gitea.com/gitea/docs/pulls/548
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Talya <[email protected]>
2026-09-15 16:56:15 +00:00
kmiitandLunny Xiao 1a284521f1 docs: Sync zh-cn and zh-tw current and 1.27 with English (#545)
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/545
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: kmiit <[email protected]>
2026-09-14 19:50:42 +00:00
Gitea Bot 42591cadac Update the runner reference pages (#547)
Automated update of the generated runner reference pages from gitea/runner (main for the develop docs, the newest stable tag for every documented series), opened by the "update runner reference" scheduled workflow.

<!-- cloudflare-preview --> Preview: https://pr-547.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/547
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Gitea Bot <[email protected]>
2026-09-14 12:25:17 +00:00
Lunny Xiaoandbircni 3258717d62 fix(api): show the name of a type in the reference, document the gmail app password (#541)
Two unrelated but small fixes, closes #258 and closes #32.

**The reference does not name its types (#258)**

Since the api reference is rendered from the openapi 3.0 document, a field of type `ReviewStateType` is rendered as the bare string enum the `$ref` points at: starlight-openapi dereferences everything and the schema has no `title`, so the name of the type is nowhere on the page. Searching the current reference for `ReviewStateType` returns nothing, which is what the issue reports (the plugin also has no route for `components/schemas`, so there is no page per type either).

`normalizeSchema()` now titles every named schema of an openapi 3.0 document with its own name, which the plugin renders next to the type of a field:

- before: `state` · `string` · Allowed values: APPROVED …
- after: `state` · `ReviewStateType` · `string` · Allowed values: APPROVED …

The go doc comments start with the name of the type, so the description would repeat it ("ChangeFilesOptions — ChangeFilesOptions options for creating …"); a leading `<name> ` is stripped from the description.

For the record, how the three generations of documents describe that type:

| Versions | Type name | Allowed values |
| --- | --- | --- |
| 1.22 – 1.25 (swagger, `ReviewStateType` definition without `enum`) | shown | missing |
| 1.26 – 1.27 (swagger, enum inlined upstream) | missing | shown |
| 1.27, next (openapi 3.0, with this change) | shown | shown |

The released swagger documents are frozen, so 1.22 – 1.26 keep what they have; from 1.27 on the reference answers the question the issue asks.

**Gmail needs an app password (#32)**

The configuration in the guide is still correct after Google turned off password-only access, because it already asks for an app password. What was missing is why there is no alternative: Gitea's mailer authenticates with `CRAM-MD5`, `PLAIN` or `LOGIN` and has no XOAUTH2, so "Sign in with Google" is not an option. Added that, together with the two things people run into — an app password needs 2-step verification and a Workspace administrator can disable app passwords for the domain — and the `587` + `smtp+starttls` variant.

Verified by building the api and the next docs: the type names show up on the operation pages, the descriptions are not duplicated, and 1.26 and older are unchanged. `pnpm check` passes.

<!-- cloudflare-preview --> Preview: https://pr-541.docs-gitea-com.pages.dev

---------

Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/541
Reviewed-by: bircni <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
2026-09-12 11:27:21 +00:00
Lunny Xiao 9a6d0d90bf docs(lfs): document the sha the contents API expects for LFS files (#542)
Closes #243.

The `sha` of the contents API is compared against the ID of the blob the commit has at that path, and for a file tracked by Git LFS that blob is the pointer file. Sending the `lfs_oid` or a checksum of the file content fails with `sha does not match`, and nothing in the documentation said so.

Adds a section to the LFS page: use the `sha` from `GET /repos/{owner}/{repo}/contents/{filepath}`, not `lfs_oid`, and note that the API does turn the content into an LFS object by itself when `.gitattributes` tracks the path (`modifyFile()` stores the object and commits the pointer), so nothing else has to be done differently.

The swagger comments upstream are being fixed in https://github.com/go-gitea/gitea/pull/38915, which will reach `/api/next/` through the scheduled job and the released reference with 1.28. The documents of 1.22 – 1.27 are frozen, so the guide is the only place where readers of the current release can find it.

<!-- cloudflare-preview --> Preview: https://pr-542.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/542
Reviewed-by: bircni <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
2026-09-12 11:16:22 +00:00
62 changed files with 1172 additions and 2192 deletions

No files matched your search

-48
View File
@@ -1,48 +0,0 @@
# The status check context of this job is "checks / depends-upstream
# (pull_request)", which the required status check `checks / *` of the protected
# main branch matches, so a pull request waiting for gitea cannot be merged.
# It is a workflow of its own so that a label change does not cancel the build
# and the preview deployment of the `checks` workflow in test.yaml.
#
# The check script comes from the pull request, like the workflow file itself:
# `pull_request` runs both from the head, so taking the script from the base
# branch would not gain anything and would leave this workflow unable to run on
# the pull request that adds it.
name: checks
on:
pull_request:
types:
- opened
- reopened
- synchronize
- edited
- labeled
- unlabeled
concurrency:
group: depends-upstream-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
depends-upstream:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: check the upstream dependencies
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
# optional, only lifts the rate limit of the unauthenticated github api
GITHUB_COM_TOKEN: ${{ secrets.GITHUB_COM_TOKEN }}
run: |
set -euo pipefail
# read the description and the labels from the api instead of the
# event context, so nothing from a pull request body is expanded into
# this script
api="${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY"
curl --silent --show-error --fail --output pull.json "$api/pulls/$PR_NUMBER"
./scripts/check-upstream-deps.sh pull.json
@@ -1,29 +0,0 @@
name: unlabel merged upstream dependencies
on:
schedule:
- cron: '15 */6 * * *' # every 6 hours, quarter past
workflow_dispatch:
jobs:
unlabel:
if: github.repository == 'gitea/docs'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: drop the label from the pull requests upstream caught up with
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
GITHUB_COM_TOKEN: ${{ secrets.GITHUB_COM_TOKEN }}
run: |
set -euo pipefail
if [ -z "${DEPLOY_TOKEN:-}" ]; then
echo "secrets.DEPLOY_TOKEN is missing, cannot remove the label"
exit 1
fi
export GITEA_API="${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY"
./scripts/unlabel-upstream-deps.sh
-32
View File
@@ -48,38 +48,6 @@ The order of the top level sidebar groups comes from `sidebars.js` (and
`versioned_sidebars/` for released versions), the label and order of every other
group from the `_category_.json` of its directory.
### Documenting an unreleased feature
A page that describes a gitea change which is not merged yet must wait for it,
otherwise the site documents something no release has. Say so in the description
of the pull request, on a line of its own, and add the `depends-on-upstream`
label:
```
Depends on: gitea#35851
```
The label is what blocks the merge: the `depends-upstream` check fails while it
is set, unless every dependency is verified as merged, and `main` requires the
`checks` contexts. The check reads the `Depends on:` lines (`gitea#<id>` or the
full pull request url, several lines are allowed) to find out what to wait for,
so the label needs at least one of them. A `gitea#<id>` mentioned anywhere else
in the description is ignored.
Without the label, a dependency that the check finds unmerged still fails it, so
forgetting the label does not let an unreleased feature through.
The `unlabel merged upstream dependencies` job runs every 6 hours, removes the
label once every referenced pull request is merged and comments on the pull
request, which reruns the check. `scripts/check-upstream-deps.sh` is the check
itself and can be run locally against the json of a pull request.
The check asks the github api whether a pull request is merged, and the runners
share the 60 requests per hour it allows without authentication. The optional
`GITHUB_COM_TOKEN` secret (a token without scopes is enough) raises that limit;
without it an unverifiable dependency only fails the check when the label is
set.
## Cutting a version
```shell
+153
View File
@@ -0,0 +1,153 @@
---
date: "2026-09-12T00:00:00+00:00"
slug: "audit-logging"
sidebar_position: 41
aliases:
- /en-us/audit-logging
---
# Audit Logging
Gitea can record security-relevant events as structured audit records: each
event has an `action`, `actor`, `scope`, `origin`, `message` and a JSON
`metadata` blob. Recording is **off by default** and does not change request
behavior when it is disabled.
This is separate from the application, router and access logs described in
[Logging Configuration](logging-config.md). Those logs are for operations and
debugging. The audit log is a durable trail of who changed what.
## Enable recording
Set `[audit].RECORD_OUTPUT` to `database` in `app.ini` and restart Gitea:
```ini
[audit]
RECORD_OUTPUT = database
RETENTION_DAYS = 30
```
Invalid values of `RECORD_OUTPUT` fall back to `disabled`. See the
[configuration cheat sheet](config-cheat-sheet.md#audit-audit) for every option.
With Docker, the same settings can be applied as
`GITEA__audit__RECORD_OUTPUT=database` and `GITEA__audit__RETENTION_DAYS=30`
before Gitea writes them into `app.ini`.
## View events
The Audit Log pages are always available and still list any events that were
stored earlier. When recording is disabled, the site administration page also
shows a warning.
| Audience | Location | Events shown |
| --- | --- | --- |
| Site administrators | Site administration → Monitoring → Audit Log (`/-/admin/monitor/audit_logs`) | Every event |
| Signed-in users | User settings → Audit Log (`/user/settings/audit_logs`) | Events scoped to that user |
| Organization owners | Organization settings → Audit Log (`/<org>/settings/audit_logs`) | Events scoped to that organization |
| Repository administrators | Repository settings → Audit Log (`/<owner>/<repo>/settings/audit_logs`) | Events scoped to that repository |
Each listing can be filtered by actor (username), action and origin, and sorted
by timestamp. The actor filter does not match the
[system actors](#actors-and-origins). Action filters accept an exact action or
a family prefix such as `user:impersonation` or `repository:webhook`.
Site administrators can download the current filtered result as JSONL
(newline-delimited JSON) from **Export JSONL**. The file name is
`gitea-audit-log-<timestamp>.jsonl`.
## Event shape
A recorded event contains:
- **Action**: a stable, colon-separated identifier such as `repository:archive`
or `user:accesstoken:add`.
- **Actor**: the user who performed the action. Actions taken while impersonating
a user record both the impersonator and the impersonated user.
- **Actor credential**: when the request authenticated with a named credential,
the event stores its kind and id, never the secret. Typical values:
`access-token:<id>`, `oauth2-grant:<id>`, `gitea-actions:<task id>`,
`deploy-key:<key id>`.
- **Scope**: the affected unit — `user`, `organization`, `repository` or
`system` (instance-wide).
- **Origin**: how the action was initiated — `ui`, `api`, `cli` or `system`.
- **Message**: a human-readable sentence rendered from a per-action template.
- **Metadata**: extra fields that fill the message template (token name, new
visibility, and so on). Secrets and token values are not stored.
- **IP address**: the client address of the request, when one exists. Events
triggered by a git push record the SSH client address for SSH pushes and
`127.0.0.1` for HTTP pushes.
- **Timestamp**: when the event was recorded.
An exported JSONL line looks like:
```json
{"action":"repository:archive","actor":{"type":"user","id":1,"name":"alice"},"scope":{"type":"repository","id":42,"name":"org/repo"},"message":"Archived repository org/repo.","time":"2026-09-12T11:00:00Z","ip_address":"203.0.113.10","origin":"ui"}
```
The `system:startup` message is kept stable across Gitea versions so operators
can parse it: `System started [Gitea {version}]`.
## Actors and origins
Most web and API requests pick up the signed-in user automatically.
Other entry points record a system actor:
- `(gitea-cli)` for `gitea admin` commands and the `system:startup` and
`system:shutdown` events
- `(gitea-auth-source)` for authentication-source syncs and for users an
authentication source creates or updates at sign-in
- `gitea-actions` for Gitea Actions tasks
- `(deploy-key)` for pushes with a deploy key
- `(Cron)` for scheduled cron tasks
- `Unknown` when no actor can be resolved
Events of the `(gitea-cli)` actor use origin `cli`. Cron tasks, git hooks and
other background work use origin `system`.
## What is recorded
Events cover security-relevant changes, grouped by action family:
- **User**: create and delete, admin, restricted and active status, name,
password and password reset requests, visibility, emails, authentication
source, 2FA, WebAuthn, OpenID, external logins, access tokens, OAuth2
applications and grants, SSH/GPG/principal keys, secrets, webhooks,
impersonation, failed two-factor authentication
- **Organization**: create and delete, name, visibility, members, teams,
OAuth2 applications, secrets, webhooks
- **Repository**: create, fork, archive, delete, rename, visibility, transfer,
mirrors, signing verification, collaborators and teams, default branch,
branch and tag protection, deploy keys, webhooks, secrets
- **Issues and pull requests**: create, delete, comments and merges
- **Projects and wiki pages**: create, update and delete
- **Actions**: enable, disable and dispatch a workflow
- **System**: startup and shutdown, instance-wide webhooks, authentication
sources, instance-wide OAuth2 applications
Recording never fails the request that triggered it. A write error is logged
and the original operation continues.
## What is not recorded
- Read-only access such as browsing, clone, fetch or API GET requests
- Logins, successful or failed, other than failed two-factor authentication
(use the [access log](logging-config.md) and
[Fail2ban Setup](fail2ban-setup.md) for authentication traffic)
- Edits to issues and pull requests
- Token or secret values
- Which SSH key a real user pushed with (deploy keys are named; ordinary SSH
user pushes are not)
## Retention
`RETENTION_DAYS` (default **30**) is the age after which recorded events are
eligible for deletion. Set it to `0` to keep events forever.
Cleanup is performed by the `cron.delete_old_audit_events` task (`SCHEDULE`
defaults to `@every 24h`, `OLDER_THAN` defaults to `[audit].RETENTION_DAYS`).
The task is registered only while `RECORD_OUTPUT` records events **and**
`RETENTION_DAYS` is greater than `0`. Turning recording off therefore also
stops pruning; existing rows stay until you delete them or turn recording back
on.
+31 -12
View File
@@ -656,6 +656,11 @@ And the following unique queues:
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
## Audit (`audit`)
- `RECORD_OUTPUT`: **disabled**: Where security-relevant events are recorded. `disabled` records nothing. `database` writes events to the `audit_event` table and shows them in the admin, organization, repository and user settings. Invalid values fall back to `disabled`. See [Audit Logging](audit-logging.md).
- `RETENTION_DAYS`: **30**: Days to keep recorded events. `0` keeps them forever. Pruning is done by `cron.delete_old_audit_events`. That task is only registered while `RECORD_OUTPUT` records events and `RETENTION_DAYS` is greater than `0`.
## Camo (`camo`)
- `ENABLED`: **false**: Enable media proxy, we support images only at the moment.
@@ -1047,7 +1052,7 @@ Release attachment has its own config options in `[repository.release]` section.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1056,7 +1061,7 @@ Release attachment has its own config options in `[repository.release]` section.
- `ENABLED`: **true**: Enable running repository health check task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run repository health check task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1065,12 +1070,13 @@ Release attachment has its own config options in `[repository.release]` section.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running repository statistics check task periodically.
- `RUN_AT_START`: **true**: Run repository statistics check task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1090,7 +1096,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1099,7 +1105,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1107,12 +1113,14 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Delete Old Action Runs (`cron.cleanup_action_runs`)
- `ENABLED`: **true**: Enable the job deleting action runs older than `RUN_RETENTION_DAYS`. Deletes nothing while that is 0.
- `RUN_AT_START`: **false**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1198,11 +1206,21 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap.
#### Cron - Delete old audit events (`cron.delete_old_audit_events`)
Deletes audit events older than the retention period. The task is only registered when `[audit].RECORD_OUTPUT` records events and `[audit].RETENTION_DAYS` is greater than `0`. See [Audit Logging](audit-logging.md).
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **720h**: any audit event older than this expression will be deleted from the database. Defaults to `[audit].RETENTION_DAYS`.
#### Cron - Check for new Gitea versions (`cron.update_checker`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1210,7 +1228,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1218,6 +1236,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1230,35 +1249,35 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@annually**: Cron syntax to set how often to rebuild
#### Cron - Stop running tasks which haven't been updated for a long time (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 5m**: Cron syntax to set how often tasks to run the check
#### Cron - Stop running tasks which have running status and continuous updates but don't end for a long time (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 30m**: Cron syntax to set how often to run the check.
#### Cron - Cancel jobs which haven't been picked up for a long time (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 6h**: Cron syntax to set how often to run the check.
#### Cron - Start cron based actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 1m**: Cron syntax to set how often to schedule tasks
## Git (`git`)
+15
View File
@@ -86,6 +86,21 @@ PROTOCOL = smtps
Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google
account. You won't be able to use your Google account password directly.
An app password is the only option: Google
[turned off access for apps that sign in with a password alone](https://workspaceupdates.googleblog.com/2023/09/winding-down-google-sync-and-less-secure-apps-support.html)
in 2024 and asks applications to use OAuth instead, which Gitea's mailer does
not implement — it authenticates with `CRAM-MD5`, `PLAIN` or `LOGIN`.
Two things to keep in mind:
- app passwords require 2-step verification on the account, and a Google
Workspace administrator can switch them off for the whole domain. If they are
not available, send through the
[Workspace SMTP relay service](https://support.google.com/a/answer/2956491)
or through another mail provider.
- port `587` works as well, with `SMTP_PORT = 587` and
`PROTOCOL = smtp+starttls`.
### ProtonMail
This feature is currently only available for select Proton for Business customers and those with Visionary and Family plans with custom domain addresses. See [ProtonMail's SMTP documentation](https://proton.me/support/smtp-submission) for more information. This limitation can be circumvented by using the ProtonMail Bridge application.
+21
View File
@@ -41,3 +41,24 @@ client that causes SSH transfers to hang: https://github.com/git-lfs/git-lfs/pul
This can be worked around on all the client machines by setting the git config:
`git config --global lfs.ssh.automultiplex false`
:::
# Changing LFS files through the API
The [contents API](https://docs.gitea.com/api/operations/repo-change-files/)
works on LFS tracked files as well: send the file content as usual and Gitea
stores it as an LFS object and commits a pointer file, as long as the path is
matched by a `filter=lfs` rule in `.gitattributes`.
What is easy to get wrong is the `sha` of the file being changed, which
`PUT`/`DELETE /repos/{owner}/{repo}/contents/{filepath}` and
`POST /repos/{owner}/{repo}/contents` require for an existing file. Gitea
compares it with the ID of the blob the commit has at that path, and for an LFS
tracked file that blob is the **pointer file**, not the content:
- use the `sha` returned by
[`GET /repos/{owner}/{repo}/contents/{filepath}`](https://docs.gitea.com/api/operations/repo-get-contents/)
- do not use `lfs_oid` from the same response, which identifies the LFS object,
and do not use a checksum of the file itself
Sending anything else fails with `sha does not match`, even though the request
looks correct.
+2
View File
@@ -16,6 +16,8 @@ The logging configuration of Gitea mainly consists of 3 types of components:
There is a fully functional log output by default, so it is not necessary to define one.
Security-relevant events (repository transfers, token changes, impersonation, and similar) are recorded separately. See [Audit Logging](audit-logging.md).
## Collecting Logs for Help
To collect logs for help and issue report, see [Support Options](help/support.md).
+1 -1
View File
@@ -43,7 +43,7 @@ You can try it out using [the online demo](https://demo.gitea.com).
- **Security**
Gitea places a strong emphasis on security, offering features such as user permission management, access control lists, and more to ensure the security of code and data.
Gitea places a strong emphasis on security, offering features such as user permission management, access control lists, [audit logging](administration/audit-logging.md), and more to ensure the security of code and data.
- **Code Review**
+1
View File
@@ -34,6 +34,7 @@ _Symbols used in table:_
| Telemetry | **✘** | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
| WebAuthn (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✓ |
| Audit log | ✓ | ✓ | ⁄ | ✓ | ✓ | ? | ? |
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Built-in Package/Container Registry | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ |
| Sync commits to an external repo (push mirror) | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ | ✓ |
+1 -1
View File
@@ -66,7 +66,7 @@ server-1 | 2026-03-11T12:57:50.796198843Z /var/lib/gitea/git is not writable
server-1 | 2026-03-11T12:57:50.796235667Z docker setup failed
```
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly-rootless`)
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:main-nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly-rootless`)
## Named volumes
+1 -1
View File
@@ -30,7 +30,7 @@ image as a service. Since there is no database available, one can be initialized
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
If you don't give the volume correct permissions, the container may not start.
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly`)
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:main-nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly`)
```yaml
networks:
+166
View File
@@ -0,0 +1,166 @@
---
date: "2026-09-03T20:00:00+02:00"
slug: "install-with-podman-quadlet"
sidebar_position: 65
aliases:
- /en-us/install-with-podman-quadlet
---
# Installation with Podman Quadlet
Similarly to [Docker](with-docker.md), [Podman](https://podman.io/) can be used to deploy Gitea.
This reference setup guides users through the setup based on Podman Quadlet.
Podman Quadlet is the native integration of Podman through systemd.
To learn more about Podman Quadlet, see [systemd units using Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
This setup installs the quadlets in `~/.config/containers/systemd/`, the directory for rootless quadlets, and uses the rootless images.
If you install them in a rootful directory such as `/etc/containers/systemd/`, use the rootful images instead.
## Basics
Since Podman v6.0 a single `gitea.quadlets` file can hold multiple quadlets separated by the `---` delimiter.
Paste the following content into a file named `gitea.quadlets`
```ini
# FileName=gitea-data
[Volume]
VolumeName=gitea-data
---
# FileName=gitea-config
[Volume]
VolumeName=gitea-config
---
# FileName=gitea
[Container]
PublishPort=2222:2222
PublishPort=3000:3000
Image=docker.gitea.com/gitea:@dockerVersion@-rootless
ContainerName=gitea
Mount=type=volume,src=gitea-data.volume,destination=/var/lib/gitea
Mount=type=volume,src=gitea-config.volume,destination=/etc/gitea
[Service]
Restart=always
[Install]
# Start with the user session
WantedBy=default.target
```
You can run the installation command
```sh
$ podman quadlet install ./gitea.quadlets --application=gitea
/home/user/.config/containers/systemd/gitea/gitea-data.volume
/home/user/.config/containers/systemd/gitea/gitea-config.volume
/home/user/.config/containers/systemd/gitea/gitea.container
```
The `--application=gitea` flag allows us to tell podman to group the quadlets together, this can help for managing and organizing the quadlets files.
You can validate the quadlets are properly installed by looking at the list command
```sh
$ podman quadlet list
NAME UNIT NAME PATH ON DISK STATUS APPLICATION POD
gitea-config.volume gitea-config-volume.service /home/user/.config/containers/systemd/gitea/gitea-config.volume active/exited gitea
gitea-data.volume gitea-data-volume.service /home/user/.config/containers/systemd/gitea/gitea-data.volume active/exited gitea
gitea.container gitea.service /home/user/.config/containers/systemd/gitea/gitea.container failed/failed gitea
```
You can start the application by running `systemctl --user start gitea` command.
`WantedBy=default.target` starts the service when the user session starts.
Rootless user services do not run without a session, so to start Gitea at boot, enable lingering for the user with `loginctl enable-linger $USER`.
## Databases
### PostgreSQL database
To start Gitea in combination with a PostgreSQL database, apply these changes to the
`gitea.quadlets` file created above.
To start Gitea with a database, we need to create a network, so the database and Gitea container can communicate.
```diff
# FileName=gitea-data
[Volume]
VolumeName=gitea-data
---
# FileName=gitea-config
[Volume]
VolumeName=gitea-config
---
+ # FileName=gitea-postgres-data
+ [Volume]
+ VolumeName=gitea-postgres-data
+ ---
+ # FileName=gitea
+ [Network]
+ NetworkName=gitea
+ ---
+ # FileName=gitea-postgres
+ [Container]
+ Image=docker.io/library/postgres:18
+ ContainerName=gitea-postgres
+ Network=gitea.network
+ Mount=type=volume,src=gitea-postgres-data.volume,destination=/var/lib/postgresql
+ Environment=POSTGRES_USER=gitea
+ Environment=POSTGRES_PASSWORD=gitea
+ Environment=POSTGRES_DB=gitea
+
+ [Service]
+ Restart=always
+
+ [Install]
+ # Start with the user session
+ WantedBy=default.target
+ ---
# FileName=gitea
+ [Unit]
+ Requires=gitea-postgres.service
+ After=gitea-postgres.service
+
[Container]
PublishPort=2222:2222
PublishPort=3000:3000
Image=docker.gitea.com/gitea:@dockerVersion@-rootless
ContainerName=gitea
Mount=type=volume,src=gitea-data.volume,destination=/var/lib/gitea
Mount=type=volume,src=gitea-config.volume,destination=/etc/gitea
+ Network=gitea.network
+ Environment=GITEA__database__DB_TYPE=postgres
+ Environment=GITEA__database__HOST=gitea-postgres:5432
+ Environment=GITEA__database__NAME=gitea
+ Environment=GITEA__database__USER=gitea
+ Environment=GITEA__database__PASSWD=gitea
[Service]
Restart=always
[Install]
# Start with the user session
WantedBy=default.target
```
## Logs
As systemd manages the container we can use `journalctl` to access the logs
```sh
$ journalctl --user --follow --unit=gitea.service
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:263:runWeb() [I] Starting Gitea on PID: 2
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:115:showWebStartupMessage() [I] Gitea version: 1.27.3 built with go1.26.7-X:jsonv2 : bindata, timetzdata,
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:116:showWebStartupMessage() [I] * RunMode: prod
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:117:showWebStartupMessage() [I] * AppPath: /usr/local/bin/gitea
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:118:showWebStartupMessage() [I] * WorkPath: /var/lib/gitea
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:119:showWebStartupMessage() [I] * CustomPath: /var/lib/gitea/custom
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:120:showWebStartupMessage() [I] * ConfigFile: /etc/gitea/app.ini
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:121:showWebStartupMessage() [I] Prepare to run install page
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:329:listen() [I] Listen: http://0.0.0.0:3000
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:333:listen() [I] AppURL(ROOT_URL): http://localhost:3000/
gitea[5967]: 2026/09/03 14:50:42 modules/graceful/server.go:52:NewServer() [I] Starting new Web server: tcp:0.0.0.0:3000 on PID: 2
```
@@ -1074,7 +1074,7 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 设置为 false 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于安排任务,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用于检查新版本的端点。
@@ -1082,7 +1082,7 @@ In-Reply-To =
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -1102,35 +1102,35 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@annually**: Cron 语法,用于设置重建索引的频率。
#### Cron - 停止长时间未更新的运行中任务 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 5m**: Cron 语法,用于设置检查的频率。
#### Cron - 停止持续更新但长时间未结束的运行中任务 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 30m**: Cron 语法,用于设置检查的频率。
#### Cron - 取消长时间未被领取的任务 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 6h**: Cron 语法,用于设置检查的频率。
#### Cron - 启动基于定时的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 1m**: Cron 语法,用于设置调度任务的频率。
## Git (`git`)
@@ -14,6 +14,8 @@ aliases:
2. 将 `https://git.example.com/foo` 反向代理到 `http://gitea:3000/foo`
3. 确保反向代理不会解码 URI。`https://git.example.com/a%2Fb`的请求应该被传递给 `http://gitea:3000/a%2Fb`。
4. 确保 `Host` 和 `X-Forwarded-Proto` 头被正确的传递给 Gitea,使 Gitea 可以看到正在访问的真实 URL。
5. 确保 Web 服务器有完整的证书(包括所有中间证书和根证书),以便 `git clone` 和 `git pull` 正常工作。
6. Gitea 会在 `/-/ws` 使用 WebSocket 连接,用于通知计数等实时更新。请确保反向代理使用 HTTP/1.1,并转发 `Upgrade` 和 `Connection` 头,参见下面的示例。否则 Gitea 会回退为定期轮询。
## 使用子路径
@@ -39,6 +41,7 @@ server {
location / {
client_max_body_size 512M;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
@@ -61,8 +64,9 @@ server {
# 确保 nginx 使用未转义 URI, 按原样保持 "%2F"。 确保 nginx 去除 "/gitea" 子路径前缀, 按原样传递 "/v2"。
rewrite ^ $request_uri;
rewrite ^(/gitea)?(/.*) $2 break;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
proxy_http_version 1.1;
# 其他的常规 HTTP 表头,见上面“使用 Nginx 作为反向代理服务”小节的配置
proxy_set_header Connection $http_connection;
@@ -107,6 +111,7 @@ server {
}
location / {
# 其他指令见上面「使用 Nginx 作为反向代理服务」小节
proxy_pass http://localhost:3000;
}
}
@@ -123,6 +128,7 @@ server {
server_name git.example.com;
location / {
# 其他指令见上面「使用 Nginx 作为反向代理服务」小节
proxy_pass http://localhost:3000;
}
}
@@ -144,6 +150,20 @@ server {
}
```
## Nginx Proxy Manager
如果使用 Nginx Proxy Manager 作为 Gitea 的反向代理,配置与原生 Nginx 略有不同。
它会[默认给自定义 location 加上一些指令](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf),因此上面 Nginx 配置里对应的指令不要再写一遍。否则会因为指令重复(尤其是 `proxy_set_header Host $host`)出现 `400 bad request`。
创建 `/` 自定义 location 时,只需在其配置中加入:
```nginx
client_max_body_size 512M;
```
在代理主机上启用 `Websockets Support`,Nginx Proxy Manager 会自行加入 WebSocket 相关指令。再额外添加 `proxy_http_version` 会导致 Nginx 拒绝启动。
## 使用 Apache HTTPD 作为反向代理服务
如果您想使用 Apache HTTPD 作为 Gitea 的反向代理服务,您可以为您的 Apache HTTPD 作如下配置(在 Ubuntu 中,配置文件通常在 `/etc/apache2/httpd.conf` 目录下):
@@ -154,30 +174,23 @@ server {
ProxyPreserveHost On
ProxyRequests off
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:3000/ nocanon
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
注:必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`
:::note
必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`。
`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本。更旧的版本**必须**去掉它,否则 Apache HTTPD 将无法启动。
:::
如果希望用 Let's Encrypt 的 webroot 验证,请在 `ProxyPass` 之前加入 `ProxyPass /.well-known !`,避免把这些请求代理到 Gitea。
## 使用 Apache HTTPD 作为反向代理服务并将 Gitea 路由至一个子路径
如果您已经有一个域名并且想与 Gitea 共享该域名,您可以增加以下配置为 Gitea 添加路由规则(在 Ubuntu 中,配置文件通常在 `/etc/apache2/httpd.conf` 目录下):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路径和 URL 后面都不要写路径符号 '/'
ProxyPass /git http://localhost:3000 nocanon
</VirtualHost>
```
```apacheconf
<VirtualHost *:80>
...
@@ -187,7 +200,7 @@ server {
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路径和 URL 后面都不要写路径符号 '/'
ProxyPass /git http://localhost:3000 nocanon
ProxyPass /git http://localhost:3000 nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
@@ -195,7 +208,55 @@ server {
然后您**必须**在 Gitea 的配置文件中正确的添加类似 `[server] ROOT_URL = http://git.example.com/git/` 的配置项。
注:必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`
:::note
必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`。`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本,更旧的版本请去掉它。
:::
## 使用 Apache HTTPD 直接提供静态资源
我们可以通过将资源分为静态和动态两种类型来调节性能。
CSS 文件、JavaScript 文件、图片和字体是静态内容。首页、仓库视图和工单列表是动态内容。
Apache HTTPD 可以直接提供静态资源,并且只代理动态资源请求给 Gitea。
将 Gitea 源代码仓库的一个快照下载到 `/path/to/gitea/`。
在此之后,在本地仓库目录运行 `make frontend` 来生成静态资源。在这个情况下,我们只对 `public/` 目录感兴趣,您可以删除剩下的其他目录。
(为了生成静态资源,您需要安装一个[带 npm 的 Node ](https://nodejs.org/en/download/)和 `make`)
取决于您的用户量的大小,您可以将流量分离到两个不同的服务器,或者为静态资源配置一个 cdn。
### 单服务器节点,单域名
将 `[server] STATIC_URL_PREFIX = /_/static` 写入您的 Gitea 配置文件:
```apacheconf
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /_/static/ !
Alias /_/static/ /path/to/gitea/public/
<Directory /path/to/gitea/public/>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
AllowEncodedSlashes NoDecode
# 注意: 路径和 URL 后面都不要写路径符号 '/'
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
:::note
必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`。`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本,更旧的版本请去掉它。
:::
## 使用 Caddy 作为反向代理服务
@@ -231,11 +292,13 @@ git.example.com {
- 使用 Microsoft Web Platform Installer 5.1 (WebPI) 安装 Application Request Routing(简称 ARR),或者在 [IIS.net](https://www.iis.net/downloads/microsoft/application-request-routing) 下载这个插件。
- 一但这个模块被安装到 IIS 上,你将会在 IIS 管理控制台看到一个叫做 URL Rewrite 的新图标。
- 安装 Windows 功能 `WebSocket Protocol`,否则 ARR 无法代理 Gitea 的 WebSocket 端点。
- 打开 IIS 管理控制台,在左边的列表中点击 `Gitea Proxy` 网页。在中间选中并且双击 URL Rewrite 的图标来加载 URL 重写的面板。
- 在管理控制台的右边选择 `Add Rule` 操作,并且在 `Inbound and Outbound Rules` 分类中选择 `Reverse Proxy Rule`。
- 在 Inbound Rules 中, 将 server name 设置为 Gitea 正在运行的主机以及对应端口。例如,如果你在 localhost 的 3000 端口上运行 Gitea,则设置为 `127.0.0.1:3000`。
- 启用 SSL Offloading
- 在 Outbound Rules 中,确保设置了 `Rewrite the domain names of the links in HTTP response`,并且将 `From:` 设置为上面的 server name,将 `To:` 设置为你的外部访问名称,例如:`git.example.com`
- 关闭 Application Request Routing 的 `Server Proxy Settings` 中的 `Reverse rewrite host in response headers`(在 IIS 管理器中选择服务器节点,打开 `Application Request Routing Cache`,再打开右侧的 `Server Proxy Settings`)。若保持开启,ARR 会把 `Location` 头里的主机改回内部地址,导致登录或表单提交后的重定向把浏览器送到 `127.0.0.1:3000` 而不是 `git.example.com`。
- 现在,根据下面的内容为您的网页编辑 `web.config`(将 `127.0.0.1:3000` 和 `git.example.com` 改为适当的值)
```xml
@@ -53,7 +53,7 @@ sudo chown 1000:1000 config/ data/
> 如果未为卷设置正确的权限,容器可能无法启动。
对于稳定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的开发版本,则可以使用 `:dev-rootless` 标签。如果您想运行发布分支的最新提交,可以使用 `:1.x-dev-rootless` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.16-dev-rootless`)。
对于稳定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的开发版本,则可以使用 `:main-nightly-rootless` 标签。如果您想运行发布分支的最新提交,可以使用 `:1.x-nightly-rootless` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.27-nightly-rootless`)。
## 自定义端口
@@ -14,7 +14,7 @@ Gitea 在其 Docker Hub 组织内提供自动更新的 Docker 镜像。可以始
## 基本
最简单的设置只是创建一个卷和一个网络,然后将 `docker.gitea.com/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `@dockerVersion@`。
最简单的设置只是创建一个卷和一个网络,然后将 `docker.gitea.com/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 安装的是最新的稳定版本。对于稳定的发行版,您也可以使用 `:1` 或指定某个发行版,例如 `@dockerVersion@`。如果您想使用最新的开发版本,则可以使用 `:main-nightly` 标签;如果您想运行发布分支的最新提交,可以使用 `:1.x-nightly` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.27-nightly`)。
```yaml
version: "3"
@@ -969,7 +969,7 @@ Gitea 创建以下非唯一队列:
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -975,7 +975,7 @@ Gitea 创建以下非唯一队列:
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -990,7 +990,7 @@ Gitea 创建以下非唯一队列:
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -990,7 +990,7 @@ Gitea 创建以下非唯一队列:
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -1101,7 +1101,7 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 设置为 false 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于安排任务,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用于检查新版本的端点。
@@ -1109,7 +1109,7 @@ In-Reply-To =
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -1129,35 +1129,35 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@annually**: Cron 语法,用于设置重建索引的频率。
#### Cron - 停止长时间未更新的运行中任务 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 5m**: Cron 语法,用于设置检查的频率。
#### Cron - 停止持续更新但长时间未结束的运行中任务 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 30m**: Cron 语法,用于设置检查的频率。
#### Cron - 取消长时间未被领取的任务 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 6h**: Cron 语法,用于设置检查的频率。
#### Cron - 启动基于定时的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 1m**: Cron 语法,用于设置调度任务的频率。
## Git (`git`)
@@ -1106,7 +1106,7 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 设置为 false 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于安排任务,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用于检查新版本的端点。
@@ -1114,7 +1114,7 @@ In-Reply-To =
- `ENABLED`: **false**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 168h**: Cron 语法,用于设置多长时间进行检查。
- `OLDER_THAN`: **8760h**: 早于此表达式的任何系统通知都将从数据库中删除。
@@ -1134,35 +1134,35 @@ In-Reply-To =
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@annually**: Cron 语法,用于设置重建索引的频率。
#### Cron - 停止长时间未更新的运行中任务 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 5m**: Cron 语法,用于设置检查的频率。
#### Cron - 停止持续更新但长时间未结束的运行中任务 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **true**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 30m**: Cron 语法,用于设置检查的频率。
#### Cron - 取消长时间未被领取的任务 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 6h**: Cron 语法,用于设置检查的频率。
#### Cron - 启动基于定时的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 启用服务。
- `RUN_AT_START`: **false**: 在启动时运行任务(如果启用)。
- `NO_SUCCESS_NOTICE`: **false**: 设置为 true 以关闭成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 设置为 true 以打开成功通知。
- `SCHEDULE`: **@every 1m**: Cron 语法,用于设置调度任务的频率。
## Git (`git`)
@@ -14,6 +14,7 @@ aliases:
2. 将 `https://git.example.com/foo` 反向代理到 `http://gitea:3000/foo`
3. 确保反向代理不会解码 URI。`https://git.example.com/a%2Fb`的请求应该被传递给 `http://gitea:3000/a%2Fb`。
4. 确保 `Host` 和 `X-Forwarded-Proto` 头被正确的传递给 Gitea,使 Gitea 可以看到正在访问的真实 URL。
5. 确保 Web 服务器有完整的证书(包括所有中间证书和根证书),以便 `git clone` 和 `git pull` 正常工作。
## 使用子路径
@@ -61,7 +62,7 @@ server {
# 确保 nginx 使用未转义 URI, 按原样保持 "%2F"。 确保 nginx 去除 "/gitea" 子路径前缀, 按原样传递 "/v2"。
rewrite ^ $request_uri;
rewrite ^(/gitea)?(/.*) $2 break;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
# 其他的常规 HTTP 表头,见上面“使用 Nginx 作为反向代理服务”小节的配置
@@ -75,7 +76,7 @@ server {
}
```
然后您**必须**在 Gitea 的配置文件中正确的添加类似 `[server] ROOT_URL = http://git.example.com/git/` 的配置项。
然后您**必须**在 Gitea 的配置文件中正确的添加类似 `[server] ROOT_URL = http://git.example.com/gitea/` 的配置项。
## 使用 Nginx 直接提供静态资源
@@ -144,6 +145,20 @@ server {
}
```
## Nginx Proxy Manager
如果使用 Nginx Proxy Manager 作为 Gitea 的反向代理,配置与原生 Nginx 略有不同。
它会[默认给自定义 location 加上一些指令](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf),因此上面 Nginx 配置里对应的指令不要再写一遍。否则会因为指令重复(尤其是 `proxy_set_header Host $host`)出现 `400 bad request`。
创建 `/` 自定义 location 时,只需在其配置中加入:
```nginx
client_max_body_size 512M;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
```
## 使用 Apache HTTPD 作为反向代理服务
如果您想使用 Apache HTTPD 作为 Gitea 的反向代理服务,您可以为您的 Apache HTTPD 作如下配置(在 Ubuntu 中,配置文件通常在 `/etc/apache2/httpd.conf` 目录下):
@@ -161,23 +176,12 @@ server {
注:必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`
如果希望用 Let's Encrypt 的 webroot 验证,请在 `ProxyPass` 之前加入 `ProxyPass /.well-known !`,避免把这些请求代理到 Gitea。
## 使用 Apache HTTPD 作为反向代理服务并将 Gitea 路由至一个子路径
如果您已经有一个域名并且想与 Gitea 共享该域名,您可以增加以下配置为 Gitea 添加路由规则(在 Ubuntu 中,配置文件通常在 `/etc/apache2/httpd.conf` 目录下):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路径和 URL 后面都不要写路径符号 '/'
ProxyPass /git http://localhost:3000 nocanon
</VirtualHost>
```
```apacheconf
<VirtualHost *:80>
...
@@ -197,6 +201,48 @@ server {
注:必须启用以下 Apache HTTPD 组件:`proxy`, `proxy_http`
## 使用 Apache HTTPD 直接提供静态资源
我们可以通过将资源分为静态和动态两种类型来调节性能。
CSS 文件、JavaScript 文件、图片和字体是静态内容。首页、仓库视图和工单列表是动态内容。
Apache HTTPD 可以直接提供静态资源,并且只代理动态资源请求给 Gitea。
将 Gitea 源代码仓库的一个快照下载到 `/path/to/gitea/`。
在此之后,在本地仓库目录运行 `make frontend` 来生成静态资源。在这个情况下,我们只对 `public/` 目录感兴趣,您可以删除剩下的其他目录。
(为了生成静态资源,您需要安装一个[带 npm 的 Node ](https://nodejs.org/en/download/)和 `make`)
取决于您的用户量的大小,您可以将流量分离到两个不同的服务器,或者为静态资源配置一个 cdn。
### 单服务器节点,单域名
将 `[server] STATIC_URL_PREFIX = /_/static` 写入您的 Gitea 配置文件:
```apacheconf
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /_/static/ !
Alias /_/static/ /path/to/gitea/public/
<Directory /path/to/gitea/public/>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
AllowEncodedSlashes NoDecode
# 注意: 路径和 URL 后面都不要写路径符号 '/'
ProxyPass / http://localhost:3000/ nocanon
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
## 使用 Caddy 作为反向代理服务
如果您想使用 Caddy 作为 Gitea 的反向代理服务,您可以在 `Caddyfile` 中添加如下配置:
@@ -53,7 +53,7 @@ sudo chown 1000:1000 config/ data/
> 如果未为卷设置正确的权限,容器可能无法启动。
对于稳定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的开发版本,则可以使用 `:dev-rootless` 标签。如果您想运行发布分支的最新提交,可以使用 `:1.x-dev-rootless` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.16-dev-rootless`)。
对于稳定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的开发版本,则可以使用 `:main-nightly-rootless` 标签。如果您想运行发布分支的最新提交,可以使用 `:1.x-nightly-rootless` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.27-nightly-rootless`)。
## 自定义端口
@@ -14,7 +14,7 @@ Gitea 在其 Docker Hub 组织内提供自动更新的 Docker 镜像。可以始
## 基本
最简单的设置只是创建一个卷和一个网络,然后将 `docker.gitea.com/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `@dockerVersion@`。
最简单的设置只是创建一个卷和一个网络,然后将 `docker.gitea.com/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 安装的是最新的稳定版本。对于稳定的发行版,您也可以使用 `:1` 或指定某个发行版,例如 `@dockerVersion@`。如果您想使用最新的开发版本,则可以使用 `:main-nightly` 标签;如果您想运行发布分支的最新提交,可以使用 `:1.x-nightly` 标签,其中 x 是 Gitea 的次要版本号(例如:`1.27-nightly`)。
```yaml
version: "3"
@@ -1079,7 +1079,7 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 設定為 false 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於安排任務,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用於檢查新版本的端點。
@@ -1087,7 +1087,7 @@ In-Reply-To =
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -1108,35 +1108,35 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@annually**: Cron 語法,用於設定重建索引的頻率。
#### Cron - 停止長時間未更新的運行中任務 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 5m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 停止持續更新但長時間未結束的運行中任務 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 30m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 取消長時間未被領取的任務 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 6h**: Cron 語法,用於設定檢查的頻率。
#### Cron - 啟動基於定時的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 1m**: Cron 語法,用於設定調度任務的頻率。
## Git (`git`)
@@ -14,6 +14,8 @@ aliases:
2. 將 `https://git.example.com/foo` 反向代理到 `http://gitea:3000/foo`
3. 確保反向代理不會解碼 URI。`https://git.example.com/a%2Fb`的請求應該被傳遞給 `http://gitea:3000/a%2Fb`。
4. 確保 `Host` 和 `X-Forwarded-Proto` 頭被正確的傳遞給 Gitea,使 Gitea 可以看到正在訪問的真實 URL。
5. 確保 Web 伺服器有完整的憑證(包括所有中間憑證和根憑證),以便 `git clone` 和 `git pull` 正常工作。
6. Gitea 會在 `/-/ws` 使用 WebSocket 連線,用於通知計數等即時更新。請確保反向代理使用 HTTP/1.1,並轉發 `Upgrade` 和 `Connection` 頭,參見下面的示例。否則 Gitea 會改為定期輪詢。
## 使用子路徑
@@ -39,6 +41,7 @@ server {
location / {
client_max_body_size 512M;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
@@ -61,8 +64,9 @@ server {
# 確保 nginx 使用未轉義 URI, 按原樣保持 "%2F"。 確保 nginx 去除 "/gitea" 子路徑前綴, 按原樣傳遞 "/v2"。
rewrite ^ $request_uri;
rewrite ^(/gitea)?(/.*) $2 break;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
proxy_http_version 1.1;
# 其他的常規 HTTP 表頭,見上面“使用 Nginx 作為反向代理服務”小節的配置
proxy_set_header Connection $http_connection;
@@ -107,6 +111,7 @@ server {
}
location / {
# 其他指令見上面「使用 Nginx 作為反向代理服務」小節
proxy_pass http://localhost:3000;
}
}
@@ -123,6 +128,7 @@ server {
server_name git.example.com;
location / {
# 其他指令見上面「使用 Nginx 作為反向代理服務」小節
proxy_pass http://localhost:3000;
}
}
@@ -144,6 +150,20 @@ server {
}
```
## Nginx Proxy Manager
如果使用 Nginx Proxy Manager 作為 Gitea 的反向代理,設定與原生 Nginx 略有不同。
它會[預設給自訂 location 加上一些指令](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf),因此上面 Nginx 設定裡對應的指令不要再寫一遍。否則會因為指令重複(尤其是 `proxy_set_header Host $host`)出現 `400 bad request`。
建立 `/` 自訂 location 時,只需在其設定中加入:
```nginx
client_max_body_size 512M;
```
在代理主機上啟用 `Websockets Support`,Nginx Proxy Manager 會自行加入 WebSocket 相關指令。再額外添加 `proxy_http_version` 會導致 Nginx 拒絕啟動。
## 使用 Apache HTTPD 作為反向代理服務
如果您想使用 Apache HTTPD 作為 Gitea 的反向代理服務,您可以為您的 Apache HTTPD 作如下設定(在 Ubuntu 中,設定文件通常在 `/etc/apache2/httpd.conf` 目錄下):
@@ -154,30 +174,23 @@ server {
ProxyPreserveHost On
ProxyRequests off
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:3000/ nocanon
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
注:必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`
:::note
必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`。
`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本。更舊的版本**必須**去掉它,否則 Apache HTTPD 將無法啟動。
:::
如果希望用 Let's Encrypt 的 webroot 驗證,請在 `ProxyPass` 之前加入 `ProxyPass /.well-known !`,避免把這些請求代理到 Gitea。
## 使用 Apache HTTPD 作為反向代理服務並將 Gitea 路由至一個子路徑
如果您已經有一個域名並且想與 Gitea 共享該域名,您可以增加以下設定為 Gitea 添加路由規則(在 Ubuntu 中,設定文件通常在 `/etc/apache2/httpd.conf` 目錄下):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路徑和 URL 後面都不要寫路徑符號 '/'
ProxyPass /git http://localhost:3000 nocanon
</VirtualHost>
```
```apacheconf
<VirtualHost *:80>
...
@@ -187,7 +200,7 @@ server {
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路徑和 URL 後面都不要寫路徑符號 '/'
ProxyPass /git http://localhost:3000 nocanon
ProxyPass /git http://localhost:3000 nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
@@ -195,7 +208,55 @@ server {
然後您**必須**在 Gitea 的設定文件中正確的添加類似 `[server] ROOT_URL = http://git.example.com/git/` 的設定項。
注:必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`
:::note
必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`。`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本,更舊的版本請去掉它。
:::
## 使用 Apache HTTPD 直接提供靜態資源
我們可以通過將資源分為靜態和動態兩種類型來調節性能。
CSS 文件、JavaScript 文件、圖片和字體是靜態內容。首頁、倉庫視圖和工單列表是動態內容。
Apache HTTPD 可以直接提供靜態資源,並且只代理動態資源請求給 Gitea。
將 Gitea 源代碼倉庫的一個快照下載到 `/path/to/gitea/`。
在此之後,在本地倉庫目錄運行 `make frontend` 來生成靜態資源。在這個情況下,我們只對 `public/` 目錄感興趣,您可以刪除剩下的其他目錄。
(為了生成靜態資源,您需要安裝一個[帶 npm 的 Node ](https://nodejs.org/en/download/)和 `make`)
取決於您的用戶量的大小,您可以將流量分離到兩個不同的服務器,或者為靜態資源設定一個 cdn。
### 單伺服器節點,單域名
將 `[server] STATIC_URL_PREFIX = /_/static` 寫入您的 Gitea 設定文件:
```apacheconf
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /_/static/ !
Alias /_/static/ /path/to/gitea/public/
<Directory /path/to/gitea/public/>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
AllowEncodedSlashes NoDecode
# 注意: 路徑和 URL 後面都不要寫路徑符號 '/'
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
:::note
必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`。`upgrade=websocket` 需要 Apache HTTPD 2.4.48 或更高版本,更舊的版本請去掉它。
:::
## 使用 Caddy 作為反向代理服務
@@ -231,11 +292,13 @@ git.example.com {
- 使用 Microsoft Web Platform Installer 5.1 (WebPI) 安裝 Application Request Routing(簡稱 ARR),或者在 [IIS.net](https://www.iis.net/downloads/microsoft/application-request-routing) 下載這個外掛。
- 一但這個模組被安裝到 IIS 上,你將會在 IIS 管理控制檯看到一個叫做 URL Rewrite 的新圖標。
- 安裝 Windows 功能 `WebSocket Protocol`,否則 ARR 無法代理 Gitea 的 WebSocket 端點。
- 打開 IIS 管理控制檯,在左邊的列表中點擊 `Gitea Proxy` 網頁。在中間選中並且雙擊 URL Rewrite 的圖標來加載 URL 重寫的面板。
- 在管理控制檯的右邊選擇 `Add Rule` 操作,並且在 `Inbound and Outbound Rules` 分類中選擇 `Reverse Proxy Rule`。
- 在 Inbound Rules 中, 將 server name 設定為 Gitea 正在運行的主機以及對應端口。例如,如果你在 localhost 的 3000 端口上運行 Gitea,則設定為 `127.0.0.1:3000`。
- 啟用 SSL Offloading
- 在 Outbound Rules 中,確保設定了 `Rewrite the domain names of the links in HTTP response`,並且將 `From:` 設定為上面的 server name,將 `To:` 設定為你的外部訪問名稱,例如:`git.example.com`
- 關閉 Application Request Routing 的 `Server Proxy Settings` 中的 `Reverse rewrite host in response headers`(在 IIS 管理員中選擇伺服器節點,打開 `Application Request Routing Cache`,再開啟右側的 `Server Proxy Settings`)。若保持開啟,ARR 會把 `Location` 頭裡的主機改回內部位址,導致登入或表單提交後的重新導向把瀏覽器送到 `127.0.0.1:3000` 而不是 `git.example.com`。
- 現在,根據下面的內容為您的網頁編輯 `web.config`(將 `127.0.0.1:3000` 和 `git.example.com` 改為適當的值)
```xml
@@ -53,7 +53,7 @@ sudo chown 1000:1000 config/ data/
> 如果未為卷設定正確的權限,容器可能無法啟動。
對於穩定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的開發版本,則可以使用 `:dev-rootless` 標籤。如果您想運行發佈分支的最新提交,可以使用 `:1.x-dev-rootless` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.16-dev-rootless`)。
對於穩定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的開發版本,則可以使用 `:main-nightly-rootless` 標籤。如果您想運行發佈分支的最新提交,可以使用 `:1.x-nightly-rootless` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.27-nightly-rootless`)。
## 自訂端口
@@ -14,7 +14,7 @@ Gitea 在其 Docker Hub 組織內提供自動更新的 Docker 鏡像。可以始
## 基本
最簡單的設定只是建立一個卷和一個網路,然後將 `docker.gitea.com/gitea:latest` 鏡像作為服務啟動。由於沒有可用的資料庫,因此可以使用 SQLite3 初始化資料庫。建立一個類似 `gitea` 的目錄,並將以下內容粘貼到名為 `docker-compose.yml` 的文件中。請注意,該卷應由設定文件中指定的 UID/GID 的使用者/組擁有。如果您不授予卷正確的權限,則容器可能無法啟動。另請注意,標籤 `:latest` 將安裝當前的開發版本。對於穩定的發行版,您可以使用 `:1` 或指定某個發行版,例如 `@dockerVersion@`。
最簡單的設定只是建立一個卷和一個網路,然後將 `docker.gitea.com/gitea:latest` 鏡像作為服務啟動。由於沒有可用的資料庫,因此可以使用 SQLite3 初始化資料庫。建立一個類似 `gitea` 的目錄,並將以下內容粘貼到名為 `docker-compose.yml` 的文件中。請注意,該卷應由設定文件中指定的 UID/GID 的使用者/組擁有。如果您不授予卷正確的權限,則容器可能無法啟動。另請注意,標籤 `:latest` 安裝的是最新的穩定版本。對於穩定的發行版,您也可以使用 `:1` 或指定某個發行版,例如 `@dockerVersion@`。如果您想使用最新的開發版本,則可以使用 `:main-nightly` 標籤;如果您想運行發佈分支的最新提交,可以使用 `:1.x-nightly` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.27-nightly`)。
```yaml
version: "3"
@@ -974,7 +974,7 @@ Gitea 建立以下非唯一隊列:
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -990,7 +990,7 @@ Gitea 建立以下非唯一隊列:
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -991,7 +991,7 @@ Gitea 建立以下非唯一隊列:
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -1106,7 +1106,7 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 設定為 false 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於安排任務,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用於檢查新版本的端點。
@@ -1114,7 +1114,7 @@ In-Reply-To =
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -1135,35 +1135,35 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@annually**: Cron 語法,用於設定重建索引的頻率。
#### Cron - 停止長時間未更新的運行中任務 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 5m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 停止持續更新但長時間未結束的運行中任務 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 30m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 取消長時間未被領取的任務 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 6h**: Cron 語法,用於設定檢查的頻率。
#### Cron - 啟動基於定時的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 1m**: Cron 語法,用於設定調度任務的頻率。
## Git (`git`)
@@ -1111,7 +1111,7 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `ENABLE_SUCCESS_NOTICE`: **true**: 設定為 false 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於安排任務,例如 `@every 168h`。
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: Gitea 用於檢查新版本的端點。
@@ -1119,7 +1119,7 @@ In-Reply-To =
- `ENABLED`: **false**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 168h**: Cron 語法,用於設定多長時間進行檢查。
- `OLDER_THAN`: **8760h**: 早於此表達式的任何系統通知都將從資料庫中刪除。
@@ -1140,35 +1140,35 @@ In-Reply-To =
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@annually**: Cron 語法,用於設定重建索引的頻率。
#### Cron - 停止長時間未更新的運行中任務 (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 5m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 停止持續更新但長時間未結束的運行中任務 (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **true**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 30m**: Cron 語法,用於設定檢查的頻率。
#### Cron - 取消長時間未被領取的任務 (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 6h**: Cron 語法,用於設定檢查的頻率。
#### Cron - 啟動基於定時的 Actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: 啟用服務。
- `RUN_AT_START`: **false**: 在啟動時運行任務(如果啟用)。
- `NO_SUCCESS_NOTICE`: **false**: 設定為 true 以關閉成功通知。
- `NOTICE_ON_SUCCESS`: **false**: 設定為 true 以打開成功通知。
- `SCHEDULE`: **@every 1m**: Cron 語法,用於設定調度任務的頻率。
## Git (`git`)
@@ -14,6 +14,7 @@ aliases:
2. 將 `https://git.example.com/foo` 反向代理到 `http://gitea:3000/foo`
3. 確保反向代理不會解碼 URI。`https://git.example.com/a%2Fb`的請求應該被傳遞給 `http://gitea:3000/a%2Fb`。
4. 確保 `Host` 和 `X-Forwarded-Proto` 頭被正確的傳遞給 Gitea,使 Gitea 可以看到正在訪問的真實 URL。
5. 確保 Web 伺服器有完整的憑證(包括所有中間憑證和根憑證),以便 `git clone` 和 `git pull` 正常工作。
## 使用子路徑
@@ -61,7 +62,7 @@ server {
# 確保 nginx 使用未轉義 URI, 按原樣保持 "%2F"。 確保 nginx 去除 "/gitea" 子路徑前綴, 按原樣傳遞 "/v2"。
rewrite ^ $request_uri;
rewrite ^(/gitea)?(/.*) $2 break;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
# 其他的常規 HTTP 表頭,見上面“使用 Nginx 作為反向代理服務”小節的配置
@@ -75,7 +76,7 @@ server {
}
```
然後您**必須**在 Gitea 的設定文件中正確的添加類似 `[server] ROOT_URL = http://git.example.com/git/` 的設定項。
然後您**必須**在 Gitea 的設定文件中正確的添加類似 `[server] ROOT_URL = http://git.example.com/gitea/` 的設定項。
## 使用 Nginx 直接提供靜態資源
@@ -144,6 +145,20 @@ server {
}
```
## Nginx Proxy Manager
如果使用 Nginx Proxy Manager 作為 Gitea 的反向代理,設定與原生 Nginx 略有不同。
它會[預設給自訂 location 加上一些指令](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf),因此上面 Nginx 設定裡對應的指令不要再寫一遍。否則會因為指令重複(尤其是 `proxy_set_header Host $host`)出現 `400 bad request`。
建立 `/` 自訂 location 時,只需在其設定中加入:
```nginx
client_max_body_size 512M;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
```
## 使用 Apache HTTPD 作為反向代理服務
如果您想使用 Apache HTTPD 作為 Gitea 的反向代理服務,您可以為您的 Apache HTTPD 作如下設定(在 Ubuntu 中,設定文件通常在 `/etc/apache2/httpd.conf` 目錄下):
@@ -161,23 +176,12 @@ server {
注:必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`
如果希望用 Let's Encrypt 的 webroot 驗證,請在 `ProxyPass` 之前加入 `ProxyPass /.well-known !`,避免把這些請求代理到 Gitea。
## 使用 Apache HTTPD 作為反向代理服務並將 Gitea 路由至一個子路徑
如果您已經有一個域名並且想與 Gitea 共享該域名,您可以增加以下設定為 Gitea 添加路由規則(在 Ubuntu 中,設定文件通常在 `/etc/apache2/httpd.conf` 目錄下):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
# 注意: 路徑和 URL 後面都不要寫路徑符號 '/'
ProxyPass /git http://localhost:3000 nocanon
</VirtualHost>
```
```apacheconf
<VirtualHost *:80>
...
@@ -197,6 +201,48 @@ server {
注:必須啟用以下 Apache HTTPD 元件:`proxy`, `proxy_http`
## 使用 Apache HTTPD 直接提供靜態資源
我們可以通過將資源分為靜態和動態兩種類型來調節性能。
CSS 文件、JavaScript 文件、圖片和字體是靜態內容。首頁、倉庫視圖和工單列表是動態內容。
Apache HTTPD 可以直接提供靜態資源,並且只代理動態資源請求給 Gitea。
將 Gitea 源代碼倉庫的一個快照下載到 `/path/to/gitea/`。
在此之後,在本地倉庫目錄運行 `make frontend` 來生成靜態資源。在這個情況下,我們只對 `public/` 目錄感興趣,您可以刪除剩下的其他目錄。
(為了生成靜態資源,您需要安裝一個[帶 npm 的 Node ](https://nodejs.org/en/download/)和 `make`)
取決於您的用戶量的大小,您可以將流量分離到兩個不同的服務器,或者為靜態資源設定一個 cdn。
### 單伺服器節點,單域名
將 `[server] STATIC_URL_PREFIX = /_/static` 寫入您的 Gitea 設定文件:
```apacheconf
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /_/static/ !
Alias /_/static/ /path/to/gitea/public/
<Directory /path/to/gitea/public/>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
AllowEncodedSlashes NoDecode
# 注意: 路徑和 URL 後面都不要寫路徑符號 '/'
ProxyPass / http://localhost:3000/ nocanon
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
```
## 使用 Caddy 作為反向代理服務
如果您想使用 Caddy 作為 Gitea 的反向代理服務,您可以在 `Caddyfile` 中添加如下設定:
@@ -53,7 +53,7 @@ sudo chown 1000:1000 config/ data/
> 如果未為卷設定正確的權限,容器可能無法啟動。
對於穩定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的開發版本,則可以使用 `:dev-rootless` 標籤。如果您想運行發佈分支的最新提交,可以使用 `:1.x-dev-rootless` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.16-dev-rootless`)。
對於穩定版本,您可以使用 `:latest-rootless`、`:1-rootless`,或指定特定的版本,如: `@dockerVersion@-rootless`。如果您想使用最新的開發版本,則可以使用 `:main-nightly-rootless` 標籤。如果您想運行發佈分支的最新提交,可以使用 `:1.x-nightly-rootless` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.27-nightly-rootless`)。
## 自訂端口
@@ -14,7 +14,7 @@ Gitea 在其 Docker Hub 組織內提供自動更新的 Docker 鏡像。可以始
## 基本
最簡單的設定只是建立一個卷和一個網路,然後將 `docker.gitea.com/gitea:latest` 鏡像作為服務啟動。由於沒有可用的資料庫,因此可以使用 SQLite3 初始化資料庫。建立一個類似 `gitea` 的目錄,並將以下內容粘貼到名為 `docker-compose.yml` 的文件中。請注意,該卷應由設定文件中指定的 UID/GID 的使用者/組擁有。如果您不授予卷正確的權限,則容器可能無法啟動。另請注意,標籤 `:latest` 將安裝當前的開發版本。對於穩定的發行版,您可以使用 `:1` 或指定某個發行版,例如 `@dockerVersion@`。
最簡單的設定只是建立一個卷和一個網路,然後將 `docker.gitea.com/gitea:latest` 鏡像作為服務啟動。由於沒有可用的資料庫,因此可以使用 SQLite3 初始化資料庫。建立一個類似 `gitea` 的目錄,並將以下內容粘貼到名為 `docker-compose.yml` 的文件中。請注意,該卷應由設定文件中指定的 UID/GID 的使用者/組擁有。如果您不授予卷正確的權限,則容器可能無法啟動。另請注意,標籤 `:latest` 安裝的是最新的穩定版本。對於穩定的發行版,您也可以使用 `:1` 或指定某個發行版,例如 `@dockerVersion@`。如果您想使用最新的開發版本,則可以使用 `:main-nightly` 標籤;如果您想運行發佈分支的最新提交,可以使用 `:1.x-nightly` 標籤,其中 x 是 Gitea 的次要版本號(例如:`1.27-nightly`)。
```yaml
version: "3"
+1 -1
View File
@@ -13,5 +13,5 @@
"engines": {
"node": ">=22"
},
"packageManager": "pnpm@12.2.1"
"packageManager": "pnpm@12.4.2"
}
+1 -1
View File
@@ -11,7 +11,7 @@
},
"dependencies": {
"tinyglobby": "0.2.17",
"yaml": "2.9.0"
"yaml": "2.9.1"
},
"peerDependencies": {
"astro": "^7.0.2"
+1 -1
View File
@@ -82,7 +82,7 @@ const variables: Record<string, VersionVariables> = {
version: 'main-nightly',
sourceVersion: 'main',
sourceBranch: 'main',
dockerVersion: 'nightly',
dockerVersion: 'main-nightly',
displayVersion: '1.28-dev',
},
'1.27': {
+209 -1632
View File
File diff suppressed because it is too large. Load diff
+16 -13
View File
@@ -68,11 +68,12 @@ runner:
# scratch directories (left behind when a host cleanup delete stalls) older than
# this duration. Setting either workdir_cleanup_age or idle_cleanup_interval to 0
# (or any non-positive value) disables stale-directory cleanup entirely, along with
# the docker network cleanup below.
# the docker network and volume cleanup below.
#workdir_cleanup_age: 24h
# Cadence for the idle cleanup pass. Besides the directories above, on runners that use
# docker it removes the per-job networks of jobs this runner did not live to tear down,
# which would otherwise hold a subnet of the daemon address pool until the host is rebuilt.
# docker it removes the per-job networks and volumes of jobs this runner did not live to
# tear down, which would otherwise hold a subnet of the daemon address pool and the job's
# workspace contents until the host is rebuilt.
#idle_cleanup_interval: 10m
# The base interval for periodic log flush to the Gitea instance.
# Logs may be sent earlier if the buffer reaches log_report_batch_size
@@ -154,7 +155,8 @@ runner:
# job_completed: ''
cache:
# Enable the built-in cache server (used by actions/cache and similar actions).
# Enable caching (used by actions/cache and similar actions). Off means no built-in server is
# started and no job is registered with an external_server either.
#enabled: true
# Directory where cache blobs are stored on disk. Default: $HOME/.cache/actcache
# Ignored when external_server is set.
@@ -190,10 +192,11 @@ cache:
# A moved tag (e.g. a re-tagged "v6") or an updated branch stays at the cached commit
# until its cache entry expires or is manually removed.
#offline_mode: false
# Serve the actions cache service v2 API. The actions that use it refuse any host they do not
# take for GitHub, so reaching it means editing that check out of their own bundle, undone
# whenever it is downloaded again. That edit is made either way, this only governs the API
# advertised. A bundle that does not match is left alone.
# Serve the actions cache service v2 API. The actions that use it fall back to v1 on any host
# they do not take for GitHub, so reaching it means editing that check out of their own bundle,
# put back after the copy into the job. That edit is made either way, this only governs the API
# advertised. A bundle that does not match is left alone. With v2, artifact uploads go via the
# cache server unless container jobs cannot reach its Docker network.
#v2: true
# How the cache server discards entries, ignored when external_server is set since that
# server applies its own. Leave a setting out for its default; 0s or 0 turns the three
@@ -271,11 +274,11 @@ container:
#require_docker: false
# Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or runner
#docker_timeout: 0s
# Bind the workspace to the host filesystem instead of using Docker volumes.
# This is required for Docker-in-Docker (DinD) setups when jobs use docker compose
# with bind mounts (e.g., ".:/app"), as volume-based workspaces are not accessible
# from the DinD daemon's filesystem. When enabled, ensure the workspace parent
# directory is also mounted into the runner container and listed in valid_volumes.
# Mount the workspace from a host directory instead of a Docker volume, so jobs
# can bind-mount it by its own path into sibling containers (".:/app" in docker
# compose). Not needed when jobs get the Docker proxy or workflows use the
# GITEA_DOCKER_WORKSPACE variable.
# The workspace parent directory must be mounted into the runner container.
#bind_workdir: false
# How long a job waits for a service container that declares a healthcheck to become
# healthy. A negative value (e.g. -1s) starts the steps without waiting.
@@ -103,13 +103,15 @@ Flags:
--detect-event Use first event type from workflow as event that triggered the workflow
-C, --directory string working directory (default ".")
-n, --dryrun dryrun mode
--env stringArray env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv)
--env stringArray env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv; override env-file)
--env-file string environment file to read and use as env in the containers (default ".env")
-E, --event string run a event name
-e, --eventpath string path to a JSON event payload file exposed as the event that triggered the workflow
--gitea-instance string Gitea instance to use.
-h, --help help for exec
-i, --image string Docker image to use. Use "-self-hosted" to run directly on the host. (default "docker.gitea.com/runner-images:ubuntu-latest")
--input stringArray set an input the workflow declares under its workflow_dispatch or workflow_call trigger, others stay invisible to the inputs context (e.g. --input name=bar; can be specified multiple times with highest precedence)
--input-file string path to an .env-format file containing key=value pairs as baseline workflow inputs (override event inputs)
--insecure-secrets NOT RECOMMENDED! Doesn't hide secrets while printing logs.
-j, --job string run a specific job ID; when several workflow files define that job, also pass --workflows/-W to select the file
--json Output logs in json format
@@ -68,11 +68,12 @@ runner:
# scratch directories (left behind when a host cleanup delete stalls) older than
# this duration. Setting either workdir_cleanup_age or idle_cleanup_interval to 0
# (or any non-positive value) disables stale-directory cleanup entirely, along with
# the docker network cleanup below.
# the docker network and volume cleanup below.
#workdir_cleanup_age: 24h
# Cadence for the idle cleanup pass. Besides the directories above, on runners that use
# docker it removes the per-job networks of jobs this runner did not live to tear down,
# which would otherwise hold a subnet of the daemon address pool until the host is rebuilt.
# docker it removes the per-job networks and volumes of jobs this runner did not live to
# tear down, which would otherwise hold a subnet of the daemon address pool and the job's
# workspace contents until the host is rebuilt.
#idle_cleanup_interval: 10m
# The base interval for periodic log flush to the Gitea instance.
# Logs may be sent earlier if the buffer reaches log_report_batch_size
@@ -154,7 +155,8 @@ runner:
# job_completed: ''
cache:
# Enable the built-in cache server (used by actions/cache and similar actions).
# Enable caching (used by actions/cache and similar actions). Off means no built-in server is
# started and no job is registered with an external_server either.
#enabled: true
# Directory where cache blobs are stored on disk. Default: $HOME/.cache/actcache
# Ignored when external_server is set.
@@ -190,10 +192,11 @@ cache:
# A moved tag (e.g. a re-tagged "v6") or an updated branch stays at the cached commit
# until its cache entry expires or is manually removed.
#offline_mode: false
# Serve the actions cache service v2 API. The actions that use it refuse any host they do not
# take for GitHub, so reaching it means editing that check out of their own bundle, undone
# whenever it is downloaded again. That edit is made either way, this only governs the API
# advertised. A bundle that does not match is left alone.
# Serve the actions cache service v2 API. The actions that use it fall back to v1 on any host
# they do not take for GitHub, so reaching it means editing that check out of their own bundle,
# put back after the copy into the job. That edit is made either way, this only governs the API
# advertised. A bundle that does not match is left alone. With v2, artifact uploads go via the
# cache server unless container jobs cannot reach its Docker network.
#v2: true
# How the cache server discards entries, ignored when external_server is set since that
# server applies its own. Leave a setting out for its default; 0s or 0 turns the three
@@ -271,11 +274,11 @@ container:
#require_docker: false
# Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or runner
#docker_timeout: 0s
# Bind the workspace to the host filesystem instead of using Docker volumes.
# This is required for Docker-in-Docker (DinD) setups when jobs use docker compose
# with bind mounts (e.g., ".:/app"), as volume-based workspaces are not accessible
# from the DinD daemon's filesystem. When enabled, ensure the workspace parent
# directory is also mounted into the runner container and listed in valid_volumes.
# Mount the workspace from a host directory instead of a Docker volume, so jobs
# can bind-mount it by its own path into sibling containers (".:/app" in docker
# compose). Not needed when jobs get the Docker proxy or workflows use the
# GITEA_DOCKER_WORKSPACE variable.
# The workspace parent directory must be mounted into the runner container.
#bind_workdir: false
# How long a job waits for a service container that declares a healthcheck to become
# healthy. A negative value (e.g. -1s) starts the steps without waiting.
-142
View File
@@ -1,142 +0,0 @@
#!/bin/bash
#
# Fails when a pull request depends on a gitea change that is not merged yet.
#
# Usage: ./scripts/check-upstream-deps.sh <pull request json>
#
# The json is what the gitea api returns for a pull request; the script reads
# the description and the labels from it. A dependency is declared on a line of
# its own in the description:
#
# Depends on: gitea#35851
# Depends on: https://github.com/go-gitea/gitea/pull/35851
#
# and may be declared several times. Only such lines count, so a pull request
# that merely mentions gitea#35851 in prose is not held back.
#
# The `depends-on-upstream` label is what blocks the merge: it fails the check
# unless every declared dependency is verified as merged. Without the label, a
# dependency that is known to be unmerged still fails, so a forgotten label does
# not let an unreleased feature through.
#
# Exit codes: 0 nothing blocks, 1 blocked, 2 usage.
#
# Environment:
# GITHUB_COM_TOKEN optional, lifts the rate limit of the github api
# UPSTREAM_LABEL label to look for, `depends-on-upstream` by default
# REQUIRE_VERIFIED set to 1 to also fail when the state cannot be determined
set -euo pipefail
LABEL="${UPSTREAM_LABEL:-depends-on-upstream}"
PULL_JSON="${1:-}"
if [ -z "$PULL_JSON" ] || [ ! -f "$PULL_JSON" ]; then
echo "usage: $0 <pull request json>" >&2
exit 2
fi
body="$(jq -r '.body // ""' "$PULL_JSON")"
# `label` is a keyword in jq 1.6, which is what the runner image has, so the
# argument cannot be named after it; `(.labels // [])` keeps it parsable there
labelled="$(jq -r --arg want "$LABEL" '[(.labels // [])[].name] | index($want) != null' "$PULL_JSON")"
require_verified="${REQUIRE_VERIFIED:-0}"
if [ "$labelled" = 'true' ]; then
# the label says the pull request is not ready, so an unverifiable dependency
# keeps it blocked instead of letting it through
require_verified=1
fi
# the ids of the `Depends on:` lines, deduplicated
refs="$(printf '%s\n' "$body" \
| grep -iE '^[[:space:]]*depends[ _-]?on[[:space:]]*:' \
| grep -oiE 'gitea#[0-9]+|github\.com/go-gitea/gitea/pull/[0-9]+' \
| grep -oE '[0-9]+' \
| sort -un || true)"
if [ -z "$refs" ]; then
if [ "$labelled" = 'true' ]; then
echo "This pull request carries the \"$LABEL\" label but does not say what it"
echo "depends on. Add a line to the description, for example:"
echo
echo " Depends on: gitea#35851"
exit 1
fi
echo "no upstream dependency declared"
exit 0
fi
github_api() {
local url="$1"
if [ -n "${GITHUB_COM_TOKEN:-}" ]; then
curl --silent --show-error --write-out '\n%{http_code}' \
-H "Authorization: Bearer $GITHUB_COM_TOKEN" "$url"
else
curl --silent --show-error --write-out '\n%{http_code}' "$url"
fi
}
unmerged=0
unknown=0
for ref in $refs; do
response="$(github_api "https://api.github.com/repos/go-gitea/gitea/pulls/$ref")"
code="$(printf '%s' "$response" | tail -n 1)"
payload="$(printf '%s' "$response" | sed '$d')"
case "$code" in
200)
if [ "$(printf '%s' "$payload" | jq -r '.merged')" = 'true' ]; then
echo "gitea#$ref is merged"
else
echo "gitea#$ref is not merged yet ($(printf '%s' "$payload" | jq -r '.state'))"
unmerged=1
fi
;;
404)
echo "gitea#$ref is not a pull request of go-gitea/gitea, reference the pull request that adds the feature"
unmerged=1
;;
403 | 429)
echo "gitea#$ref: the github api rejected the request (rate limit), cannot tell whether it is merged"
unknown=1
;;
*)
echo "gitea#$ref: unexpected response $code from the github api, cannot tell whether it is merged"
unknown=1
;;
esac
done
if [ "$unknown" -eq 1 ] && [ -z "${GITHUB_COM_TOKEN:-}" ]; then
echo
echo "The github api allows 60 unauthenticated requests per hour and address,"
echo "which the runners share. Set the GITHUB_COM_TOKEN secret to a token with"
echo "no scopes to raise that limit."
fi
if [ "$unmerged" -eq 1 ] || { [ "$unknown" -eq 1 ] && [ "$require_verified" = '1' ]; }; then
echo
if [ "$labelled" = 'true' ]; then
echo "This pull request is labelled \"$LABEL\", so it stays blocked until every"
echo "dependency above is merged into gitea main. The scheduled job removes the"
echo "label and reruns this check as soon as that is the case."
else
echo "The documentation of an unreleased feature can only be merged once the"
echo "feature itself is in gitea main. Add the \"$LABEL\" label so the pull"
echo "request is picked up by the job that watches for it."
fi
exit 1
fi
if [ "$unknown" -eq 1 ]; then
echo
echo "Could not verify every dependency, letting the check pass: the pull request"
echo "does not carry the \"$LABEL\" label."
exit 0
fi
if [ "$labelled" = 'true' ]; then
echo
echo "every declared dependency is merged, the \"$LABEL\" label can be removed"
fi
-80
View File
@@ -1,80 +0,0 @@
#!/bin/bash
#
# Removes the `depends-on-upstream` label from every open pull request whose
# referenced gitea pull requests are all merged, and says so in a comment.
# Removing the label reruns the `depends-upstream` check of that pull request.
#
# Usage: ./scripts/unlabel-upstream-deps.sh
#
# Environment:
# GITEA_API api of the repository, e.g. https://gitea.com/api/v1/repos/gitea/docs
# DEPLOY_TOKEN token used to remove the label and to comment
# GITHUB_COM_TOKEN optional, lifts the rate limit of the github api
# UPSTREAM_LABEL label to look for, `depends-on-upstream` by default
# DRY_RUN set to 1 to only report what would happen
set -euo pipefail
LABEL="${UPSTREAM_LABEL:-depends-on-upstream}"
API="${GITEA_API:?GITEA_API is required}"
DRY_RUN="${DRY_RUN:-0}"
gitea_api() {
local method="$1" url="$2" data="${3:-}"
local args=(--silent --show-error --fail -X "$method")
if [ -n "${DEPLOY_TOKEN:-}" ]; then args+=(-H "Authorization: token $DEPLOY_TOKEN"); fi
if [ -n "$data" ]; then args+=(-H 'Content-Type: application/json' --data "$data"); fi
curl "${args[@]}" "$url"
}
# see the note in check-upstream-deps.sh about the argument name
label_id="$(gitea_api GET "$API/labels?limit=100" | jq -r --arg want "$LABEL" \
'.[] | select(.name == $want) | .id')"
if [ -z "$label_id" ]; then
echo "the repository has no \"$LABEL\" label, nothing to do"
exit 0
fi
pulls="$(gitea_api GET "$API/pulls?state=open&limit=50")"
indexes="$(printf '%s' "$pulls" | jq -r --arg want "$LABEL" \
'.[] | select([(.labels // [])[].name] | index($want) != null) | .number')"
if [ -z "$indexes" ]; then
echo "no open pull request carries the \"$LABEL\" label"
exit 0
fi
here="$(cd "$(dirname "$0")" && pwd)"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
for index in $indexes; do
gitea_api GET "$API/pulls/$index" > "$work/pull.json"
# the check script exits 0 when every reference is merged; it needs the label
# to be absent from its input to stay quiet about it, so drop it here
jq 'del(.labels)' "$work/pull.json" > "$work/pull-unlabelled.json"
# REQUIRE_VERIFIED keeps a dependency whose state could not be determined from
# counting as merged, which would drop the label too early
if ! output="$(REQUIRE_VERIFIED=1 "$here/check-upstream-deps.sh" "$work/pull-unlabelled.json" 2>&1)"; then
echo "#$index still waits for upstream:"
printf '%s\n' "$output" | sed 's/^/ /'
continue
fi
if printf '%s' "$output" | grep -q 'no upstream dependency declared'; then
echo "#$index carries the label but declares no dependency, leaving it alone"
continue
fi
if [ "$DRY_RUN" = '1' ]; then
echo "#$index would lose the label:"
printf '%s\n' "$output" | sed 's/^/ /'
continue
fi
gitea_api DELETE "$API/issues/$index/labels/$label_id" > /dev/null
comment="$(printf 'Every referenced gitea pull request is merged, so the `%s` label was removed and the check was rerun.\n\n%s' "$LABEL" "$output")"
gitea_api POST "$API/issues/$index/comments" "$(jq -n --arg body "$comment" '{body: $body}')" > /dev/null
echo "#$index unlabelled"
done
+1 -1
View File
@@ -61,7 +61,7 @@ export default defineConfig({
if (
!useDocSearch &&
source === '@pagefind/default-ui' &&
importer?.includes('starlight/components/Search.astro')
importer?.includes('starlight/dist/components/Search.astro')
) {
pagefindUiRedirected = true;
return path.join(repoRoot, 'sites/docs/src/lib/pagefind-ui.ts');
+4 -4
View File
@@ -11,13 +11,13 @@
"check": "astro check"
},
"dependencies": {
"@astrojs/starlight": "0.41.11",
"@astrojs/starlight-docsearch": "0.7.0",
"@astrojs/starlight": "0.42.1",
"@astrojs/starlight-docsearch": "0.8.0",
"@gitea-docs/content-loader": "workspace:*",
"@pagefind/default-ui": "1.5.2",
"astro": "7.2.10",
"astro": "7.3.2",
"sharp": "0.35.4",
"starlight-openapi": "0.26.1"
"starlight-openapi": "0.26.2"
},
"devDependencies": {
"@astrojs/check": "0.9.10",
+33
View File
@@ -27,6 +27,11 @@ interface Operation {
operationId?: string;
}
interface Schema {
title?: string;
description?: string;
}
interface SwaggerDocument {
openapi?: string;
basePath?: string;
@@ -34,6 +39,7 @@ interface SwaggerDocument {
schemes?: string[];
tags?: { name: string; description?: string }[];
paths?: Record<string, Record<string, Operation | unknown>>;
components?: { schemas?: Record<string, Schema> };
}
const httpMethods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'];
@@ -95,6 +101,7 @@ function normalizeSchema(source: string, name: string): string {
hyphenateOperationIds(document);
describeTags(document);
nameSchemas(document);
mkdirSync(cacheDir, { recursive: true });
const target = path.join(cacheDir, name);
@@ -123,6 +130,32 @@ function describeTags(document: SwaggerDocument): void {
document.tags = [...described.values()];
}
/**
* Titles the named schemas of an openapi 3.0 document with their own name.
*
* starlight-openapi dereferences every `$ref`, so a field of type
* `ReviewStateType` is rendered as the bare string enum it points at and the
* name of the type is nowhere on the page: searching the reference for a type
* name found in an sdk or in an error message turns up nothing (gitea/docs#258).
* The plugin renders `title` next to the type of a field, so setting it brings
* the name back, next to the allowed values.
*
* Swagger 2.0 documents are left alone, they are rendered with the name of the
* definition already.
*/
function nameSchemas(document: SwaggerDocument): void {
for (const [name, schema] of Object.entries(document.components?.schemas ?? {})) {
if (!schema || typeof schema !== 'object') continue;
if (!schema.title) schema.title = name;
// the go doc comments start with the name of the type, which would read
// "ChangeFilesOptions — ChangeFilesOptions options for ..." once the title
// is rendered in front of the description
if (schema.description?.startsWith(`${name} `)) {
schema.description = schema.description.slice(name.length + 1);
}
}
}
/**
* One starlight-openapi schema per documented api version, each mounted at the
* route of its version: `/api/` for the latest release, `/api/1.26/` and
+1 -1
View File
@@ -51,7 +51,7 @@
/* Centre the mobile menu button on the navigation row instead of on the whole
header bar, which the announcement strip made taller. */
starlight-menu-button button {
.sl-menu-button {
top: calc(
var(--gitea-announcement-height) + (var(--gitea-nav-row-height) - var(--sl-menu-button-size)) / 2
);
+39
View File
@@ -6311,6 +6311,14 @@
"type": "integer",
"x-go-name": "SourceID"
},
"type": {
"allOf": [
{
"$ref": "#/components/schemas/UserTypeString"
}
],
"description": "The user type"
},
"visibility": {
"allOf": [
{
@@ -10722,6 +10730,14 @@
"type": "integer",
"x-go-name": "StarredRepos"
},
"type": {
"allOf": [
{
"$ref": "#/components/schemas/UserTypeString"
}
],
"description": "the user type"
},
"visibility": {
"allOf": [
{
@@ -10878,6 +10894,14 @@
"type": "object",
"x-go-package": "gitea.dev/modules/structs"
},
"UserTypeString": {
"enum": [
"User",
"Organization",
"Bot"
],
"type": "string"
},
"VisibilityString": {
"enum": [
"public",
@@ -12058,6 +12082,9 @@
"403": {
"$ref": "#/components/responses/forbidden"
},
"409": {
"$ref": "#/components/responses/error"
},
"422": {
"$ref": "#/components/responses/validationError"
}
@@ -12142,6 +12169,9 @@
"403": {
"$ref": "#/components/responses/forbidden"
},
"409": {
"$ref": "#/components/responses/error"
},
"422": {
"$ref": "#/components/responses/validationError"
}
@@ -27149,6 +27179,9 @@
},
"404": {
"$ref": "#/components/responses/notFound"
},
"409": {
"$ref": "#/components/responses/error"
}
},
"summary": "Merge a branch from upstream",
@@ -34999,6 +35032,12 @@
"201": {
"$ref": "#/components/responses/EmailList"
},
"400": {
"$ref": "#/components/responses/error"
},
"409": {
"$ref": "#/components/responses/error"
},
"422": {
"$ref": "#/components/responses/validationError"
}
+37
View File
@@ -945,6 +945,9 @@
"403": {
"$ref": "#/responses/forbidden"
},
"409": {
"$ref": "#/responses/error"
},
"422": {
"$ref": "#/responses/validationError"
}
@@ -1029,6 +1032,9 @@
"403": {
"$ref": "#/responses/forbidden"
},
"409": {
"$ref": "#/responses/error"
},
"422": {
"$ref": "#/responses/validationError"
}
@@ -14991,6 +14997,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"409": {
"$ref": "#/responses/error"
}
}
}
@@ -22273,6 +22282,12 @@
"201": {
"$ref": "#/responses/EmailList"
},
"400": {
"$ref": "#/responses/error"
},
"409": {
"$ref": "#/responses/error"
},
"422": {
"$ref": "#/responses/validationError"
}
@@ -29377,6 +29392,17 @@
"format": "int64",
"x-go-name": "SourceID"
},
"type": {
"description": "The user type",
"type": "string",
"enum": [
"User",
"Organization",
"Bot"
],
"x-go-enum-desc": "User UserTypeStringUser\nOrganization UserTypeStringOrganization\nBot UserTypeStringBot",
"x-go-name": "Type"
},
"visibility": {
"description": "User visibility level: public, limited, or private",
"type": "string",
@@ -33739,6 +33765,17 @@
"format": "int64",
"x-go-name": "StarredRepos"
},
"type": {
"description": "the user type",
"type": "string",
"enum": [
"User",
"Organization",
"Bot"
],
"x-go-enum-desc": "User UserTypeStringUser\nOrganization UserTypeStringOrganization\nBot UserTypeStringBot",
"x-go-name": "Type"
},
"visibility": {
"description": "User visibility level option: public, limited, private",
"type": "string",
@@ -942,7 +942,7 @@ Default templates for project boards:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -951,7 +951,7 @@ Default templates for project boards:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -960,12 +960,13 @@ Default templates for project boards:
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -985,7 +986,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -994,7 +995,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1002,6 +1003,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1070,7 +1072,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1078,7 +1080,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1086,6 +1088,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -992,7 +992,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1001,7 +1001,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1010,12 +1010,13 @@ Default templates for project board view:
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1035,7 +1036,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1044,7 +1045,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1113,7 +1114,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1121,7 +1122,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1129,6 +1130,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1024,7 +1024,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1033,7 +1033,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1042,12 +1042,13 @@ Default templates for project board view:
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1067,7 +1068,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1076,7 +1077,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1084,6 +1085,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1159,7 +1161,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1167,7 +1169,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1175,6 +1177,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1026,7 +1026,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1035,7 +1035,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1044,12 +1044,13 @@ Default templates for project board view:
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1069,7 +1070,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1078,7 +1079,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1086,6 +1087,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1161,7 +1163,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1169,7 +1171,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1177,6 +1179,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1056,7 +1056,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1065,7 +1065,7 @@ Default templates for project board view:
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1074,12 +1074,13 @@ Default templates for project board view:
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1099,7 +1100,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1108,7 +1109,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1116,6 +1117,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1205,7 +1207,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1213,7 +1215,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1221,6 +1223,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1233,35 +1236,35 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@annually**: Cron syntax to set how often to rebuild
#### Cron - Stop running tasks which haven't been updated for a long time (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 5m**: Cron syntax to set how often tasks to run the check
#### Cron - Stop running tasks which have running status and continuous updates but don't end for a long time (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 30m**: Cron syntax to set how often to run the check.
#### Cron - Cancel jobs which haven't been picked up for a long time (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 6h**: Cron syntax to set how often to run the check.
#### Cron - Start cron based actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 1m**: Cron syntax to set how often to schedule tasks
## Git (`git`)
@@ -1069,7 +1069,7 @@ Release attachment has its own config options in `[repository.release]` section.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
@@ -1078,7 +1078,7 @@ Release attachment has its own config options in `[repository.release]` section.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `RUN_AT_START`: **false**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **_empty_**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
@@ -1087,12 +1087,13 @@ Release attachment has its own config options in `[repository.release]` section.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
- `ENABLED`: **true**: Enable running Update mirrors task periodically.
- `RUN_AT_START`: **true**: Run Update mirrors task when Gitea starts.
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
#### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
@@ -1112,7 +1113,7 @@ Update migrated repositories' issues and comments' posterid, it will always atte
- `ENABLED`: **true**: Enable update migration poster id job.
- `RUN_AT_START`: **true**: Update migrated repositories' issues and comments' posterid when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
@@ -1121,7 +1122,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable synchronize external user data job
- `RUN_AT_START`: **false**: Synchronize external user data when starting server
- `NOTICE_ON_SUCCESS`: **false**: Notice if not success
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
@@ -1129,6 +1130,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable cleanup expired actions assets job.
- `RUN_AT_START`: **true**: Run job at start time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@midnight** : Cron syntax for the job.
#### Cron - Cleanup Deleted Branches (`cron.deleted_branches_cleanup`)
@@ -1218,7 +1220,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
- `HTTP_ENDPOINT`: **https://dl.gitea.com/gitea/version.json**: the endpoint that Gitea will check for newer versions
@@ -1226,7 +1228,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **8760h**: any system notice older than this expression will be deleted from database.
@@ -1234,6 +1236,7 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **false**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 24h**: Cron syntax to set how often to check.
- `OLDER_THAN`: **168h**: Only attempt to garbage collect LFSMetaObjects older than this (default 7 days)
- `LAST_UPDATED_MORE_THAN_AGO`: **72h**: Only attempt to garbage collect LFSMetaObjects that have not been attempted to be garbage collected for this long (default 3 days)
@@ -1246,35 +1249,35 @@ Synchronize external user data (only LDAP user synchronization is supported)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@annually**: Cron syntax to set how often to rebuild
#### Cron - Stop running tasks which haven't been updated for a long time (`cron.stop_zombie_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 5m**: Cron syntax to set how often tasks to run the check
#### Cron - Stop running tasks which have running status and continuous updates but don't end for a long time (`cron.stop_endless_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 30m**: Cron syntax to set how often to run the check.
#### Cron - Cancel jobs which haven't been picked up for a long time (`cron.cancel_abandoned_jobs`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 6h**: Cron syntax to set how often to run the check.
#### Cron - Start cron based actions (`cron.start_schedule_tasks`)
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
- `NOTICE_ON_SUCCESS`: **false**: Set to true to switch on success notices.
- `SCHEDULE`: **@every 1m**: Cron syntax to set how often to schedule tasks
## Git (`git`)
@@ -66,7 +66,7 @@ server-1 | 2026-03-11T12:57:50.796198843Z /var/lib/gitea/git is not writable
server-1 | 2026-03-11T12:57:50.796235667Z docker setup failed
```
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly-rootless`)
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:main-nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly-rootless`)
## Named volumes
@@ -30,7 +30,7 @@ image as a service. Since there is no database available, one can be initialized
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
If you don't give the volume correct permissions, the container may not start.
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly`)
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:main-nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly`)
```yaml
networks:
@@ -51,6 +51,11 @@ Example:
> This bug was introduced in [e59ff077](#)
Commits in other repositories can be referred to as well
using the form `owner/repository@e59ff077`:
> This bug was introduced in [mike/compiler@e59ff077](#)
## Issues and Pull Requests
A reference to another issue or pull request can be created using the simple
@@ -177,7 +182,7 @@ In the examples, `User1/Repo1` refers to the repository where the reference is u
| `UserZ/RepoZ!1234` | - | no | A link to issue/pull 1234 in `UserZ/RepoZ` |
| `UserZ/RepoZ#1234` | - | yes | A link to _external issue_ 1234 for `UserZ/RepoZ` |
| `UserZ/RepoZ!1234` | - | yes | A link to _PR_ 1234 for `UserZ/RepoZ` |
| **Alphanumeric issue IDs:** | - | - | - |
| **Alphanumeric issue IDs:** | - | - | - |
| `AAA-1234` | yes | - | A link to _external issue_ `AAA-1234` for `User1/Repo1` |
| `!1234` | yes | - | A link to _PR_ 1234 for `User1/Repo1` |
| `User1/Repo1!1234` | yes | - | A link to _PR_ 1234 for `User1/Repo1` |