18 Commits
Author SHA1 Message Date
878c885050 docs(packages): document terraform module registry (#433)
Ref: https://github.com/go-gitea/gitea/pull/38040

Adds docs/usage/packages/terraform-module.md describing the v1 scope,
naming rules, authentication, service discovery, HTTP API surface and
[packages] settings for the new private Terraform Module Registry.

---------

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/433
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Michael Lopez <[email protected]>
2026-11-07 11:43:22 +00:00
silverwind 6135d1dabf Trim the Actions comparison to actual differences (#638)
`$/` is [GitHub's self-repository prefix](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#example-using-an-action-in-the-same-repository-as-the-workflow-at-the-running-commit-recommended) with the same semantics, so it is no Gitea addition. The `builtin:checkout` input list was outdated since https://gitea.com/gitea/runner/pulls/1277 made it match `actions/checkout`.

Reviewed-on: https://gitea.com/gitea/docs/pulls/638
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-11-07 09:42:48 +00:00
wxiaoguangandLunny Xiao 0ddb9a2071 codeowners (#634)
https://github.com/go-gitea/gitea/pull/40243
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/634
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: wxiaoguang <[email protected]>
2026-11-06 20:00:46 +00:00
silverwind 71869c6e24 Document MSSQL database preparation (#636)
The database preparation page covered only MySQL and PostgreSQL. MSSQL setups without schema permissions break on upgrades, like in https://github.com/go-gitea/gitea/issues/40256.

The new section shows the login, database and user setup with the roles Gitea needs, for main and 28, including zh-cn and zh-tw.

_Written by Claude (Opus 5.5)._

Reviewed-on: https://gitea.com/gitea/docs/pulls/636
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-11-06 17:12:50 +00:00
silverwind 46b5401a81 Document the new DEFAULT_DELETE_BRANCH_AFTER_MERGE default (#608)
Documents https://github.com/go-gitea/gitea/pull/39975 for main, which changes the default of `DEFAULT_DELETE_BRANCH_AFTER_MERGE` to `true`.

Reviewed-on: https://gitea.com/gitea/docs/pulls/608
Reviewed-by: Lunny Xiao <[email protected]>
2026-11-05 23:34:03 +00:00
Gitea BotandLunny Xiao f6e17361fe Update the runner reference pages (#628)
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-628.docs-gitea-com.pages.dev

---------

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/628
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Gitea Bot <[email protected]>
2026-11-02 05:07:00 +00:00
Gitea Bot c3cff4ab08 Update the latest api documents (#627)
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-627.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/627
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Gitea Bot <[email protected]>
2026-11-02 03:39:31 +00:00
Renovate Bot aa975da532 chore(deps): update dependencies (#626)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | Pending |
|---|---|---|---|---|---|---|
| [@astrojs/check](https://github.com/withastro/astro/tree/main/packages/language-tools/astro-check) ([source](https://github.com/withastro/astro/tree/HEAD/packages/language-tools/astro-check)) | [`0.9.11` → `0.9.12`](https://renovatebot.com/diffs/npm/@astrojs%2fcheck/0.9.11/0.9.12) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fcheck/0.9.12?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fcheck/0.9.11/0.9.12?slim=true) | devDependencies | patch |  |
| [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.42.6` → `0.42.7`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.42.6/0.42.7) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight/0.42.7?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight/0.42.6/0.42.7?slim=true) | dependencies | patch | `0.42.8` |
| [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`7.4.1` → `7.4.2`](https://renovatebot.com/diffs/npm/astro/7.4.1/7.4.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/astro/7.4.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/astro/7.4.1/7.4.2?slim=true) | dependencies | patch | `7.4.4` (+1) |
| [node](https://github.com/actions/node-versions) | `24` → `26` | ![age](https://developer.mend.io/api/mc/badges/age/github-releases/actions%2fnode-versions/26.12.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-releases/actions%2fnode-versions/24.22.2/26.12.1?slim=true) | uses-with | major | `26.13.0` |
| [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.15.0` → `12.16.1`](https://renovatebot.com/diffs/npm/pnpm/12.15.0/12.16.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/12.16.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/12.15.0/12.16.1?slim=true) | packageManager | minor |  |

---

### Release Notes

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

### [`v0.9.12`](https://github.com/withastro/astro/blob/HEAD/packages/language-tools/astro-check/CHANGELOG.md#0912)

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

##### Patch Changes

- [#&#8203;18455](https://github.com/withastro/astro/pull/18455) [`7af66fc`](https://github.com/withastro/astro/commit/7af66fc785d85b1df1f98e7123a52b2306250985) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes the `astro-check` binary ignoring its first two command-line arguments, so flags such as `--help`, `--root`, `--watch`, and `--tsconfig` are respected again. If your scripts padded the arguments to work around this (for example, `astro-check -- -- --tsconfig ./tsconfig.app.json`), remove the padding.
- Updated dependencies \[[`044148d`](https://github.com/withastro/astro/commit/044148d5cfbc90e0277b3205a52ec73bc452bb7e)]:
  - [@&#8203;astrojs/language-server](https://github.com/astrojs/language-server)@2.17.3

</details>

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

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

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

##### Patch Changes

- [#&#8203;4264](https://github.com/withastro/starlight/pull/4264) [`94e0985`](https://github.com/withastro/starlight/commit/94e0985ddbbbd5c0f50a4cea94dc2c92de0a607c) Thanks [@&#8203;chrispezza](https://github.com/chrispezza)! - Fixes a layout shift where the table of contents could be painted at the start of the content area and then jump to the end when a page's HTML arrived in several chunks

- [#&#8203;4285](https://github.com/withastro/starlight/pull/4285) [`6f22edd`](https://github.com/withastro/starlight/commit/6f22eddf21c90aed7bd4e3c82e48615a56268a69) Thanks [@&#8203;tunetheweb](https://github.com/tunetheweb)! - Improves hero image loading by adding `fetchpriority="high"` hint for browsers

</details>

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

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

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

##### Patch Changes

- [#&#8203;18430](https://github.com/withastro/astro/pull/18430) [`dda9ec3`](https://github.com/withastro/astro/commit/dda9ec395c89a1420abb3b8f88b5c7f1f385f82e) Thanks [@&#8203;Abhirup-99](https://github.com/Abhirup-99)! - Speeds up content sync with `experimental.collectionStorage: "chunked"` by computing each character's UTF-8 width from its code point instead of encoding every character through `TextEncoder`. On a store of \~44k entries this cuts the chunking step from about 60 seconds to well under a second, with byte-identical output.

- [#&#8203;18438](https://github.com/withastro/astro/pull/18438) [`5e0eaa4`](https://github.com/withastro/astro/commit/5e0eaa4415a9081efdaeb3d9af3717ce3226ad18) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes `astro dev` with `@astrojs/cloudflare` failing with ``Calling `require` for "node-fetch"`` when a server dependency such as `cross-fetch` requires `node-fetch`

- [#&#8203;18376](https://github.com/withastro/astro/pull/18376) [`a4e201d`](https://github.com/withastro/astro/commit/a4e201d79f19caa6bf4222f42167aeb602c066e6) Thanks [@&#8203;okxint](https://github.com/okxint)! - Fixes `astro dev` treating a stale lock file containing a Linux thread ID as a running Astro server. A successful process lookup with no matching PID now marks the lock as stale, preventing `astro dev stop` and `astro dev --force` from killing the unrelated process that owns the thread.

- [#&#8203;18467](https://github.com/withastro/astro/pull/18467) [`d1fb7d3`](https://github.com/withastro/astro/commit/d1fb7d36dad440c57d62b071e752ae220cca2baa) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes the `defineConfig()` types for `i18n.defaultLocale`, `i18n.fallback`, and `i18n.domains` so they accept a custom locale's `path` instead of its `codes`, matching how Astro validates and uses these values

- [#&#8203;18475](https://github.com/withastro/astro/pull/18475) [`cf27e70`](https://github.com/withastro/astro/commit/cf27e70a9057ce29ade2a8a843bd9275a696e9ab) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Bumps the minimum supported Node.js version to 22.23.4, which includes the fixes from the [October 2026 Node.js security releases](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases)

  This is a patch release because the [Node.js support and upgrade policy](https://docs.astro.build/en/upgrade-astro/#nodejs-support-and-upgrade-policies) allows the Core team to raise the minimum Maintenance LTS version in a patch release when a disclosed and fixed Node.js security flaw affects Astro.

- [#&#8203;18451](https://github.com/withastro/astro/pull/18451) [`7a0ba6f`](https://github.com/withastro/astro/commit/7a0ba6f48ebae256a1ce49de4f1c62c009ff94e2) Thanks [@&#8203;DenisCDev](https://github.com/DenisCDev)! - Fixes `astro sync`, `astro check` and `astro build` replacing the optimized dependencies of a dev server running in the same project, which broke framework islands in that dev server until it was restarted with `--force`

- [#&#8203;18336](https://github.com/withastro/astro/pull/18336) [`e943003`](https://github.com/withastro/astro/commit/e943003259c3bb4d528d3d49c8ccd3eb8f84b8b5) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes inline styles in dev so that framework-transformed CSS is used, such as scoped styles and `v-bind()` in Vue single-file components

- [#&#8203;18399](https://github.com/withastro/astro/pull/18399) [`829fc00`](https://github.com/withastro/astro/commit/829fc00629ef715fc606b89c6e684ca93f9253b9) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes a dev server error (`Could not find server component name`) for a `server:defer` island that imports `astro:actions` or `astro:config/server`, when its page was not the first island page loaded after starting the server

- [#&#8203;18330](https://github.com/withastro/astro/pull/18330) [`4db9e0d`](https://github.com/withastro/astro/commit/4db9e0d1e6a54c2300b96a0ff0cfaf5c188cecda) Thanks [@&#8203;Samuteg](https://github.com/Samuteg)! - Fixes the `astro:env/server` virtual module being generated with invalid JS in dev when any environment variable contains `$` replacement patterns (`` $` ``, `$&`, `$'`, `$1`, …). The inlined env JSON was passed as a string to `String.replace`, so e.g. the `KITTY_PUBLIC_KEY` value set by default in Kitty terminals corrupted the module and broke dev with `Failed to parse source for import analysis`

- Updated dependencies \[[`cf27e70`](https://github.com/withastro/astro/commit/cf27e70a9057ce29ade2a8a843bd9275a696e9ab)]:
  - [@&#8203;astrojs/telemetry](https://github.com/astrojs/telemetry)@3.4.1
  - [@&#8203;astrojs/markdown-satteri](https://github.com/astrojs/markdown-satteri)@0.4.5

</details>

<details>
<summary>actions/node-versions (node)</summary>

### [`v26.12.1`](https://github.com/actions/node-versions/releases/tag/26.12.1-39618969937): 26.12.1

[Compare Source](https://github.com/actions/node-versions/compare/26.12.0-38668157440...26.12.1-39618969937)

Node.js 26.12.1

### [`v26.12.0`](https://github.com/actions/node-versions/releases/tag/26.12.0-38668157440): 26.12.0

[Compare Source](https://github.com/actions/node-versions/compare/26.11.1-37718106145...26.12.0-38668157440)

Node.js 26.12.0

### [`v26.11.1`](https://github.com/actions/node-versions/releases/tag/26.11.1-37718106145): 26.11.1

[Compare Source](https://github.com/actions/node-versions/compare/26.11.0-37718124002...26.11.1-37718106145)

Node.js 26.11.1

### [`v26.11.0`](https://github.com/actions/node-versions/releases/tag/26.11.0-37718124002): 26.11.0

[Compare Source](https://github.com/actions/node-versions/compare/26.10.0-35737674515...26.11.0-37718124002)

Node.js 26.11.0

### [`v26.10.0`](https://github.com/actions/node-versions/releases/tag/26.10.0-35737674515): 26.10.0

[Compare Source](https://github.com/actions/node-versions/compare/26.9.0-35174947414...26.10.0-35737674515)

Node.js 26.10.0

### [`v26.9.0`](https://github.com/actions/node-versions/releases/tag/26.9.0-35174947414): 26.9.0

[Compare Source](https://github.com/actions/node-versions/compare/26.8.2-34429851330...26.9.0-35174947414)

Node.js 26.9.0

### [`v26.8.2`](https://github.com/actions/node-versions/releases/tag/26.8.2-34429851330): 26.8.2

[Compare Source](https://github.com/actions/node-versions/compare/26.8.1-33034053154...26.8.2-34429851330)

Node.js 26.8.2

### [`v26.8.1`](https://github.com/actions/node-versions/releases/tag/26.8.1-33034053154): 26.8.1

[Compare Source](https://github.com/actions/node-versions/compare/26.8.0-33034064325...26.8.1-33034053154)

Node.js 26.8.1

### [`v26.8.0`](https://github.com/actions/node-versions/releases/tag/26.8.0-33034064325): 26.8.0

[Compare Source](https://github.com/actions/node-versions/compare/26.7.0-31064755789...26.8.0-33034064325)

Node.js 26.8.0

### [`v26.7.0`](https://github.com/actions/node-versions/releases/tag/26.7.0-31064755789): 26.7.0

[Compare Source](https://github.com/actions/node-versions/compare/26.6.0-30872438625...26.7.0-31064755789)

Node.js 26.7.0

### [`v26.6.0`](https://github.com/actions/node-versions/releases/tag/26.6.0-30872438625): 26.6.0

[Compare Source](https://github.com/actions/node-versions/compare/26.5.1-30508404249...26.6.0-30872438625)

Node.js 26.6.0

### [`v26.5.1`](https://github.com/actions/node-versions/releases/tag/26.5.1-30508404249): 26.5.1

[Compare Source](https://github.com/actions/node-versions/compare/26.5.0-28944078721...26.5.1-30508404249)

Node.js 26.5.1

### [`v26.5.0`](https://github.com/actions/node-versions/releases/tag/26.5.0-28944078721): 26.5.0

[Compare Source](https://github.com/actions/node-versions/compare/26.4.0-28176665805...26.5.0-28944078721)

Node.js 26.5.0

### [`v26.4.0`](https://github.com/actions/node-versions/releases/tag/26.4.0-28176665805): 26.4.0

[Compare Source](https://github.com/actions/node-versions/compare/26.3.1-27765697053...26.4.0-28176665805)

Node.js 26.4.0

### [`v26.3.1`](https://github.com/actions/node-versions/releases/tag/26.3.1-27765697053): 26.3.1

[Compare Source](https://github.com/actions/node-versions/compare/26.3.0-26776574275...26.3.1-27765697053)

Node.js 26.3.1

### [`v26.3.0`](https://github.com/actions/node-versions/releases/tag/26.3.0-26776574275): 26.3.0

[Compare Source](https://github.com/actions/node-versions/compare/26.2.0-26201774761...26.3.0-26776574275)

Node.js 26.3.0

### [`v26.2.0`](https://github.com/actions/node-versions/releases/tag/26.2.0-26201774761): 26.2.0

[Compare Source](https://github.com/actions/node-versions/compare/26.1.0-25496618813...26.2.0-26201774761)

Node.js 26.2.0

### [`v26.1.0`](https://github.com/actions/node-versions/releases/tag/26.1.0-25496618813): 26.1.0

[Compare Source](https://github.com/actions/node-versions/compare/26.0.0-25413736946...26.1.0-25496618813)

Node.js 26.1.0

### [`v26.0.0`](https://github.com/actions/node-versions/releases/tag/26.0.0-25413736946): 26.0.0

[Compare Source](https://github.com/actions/node-versions/compare/24.22.2-40806817314...26.0.0-25413736946)

Node.js 26.0.0

</details>

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

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

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.16.0...v12.16.1)

This release fixes `pnpm install` hanging on a cold store in workspaces that install Cargo crates, and `pnpm pack` shipping a file that `files` excludes by name.

##### Patch Changes

- `pnpm install` no longer hangs on a cold store in a workspace that also installs Cargo crates or a Rust toolchain.

- `pnpm pack` and `pnpm publish` now apply a `files` entry that names a file after the glob and directory entries, as npm does. A file excluded by name, such as `!dist/index.js`, stays out even when a later `dist/**` matches it. A file named by its path, such as `lib/secret.js`, ships even when a later `!lib/*.js` matches it.

- `pnpm install` no longer leaves a broken symlink in an injected workspace dependency when the package links to a file outside its published files and pnpm imports by hardlink. Installing a git dependency now skips internal directory symlinks when importing its files into the store.

- `pnpm install` now relinks a command that a workspace project renames into the projects that depend on it when `sharedWorkspaceLockfile` is `false` [pnpm/tasks#224](https://github.com/pnpm/tasks/issues/224).

- `pnpm install` and `pnpm rebuild` now refresh privately hoisted `.bin` shims in `node_modules/.pnpm/node_modules/.bin` after a dependency build replaces a script target with a native executable [#&#8203;17402](https://github.com/pnpm/pnpm/issues/17402).

- `pnpm install` now reads a package's manifest to decide its peer dependencies when it updates an existing lockfile, as it does when it resolves from scratch.

- Commands, `pnpm --version`, `pnpm self-update`, and invocations with unknown flags now apply the same `packageManager` and `devEngines.packageManager` settings when switching to the pinned pnpm version or recording it in `pnpm-lock.yaml`. `--config.<key>` flags and `lockfileDir` now reach the version switch and lockfile sync on every entry point. Unreadable settings in `pnpm-workspace.yaml` or the global `config.yaml` that do not affect the pin decision no longer block the version switch [pnpm/tasks#222](https://github.com/pnpm/tasks/issues/222).

- pnpm now accepts the `--cache-dir <dir>` flag, as in `pnpm install --cache-dir /tmp/pnpm-cache` [#&#8203;17422](https://github.com/pnpm/pnpm/issues/17422).

- When the version or range given to `pnpm unpublish` matches every published version, the error now says so and shows the same command with `--force`. Before, the error suggested running `pnpm unpublish <pkg>@<version>`, the command that had just failed.

<!-- 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.16.0`](https://github.com/pnpm/pnpm/releases/tag/v12.16.0): pnpm 12.16

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.15.0...v12.16.0)

This release adds a global `--env-file` flag, updates to a symlinked `pnpm-lock.yaml`, and `pnpm setup --no-modify-path`. It also fixes two security issues, in zstd decompression and in signing.

##### Minor Changes

- Added a repeatable global `--env-file <path>` flag to load environment variables from dotenv-style files before running a command. Later files override earlier files, variables already in the environment are preserved, and loaded variables are visible to user-level `.npmrc` interpolation and lifecycle scripts [#&#8203;7111](https://github.com/pnpm/pnpm/issues/7111).

- pnpm can now update a `pnpm-lock.yaml` that is a symlink. List the directories the lockfile may link into in the `symlinkedLockfileTargetDirs` setting, in the global config or with `PNPM_CONFIG_SYMLINKED_LOCKFILE_TARGET_DIRS`. pnpm writes the update to the file the symlink points to if that file is inside one of these directories. The symlink stays in place. pnpm ignores this setting in `pnpm-workspace.yaml` [#&#8203;17222](https://github.com/pnpm/pnpm/issues/17222).

- Added a `--no-modify-path` option to `pnpm setup`. It installs pnpm without adding it to `PATH`, leaving the shell config file, the Windows registry, and the GitHub Actions environment files unchanged. `pnpm setup` then prints the lines to add yourself [get.pnpm.io#37](https://github.com/pnpm/get.pnpm.io/issues/37).

##### Patch Changes

##### Security

- Fixed memory exposure and allocation handling vulnerabilities when processing zstd-compressed data [#&#8203;17388](https://github.com/pnpm/pnpm/pull/17388).

- Signing in pnpm and pnpr no longer uses arithmetic that may leak the private key through timing. This covers shared artifacts, OCI registry tokens, and OIDC login state [advisory](https://rustsec.org/advisories/RUSTSEC-2026-0387).

##### Installing packages

- A dependency symlink that pnpm cannot point at the wanted target now fails the install with an error that names the link. This happens when the filesystem still serves the old link after pnpm removed it, as a `node_modules` served by a virtual filesystem does. pnpm used to remove the link again without end and crashed with a segmentation fault once the thread ran out of stack.

- Concurrent workspace installs no longer lose store-index rows when initializing the shared SQLite index [#&#8203;17388](https://github.com/pnpm/pnpm/pull/17388).

- Agent skill links now keep the same target across installs when a package version is installed with several sets of peer dependencies. An install no longer fails with `ERR_PNPM_AGENT_SKILL_PATH_OCCUPIED` on a skill link that pnpm created for another of those copies [#&#8203;17319](https://github.com/pnpm/pnpm/issues/17319).

- pnpm now fails at once, without retrying, when a downloaded package archive contains a rejected entry path [#&#8203;17205](https://github.com/pnpm/pnpm/issues/17205).

- pnpm now builds a git-hosted dependency in every new location it links the dependency into, such as a new global virtual store slot or a fresh `node_modules`. When the side-effects cache holds the build output, pnpm restores it from there. Before, only the install that fetched the dependency built it. This also fixes dependencies that are already in the store [#&#8203;17224](https://github.com/pnpm/pnpm/issues/17224).

- Changes a `preResolution` hook makes to the lockfiles now take effect. The hook now also runs when pnpm installs from an up-to-date lockfile. An error thrown by the hook now fails the install.

- A custom fetcher in the pnpmfile can now call `fetchers.directory` to fetch a package from a local directory. The call rejects with `ERR_PNPM_TARBALL_INTEGRITY` if the lockfile pins an archive integrity for the package. Previously, calling `fetchers.directory` failed with a `TypeError`.

- `packageImportMethod: copy` now also applies to packages that have lifecycle scripts or patches. On a filesystem that supports block cloning, such as ReFS or a Dev Drive on Windows, these packages were cloned [#&#8203;17195](https://github.com/pnpm/pnpm/issues/17195).

- With `nodeLinker: hoisted` and `autoInstallPeers: false`, a package that workspace projects use with different peer versions is now installed once per peer variant, so each project's copy resolves that project's peer [#&#8203;17395](https://github.com/pnpm/pnpm/issues/17395).

- Under `nodeLinker: hoisted`, `pnpm install` now leaves a patched package that is already in place alone. The same holds for a package whose peers include a patched package, such as every package peering on a patched `react-native` [#&#8203;17188](https://github.com/pnpm/pnpm/issues/17188).

- With `nodeLinker: hoisted`, an install that stops partway no longer leaves the next install trusting the packages it was replacing. Before, reverting the change that started the stopped install, such as a patch edit, kept the half-replaced package in `node_modules`.

##### Repeat installs and changed settings

- A repeat `pnpm install` now acts on a change to these settings. Before, it reported "Already up to date".

  - `storeDir` or `virtualStoreDir`: it recreates `node_modules`.
  - `globalVirtualStoreDir`: it links the packages from the new directory.
  - `virtualStoreDirMaxLength`: it renames the virtual store directories.
  - `dangerouslyAllowAllBuilds` turned on: it runs the builds it skipped.
  - `trustLockfile` turned off: it verifies the lockfile.

- `pnpm add`, `pnpm remove`, and `pnpm update` now fail if `node_modules` does not match the current settings. Run `pnpm install` to recreate it. Previously, these commands removed and reinstalled `node_modules` without asking. They report:

  - `ERR_PNPM_UNEXPECTED_STORE` if `node_modules` was linked from a different store.
  - `ERR_PNPM_UNEXPECTED_VIRTUAL_STORE` if it was linked from a different virtual store directory.
  - `ERR_PNPM_MODULES_BREAKING_CHANGE` if it was installed by an incompatible pnpm version, or if `node_modules/.modules.yaml` cannot be read.
  - `ERR_PNPM_NODE_LINKER_DIFF` if it was installed with a different `nodeLinker`.

  `pnpm update` now also fails with `ERR_PNPM_HOIST_PATTERN_DIFF` and the other errors `pnpm add` reports for a changed hoist pattern or `virtualStoreDirMaxLength`.

- An install filtered to some workspace projects now fails if `node_modules` was installed with a different `nodeLinker`, `hoistPattern`, `publicHoistPattern`, store, or virtual store. Before, it recreated `node_modules` and left the projects it skipped without their dependencies. A `pnpm install` of the whole workspace still recreates `node_modules` [pnpm/tasks#217](https://github.com/pnpm/tasks/issues/217).

- `pnpm install` and the `verifyDepsBeforeRun` check now notice an edited patch file when `sharedWorkspaceLockfile` is `false`.

- `pnpm install` now takes its fast path in a workspace with `patchedDependencies` when the previous install ran with another major version of pnpm.

- `pnpm install` now relinks the bins of a workspace package when its `bin` field changes, including with `--frozen-lockfile` and an unchanged lockfile. A filtered install relinks them in the selected projects, and the next install that covers the remaining projects relinks them there [#&#8203;17324](https://github.com/pnpm/pnpm/issues/17324).

- `pnpm install` now removes command shims from `node_modules/.bin` when a workspace dependency renames or removes an entry from its `bin` field [pnpm/tasks#211](https://github.com/pnpm/tasks/issues/211).

##### Resolving dependencies and the lockfile

- A package that a plain range and a `<prefix>:` specifier both resolve from one registry is now recorded once in `pnpm-lock.yaml` and installed once. The lockfile key names the registry a package resolved from. When that registry declares a prefix, through `prefix` in `registries` or through `namedRegistries`, the package is keyed `<name>@<prefix>:<version>` however its dependency was written: with the prefix, as a plain range its scope routes to that registry, or through the default registry. Before, the plain range was keyed `<name>@<version>`, so one tarball was installed twice and `instanceof` checks and module singletons broke between the two copies. The same name and version served by two registries still get separate entries. When several prefixes declare one registry, its packages are keyed by the lexicographically smallest prefix.

  If a scope you route reaches a registry that also declares a prefix, your next `pnpm install` re-keys those entries, which shows up as a lockfile diff. Commit it. `pnpm install --frozen-lockfile` installs the lockfile as recorded.

- `pnpm install` now resolves a scope's packages again when the scope is routed to another registry in `registries`. Before, the lockfile kept the versions and integrity resolved from the old registry, so the install failed when the new registry did not serve a locked version or served different content. pnpm records in the workspace state which registry each scope routed to, so a fresh clone without that record installs the lockfile as recorded. Changing the default registry resolves nothing again, and `pnpm install --frozen-lockfile` is unchanged.

- When `autoDedupe` is off, a workspace project's dependencies now resolve from its own ranges, like they do with `sharedWorkspaceLockfile: false`. Previously, another project's narrower range could hold them back. For example, `ajv: "*"` now resolves to the latest Ajv even if another project depends on `ajv@^6`. Packages that a project lists in `peerDependencies` still follow the versions other projects use. `pnpm dedupe` and installs with `autoDedupe: true` still pick one version that satisfies every range. Set `autoDedupe: true` if CI runs `pnpm dedupe --check` [#&#8203;17235](https://github.com/pnpm/pnpm/issues/17235).

- An optional dependency written with a named-registry prefix, such as `work:^1.0.0`, now fails the install when it cannot be resolved but the lockfile already has a matching entry from that registry. Such a dependency was skipped, which removed its entries from the lockfile.

- With `injectWorkspacePackages: true`, a `workspace:` dependency written as a relative path, such as `workspace:../lib-a`, in a workspace package now resolves from that package's directory [#&#8203;17284](https://github.com/pnpm/pnpm/issues/17284).

- Fixed `pnpm install` failing with `ERR_PNPM_UNSUPPORTED_PROTOCOL` when a workspace package injected through a relative path, such as `workspace:../lib`, has `catalog:` dependencies. Their catalog entries now resolve the way they do for a package injected by name [#&#8203;17280](https://github.com/pnpm/pnpm/issues/17280).

- `pnpm dedupe` now refreshes cached registry metadata while re-resolving locked versions [#&#8203;17208](https://github.com/pnpm/pnpm/issues/17208).

- `pnpm dedupe --check` no longer fails when the only difference is a `deprecated` notice that the registry added or removed after the lockfile was written [#&#8203;17198](https://github.com/pnpm/pnpm/issues/17198).

- Installs delegated to a pnpr server now resolve every prefix declared for a registry URL. A dependency or lockfile entry that used the second of two prefixes for the same registry, such as `zeta:` next to `work:` in `namedRegistries`, failed on the server [pnpm/tasks#204](https://github.com/pnpm/tasks/issues/204).

- Registry revisions are now addressed at `<registry>/<name>@<version>+r<revision>` [pnpm/tasks#208](https://github.com/pnpm/tasks/issues/208).

##### Adding packages and global packages

- `pnpm add <pkg>@<tag>` and `pnpm add <pkg>@<range>` now install the version the tag or range resolves to, even when the saved range allows a newer one [#&#8203;17234](https://github.com/pnpm/pnpm/issues/17234).

- `pnpm add <pkg>` without a version now installs the version under the dist-tag set by the `tag` setting. An `npm:` alias or a `jsr:` dependency without a version resolves that tag too. The setting is read from `pnpm-workspace.yaml`, the global config, `PNPM_CONFIG_TAG`, and `--config.tag`, and defaults to `latest`.

- `pnpm add` now accepts the lowercase short options `-p`, `-d`, `-o`, and `-e` as aliases of `--save-prod`, `--save-dev`, `--save-optional`, and `--save-exact`.

- `pnpm -D install <pkg>` now saves the package to devDependencies. An `add` option such as `-D` or `-E` written before `install <pkg>` was rejected as an unexpected argument.

- `pnpm add -T` now reports that the short option is ambiguous and points to `--save-types` and `--tilde`.

- Global packages installed with `pnpm add -g` are now linked from the global virtual store, so global packages that share dependencies share one copy. Set `virtualStoreType: project` to give each global install its own virtual store.

- `pnpm add -g` and the other `--global` commands now fail with `ERR_PNPM_CONFIG_CONFLICT_VIRTUAL_STORE_DIR_WITH_GLOBAL` when `--virtual-store-dir` is passed. A custom `--hoist-pattern` fails with `ERR_PNPM_CONFIG_CONFLICT_HOIST_PATTERN_WITH_GLOBAL`. Passing `--link-workspace-packages`, `--shared-workspace-lockfile`, or `--config.lockfile-dir` with `--global` also fails, with the matching `ERR_PNPM_CONFIG_CONFLICT_*_WITH_GLOBAL` code.

##### Registries, proxies, and login

- pnpm now reads the `strictSsl` and `localAddress` settings from `pnpm-workspace.yaml`, the global `config.yaml`, `PNPM_CONFIG_*` environment variables, and `--config.*` options. This includes `pnpm self-update` and the download of the pnpm version pinned in `packageManager`. Before, pnpm read them only from `.npmrc` as `strict-ssl` and `local-address` and ignored the other sources [pnpm/tasks#201](https://github.com/pnpm/tasks/issues/201).

- When Corepack runs pnpm and the native binary has to be downloaded, the download now uses the proxy from pnpm's config. That proxy comes from `PNPM_CONFIG_HTTPS_PROXY` and the matching variables, the global `config.yaml`, and the user `.npmrc`. Previously, the download read the proxy only from `HTTPS_PROXY`, `HTTP_PROXY`, and `NO_PROXY` [pnpm/tasks#215](https://github.com/pnpm/tasks/issues/215).

- When the `pnpm` package downloads its native binary on first run, as it does under Corepack, it now trusts the CA certificates from the `ca`, `ca[]`, and `cafile` settings of `.npmrc`, including the ones scoped to the registry. A registry behind a private CA failed with `fetch failed` before, unless `NODE_EXTRA_CA_CERTS` named the CA. A project `.npmrc` is used only while the download is checked against npm's signature. Node.js versions that cannot add CA certificates after startup still need `NODE_EXTRA_CA_CERTS`.

- `pnpm login` saves the token in `<pnpm config>/auth.ini` again. Since v12.1.0, an unscoped login had made its registry the default for every project that did not name a registry. A login now also removes the token an earlier login saved for that registry or scope under `_auth` in the global `config.yaml`. `pnpm login --scope` still routes the scope through the global `registries` setting.

- pnpm no longer warns that a `registries` entry routed through the `@` scope matches no configured registry. pnpm applied such an entry and its options such as `serverType` while reporting it as ignored [pnpm/tasks#184](https://github.com/pnpm/tasks/issues/184).

##### Running scripts and other commands

- `pnpm ci --lockfile` and `pnpm ci --config.lockfile=true` no longer delete `pnpm-lock.yaml`. `pnpm ci` now always keeps the lockfile and runs a frozen install from it.

- `pnpm deploy --legacy` now checks the workspace lockfile against `minimumReleaseAge` and the other resolution policies, as `pnpm install` does, and fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION` when a locked version is too new. It used to deploy an older version that is not in the lockfile without a warning [#&#8203;17209](https://github.com/pnpm/pnpm/issues/17209).

- `pnpm deploy` now keeps a deployed symlink to a directory inside the project even if the directory is not among the deployed files, such as a link into `node_modules` [#&#8203;17288](https://github.com/pnpm/pnpm/issues/17288).

- `pnpm pack` and `pnpm publish` now keep `pnpm.config` in the published `package.json`. They also always include the file `pnpm.config` points to in the tarball [#&#8203;17210](https://github.com/pnpm/pnpm/issues/17210).

- `pnpm -r publish --batch` now sends `PUT /-/pnpr/v0/publish`, the batch publish endpoint that pnpr serves.

- `pnpm audit --ignore` and `pnpm audit --ignore-unfixable` now exit with a non-zero code when vulnerabilities at or above the audit level remain after ignoring. Before, these commands always exited with code 0.

- `pnpm audit --fix` and `pnpm audit --interactive` now fail with `ERR_PNPM_AUDIT_FIX_WITH_IGNORE` when combined with `--ignore` or `--ignore-unfixable`. Before, the fix ran and the ignore flags had no effect.

- `pnpm -r run <script>` now honors the `requiredScripts` setting from `pnpm-workspace.yaml`. If the script is listed there and a selected project does not define it, the run fails with `ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT` and names the projects that lack it.

- `pnpm run` and `pnpm exec` no longer report the dependencies as out of date after a lockfile change when `dedupePeers` is `true` [#&#8203;17322](https://github.com/pnpm/pnpm/issues/17322).

- On macOS, killing pnpm while it runs scripts in several projects at once now ends every one of those scripts. Before, a script could keep running after pnpm died.

- `pnpm run`, `pnpm exec`, and `pnpm dlx` no longer dump a core file for `pnpm` itself when a command they started dies from a signal [#&#8203;17204](https://github.com/pnpm/pnpm/issues/17204).

- The `runtime` setting is now read. Setting `runtime: false` in `pnpm-workspace.yaml`, `pnpm_config_runtime=false`, or `--config.runtime=false` stops `pnpm install`, `pnpm add`, `pnpm dedupe`, and the other installing commands from installing the runtimes in `devEngines.runtime` and `engines.runtime`. `pnpm dedupe` now also accepts `--no-runtime`.

- Directory selectors with `legacyDirFiltering: true` now include the project in the named directory along with its descendants. Excluding a directory also excludes that project [pnpm/tasks#196](https://github.com/pnpm/tasks/issues/196).

- `pnpm help --all` and `pnpm help -a` now print the full list of commands. They used to fail with an "unrecognized subcommand" error.

- Reading the file-creation mask on Linux no longer sets it. pnpm had to replace the mask to learn what it was, and a file another thread created in the window between the two calls was created unmasked.

- pnpm now passes an interrupt on to the handler it replaced, with the arguments that handler expects. A handler that asked for the signal's details was called without them. Only a program that embeds pnpm and installs its own `SIGINT`, `SIGTERM` or `SIGHUP` handler was affected.

##### Store

- `pnpm store prune` now keeps the packages that a project still uses when pnpm copied or cloned them into `node_modules`. These include patched packages, built packages, and every package installed with `packageImportMethod: copy`. Before, the prune removed them, and the next install downloaded them again [#&#8203;7192](https://github.com/pnpm/pnpm/issues/7192).

- `pnpm store prune` now keeps the packages of a project when the store path reaches its directory through a symlink. Previously, prune dropped such a project from its list and removed the packages only that project used from the global virtual store.

- `pnpm store prune` now removes the package metadata cache, the `metadata*` directories in the cache directory. This clears the outdated integrity checksums that cause `ERR_PNPM_TARBALL_INTEGRITY` when a registry republishes a version.

##### Speed

- `pnpm install` resolves dependencies faster in large workspaces on Linux, macOS, and Windows on x64 and arm64.

- Sped up cold installs and `pnpm fetch` on macOS. pnpm now links downloaded packages into the virtual store on a separate thread, so a slow link pass no longer pauses the downloads that are still in flight [#&#8203;17271](https://github.com/pnpm/pnpm/issues/17271).

- Sped up installs that add new projects to a workspace with a peer-heavy lockfile. pnpm now reads the lockfile's locked peer versions once for all new projects [#&#8203;17311](https://github.com/pnpm/pnpm/issues/17311).

- Warm installs no longer read the `package.json` of every git-hosted dependency. pnpm now stores the manifest of a git-hosted package in the store index when it fetches the package.

- `pnpm update --depth <n>` with a large `n`, such as the `--depth=9999` that `update-browserslist-db` runs, now finishes as fast as `--depth Infinity`. It used memory and stack in proportion to `n` on lockfiles with dependency cycles, and could run out of memory or crash [#&#8203;17329](https://github.com/pnpm/pnpm/issues/17329).

##### Output and warnings

- Output that fills the terminal, such as `pnpm run --stream` script output, is now written once. Before, every new line also rewrote all the lines already on screen [#&#8203;17387](https://github.com/pnpm/pnpm/issues/17387).

- pnpm now warns when a pnpmfile defines the `importPackage` hook. pnpm does not run this hook. Use the `packageImportMethod` setting to choose how packages are written to `node_modules`.

- `pnpm` now warns when a project's `pnpm-workspace.yaml` sets `ci`, `globalShims`, or `tools`, and names where to set them instead. These settings were already ignored there without a warning. `pnpm config set` also refuses to write them to a project's `pnpm-workspace.yaml`.

- pnpm no longer documents the `scriptsPrependNodePath` setting, which has no effect. A `pnpm-workspace.yaml` that sets it still loads.

<!-- 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>

---

### 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 CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODEuNyIsInVwZGF0ZWRJblZlciI6IjQ0LjE5OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.com/gitea/docs/pulls/626
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
2026-11-02 00:49:41 +00:00
silverwindandLunny Xiao 6632d38fe2 Document the commitstatus token scope (#622)
Documents https://github.com/go-gitea/gitea/pull/40144 for main, which adds `read:commitstatus` and `write:commitstatus` token scopes so CI integrations can report commit statuses without full repository access. The repository scopes include them.

Adds the scope to the OAuth2 provider scope table and the API usage permission list. Draft until the Gitea PR merges.

_Written by Claude (Opus 5.5)._

---------

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/622
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-11-01 18:19:38 +00:00
silverwindandbircni ef57d8d2c0 Document gitea-cli OAuth2 application (#620)
Documents https://github.com/go-gitea/gitea/pull/40036 for main, which renames the built-in tea OAuth2 application to gitea-cli and keeps `tea` as an alias in `[oauth2] DEFAULT_APPLICATIONS`.

The default list and the pre-configured applications table also gain the missing gitea-app and gitea-vscode entries.

_Written by Claude (Opus 5.5)._

---------

Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/620
Reviewed-by: bircni <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-11-01 12:50:48 +00:00
bircni ba4abd749d update to 28.3.0 (#623)
Bump the v28 docs to the 28.3.0 release:

- point the `28` version variables (`version`, `sourceVersion`, `dockerVersion`, `displayVersion`) at 28.3.0
- update the v28 entry in `update_api_docs.sh` to `28.3.0`
- regenerate `static/swagger-28.json` and `static/openapi3-28.json` from the `v28.3.0` tag, which picks up the updated `Deadline` and `Labels` descriptions from go-gitea/gitea#39869 and go-gitea/gitea#39873

Reviewed-on: https://gitea.com/gitea/docs/pulls/623
Reviewed-by: silverwind <[email protected]>
2026-11-01 10:11:04 +00:00
silverwind 8197192134 Document GITEA_* env aliases, missing variables and accurate examples (#618)
https://gitea.com/gitea/runner/pulls/1358 mirrors every built-in `GITHUB_*` variable as `GITEA_*`. The variables page now lists both names for each, in the same paired style as the context table.

It also adds variables that runners already set but the page left out (`*_ACTOR_ID`, `*_REF_PROTECTED`, `*_REPOSITORY_ID`, `*_REPOSITORY_OWNER_ID`, `*_TRIGGERING_ACTOR`, `*_WORKFLOW_SHA`, `ACT`, `ImageOS`, `RUNNER_DEBUG`, `RUNNER_ENVIRONMENT`, `RUNNER_NAME`, `RUNNER_WORKSPACE`, `TRACEPARENT`, `TRACESTATE`).

Examples copied from GitHub's runner (`/home/runner/work/_temp/...` paths, `__run`, `ghs_***`) are replaced with the values gitea-runner and Gitea actually produce, using placeholder users, repositories and instance URLs.

The zh-cn and zh-tw pages get the environment variable section they never had.

Reviewed-on: https://gitea.com/gitea/docs/pulls/618
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
2026-10-31 05:25:00 +00:00
brock0124andLunny Xiao 97fa45dabc fix(Hem Chart Registry docs): typo (#614)
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/614
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: brock0124 <[email protected]>
2026-10-29 02:19:31 +00:00
ee9e91cdeb Add project workflow documentation (#308)
Documentation for https://github.com/go-gitea/gitea/pull/30205

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/308
Reviewed-by: silverwind <[email protected]>
2026-10-28 16:12:53 +00:00
Renovate BotandLunny Xiao d301461648 chore(deps): update dependencies (#611)
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | Pending |
|---|---|---|---|---|---|---|
| [@astrojs/check](https://github.com/withastro/astro/tree/main/packages/language-tools/astro-check) ([source](https://github.com/withastro/astro/tree/HEAD/packages/language-tools/astro-check)) | [`0.9.10` → `0.9.11`](https://renovatebot.com/diffs/npm/@astrojs%2fcheck/0.9.10/0.9.11) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fcheck/0.9.11?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fcheck/0.9.10/0.9.11?slim=true) | devDependencies | patch | `0.9.12` |
| [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`7.3.8` → `7.4.1`](https://renovatebot.com/diffs/npm/astro/7.3.8/7.4.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/astro/7.4.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/astro/7.3.8/7.4.1?slim=true) | dependencies | minor | `7.4.2` |
| [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.13.0` → `12.15.0`](https://renovatebot.com/diffs/npm/pnpm/12.13.0/12.15.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/12.15.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/12.13.0/12.15.0?slim=true) | packageManager | minor |  |
| [ubuntu](https://github.com/actions/runner-images) | `24.04` → `26.04` | ![age](https://developer.mend.io/api/mc/badges/age/github-runners/ubuntu/26.04?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-runners/ubuntu/24.04/26.04?slim=true) | github-runner | major |  |

---

### Release Notes

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

### [`v0.9.11`](https://github.com/withastro/astro/blob/HEAD/packages/language-tools/astro-check/CHANGELOG.md#0911)

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

##### Patch Changes

- [#&#8203;18445](https://github.com/withastro/astro/pull/18445) [`d736df7`](https://github.com/withastro/astro/commit/d736df7a9cc03c12b22e538f058fb1f769672471) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes the `--preserveWatchOutput` help text, which described the opposite of the flag's behavior. Setting it to `true` keeps output between checks in watch mode.

- [#&#8203;18444](https://github.com/withastro/astro/pull/18444) [`c55134c`](https://github.com/withastro/astro/commit/c55134c1d3c238a43e17cfeff136375a4d9d5d35) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes `astro check --watch` exiting immediately when the project path contains `node_modules` or `.git`

</details>

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

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

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

##### Patch Changes

- [#&#8203;18425](https://github.com/withastro/astro/pull/18425) [`6fdc36e`](https://github.com/withastro/astro/commit/6fdc36ed97316d932d2e143b85739f0af37ab329) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Preserves the last modified date of cached optimized images and incrementally restored build output when copying them into the build output on all platforms

- [#&#8203;18419](https://github.com/withastro/astro/pull/18419) [`395d195`](https://github.com/withastro/astro/commit/395d19525986a276bf81af7bd365e7a35dc20ef3) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes a typo in the error message shown when a font `cssVariable` is invalid

- [#&#8203;18401](https://github.com/withastro/astro/pull/18401) [`484822f`](https://github.com/withastro/astro/commit/484822fbba652745c4f2da5ef434a350203578e2) Thanks [@&#8203;danielmlr](https://github.com/danielmlr)! - Fixes a bug where projects whose path contains an apostrophe (`'`) failed to load sessions, middleware, a cache provider, or a `src/fetch.ts` handler

- [#&#8203;18407](https://github.com/withastro/astro/pull/18407) [`a6e00be`](https://github.com/withastro/astro/commit/a6e00beae6c134d0c1b5248eb02fbf119b7d64e9) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes a `TSCONFIG_ERROR` during `astro build` when a parent directory contains a `tsconfig.json` that cannot be resolved, such as one extending `astro/tsconfigs/strict` without installed dependencies

- [#&#8203;18427](https://github.com/withastro/astro/pull/18427) [`908f167`](https://github.com/withastro/astro/commit/908f1672a9fe6c40e6b73bfb0307f0d1f3ac2057) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes an `Unterminated string` build error when application code imports from `astro/config` (for example, `fontProviders` in a shared fonts module)

- [#&#8203;18428](https://github.com/withastro/astro/pull/18428) [`40e7d54`](https://github.com/withastro/astro/commit/40e7d54c7f969b402f011d32ccd87123835d0aa1) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes missing styles in production builds for conditionally rendered framework components (e.g. Svelte components inside `{#if}` blocks) imported by a hydrated island

- [#&#8203;18424](https://github.com/withastro/astro/pull/18424) [`617ff59`](https://github.com/withastro/astro/commit/617ff59820b4a5777eb5d3765c09d29082b11acc) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes style-only HMR in `.astro` components falling back to a full page reload when a PostCSS plugin (such as `@unocss/postcss`) lists the component as a dependency of its own style

- [#&#8203;18274](https://github.com/withastro/astro/pull/18274) [`70834bb`](https://github.com/withastro/astro/commit/70834bbea43695c563358ea055d32ecb5e0a78dd) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixes increasing memory usage when editing the Astro configuration while the dev server is running

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

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

##### Minor Changes

- [#&#8203;17894](https://github.com/withastro/astro/pull/17894) [`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Adds a new `--timings` flag to `astro build` to help you find what slows down your builds

  When a build takes longer than expected, it can be hard to tell whether the cause is an integration, a Markdown processor plugin, image processing, or even syntax highlighting. Add the `--timings` flag to your build command to print a summary once the build finishes:

  ```sh
  astro build --timings
  ```

  This is helpful to decide what to optimize first, or to compare build times before and after a change to your project.

- [#&#8203;17830](https://github.com/withastro/astro/pull/17830) [`a937b0d`](https://github.com/withastro/astro/commit/a937b0d3ec236c8dd1c62a7a4da7c65b2fdbb7c1) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Adds a new optional `getFontProperties()` callback to font providers

  Font providers can now expose the weights, styles, subsets and formats a font family actually has. Astro uses it when resolving your font configuration to warn about values a provider cannot serve, for example a weight a font family does not offer.

  All built-in providers implement it. If you maintain a custom font provider, implementing this callback is optional for now but it will be required in Astro 8:

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

  const provider: FontProvider = {
  	name: 'my-provider',
  	resolveFont: ({ familyName }) => {
  		// ...
  	},
  	getFontProperties: ({ familyName }) => ({
  		weights: ['400', '700'],
  		styles: ['normal', 'italic'],
  		subsets: ['latin'],
  		formats: ['woff2'],
  	}),
  };
  ```

- [#&#8203;17830](https://github.com/withastro/astro/pull/17830) [`a937b0d`](https://github.com/withastro/astro/commit/a937b0d3ec236c8dd1c62a7a4da7c65b2fdbb7c1) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Adds a `fetch()` function to the font provider `init()` context

  This function requests a provider API, retrying transient failures and more. It lets providers that wrap a 3rd-party unifont provider pass the context to it directly:

  ```ts
  import type { FontProvider } from 'astro';
  import type { InitializedProvider } from 'unifont';
  import { acmeProvider } from '@acme/unifont-provider';

  export function acmeFontProvider(): FontProvider {
  	const provider = acmeProvider();
  	let initializedProvider: InitializedProvider | undefined;
  	return {
  		name: provider._name,
  		async init(context) {
  			initializedProvider = await provider(context);
  		},
  		// ...
  	};
  }
  ```

- [#&#8203;18015](https://github.com/withastro/astro/pull/18015) [`0b30239`](https://github.com/withastro/astro/commit/0b302391059dbc4f8ece24d7b44599c7ec9fef24) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Adds `experimental.redirectPage`, letting you provide your own `src/pages/3xx.astro` in place of the redirect page Astro generates in static builds.

  A static site has no server to send an HTTP `Location` header, so Astro generates a small HTML page with a `<meta http-equiv="refresh">` tag for each redirect it builds:

  - Your [`redirects`](https://docs.astro.build/en/reference/configuration-reference/#redirects) entries
  - `Astro.redirect()` calls in prerendered pages
  - i18n redirects

  That page's markup, wording, and refresh delay were fixed, so you could not brand or translate it.

  To enable this feature, add the experimental flag to your Astro config:

  ```js
  // astro.config.mjs
  import { defineConfig } from 'astro/config';

  export default defineConfig({
    experimental: {
      redirectPage: true,
    },
  });
  ```

  Then create `src/pages/3xx.astro`. Astro renders it once per redirect, passing that redirect's details as props:

  ```astro
  ---
  // src/pages/3xx.astro
  import type { RedirectPageProps as Props } from 'astro';

  const { from, to, status, delay } = Astro.props;
  ---

  <html lang="en">
    <head>
      <meta http-equiv="refresh" content={`${delay};url=${to}`} />
      <meta name="robots" content="noindex" />
      <title>Redirecting…</title>
    </head>
    <body>
      <p>This page has moved. <a href={to}>Continue to {to}</a>.</p>
    </body>
  </html>
  ```

  Your page must render a `<meta http-equiv="refresh">` tag pointing at `to`, because in a static build that tag is the redirect. Astro logs a warning during the build if it is missing.

  See the [experimental redirect page documentation](https://docs.astro.build/en/reference/experimental-flags/redirect-page/) for more information.

- [#&#8203;18265](https://github.com/withastro/astro/pull/18265) [`910ee69`](https://github.com/withastro/astro/commit/910ee69147c4c2460f2b31a294bc70c5269f44d4) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Adds a `notFound()` handler to `astro/fetch` and `astro/hono` that renders the custom 404 page when no route matches, including a prerendered `404.astro`

  Add it before `pages()` in a custom worker or server entrypoint that does not run inside `App.render`, such as a Hono app used directly as a Cloudflare worker. Without it, `pages()` and `middleware()` return an empty 404 with an internal `X-Astro-Error` header for unmatched routes. `astro()` already includes this handling.

  ```ts
  import { Hono } from 'hono';
  import { notFound, pages } from 'astro/hono';
  import { cf } from '@astrojs/cloudflare/hono';

  const app = new Hono();
  app.use(cf());
  app.use(notFound());
  app.use(pages());
  export default app;
  ```

- [#&#8203;18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Adds support for separate `build` and `runtime` image services

  `image.service` now also accepts a `build` and a `runtime` service. The `build` service optimizes images on prerendered pages when you build your site, and is also used during development. The `runtime` service handles images on on-demand rendered pages and the image endpoint of your deployed site.

  The following example uses Sharp to optimize images on prerendered pages, and an image CDN for on-demand rendered pages:

  ```js
  // astro.config.mjs
  import { defineConfig } from 'astro/config';

  export default defineConfig({
    image: {
      service: {
        build: { entrypoint: 'astro/assets/services/sharp' },
        runtime: { entrypoint: 'my-image-cdn-service' },
      },
    },
  });
  ```

##### Changes for integration authors

`config.image.service` keeps the shape the user configured it with. When a project sets `build` and `runtime` services, `config.image.service.entrypoint` and `config.image.service.config` are `undefined`.

If your integration reads `image.service`, check for the `runtime` property to get the service you need:

```ts
'astro:config:done': ({ config }) => {
  const { service } = config.image;
  const runtimeService = 'runtime' in service ? service.runtime : service;

  if (runtimeService.entrypoint === 'astro/assets/services/sharp') {
    // ...
  }
},
```

Setting `image.service` with `updateConfig()` replaces the existing service instead of merging with it when the two use different shapes. For example, setting a single service in a project that uses `build` and `runtime` services replaces both.

- [#&#8203;18277](https://github.com/withastro/astro/pull/18277) [`2715958`](https://github.com/withastro/astro/commit/2715958666b0a706b069d0592da3a070b3796a9b) Thanks [@&#8203;florian-lefebvre](https://github.com/florian-lefebvre)! - Increases the minimum Node.js version to 22.22.0

  The minimum supported Node.js version is now 22.22.0, the latest Node.js 22 release supported by StackBlitz. This change is in line with Astro's [Node.js support policy](https://docs.astro.build/en/upgrade-astro/#support).

- [#&#8203;18313](https://github.com/withastro/astro/pull/18313) [`71e2b24`](https://github.com/withastro/astro/commit/71e2b24bb365e5a8809fc0432716f91ecc6d8ab5) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Allows integrations to control where Astro writes client, server, and prerender build output.

  Custom prerenderers can access the final output locations through the new `outputDirectories` context:

  ```ts
  setPrerenderer((defaultPrerenderer, { outputDirectories }) => {
    const { client, server, prerender } = outputDirectories

    return createPrerenderer({
      defaultPrerenderer,
      client,
      server,
      prerender,
    })
  })
  ```

- [#&#8203;18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Lets custom prerenderers report the images used on prerendered pages

  Astro now generates images on prerendered pages from the image information that a prerenderer's `getStaticPaths()` and `render()` return. If your prerenderer wraps Astro's default one, pass this information through:

  ```js
  setPrerenderer((defaultPrerenderer) => ({
    name: 'my-prerenderer',
    async setup() {
      await defaultPrerenderer.setup?.();
    },
    async getStaticPaths() {
      const result = await defaultPrerenderer.getStaticPaths();
      const { paths, metadata } = Array.isArray(result) ? { paths: result } : result;
      return { paths: paths.filter(({ pathname }) => !pathname.startsWith('/drafts')), metadata };
    },
    render(request, options) {
      return defaultPrerenderer.render(request, options);
    },
    async teardown() {
      await defaultPrerenderer.teardown?.();
    },
  }));
  ```

  Returning a plain array from `getStaticPaths()` or a plain `Response` from `render()` still works, but is deprecated: images used on those pages are not generated.

- [#&#8203;17932](https://github.com/withastro/astro/pull/17932) [`b905ff1`](https://github.com/withastro/astro/commit/b905ff1a8649b7a9a9056d9b05ca25ae7b3c07a1) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Adds support for experimental parallel prerendering

  This experimental feature makes `astro build` render your static pages in parallel, using multiple CPU cores at once instead of one. On sites with many pages, this can significantly reduce build times, at the cost of higher memory usage.

  To enable this feature, add the experimental flag in your Astro config:

  ```js
  // astro.config.mjs
  import { defineConfig } from 'astro/config';

  export default defineConfig({
    experimental: {
      parallelPrerender: true,
    },
  });
  ```

  By default, Astro uses all available CPU cores but one. Each additional worker increases the memory used by your build. If your build runs out of memory, or does not get faster, set `workers` to a lower number:

  ```js
  // astro.config.mjs
  import { defineConfig } from 'astro/config';

  export default defineConfig({
    experimental: {
      parallelPrerender: {
        workers: 4,
      },
    },
  });
  ```

  Each worker renders as many pages at once as your [`build.concurrency`](https://docs.astro.build/en/reference/configuration-reference/#buildconcurrency) setting allows.

  This feature has no effect when your adapter provides its own way of prerendering pages. Among official adapters, this only applies to `@astrojs/cloudflare`. Astro logs a warning during the build when the flag is ignored.

  For more information on enabling and using this feature in your project, see the [experimental parallel prerendering docs](https://docs.astro.build/en/reference/experimental-flags/parallel-prerender/).

##### Patch Changes

- [#&#8203;18313](https://github.com/withastro/astro/pull/18313) [`71e2b24`](https://github.com/withastro/astro/commit/71e2b24bb365e5a8809fc0432716f91ecc6d8ab5) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes deployment integrations being unable to use Vite manifests when preparing build output

- [#&#8203;18270](https://github.com/withastro/astro/pull/18270) [`0c3bf11`](https://github.com/withastro/astro/commit/0c3bf116ee70aae4772313fc167a372c7d54869e) Thanks [@&#8203;ArmandPhilippot](https://github.com/ArmandPhilippot)! - Fixes the JSDoc for CSP utilities to point to the render context reference in docs.

- [#&#8203;18368](https://github.com/withastro/astro/pull/18368) [`1f04637`](https://github.com/withastro/astro/commit/1f04637a6ca23b59e8982424248ead47d6a3ec31) Thanks [@&#8203;43081j](https://github.com/43081j)! - Replaces internal use of `find-proc` with `tinyps`.

- [#&#8203;18355](https://github.com/withastro/astro/pull/18355) [`59b9cc0`](https://github.com/withastro/astro/commit/59b9cc00726495bb45f5c4b000dbbb7b5a19d662) Thanks [@&#8203;matthewp](https://github.com/matthewp)! - Fixes prerender errors being silently swallowed when using a custom `src/fetch.ts` with an adapter that prerenders in its own runtime, such as `@astrojs/cloudflare`. Previously, a page that threw during prerendering was written as an empty HTML file and the build succeeded. The build now fails with the underlying error.

- [#&#8203;18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixes original images being kept despite only `width` or `height` being read.

- [#&#8203;18353](https://github.com/withastro/astro/pull/18353) [`af54bfa`](https://github.com/withastro/astro/commit/af54bfaebff9180cb96822c0da11737b4b26e65a) Thanks [@&#8203;astro-factory](https://github.com/apps/astro-factory)! - Fixes `glob()` loader swallowing rendering errors during content sync, which allowed `astro build` to exit successfully (code 0) even when a remark/rehype plugin threw an error

- [#&#8203;18271](https://github.com/withastro/astro/pull/18271) [`23e8e28`](https://github.com/withastro/astro/commit/23e8e28c22effe006fe19abb193802e2fec8eaab) Thanks [@&#8203;ArmandPhilippot](https://github.com/ArmandPhilippot)! - Fixes the `sync` command description in `astro help`, which only mentioned content collections.

- Updated dependencies \[[`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8), [`2715958`](https://github.com/withastro/astro/commit/2715958666b0a706b069d0592da3a070b3796a9b)]:
  - [@&#8203;astrojs/internal-helpers](https://github.com/astrojs/internal-helpers)@0.13.0
  - [@&#8203;astrojs/markdown-satteri](https://github.com/astrojs/markdown-satteri)@0.4.4
  - [@&#8203;astrojs/telemetry](https://github.com/astrojs/telemetry)@3.4.0

</details>

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

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

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.14.0...v12.15.0)

This release lets `pnpm-workspace.yaml` delegate settings to other files and config dependencies with `include`, adds `lockfile.integrityTarget: tar` and tar-registry support, accepts zstd-compressed registry responses, and honors `SOURCE_DATE_EPOCH` in `pnpm deploy` and `pnpm install`. It also rejects registry metadata that names a different package than the one requested and speeds up workspace installs and macOS file linking.

##### Minor Changes

- `pnpm-workspace.yaml` can now delegate settings to other YAML files and to config dependencies through a new `include` field. Each source may define only the settings the root manifest delegates to it. Every setting has one owner. Commands that change settings write each one to the file that owns it. A relative path in an included file is relative to that file. See [Splitting Settings Across Files](https://pnpm.io/config-includes).

  A config dependency supplies its settings through the YAML file named in the `pnpm.config` field of its `package.json`. The new `bootConfig` setting sets the release-age and trust policy pnpm uses to install config dependencies and the pnpm version from `packageManager`.

- Added the `lockfile.integrityTarget` setting. With `integrityTarget: tar`, `pnpm-lock.yaml` pins the hash of every package's uncompressed tar, so the lockfile no longer changes when a registry recompresses its tarballs or serves them as tars. pnpm learns a version's tar hash from the store or by downloading it once. `pnpm audit signatures` ties the tar hash to the signed `.tgz` integrity.

  ```yaml title="pnpm-workspace.yaml"
  lockfile:
    integrityTarget: tar
  ```

- pnpm can now install from a registry that serves uncompressed tars with zstd or gzip content coding. `pnpm-lock.yaml` records the hash of each tar. Declare such a registry with `serverType: pnpr` in `registries` to keep tarball URLs out of the lockfile. See [Tar registries](https://pnpm.io/registries#tar-registries).

  pnpm now decodes the content coding of tarball downloads itself. It rejects a zstd response whose window is larger than 8 MiB.

  Added the `maxTarballUnpackedSize` setting. It caps the bytes the files of one package may unpack to, 4 GiB by default.

- Registry revisions now always pin the hash of the uncompressed tar, the original included. pnpm records an original selected through the revision protocol, for example with a `+r0` specifier, as `revision: 0` in the lockfile and fetches it from the registry's digest route. pnpm checks a revision's tar whether the registry sends it as a tar, gzip, or zstd. Revision metadata must list revision 0 and mark the selected revision. pnpm rejects incomplete revision metadata with `ERR_PNPM_MALFORMED_METADATA`.

- pnpm now accepts zstd-compressed responses. Registries that serve zstd send package metadata in fewer bytes than with gzip, most of all the full metadata that settings such as `minimumReleaseAge` and `trustPolicy` read.

- `pnpm deploy` and `pnpm install` now use the `SOURCE_DATE_EPOCH` environment variable as an upper bound for timestamps in `node_modules/.modules.yaml` and `node_modules/.pnpm-workspace-state-v1.json`. With an equivalently prepared deploy target and an epoch no later than the timestamps that would otherwise be recorded, deploying the same project twice produces identical files [#&#8203;17171](https://github.com/pnpm/pnpm/issues/17171).

- `pnpm update --interactive` now highlights the row under the cursor in cyan while keeping the colors of its version changes.

##### Patch Changes

##### Security

- pnpm now fails with `ERR_PNPM_REGISTRY_NAME_MISMATCH` if a registry returns metadata for a package other than the one requested. Before, pnpm installed the package under the name in the metadata, so `allowBuilds` rules for the requested package did not apply to it.

- `minimumReleaseAgeExcludePrune` and `trustPolicyExcludePrune` now keep exclusions for resolved configuration dependencies and their transitive dependencies [#&#8203;17142](https://github.com/pnpm/pnpm/issues/17142).

##### Resolving dependencies

- When `pnpm install` resolves a dependency again, it now reuses a version that the install already resolved for the same package, as a fresh install does. Before, it kept the version the lockfile pinned and added a second copy of the package. A locked version still stays when nothing else in the install prefers another version. To pin a transitive dependency on purpose, use `overrides` [#&#8203;17084](https://github.com/pnpm/pnpm/issues/17084).

- When another workspace project adds a different version of a package, a project's auto-installed peer on that package now moves to the version a fresh install picks. It used to stay on its locked version while any other project still accepted that version [#&#8203;17058](https://github.com/pnpm/pnpm/issues/17058).

- A package that lists the same dependency in `dependencies` and as an optional peer now gets the peer bound when a project adds a provider for it later. The lockfile now records every peer a package declares, including one its own dependency supplies [#&#8203;17056](https://github.com/pnpm/pnpm/issues/17056).

- `pnpm install --prod` and `pnpm deploy --prod` no longer drop a dependency that a package declares both as an optional peer and as its own dependency, when the package resolved it as its own dependency and a dev dependency provides the same package under another alias.

- `pnpm install` with an existing lockfile and a second `pnpm dedupe` now keep optional peer bindings that point into a dependency cycle or back into the dependent package. Before, the second run dropped the optional peer binding from the lockfile snapshot key.

- `pnpm install` and `pnpm dedupe` now preserve own-dependency and peer-dependency bindings when reusing a lockfile whose peer suffixes were hashed by `peersSuffixMaxLength`.

  Upgrading a direct dependency in one workspace project now refreshes matching transitive pins in sibling projects during the same `pnpm install` pass.

- With `resolvePeersFromWorkspaceRoot: false`, a workspace project no longer binds a peer to a version that only another project's dependencies provide. pnpm now auto-installs a version that satisfies the peer range for that project. Before, the project got a version outside the range, with no peer warning.

- `pnpm install`, `pnpm add`, and `pnpm update` now reuse the lockfile's resolution for dependencies that take part in a dependency cycle, such as `mlly` and `pkg-types`. They re-resolved those packages and everything that depends on them from the registry before [pnpm/tasks#130](https://github.com/pnpm/tasks/issues/130).

- pnpm now measures a `pnpm.overrides` entry written as a `workspace:` path, such as `workspace:./packages/foo`, from the directory holding `pnpm-workspace.yaml`. It used to be measured from each package the override rewrote. The install then linked a directory that does not exist, or failed if workspace packages were injected [#&#8203;17010](https://github.com/pnpm/pnpm/issues/17010).

- `pnpm install` now removes config dependencies that are no longer declared, including when the entire `configDependencies` setting is removed. Frozen installs reject a lockfile that still records removed config dependencies.

- `pnpm install --update-checksums` now re-resolves every locked package and records the integrity the registry reports now.

- `pnpm add` and `pnpm install` now accept `gist:<id>` dependencies and GitHub Gist URLs, and install them from the gist's archive. `pnpm pkg fix` normalizes a `gist:` repository the way `npm pkg fix` does, `pnpm licenses` links a gist package to its gist page, and `pnpm sbom` reports the repository of a package whose `repository` field is a `gist:` shorthand.

- `pnpm add` now reads the package name correctly from a tarball URL under a registry URL that has a path, such as `https://example.com/npm/`, and installs a registry tarball URL with a malformed percent escape as a plain tarball URL. Before, the registry path became part of the name, so a scoped package failed with `ERR_PNPM_INVALID_PACKAGE_NAME`.

- With `minimumReleaseAge` set, pnpm now revalidates a package's cached full metadata with a single ETag request so an unchanged registry answers with `304`, even when the registry does not list a publish time for every version. Previously, pnpm downloaded that metadata again whenever the cached copy was older than `minimumReleaseAge`. With `resolutionMode` set to `lowest-direct` or `time-based`, pnpm also reuses that metadata across every workspace project that depends on the package.

- When pnpm revalidates cached registry metadata, it now sends `If-Modified-Since` when the registry's modification time is a date without a time, and no longer crashes when the modification time is before 1970.

- Added protocol versioning between the pnpm client and pnpr server, verified applied resolution policies in resolution responses, and preserved structured error codes across the wire.

##### Performance

- Sped up `pnpm install` on macOS. On a 12-core Mac, installing 1352 packages from a warm store took 1.3 seconds, down from 2.2. pnpm now writes package files into `node_modules` with 4 threads on macOS, whatever the number of CPU cores. Set the `PNPM_MACOS_LINK_THREADS` environment variable to use a different number of threads, or to `0` to write files with the threads pnpm uses for the rest of the install.

- `pnpm install` is faster and uses less memory in large workspaces with `sharedWorkspaceLockfile: false`. Each project's install no longer reads the manifests of every other workspace project again. Installs that wait for their workspace dependencies now count toward `workspaceConcurrency` [#&#8203;16966](https://github.com/pnpm/pnpm/issues/16966).

- Sped up workspace project discovery, dependency resolution, lockfile up-to-date checks, and peer dependency checks in large workspaces [#&#8203;16839](https://github.com/pnpm/pnpm/issues/16839) [pnpm/tasks#9](https://github.com/pnpm/tasks/issues/9). On a workspace with 6,833 projects, the lockfile up-to-date check uses about 1 second less CPU time. The peer dependency check at the end of an install now checks linked workspace projects against the manifests already in memory, without reading each `package.json` again.

- Sped up bin linking and build planning during `pnpm install`. Package binary targets and shebang runtimes are now precalculated during tarball extraction and served in `pnpr` registry metadata alongside verified `requiresBuild`, tarball size, and file-count metadata.

- Lowered peak memory when pnpm downloads many packuments, such as during lockfile verification with `trustPolicy` on Linux. In one 1,800-entry workspace, a lockfile update now peaks at 1.8 to 2.0 GB. It peaked at 2.6 to 3.7 GB before [#&#8203;17020](https://github.com/pnpm/pnpm/issues/17020).

- `pnpm install` in a Cargo workspace skips crates that an earlier install already unpacked into the store. Before, a repeat install processed every crate in `Cargo.lock` again. `pnpm install --force` unpacks every crate again [pnpm/tasks#69](https://github.com/pnpm/tasks/issues/69).

##### Linking node_modules and workspaces

- Concurrent installs that import the same package into one project now all complete. One of them used to fail with `ENOTEMPTY` when its copy of the package collided with the copy another install had already placed [pnpm/tasks#48](https://github.com/pnpm/tasks/issues/48).

- `pnpm install` now succeeds when `node_modules` is a symlink to an existing directory. Dependency hoisting previously rejected a symlinked `node_modules` as an invalid destination [#&#8203;17157](https://github.com/pnpm/pnpm/issues/17157).

- A filtered first install under the isolated linker now links every workspace project by name into `node_modules/.pnpm/node_modules`, not only the selected ones [pnpm/tasks#155](https://github.com/pnpm/tasks/issues/155).

- With `nodeLinker: hoisted`, a filtered install such as `pnpm --filter app add <pkg>` keeps the root `node_modules` links and bins of the workspace projects it did not select. A project with no dependencies of its own lost them until the next full install.

- `pnpm install --filter` with `nodeLinker: hoisted` and `--prod` or `--dev` now preserves previously installed dependency groups for unselected workspace projects [pnpm/tasks#164](https://github.com/pnpm/tasks/issues/164). Repeat filtered installs also re-resolve when a transitive injected workspace dependency or a linked dependency's version changes.

- With `sharedWorkspaceLockfile: false`, `pnpm install` now runs the workspace root's pnpmfile for every project, after the project's own pnpmfile. Before, it ran only the pnpmfile in the project's directory.

- `pnpm install` and `pnpm peers check` now detect peer dependency issues and report linked package versions in linked projects that use `package.json5` or `package.yaml` [pnpm/tasks#172](https://github.com/pnpm/tasks/issues/172).

- `pnpm install` and `pnpm peers check` no longer report an unmet peer when a workspace package's peer is provided by a remote tarball URL. pnpm now compares the peer range with the version in the tarball's manifest [#&#8203;17037](https://github.com/pnpm/pnpm/issues/17037).

- `pnpm prune` now removes extraneous direct packages from `node_modules` when `package.json` and `pnpm-lock.yaml` are already in sync. `pnpm prune` also honors `--filter`, `--recursive`, `sharedWorkspaceLockfile: false`, and the `trustLockfile` setting and `--trust-lockfile` flag. With the lockfile trusted, `pnpm prune --prod` works offline when every package is in the store [#&#8203;16999](https://github.com/pnpm/pnpm/issues/16999).

##### Injected workspace packages

- `pnpm install --frozen-lockfile` now fails with `ERR_PNPM_OUTDATED_LOCKFILE` when a local directory dependency or injected workspace package changes a dependency to a different tarball URL or git commit [#&#8203;17129](https://github.com/pnpm/pnpm/issues/17129). It also fails when an injected workspace package changes a dependency's named-registry range, such as `work:^2.0.0`, to one the locked version no longer satisfies.

- `pnpm install --frozen-lockfile` now accepts the lockfile it wrote for a `file:` dependency on a directory without a `package.json`. It also accepts the lockfile for an injected workspace package that bundles a dependency in `bundledDependencies`, lists a dependency in both `dependencies` and `optionalDependencies`, or publishes from a `publishConfig.directory` whose `package.json` lists other dependencies than the project's own. Before, these failed with `ERR_PNPM_OUTDATED_LOCKFILE`.

- The lockfile now records a `catalog:` peer dependency of an injected workspace package as written in its `package.json`. It recorded the catalog's range before, so editing the catalog changed the consumer's lockfile entry [pnpm/tasks#153](https://github.com/pnpm/tasks/issues/153).

- `pnpm install` now resolves a git, tarball, or tag dependency of an injected workspace package again when its spec changes. Before, it kept the old version.

- Repeat installs and `verifyDepsBeforeRun` now re-check projects that inject a modified workspace package, including when `sharedWorkspaceLockfile` is `false` [#&#8203;17007](https://github.com/pnpm/pnpm/issues/17007), and accept aliased `workspace:` ranges on linked dependencies.

- An injected workspace package that was linked now becomes a copy when the project that depends on it starts providing one of its peers at a version the package's own workspace context lacks. The link used to stay until that dependency was updated, so the package could not find the peer the project provides [#&#8203;17057](https://github.com/pnpm/pnpm/issues/17057).

- An injected workspace package now keeps only the files its manifest lists after a lifecycle script or a script named in `syncInjectedDepsAfterScripts` rebuilds it. Before, these refreshes copied every file of the package directory into the injected copy, including files that `files` or `.npmignore` leave out. With `deployAllFiles: true` the copy still gets every file.

- A script listed in `syncInjectedDepsAfterScripts` now keeps a package's links to its own files as links in the injected copies, the way `pnpm install` writes them, and updates those copies when `sharedWorkspaceLockfile` is `false`. Before, a directory link the script added became a real directory or went missing with `deployAllFiles`, and with `sharedWorkspaceLockfile: false` the copies kept the files from the last install.

##### Running scripts and checking dependencies

- Pressing Ctrl+C during `pnpm -r run` or `pnpm --filter <pkg> run` no longer reports `ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL`. pnpm now ends with the interrupted script's status, such as 130 for a script that SIGINT ended on Linux or macOS [#&#8203;16964](https://github.com/pnpm/pnpm/issues/16964).

- With `enableGlobalVirtualStore`, a Node.js resolve hook that a script registers now sees the importer as `context.parentURL` after pnpm's `NODE_PATH` fallback fails to find a bare specifier. Hooks that resolve tsconfig `paths` aliases from the importer failed with `ERR_MODULE_NOT_FOUND` [#&#8203;16979](https://github.com/pnpm/pnpm/issues/16979).

- `pnpm run`, `pnpm exec`, and `pnpm restart` now pass the install flags they were given, such as `--lockfile-dir`, `--modules-dir`, `--store-dir`, `--offline`, and `--ignore-scripts`, to the `pnpm install` that `verifyDepsBeforeRun: install` starts. When that install leaves the dependencies out of date, pnpm now prints a warning.

- A repeated `pnpm install --filter` now finishes without reinstalling when the selected projects are up to date, and so does `pnpm install` once filtered commands have installed every project. After a filtered install, `pnpm run` and `pnpm exec` now install a selected project whose dependencies changed in between [#&#8203;17011](https://github.com/pnpm/pnpm/issues/17011), require the workspace root when a filtered install with `pruneDirectDependencies: true` skipped it [pnpm/tasks#181](https://github.com/pnpm/tasks/issues/181), and preserve the recorded ignored build scripts of unselected projects.

- The check that runs before a script now holds the workspace projects that the selected project depends on, including with `sharedWorkspaceLockfile: false` and for workspace dependencies declared with `link:`. `--filter=<project>...` now selects `link:` dependencies as well. In a workspace that has no `package.json` at its root, `pnpm run` and `pnpm exec` no longer reinstall before every command when the dependencies are up to date.

- `verifyDepsBeforeRun` and repeat `pnpm install` runs now apply `overrides` before comparing a modified `package.json` with `pnpm-lock.yaml` [#&#8203;17127](https://github.com/pnpm/pnpm/issues/17127). `pnpm install` with `optimisticRepeatInstall` now re-runs when `configDependencies` changed, `verifyDepsBeforeRun` reports `node_modules` out of date when `useGitBranchLockfile` is enabled and the branch lockfile is missing, and in a single-project repository both checks record a successful lockfile check so later runs skip it until the lockfile changes [#&#8203;16993](https://github.com/pnpm/pnpm/issues/16993).

- `pnpm install` and `verifyDepsBeforeRun` now compare manifests, lockfiles, and patch files by content hash. They notice an edit that kept the file's modification time, as `cp -p`, `rsync -a`, or an archive extraction leave it, and a patch file that was copied or touched without changing its content no longer marks dependencies as outdated [#&#8203;16988](https://github.com/pnpm/pnpm/issues/16988).

##### Deploying, packing, and other commands

- `pnpm deploy` now deploys `file:` dependencies that live outside the workspace directory. It failed with "Refusing to deploy unsafe lockfile path" [#&#8203;16983](https://github.com/pnpm/pnpm/issues/16983).

- `pnpm deploy` now records the peer dependencies of the workspace packages it copies into the deployed lockfile. Before, pnpm rejected that lockfile with `--frozen-lockfile` when a deployed workspace package declared a peer and `injectWorkspacePackages` was off [#&#8203;17093](https://github.com/pnpm/pnpm/issues/17093).

- `pnpm install --frozen-lockfile` and `verifyDepsBeforeRun` now succeed inside a directory created by `pnpm deploy`. `pnpm deploy` writes self-contained workspace and lockfile settings, prunes unused `patchedDependencies`, and preserves workspace-level dependency resolutions on deployed directory dependencies.

- On macOS, `pnpm deploy` no longer writes a second, unused copy of every package to `node_modules/.pnpm/@` in the deploy directory [#&#8203;17116](https://github.com/pnpm/pnpm/issues/17116).

- `pnpm patch-commit` and `pnpm install` now apply a patch that renames or moves a file of the patched package. Such a patch failed with "rename/copy operations in patches are not yet supported".

- In workspaces with `sharedWorkspaceLockfile: false`, `pnpm patch`, `pnpm patch-commit`, and `pnpm patch-remove` now resolve patch files and `patchedDependencies` entries at the workspace root. `pnpm install` checks configured patches across all workspace projects before reporting unused patches.

- `pnpm pack` and `pnpm publish` no longer include editor swap files such as `.*.swp`, macOS `._*` files, `.lock-wscript`, `.wafpickle-*`, `build/config.gypi`, or `archived-packages/` in the tarball. Naming one of these files in `files` still includes it [#&#8203;16955](https://github.com/pnpm/pnpm/issues/16955).

- `pnpm pack` and `pnpm publish` now support extended glob patterns and brace ranges such as `part{1..3}.js` and `part{a..c}.js`, including descending ranges, steps, and zero padding, in `files`, `.npmignore`, and `.gitignore`. Explicitly listed internal directory symlinks are preserved below excluded directories, entry points honor nested ignore files, ignore negations can re-include default-excluded logs and backup files, and nested lockfiles follow the package's file selection rules.

- Trusted publishing with OIDC now works with registries whose URL has a path, such as `https://registry.example/npm/private/`. pnpm previously sent the token exchange request to the root of the registry host.

- `pnpm deprecate` and `pnpm unpublish` now work for packages whose registry metadata is larger than 10 MiB, such as `typescript`. They accept up to 50 MiB, the same limit as `pnpm owner`.

- `pnpm owner ls` now lists the owners of a package on the npm registry. It reported every package as not found.

- `pnpm licenses list --prod` now includes optional dependencies, including transitive ones. Pass `--no-optional` to leave them out. `pnpm licenses list` also reports no licenses for workspace projects not recorded in the lockfile, errors when `pnpm-lock.yaml` is missing, and formats empty results as the requested text or JSON [pnpm/tasks#174](https://github.com/pnpm/tasks/issues/174).

- `pnpm why` now reads each selected workspace project's lockfile and modules directory when `sharedWorkspaceLockfile` is `false` [pnpm/tasks#169](https://github.com/pnpm/tasks/issues/169).

- `pnpm pkg fix` now converts a `repository` string such as `github:pnpm/example` to the object form, as `npm pkg fix` does. It also normalizes a GitHub, GitLab, or Bitbucket repository URL the way `npm pkg fix` does [#&#8203;16980](https://github.com/pnpm/pnpm/issues/16980).

##### Configuration and setting up pnpm

- Registry credentials and TLS settings passed with `--config`, such as `--config.//registry.example.com/:_authToken=<token>`, are now applied. They take precedence over the same settings in `.npmrc` files.

- pnpm now reads only the settings it needs to decide whether to switch to the pnpm version a project pins. A setting outside them can no longer fail that decision or change its outcome. For example, `pnpm --version` no longer fails in a pinned project whose `pnpm-workspace.yaml` has a setting this pnpm cannot read. Projects that pin neither pnpm nor a runtime skip this check without reading any settings.

- When pnpm switches to the version a project pins, an option only the pinned pnpm knows now reaches that pnpm when it comes immediately before the command name, as in `pnpm --new-flag install`. When switching for `pnpm --version` or an unrecognized command line, pnpm also honors `--color`, `--no-color`, `--reporter`, and `--loglevel` wherever they appear on the command line.

- `pnpm self-update` now updates the project's pnpm pin when Homebrew installed pnpm or Corepack runs it, leaving the global pnpm alone [#&#8203;17001](https://github.com/pnpm/pnpm/issues/17001). Run inside a workspace package, `pnpm self-update` updates the pin in the workspace root's manifest, including in `package.yaml` or `package.json5`.

- `pnpm setup` now completes when Windows registry environment values cannot be read or written. It prints PowerShell commands to configure `PNPM_HOME` and `PATH` without registry access [#&#8203;17167](https://github.com/pnpm/pnpm/issues/17167).

- `pnpm setup` now succeeds when it cannot tell which shell configuration file to update, for example in a container where `SHELL` is not set. It installs pnpm and prints the `PNPM_HOME` and `PATH` lines to add yourself. Previously it failed with `ERR_PNPM_UNKNOWN_SHELL`, and so did the installer script at get.pnpm.io [#&#8203;16973](https://github.com/pnpm/pnpm/issues/16973).

- In StackBlitz WebContainers, `pnpm` no longer crashes intermittently with `Parking not supported on this platform`, and running a command that does not exist now reports that the command was not found. Previously it sometimes failed with a generic error.

<!-- 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.14.0`](https://github.com/pnpm/pnpm/releases/tag/v12.14.0): pnpm 12.14.0

[Compare Source](https://github.com/pnpm/pnpm/compare/v12.13.0...v12.14.0)

This release adds the `sideEffectsCache.exclude` setting, stops `pnpm install` from waiting on the daily update check, and keeps pnpm from aborting with a core dump when the reader of its output exits.

##### Minor Changes

- Added the `sideEffectsCache.exclude` setting for packages whose build depends on something pnpm cannot include in the cache key, such as the system libraries a native addon links against. pnpm builds the listed packages in every project and never restores or saves their builds through the side-effects cache, locally or on a `remoteCache` server. Under the global virtual store, each project gets its own copy of these packages and of the packages that depend on them. Entries use the same `name`, `@scope/*`, and `name@version` patterns as `minimumReleaseAgeExclude` [#&#8203;5271](https://github.com/pnpm/pnpm/issues/5271).

- `pnpm login` now prints the `npm-notice` response header during web-based login. Registries use it to show the verification code that completes the sign-in in the browser.

##### Patch Changes

##### Installing packages

- `pnpm install` and `pnpm add` no longer wait for the daily update check. If the command finishes first, pnpm skips the update notice and checks again next time. On a registry that accepted the connection but never answered, an install that had nothing to do used to take minutes [#&#8203;16839](https://github.com/pnpm/pnpm/issues/16839).

- `pnpm install`, `pnpm add` and `pnpm update` now reuse `pnpm-lock.yaml` when the workspace configures a catalog entry that no dependency references, such as an unused entry or one whose package an `overrides` entry replaces. Before, every resolution in such a workspace resolved all dependencies again from the registry [#&#8203;16923](https://github.com/pnpm/pnpm/issues/16923).

- `pnpm install` now looks up a git dependency's branch or tag once per install, even when many workspace projects depend on it. With `linkWorkspacePackages` enabled, it used to run `git ls-remote` once per project [#&#8203;16899](https://github.com/pnpm/pnpm/issues/16899).

- A filtered install, such as `pnpm install --filter <pkg>`, now keeps the `pnpm-lock.yaml` entries of workspace projects that are missing from disk, as in a sparse checkout. Their importers, packages, and catalog entries stay even when the filter matches every project on disk [#&#8203;16931](https://github.com/pnpm/pnpm/issues/16931).

- pnpm now decides whether a dependency that a package also declares as an optional peer is linked as a dependency or as a peer from the shallowest path that reaches the package. When an existing lockfile records such a dependency as a regular dependency and a newly added dependency now provides the peer, pnpm records it as a peer, as a fresh install does. The lockfile entry of such a package can change on the next install [#&#8203;16901](https://github.com/pnpm/pnpm/issues/16901).

- An install that adds nothing to the store no longer changes the modification time of the store directory. CI caches that check modification times, such as GitLab's, no longer re-upload an unchanged store [#&#8203;16929](https://github.com/pnpm/pnpm/issues/16929).

##### Running commands and scripts

- pnpm no longer aborts with a core dump when the reader of its output has exited, as in `pnpm list | head -1` or `pnpm start 2>&1 | head -1`. The command finishes with its usual exit code, and a failing script's exit code is kept. A write to stdout that fails for another reason, such as a full disk, ends the command with exit code 1 [#&#8203;16904](https://github.com/pnpm/pnpm/issues/16904) [pnpm/tasks#132](https://github.com/pnpm/tasks/issues/132).

- On Windows, `pnpm exec`, `pnpm run`, and commands such as `pnpm nx` now return when the command they run exits, even if it left a detached process running and pnpm's output is redirected or piped. Previously a shell reading that output waited until the detached process, such as the Nx daemon, exited [#&#8203;16930](https://github.com/pnpm/pnpm/issues/16930).

- Commands that do not write the project manifest now leave a missing `package.json` absent. This covers queries such as `pnpm why` and `pnpm outdated`, `pnpm fetch`, `pnpm dedupe --check`, and commands that exit with an error, such as `pnpm rt ls`. These commands used to create one from the initialization template. `pnpm sbom` run from a lockfile alone now reports the root component as `unknown` with version `0.0.0` [#&#8203;16907](https://github.com/pnpm/pnpm/issues/16907).

- `pnpm run` now reports a failed script as a JSON record under `--reporter=ndjson`. It printed a plain `[ELIFECYCLE]` line to stderr.

- `pnpm run` no longer prints `[ELIFECYCLE] Command failed with exit code N.` to stderr when a script fails under `--reporter=silent`, `--silent`, or `--loglevel=silent`.

- `pnpm pipeline --dry-run` no longer writes a run report when no projects are selected. With `--json` it prints `{"tasks": []}` [pnpm/tasks#126](https://github.com/pnpm/tasks/issues/126).

##### Packing and publishing

- `pnpm pack` and `pnpm publish` now ship the whole gitignored directory that `main`, `browser`, or `bin` points into, as npm does. Previously only the `main` and `bin` files themselves were packed, and a gitignored `browser` file was left out [#&#8203;16908](https://github.com/pnpm/pnpm/issues/16908).

- `pnpm pack` and `pnpm publish` now honor a `.npmignore` or `.gitignore` inside a subdirectory when `package.json` has a `files` field. The package root's ignore files and those inherited from the workspace are still skipped [#&#8203;16909](https://github.com/pnpm/pnpm/issues/16909).

##### Setting up pnpm and toolchains

- `--registry`, `--https-proxy`, `--http-proxy`, and `--no-proxy` now apply when pnpm resolves and downloads the pnpm version a project pins in `packageManager`. Before, these lookups went to `https://registry.npmjs.org/`, which a firewall that only allows a private registry blocks [#&#8203;16911](https://github.com/pnpm/pnpm/discussions/16911).

- On Windows, `pnpm install` now installs the Rust toolchain for rustup's default host, so a machine set up with `rustup set default-host x86_64-pc-windows-gnu` gets the MinGW toolchain. Without a default host, pnpm installs the MSVC toolchain for the machine's architecture, as rustup does. This includes a pnpm built for MinGW, such as the MSYS2 package, which has installed the MinGW toolchain since 12.13.0. An x64 pnpm on ARM64 Windows now installs the ARM64 toolchain [#&#8203;16854](https://github.com/pnpm/pnpm/issues/16854).

<!-- 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>

---

### 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 CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTEuMiIsInVwZGF0ZWRJblZlciI6IjQ0LjE4MS43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

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

---------

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/611
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
2026-10-26 22:30:15 +00:00
Gitea Bot 4ea46e6315 Update the latest api documents (#612)
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-612.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/612
Co-authored-by: Gitea Bot <[email protected]>
2026-10-26 16:10:40 +00:00
silverwindandLunny Xiao cb424640a2 docs: document Forwarded header and client port for REVERSE_PROXY_LIMIT (#560)
Document https://github.com/go-gitea/gitea/pull/39190, which reads the RFC 7239 `Forwarded` header when `X-Forwarded-For` is absent and keeps the forwarded client port.

- `REVERSE_PROXY_LIMIT`: list `X-Real-IP`, `X-Forwarded-For` and `Forwarded` in the order they are read, and where the client port comes from, also in zh-cn and zh-tw
- Reverse proxies: require the proxy to set `X-Real-IP`, since Caddy, Apache and HAProxy pass a client-sent one through by default, and mention `X-Real-Port` for logging the client port

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/560
Reviewed-by: Lunny Xiao <[email protected]>
2026-10-23 22:44:51 +00:00
bircniandsilverwind 09bb4cabcf Add documentation for gt, the Gitea CLI (#603)
Adds a CLI product for gt (https://gitea.com/gitea/cli), set up like the runner, with short guides for installation, logging in, CI and scripting. Each command's details stay in gt <command> --help. Until the first release, the docs are served at /cli/; make cut-version PRODUCT=cli VERSION=0.1 adds the release series.

Closes https://gitea.com/gitea/cli/issues/16

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

---------

Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/603
Reviewed-by: Lunny Xiao <[email protected]>
Reviewed-by: silverwind <[email protected]>
2026-10-23 12:16:49 +00:00
66 changed files with 5591 additions and 5330 deletions

No files matched your search

+2 -2
View File
@@ -8,7 +8,7 @@ on:
jobs:
build-docs:
runs-on: ubuntu-24.04
runs-on: ubuntu-26.04
env:
NODE_OPTIONS: --max-old-space-size=8192
# search only appears once the credentials are set, the build falls back
@@ -21,7 +21,7 @@ jobs:
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: 24
node-version: 26
cache: pnpm
- name: prepare awesome list
run: |
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: 24
node-version: 26
cache: pnpm
- name: prepare awesome list
run: |
+1 -1
View File
@@ -92,7 +92,7 @@ update-runner-docs:
update-runner-docs-released:
./update_runner_docs.sh --released
# freezes the current docs or runner tree as a new version, see
# freezes the current docs, runner or cli tree as a new version, see
# scripts/cut-version.mjs
.PHONY: cut-version
cut-version:
+13 -1
View File
@@ -3,13 +3,14 @@
The sources of [docs.gitea.com](https://docs.gitea.com), built with
[Astro](https://astro.build) and [Starlight](https://starlight.astro.build).
The site covers three products, all served from this repository:
The site covers four products, all served from this repository:
| Product | Content | Versions | Languages |
| --- | --- | --- | --- |
| Docs | `docs/`, `versioned_docs/`, `i18n/` | next, 28, 1.27 … 1.22 | English, 简体中文, 繁體中文 |
| API | `static/swagger-*.json`, `static/openapi3-*.json` | next, 28, 1.27 … 1.22 | English |
| Runner | `runner-docs/`, `runner-docs_versioned_docs/` | develop, 5 … 0 | English |
| CLI | `cli-docs/`, `cli-docs_versioned_docs/` | develop | English |
The enterprise documentation is built and deployed from its own repository and
reached through `/enterprise/`, which a Cloudflare worker maintained elsewhere
@@ -53,6 +54,7 @@ group from the `_category_.json` of its directory.
```shell
make cut-version PRODUCT=docs VERSION=1.28
make cut-version PRODUCT=runner VERSION=6
make cut-version PRODUCT=cli VERSION=0.1
```
This freezes the current tree, its translations and its sidebar. The label of
@@ -115,6 +117,16 @@ workflow runs weekly and opens a pull request whenever the runner's CLI or
example configuration changed. Generating them needs Go, since the script builds
the runner binary.
## CLI docs
The documentation of `gt`, the Gitea CLI from
[gitea/cli](https://gitea.com/gitea/cli), is laid out like the runner docs, with
its sidebar in `cli-sidebars.js`. No series is documented yet, so `cli-docs/` is
served at `/cli/`. Once a release exists, cut its series and list it in
`cliSeries` in `packages/content-loader/src/products.ts`, which moves the develop
docs to `/cli/develop/`. The guides leave the flags of each command to
`gt <command> --help`.
## Deployment
`main` is built and published by the `Build and Publish Docs site` workflow, to
+55
View File
@@ -0,0 +1,55 @@
---
sidebar_position: 3
---
# Logging in
On a terminal, `gt auth login` asks for the instance and how to log in. gt never asks for
your password.
## OAuth in a browser
```bash
gt auth login --host https://gitea.example.com --oauth
```
gt opens the instance's authorization page, so single sign-on and two-factor
authentication work as on the web. The browser has to run on the same machine as gt.
`--scopes` limits the token to fewer [scopes](/development/oauth2-provider#scopes); gt
refreshes OAuth tokens on its own.
## Access token
Create a token under **Settings > Applications** on the instance and pass it on stdin:
```bash
gt auth login --host https://gitea.example.com --with-token < token.txt
```
The token needs `read:user`, and the scopes of what you do with gt, such as
`write:repository` and `write:issue` for working on pull requests.
## SSH key
gt can sign its requests with an SSH key registered for your account instead of using a
token:
```bash
gt auth login --host https://gitea.example.com --ssh-key ~/.ssh/id_ed25519
```
## Accounts
Tokens go to the system keyring, or with `--credential-store file` to gt's configuration
directory on machines without one. Run `gt auth login` once per instance and account.
gt picks the instance from the repository's remote or `--host`, and the account with
`gt auth switch` or `--user`. `gt auth status` lists your accounts and `gt auth logout`
removes one.
For instances behind an access proxy, `--header` and `--client-cert` add headers and a
client certificate.
## Git over HTTPS
`gt auth setup-git` lets `git push` and `git fetch` over HTTPS use gt's login. gt's own
clone and checkout commands need no setup.
+40
View File
@@ -0,0 +1,40 @@
---
sidebar_position: 4
---
# Using gt in CI
Give gt a token and an instance through the environment, and turn prompts off:
| Variable | Description |
| --- | --- |
| `GITEA_TOKEN` | Access token; gt never stores it |
| `GITEA_CLI_HOST` or `GITEA_INSTANCE_URL` | URL of the instance |
| `GITEA_CLI_REPO` | Repository, like `--repo` |
`--no-input` makes a command fail instead of prompting, and `--yes` confirms changes in
advance.
## Gitea Actions
Gitea does not allow secret names that start with `GITEA_`, so store the token as, for
example, `GT_TOKEN`:
```yaml
on:
push:
branches: [main]
jobs:
staging:
runs-on: ubuntu-latest
env:
GITEA_TOKEN: ${{ secrets.GT_TOKEN }}
GITEA_CLI_HOST: ${{ gitea.server_url }}
GITEA_CLI_REPO: ${{ gitea.repository }}
steps:
- run: curl -fsSL https://gitea.com/gitea/cli/raw/branch/main/scripts/install.sh | sh
- run: gt workflow run deploy.yml --ref main --field env=staging --no-input
```
`gt run watch` and `gt pr checks --watch` wait for runs and checks and fail when one fails.
+38
View File
@@ -0,0 +1,38 @@
---
sidebar_position: 1
slug: /
---
# Gitea CLI
[gt](https://gitea.com/gitea/cli) is the official command line client for Gitea. It works
with repositories, issues, pull requests, releases, Actions and the other resources of a
Gitea instance, from a terminal or a script.
:::info Development version
These pages describe builds from the `main` branch, published as `nightly` binaries and images.
:::
gt needs Gitea 28 or later, and Git for the commands that clone, check out or push.
## Getting started
1. [Install gt](installation.md).
2. [Log in](authentication.md):
```bash
gt auth login
```
3. Run commands in a clone of a repository on that instance, or select one with `--repo`:
```bash
gt issue list --label bug
gt pr checkout 13
gt issue view 42 --repo gitea.com/gitea/cli
```
`gt doctor` checks your setup and suggests a fix for each problem it finds.
`gt <command> --help` lists the flags of a command, and `gt help environment` the global
flags and environment variables.
+37
View File
@@ -0,0 +1,37 @@
---
sidebar_position: 2
---
# Installation
gt is a single binary for Linux, macOS, Windows and FreeBSD.
## Install script
The install script downloads gt from [dl.gitea.com](https://dl.gitea.com/gitea-cli/),
verifies its checksum and installs it.
```bash
# Linux, macOS, FreeBSD
curl -fsSL https://gitea.com/gitea/cli/raw/branch/main/scripts/install.sh | sh
```
```powershell
# Windows
irm https://gitea.com/gitea/cli/raw/branch/main/scripts/install.ps1 | iex
```
Set `GITEA_CLI_VERSION` to install a specific version, or `nightly` for the latest build
of `main`.
## Other ways
- **Binaries:** download them from [dl.gitea.com/gitea-cli](https://dl.gitea.com/gitea-cli/).
- **Docker:** the [`gitea/gitea-cli`](https://hub.docker.com/r/gitea/gitea-cli) image runs
`gt` as its entry point.
- **Go:** `go install gitea.dev/cli/cmd/gt@latest`
## Shell completion and man pages
`gt completion <shell>` prints the completion script for bash, zsh, fish or PowerShell;
`gt completion <shell> --help` shows how to load it. `gt man` prints the manual.
+22
View File
@@ -0,0 +1,22 @@
---
sidebar_position: 5
---
# Output and scripting
Scripts should read JSON: the text output is meant for people and may change.
```bash
gt pr view 123 --json number,title,state
gt issue list --json number,title --jq '.[] | "\(.number)\t\(.title)"'
```
`--json` prints all fields or the ones you list; the **JSON FIELDS** section of a command's
`--help` names them. `--jq` filters the result without needing jq installed. Piped lists
print as tab-separated values.
gt exits with 0 on success, 1 when a command fails, 2 on a usage error and 4 when
authentication is missing or rejected; `gt help exit-codes` lists all codes.
`gt api` calls any API endpoint with gt's login, and `gt alias set` defines shortcuts for
commands you use often.
+1
View File
@@ -0,0 +1 @@
[]
+16
View File
@@ -0,0 +1,16 @@
// Sidebar of the gt (Gitea CLI) documentation (develop version).
// Released versions carry their own copy in
// cli-docs_versioned_sidebars/version-<version>-sidebars.json.
module.exports = {
cli: [
{
type: 'doc',
id: 'index',
label: 'What is gt?',
},
'installation',
'authentication',
'ci',
'scripting',
],
};
+4 -2
View File
@@ -1,11 +1,13 @@
# Redirects for legacy URLs and routes the site no longer serves directly.
# The api reference and the runner docs are separate products, published in
# english only, so they have no localized copy.
# The api reference, the runner and the cli docs are separate products,
# published in english only, so they have no localized copy.
/zh-cn/api/* /api/:splat 301
/zh-tw/api/* /api/:splat 301
/zh-cn/runner/* /runner/:splat 301
/zh-tw/runner/* /runner/:splat 301
/zh-cn/cli/* /cli/:splat 301
/zh-tw/cli/* /cli/:splat 301
# The version served at the root of a product is also reachable under its
# number, which is what the release notes and old links use.
+3 -1
View File
@@ -7,6 +7,7 @@
"https://docs.gitea.com/zh-cn/",
"https://docs.gitea.com/zh-tw/",
"https://docs.gitea.com/runner/",
"https://docs.gitea.com/cli/",
"https://docs.gitea.com/api/",
"https://docs.gitea.com/enterprise/"
],
@@ -15,7 +16,8 @@
"https://docs.gitea.com/1.2*/**",
"https://docs.gitea.com/*/1.2*/**",
"https://docs.gitea.com/api/1.2*/**",
"https://docs.gitea.com/runner/[0-9]/**"
"https://docs.gitea.com/runner/[0-9]/**",
"https://docs.gitea.com/cli/[0-9]*/**"
],
"selectors": {
"lvl0": { "selector": "//nav[contains(@aria-labelledby,'starlight__sidebar')]//a[@aria-current='page']/ancestor::details//summary//span", "type": "xpath", "global": true, "default_value": "Documentation" },
+6 -4
View File
@@ -179,7 +179,7 @@ In addition, there is _`StaticRootPath`_ which can be set as a built-in at build
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
- `RETARGET_CHILDREN_ON_MERGE`: **true**: Retarget child pull requests to the parent pull request branch target on merge of parent pull request. It only works on merged PRs where the head and base branch target the same repo.
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **false**: Set the default value for "Delete pull request branch after merge by default" for new repositories.
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **true**: Set the default value for "Delete pull request branch after merge by default" for new repositories.
- `DEFAULT_TITLE_SOURCE`: **auto**: Default source for the pull request title when opening a new PR. Valid options:
- `first-commit`: Uses the oldest commit's summary as the title. If there are multiple commits, still uses the first commit's message.
- `auto`: Uses the commit's summary when the PR contains a single commit; when there are multiple commits, converts the branch name into a human-readable title by normalizing separators and casing.
@@ -595,7 +595,8 @@ And the following unique queues:
authentication provided email.
- `REVERSE_PROXY_AUTHENTICATION_FULL_NAME`: **X-WEBAUTH-FULLNAME**: Header name for reverse proxy
authentication provided full name.
- `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request.
- `REVERSE_PROXY_LIMIT`: **1**: Interpret the X-Real-IP, X-Forwarded-For or Forwarded header, in that order, and set this as the remote IP for the request.
The client port is taken from the header value or, with X-Real-IP, from X-Real-Port.
Number of trusted proxy count. Set to zero to not use these headers.
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all.
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: Set the `X-Frame-Options` header value for all HTTP responses. Set to `unset` to not send the header. Previously located in `[cors]`.
@@ -1355,7 +1356,7 @@ These options are written into the gitconfig file under `[git] HOME_PATH` when G
- `JWT_SECRET_URI`: **_empty_**: Instead of defining JWT_SECRET in the configuration, this configuration option can be used to give Gitea a path to a file that contains the secret (example value: `file:/etc/gitea/oauth2_jwt_secret`)
- `JWT_SIGNING_PRIVATE_KEY_FILE`: **jwt/private.pem**: Private key file path used to sign OAuth2 tokens. The path is relative to `APP_DATA_PATH`. This setting is only needed if `JWT_SIGNING_ALGORITHM` is set to `RS256`, `RS384`, `RS512`, `ES256`, `ES384` or `ES512`. The file must contain a RSA or ECDSA private key in the PKCS8 format. If no key exists a 4096 bit key will be created for you.
- `MAX_TOKEN_LENGTH`: **32767**: Maximum length of token/cookie to accept from OAuth2 provider
- `DEFAULT_APPLICATIONS`: **git-credential-oauth, git-credential-manager, tea, gitea-app**: Pre-register OAuth applications for some services on startup. See the [OAuth2 documentation](/development/oauth2-provider.md) for the list of available options.
- `DEFAULT_APPLICATIONS`: **git-credential-oauth, git-credential-manager, gitea-cli, gitea-app, gitea-vscode**: Pre-register OAuth applications for some services on startup. See the [OAuth2 documentation](/development/oauth2-provider.md) for the list of available options. `tea` is accepted as an alias of `gitea-cli`.
- `CUSTOM_SCHEMES`: **_empty_**: By default, OAuth2 applications can only use "http" and "https" as their redirect URI schemes.
If you need to use other schemes (e.g. for desktop applications), you can specify them here as a comma-separated list.
For example: set "my-scheme, com.example.app" to support "my-scheme://..." and "com.example.app://..." redirect URIs.
@@ -1487,8 +1488,9 @@ These lists are enforced on direct connections only. When a proxy is configured
- `LIMIT_SIZE_RPM`: **-1**: Maximum size of a RPM upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_RUBYGEMS`: **-1**: Maximum size of a RubyGems upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_SWIFT`: **-1**: Maximum size of a Swift upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_TERRAFORM_MODULE`: **-1**: Maximum size of a Terraform module archive upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`). Archives are additionally capped at 32 MiB decompressed.
- `LIMIT_SIZE_TERRAFORM_STATE`: **-1**: Maximum size of a Terraform state upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_VAGRANT`: **-1**: Maximum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
- `LIMIT_SIZE_TERRAFORM_STATE``: **-1**: Maximum size of a Terraform state upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
## Mirror (`mirror`)
+1
View File
@@ -16,6 +16,7 @@ aliases:
4. Make sure `Host` and `X-Forwarded-Proto` headers are correctly passed to Gitea to make Gitea see the real URL being visited.
5. Make sure your webserver has a certificate, including all intermediate and RootCA certificates, for `git clone` and `git pull` to work.
6. Gitea uses a WebSocket connection at `/-/ws` for real-time updates like the notification counter. Make sure the reverse-proxy talks HTTP/1.1 and forwards the `Upgrade` and `Connection` headers, see the examples below. Without it, Gitea falls back to periodic polling.
7. Make sure the reverse-proxy sets the `X-Real-IP` header, otherwise Gitea uses a client-sent value. For example `header_up X-Real-IP {remote_host}` in Caddy's `reverse_proxy`, `RequestHeader set X-Real-IP "expr=%{REMOTE_ADDR}"` in Apache or `http-request set-header X-Real-IP %[src]` in HAProxy. To log the client port, also set `X-Real-Port`, for example `proxy_set_header X-Real-Port $remote_port;` in nginx.
### Use a sub-path
+1
View File
@@ -73,6 +73,7 @@ By default, this creates a token with very limited permissions. To complete your
- `activitypub`
- `admin`
- `commitstatus` (included in `repository`)
- `issue`
- `misc`
- `notification`
+6 -1
View File
@@ -111,6 +111,9 @@ Gitea token scopes are as follows:
| **admin** | `/admin/*` API routes: Site-wide administrative operations (hidden for non-admin accounts). |
| &nbsp;&nbsp;&nbsp; **read:admin** | Grants read access for admin operations, such as getting cron jobs or registered user emails. |
| &nbsp;&nbsp;&nbsp; **write:admin** | Grants read/write/delete access for admin operations, such as running cron jobs or updating user accounts. |
| **commitstatus** | `/repos/{owner}/{repo}/statuses/{sha}` and `/repos/{owner}/{repo}/commits/{ref}/status(es)` API routes: Commit status operations. |
| &nbsp;&nbsp;&nbsp; **read:commitstatus** | Grants read access to commit statuses. Included in `read:repository`. |
| &nbsp;&nbsp;&nbsp; **write:commitstatus** | Grants read/write access to commit statuses, such as reporting CI results. Included in `write:repository`. |
| **issue** | `issues/*`, `labels/*`, `milestones/*` API routes: Issue-related operations. |
| &nbsp;&nbsp;&nbsp; **read:issue** | Grants read access for issues operations, such as getting issue comments, issue attachments, and milestones. |
| &nbsp;&nbsp;&nbsp; **write:issue** | Grants read/write/delete access for issues operations, such as posting or editing an issue comment or attachment, and updating milestones. |
@@ -141,7 +144,9 @@ Gitea creates OAuth applications for the following services by default on startu
|-----------|-----------|---------|
|[git-credential-oauth](https://github.com/hickford/git-credential-oauth)|Git credential helper|`a4792ccc-144e-407e-86c9-5e7d8d9c3269`|
|[Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager)|Git credential helper|`e90ee53c-94e2-48ac-9358-a874fb9e0662`|
|[tea](https://gitea.com/gitea/tea)|tea|`d57cb8c4-630c-4168-8324-ec79935e18d4`|
|[Gitea CLI](https://gitea.com/gitea/cli)|Gitea CLI|`d57cb8c4-630c-4168-8324-ec79935e18d4`|
|Gitea App|Official Gitea mobile app|`b757811a-05c8-4c76-8d74-a5ee3d2073f2`|
|[gitea-vscode](https://gitea.com/gitea/gitea-vscode)|VS Code extension|`75a9ec3e-42b5-40cb-9144-9ea96ecd56a6`|
To prevent unexpected behavior, they are being displayed as locked in the UI and their creation can instead be controlled by the `DEFAULT_APPLICATIONS` parameter in `app.ini`.
+23 -1
View File
@@ -8,7 +8,7 @@ aliases:
# Database Preparation
You need a database to use Gitea. Gitea supports PostgreSQL (>= 12), MySQL (>= 8.0), MariaDB (>= 10.4), SQLite (builtin), and MSSQL (>= 2012 SP4). This page will guide into preparing database. Only PostgreSQL and MySQL will be covered here since those database engines are widely-used in production. If you plan to use SQLite, you can ignore this chapter.
You need a database to use Gitea. Gitea supports PostgreSQL (>= 12), MySQL (>= 8.0), MariaDB (>= 10.4), SQLite (builtin), and MSSQL (>= 2012 SP4). This page will guide into preparing database. PostgreSQL, MySQL and MSSQL are covered here. If you plan to use SQLite, you can ignore this chapter.
:::warning
Converting one database type to another is not a well-tested process and you may experience issues. It is better to choose the final database type at the type of the first installation. Be aware that SQLite does not scale; if you expect your instance to grow at a later time, you should choose another database type.
@@ -177,6 +177,28 @@ All steps below requires that the database engine of your choice is installed on
You should be prompted to enter password for the database user, and connected to the database.
## MSSQL
1. As an administrator, create the login, a database with case-sensitive collation, and its user. Replace the password `'gitea'` with a secure one:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
Upgrades change the database schema, so the user needs `db_owner`, or `db_ddladmin`, `db_datareader` and `db_datawriter`. With the latter, also run `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;` as administrator.
2. On your Gitea server, test the connection to the database:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## Database Connection over TLS
If the communication between Gitea and your database instance is performed through a private network, or if Gitea and the database are running on the same server, this section can be omitted since the security between Gitea and the database instance is not critically exposed. If instead the database instance is on a public network, use TLS to encrypt the connection to the database, as it is possible for third-parties to intercept the traffic data.
+2 -9
View File
@@ -19,14 +19,7 @@ Gitea Actions is designed to be compatible with GitHub Actions, with the differe
`uses:` accepts these prefixes:
- `self:` references your own Gitea instance, e.g. `uses: self:owner/repo@v1` or `uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:` runs an action built into Gitea Runner, which needs no download and no Node in the job image, e.g. `uses: builtin:checkout`
`builtin:checkout` accepts the `repository`, `ref`, `token`, `path` and `fetch-depth` inputs of `actions/checkout` with the same defaults, and fails on any other input.
### Workflow-relative actions
`$/` references the repository and commit of the workflow, or of the enclosing composite action, e.g. `uses: $/.gitea/actions/build`.
Unlike `./`, it needs no checkout first.
- `builtin:` runs an action built into Gitea Runner, which needs no download and does not depend on Node.js, e.g. `uses: builtin:checkout`
### Actions written in Go
@@ -92,7 +85,7 @@ See [Actions job token permissions](token-permissions.md).
Actions without a host, like `uses: actions/checkout@v4`, are downloaded from `https://github.com`, or from your own instance when `[actions].DEFAULT_ACTIONS_URL` is `self`.
See the [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions).
For other sources, see [Absolute action URLs](#absolute-action-urls), [Action prefixes](#action-prefixes) and [Workflow-relative actions](#workflow-relative-actions).
For other sources, see [Absolute action URLs](#absolute-action-urls) and [Action prefixes](#action-prefixes).
### Context availability
+72 -58
View File
@@ -9,53 +9,67 @@ sidebar_position: 25
## Environment variables
These environment variables are set automatically in every workflow run and can be accessed directly (e.g. `$CI` in shell scripts).
A `GITEA_*` name listed with a `GITHUB_*` name holds the same value.
| Name | Description | Example |
|---|---|---|
| `ACT` | Always set to `true`, unless the runner is configured with `runner.set_act_env: false`. | `true` |
| `CI` | Always set to `true`. | `true` |
| `GITEA_ACTIONS` | Always set to `true`. Useful to distinguish Gitea Actions from other CI systems. | `true` |
| `GITEA_ACTIONS_RUNNER_VERSION` | The version of the runner executing the workflow. | `1.0.8` |
| `GITEA_DOCKER_WORKSPACE` | The workspace path as the Docker daemon sees it, for bind mounts into containers a job starts, e.g. `${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data` in a compose file. Only set for jobs running in a container. | `/var/lib/docker/volumes/GITEA-ACTIONS-TASK-42_***/_data` |
| `GITEA_ENV`<br/>`GITHUB_ENV` | Path to the file that sets environment variables for subsequent steps. | `/home/runner/work/_temp/_runner_file_commands/set_env_***` |
| `GITEA_OUTPUT`<br/>`GITHUB_OUTPUT` | Path to the file that sets step output parameters. | `/home/runner/work/_temp/_runner_file_commands/set_output_***` |
| `GITEA_PATH`<br/>`GITHUB_PATH` | Path to the file that adds system `PATH` entries for subsequent steps. | `/home/runner/work/_temp/_runner_file_commands/add_path_***` |
| `GITEA_STATE`<br/>`GITHUB_STATE` | Path to the file that sets step state variables. | `/home/runner/work/_temp/_runner_file_commands/save_state_***` |
| `GITEA_STEP_SUMMARY`<br/>`GITHUB_STEP_SUMMARY` | Path to the file for writing job summaries. | `/home/runner/work/_temp/_runner_file_commands/step_summary_***` |
| `GITHUB_ACTIONS` | Always set to `true`. | `true` |
| `GITHUB_ACTION` | The name of the action currently running, or the step `id`. | `__run` |
| `GITHUB_ACTION_PATH` | The path where the action is located. | `/home/runner/work/_actions/actions/checkout/v4` |
| `GITHUB_ACTION_REF` | The ref of the action being executed. | `v4` |
| `GITHUB_ACTION_REPOSITORY` | The owner and repository of the action. | `actions/checkout` |
| `GITHUB_ACTOR` | The username of the user that triggered the workflow. | `silverwind` |
| `GITHUB_API_URL` | The URL of the REST API. | `https://gitea.com/api/v1` |
| `GITHUB_BASE_REF` | The target branch of a pull request. | `main` |
| `GITHUB_EVENT_NAME` | The name of the event that triggered the workflow. | `push` |
| `GITHUB_EVENT_PATH` | Path to the file containing the event webhook payload. | `/home/runner/work/_temp/_github_workflow/event.json` |
| `GITHUB_GRAPHQL_URL` | Empty in Gitea (GraphQL is not supported). | _(empty)_ |
| `GITHUB_HEAD_REF` | The source branch of a pull request. | `feature-branch` |
| `GITHUB_JOB` | The `job_id` of the current job. | `build` |
| `GITHUB_REF` | The fully-formed ref that triggered the workflow. | `refs/heads/main` |
| `GITHUB_REF_NAME` | The short ref name. | `main` |
| `GITHUB_REF_TYPE` | The type of ref: `branch` or `tag`. | `branch` |
| `GITHUB_REPOSITORY` | The owner and repository name. | `gitea/docs` |
| `GITHUB_REPOSITORY_OWNER` | The repository owner's username. | `gitea` |
| `GITHUB_RETENTION_DAYS` | The number of days that artifacts are kept, empty when kept forever. | `90` |
| `GITHUB_RUN_ATTEMPT` | The attempt number of the workflow run. | `1` |
| `GITHUB_RUN_ID` | A unique number for each workflow run. | `1234` |
| `GITHUB_RUN_NUMBER` | A unique number for each run of a particular workflow. | `42` |
| `GITHUB_SERVER_URL` | The URL of the Gitea instance. | `https://gitea.com` |
| `GITHUB_SHA` | The commit SHA that triggered the workflow. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITHUB_WORKFLOW` | The name of the workflow. | `CI` |
| `GITHUB_WORKSPACE` | The default working directory on the runner. | `/workspace/gitea/docs` |
| `GITEA_ACTION`<br/>`GITHUB_ACTION` | The `id` of the current step, or its index when it has none. | `0` |
| `GITEA_ACTION_PATH`<br/>`GITHUB_ACTION_PATH` | The path where the action is located. Only set in composite actions. | `/var/run/act/actions/***` |
| `GITEA_ACTION_REF`<br/>`GITHUB_ACTION_REF` | The ref of the action being executed. | `v4` |
| `GITEA_ACTION_REPOSITORY`<br/>`GITHUB_ACTION_REPOSITORY` | The owner and repository of the action. | `actions/checkout` |
| `GITEA_ACTIONS`<br/>`GITHUB_ACTIONS` | Always set to `true`. `GITEA_ACTIONS` is useful to distinguish Gitea Actions from other CI systems. | `true` |
| `GITEA_ACTIONS_RUNNER_VERSION` | The version of the runner executing the workflow. | `v5.2.4` |
| `GITEA_ACTOR`<br/>`GITHUB_ACTOR` | The username of the user that triggered the workflow. | `alice` |
| `GITEA_ACTOR_ID`<br/>`GITHUB_ACTOR_ID` | The ID of the user that triggered the workflow. | `1` |
| `GITEA_API_URL`<br/>`GITHUB_API_URL` | The URL of the REST API. | `https://gitea.example.com/api/v1` |
| `GITEA_BASE_REF`<br/>`GITHUB_BASE_REF` | The target branch of a pull request. | `main` |
| `GITEA_DOCKER_WORKSPACE` | The workspace path as the Docker daemon sees it, for bind mounts into containers a job starts, e.g. `${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data` in a compose file. Only set for jobs running in a container. | `/var/lib/docker/volumes/GITEA-ACTIONS-TASK-42-***/_data` |
| `GITEA_ENV`<br/>`GITHUB_ENV` | Path to the file that sets environment variables for subsequent steps. | `/var/run/act/workflow/envs.txt` |
| `GITEA_EVENT_NAME`<br/>`GITHUB_EVENT_NAME` | The name of the event that triggered the workflow. | `push` |
| `GITEA_EVENT_PATH`<br/>`GITHUB_EVENT_PATH` | Path to the file containing the event webhook payload. | `/var/run/act/workflow/event.json` |
| `GITEA_GRAPHQL_URL`<br/>`GITHUB_GRAPHQL_URL` | Empty in Gitea (GraphQL is not supported). | _(empty)_ |
| `GITEA_HEAD_REF`<br/>`GITHUB_HEAD_REF` | The source branch of a pull request. | `feature-branch` |
| `GITEA_JOB`<br/>`GITHUB_JOB` | The `job_id` of the current job. | `build` |
| `GITEA_OUTPUT`<br/>`GITHUB_OUTPUT` | Path to the file that sets step output parameters. | `/var/run/act/workflow/outputcmd.txt` |
| `GITEA_PATH`<br/>`GITHUB_PATH` | Path to the file that adds system `PATH` entries for subsequent steps. | `/var/run/act/workflow/pathcmd.txt` |
| `GITEA_REF`<br/>`GITHUB_REF` | The fully-formed ref that triggered the workflow. | `refs/heads/main` |
| `GITEA_REF_NAME`<br/>`GITHUB_REF_NAME` | The short ref name. | `main` |
| `GITEA_REF_PROTECTED`<br/>`GITHUB_REF_PROTECTED` | `true` if branch protections are configured for the ref that triggered the workflow. | `true` |
| `GITEA_REF_TYPE`<br/>`GITHUB_REF_TYPE` | The type of ref: `branch` or `tag`. | `branch` |
| `GITEA_REPOSITORY`<br/>`GITHUB_REPOSITORY` | The owner and repository name. | `owner/repo` |
| `GITEA_REPOSITORY_ID`<br/>`GITHUB_REPOSITORY_ID` | The ID of the repository. | `123` |
| `GITEA_REPOSITORY_OWNER`<br/>`GITHUB_REPOSITORY_OWNER` | The repository owner's username. | `owner` |
| `GITEA_REPOSITORY_OWNER_ID`<br/>`GITHUB_REPOSITORY_OWNER_ID` | The ID of the repository owner. | `45` |
| `GITEA_RETENTION_DAYS`<br/>`GITHUB_RETENTION_DAYS` | The number of days that artifacts are kept, empty when kept forever. | `90` |
| `GITEA_RUN_ATTEMPT`<br/>`GITHUB_RUN_ATTEMPT` | The attempt number of the workflow run. | `1` |
| `GITEA_RUN_ID`<br/>`GITHUB_RUN_ID` | A unique number for each workflow run. | `1234` |
| `GITEA_RUN_NUMBER`<br/>`GITHUB_RUN_NUMBER` | A unique number for each run of a particular workflow. | `42` |
| `GITEA_SERVER_URL`<br/>`GITHUB_SERVER_URL` | The URL of the Gitea instance. | `https://gitea.example.com` |
| `GITEA_SHA`<br/>`GITHUB_SHA` | The commit SHA that triggered the workflow. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_STATE`<br/>`GITHUB_STATE` | Path to the file that sets step state variables. | `/var/run/act/workflow/statecmd.txt` |
| `GITEA_STEP_SUMMARY`<br/>`GITHUB_STEP_SUMMARY` | Path to the file for writing job summaries. | `/var/run/act/workflow/step-summary-0.md` |
| `GITEA_TRIGGERING_ACTOR`<br/>`GITHUB_TRIGGERING_ACTOR` | The username of the user that initiated the workflow run. May differ from `GITEA_ACTOR` on re-runs. | `alice` |
| `GITEA_WORKFLOW`<br/>`GITHUB_WORKFLOW` | The name of the workflow. | `CI` |
| `GITEA_WORKFLOW_SHA`<br/>`GITHUB_WORKFLOW_SHA` | The commit SHA of the workflow file. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_WORKSPACE`<br/>`GITHUB_WORKSPACE` | The default working directory on the runner. | `/workspace/owner/repo` |
| `TRACEPARENT` | The W3C trace context of the job's span, so instrumented tools can add spans to the job's trace. Only set when the runner exports traces, see [Monitoring](/runner/monitoring/#opentelemetry). | `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` |
| `TRACESTATE` | Vendor-specific trace data that accompanies `TRACEPARENT`. Only set when the trace carries any. | `rojo=00f067aa0ba902b7` |
### Runner environment variables
| Name | Description | Example |
|---|---|---|
| `ImageOS` | The OS and release of the job's image, read by `setup-*` actions. | `ubuntu24` |
| `RUNNER_ARCH` | The architecture of the runner. | `X64` |
| `RUNNER_DEBUG` | Set to `1` when the `ACTIONS_STEP_DEBUG` secret is `true`, unset otherwise. | `1` |
| `RUNNER_ENVIRONMENT` | Always set to `self-hosted`. | `self-hosted` |
| `RUNNER_NAME` | The name of the runner executing the job. | `my-runner` |
| `RUNNER_OS` | The operating system of the runner. | `Linux` |
| `RUNNER_TEMP` | Path to a temporary directory on the runner. | `/tmp` |
| `RUNNER_TOOL_CACHE` | Path to the tool cache directory on the runner. | `/opt/hostedtoolcache` |
| `RUNNER_WORKSPACE` | The parent directory of `GITEA_WORKSPACE`. | `/workspace/owner` |
### Internal environment variables
@@ -65,10 +79,10 @@ These are used internally by the runner and actions. They are typically not need
|---|---|---|
| `ACTIONS_CACHE_URL` | URL for the actions cache service. | `http://192.168.1.10:8088/` |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | Token for OIDC requests. Only set when `id-token: write` is granted. | `***` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | URL to request OIDC tokens. Only set when `id-token: write` is granted. | `https://gitea.com/api/actions/oidc/token?` |
| `ACTIONS_RESULTS_URL` | URL for storing artifacts. | `https://gitea.com` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | URL to request OIDC tokens. Only set when `id-token: write` is granted. | `https://gitea.example.com/api/actions/oidc/token?` |
| `ACTIONS_RESULTS_URL` | URL for storing artifacts. | `https://gitea.example.com` |
| `ACTIONS_RUNTIME_TOKEN` | Authentication token for the Actions pipeline API. | `***` |
| `ACTIONS_RUNTIME_URL` | URL for the Gitea Actions pipeline API. | `https://gitea.com/api/actions_pipeline/` |
| `ACTIONS_RUNTIME_URL` | URL for the Gitea Actions pipeline API. | `https://gitea.example.com/api/actions_pipeline/` |
## Context variables
@@ -76,39 +90,39 @@ These variables are available in workflow expressions via `${{ gitea.<name> }}`.
| Name | Description | Example |
|---|---|---|
| `gitea.action`<br/>`github.action` | The name of the action currently running, or the `id` of a step. | `__run` |
| `gitea.action_path`<br/>`github.action_path` | The path where an action is located. Only supported in composite actions. | `/home/runner/work/_actions/actions/checkout/v4` |
| `gitea.action`<br/>`github.action` | The `id` of the current step, or its index when it has none. | `0` |
| `gitea.action_path`<br/>`github.action_path` | The path where an action is located. Only supported in composite actions. | `/var/run/act/actions/***` |
| `gitea.action_ref`<br/>`github.action_ref` | The ref of the action being executed. | `v4` |
| `gitea.action_repository`<br/>`github.action_repository` | The owner and repository name of the action. | `actions/checkout` |
| `gitea.action_status`<br/>`github.action_status` | The current result of a composite action. | `success` |
| `gitea.actor`<br/>`github.actor` | The username of the user that triggered the initial workflow run. | `silverwind` |
| `gitea.api_url`<br/>`github.api_url` | The URL of the REST API. | `https://gitea.com/api/v1` |
| `gitea.actor`<br/>`github.actor` | The username of the user that triggered the initial workflow run. | `alice` |
| `gitea.api_url`<br/>`github.api_url` | The URL of the REST API. | `https://gitea.example.com/api/v1` |
| `gitea.base_ref`<br/>`github.base_ref` | The target branch of a pull request. Only set for `pull_request` and `pull_request_target` events. | `main` |
| `gitea.env`<br/>`github.env` | Path on the runner to the file that sets environment variables from workflow commands. Unique to each step. | `/home/runner/work/_temp/_runner_file_commands/set_env_***` |
| `gitea.env`<br/>`github.env` | Path on the runner to the file that sets environment variables from workflow commands. | `/var/run/act/workflow/envs.txt` |
| `gitea.event`<br/>`github.event` | The full event webhook payload as an object. See [Event payload](#event-payload). | `{...}` |
| `gitea.event_name`<br/>`github.event_name` | The name of the event that triggered the workflow run. | `push` |
| `gitea.event_path`<br/>`github.event_path` | Path on the runner to the file containing the full event webhook payload. | `/home/runner/work/_temp/_github_workflow/event.json` |
| `gitea.event_path`<br/>`github.event_path` | Path on the runner to the file containing the full event webhook payload. | `/var/run/act/workflow/event.json` |
| `gitea.head_ref`<br/>`github.head_ref` | The source branch of a pull request. Only set for `pull_request` and `pull_request_target` events. | `feature-branch` |
| `gitea.job`<br/>`github.job` | The `job_id` of the current job. | `build` |
| `gitea.ref`<br/>`github.ref` | The fully-formed ref that triggered the workflow. | `refs/heads/main` |
| `gitea.ref_name`<br/>`github.ref_name` | The short ref name. | `main` |
| `gitea.ref_protected`<br/>`github.ref_protected` | `true` if branch protections are configured for the ref that triggered the workflow run. | `true` |
| `gitea.ref_type`<br/>`github.ref_type` | The type of ref: `branch` or `tag`. | `branch` |
| `gitea.path`<br/>`github.path` | Path on the runner to the file that sets system `PATH` variables from workflow commands. Unique to each step. | `/home/runner/work/_temp/_runner_file_commands/add_path_***` |
| `gitea.repository`<br/>`github.repository` | The owner and repository name. | `gitea/docs` |
| `gitea.repository_owner`<br/>`github.repository_owner` | The repository owner's username. | `gitea` |
| `gitea.repositoryUrl`<br/>`github.repositoryUrl` | The HTML URL to the repository. | `https://gitea.com/gitea/docs` |
| `gitea.path`<br/>`github.path` | Path on the runner to the file that sets system `PATH` variables from workflow commands. | `/var/run/act/workflow/pathcmd.txt` |
| `gitea.repository`<br/>`github.repository` | The owner and repository name. | `owner/repo` |
| `gitea.repository_owner`<br/>`github.repository_owner` | The repository owner's username. | `owner` |
| `gitea.repositoryUrl`<br/>`github.repositoryUrl` | The HTML URL to the repository. | `https://gitea.example.com/owner/repo` |
| `gitea.retention_days`<br/>`github.retention_days` | The number of days that artifacts are kept, empty when kept forever. | `90` |
| `gitea.run_id`<br/>`github.run_id` | A unique number for each workflow run within a repository. Does not change on re-run. | `1234` |
| `gitea.run_number`<br/>`github.run_number` | A unique number for each run of a particular workflow. Starts at 1 and increments with each new run. | `42` |
| `gitea.run_attempt`<br/>`github.run_attempt` | A unique number for each re-run attempt. Starts at 1 and increments with each re-run. | `1` |
| `gitea.secret_source`<br/>`github.secret_source` | The source of a secret used in a workflow. Always `Actions` in Gitea. | `Actions` |
| `gitea.server_url`<br/>`github.server_url` | The URL of the Gitea instance. | `https://gitea.com` |
| `gitea.server_url`<br/>`github.server_url` | The URL of the Gitea instance. | `https://gitea.example.com` |
| `gitea.sha`<br/>`github.sha` | The commit SHA that triggered the workflow. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `gitea.token`<br/>`github.token` | A token to authenticate on behalf of the Gitea App installed on the repository. See [Token permissions](token-permissions.md). | `ghs_***` |
| `gitea.triggering_actor`<br/>`github.triggering_actor` | The username of the user that initiated the workflow run. May differ from `actor` on re-runs. | `silverwind` |
| `gitea.token`<br/>`github.token` | A token to authenticate on behalf of the Gitea App installed on the repository. See [Token permissions](token-permissions.md). | `***` |
| `gitea.triggering_actor`<br/>`github.triggering_actor` | The username of the user that initiated the workflow run. May differ from `actor` on re-runs. | `alice` |
| `gitea.workflow`<br/>`github.workflow` | The name of the workflow. If unnamed, the full path of the workflow file. | `CI` |
| `gitea.workspace`<br/>`github.workspace` | The default working directory on the runner and the default location of your repository when using the `checkout` action. | `/workspace/gitea/docs` |
| `gitea.workspace`<br/>`github.workspace` | The default working directory on the runner and the default location of your repository when using the `checkout` action. | `/workspace/owner/repo` |
| `gitea.gitea_default_actions_url` | The default URL for downloading actions. Gitea-specific. | `https://github.com` |
### Event payload
@@ -124,11 +138,11 @@ These fields exist in almost every payload:
| Name | Description | Example |
|---|---|---|
| `gitea.event.action` | The activity type. Only set for events that have activity types, see [supported events](faq.md#what-workflow-trigger-events-does-gitea-support). | `opened` |
| `gitea.event.repository.full_name` | The owner and name of the repository. | `gitea/docs` |
| `gitea.event.repository.full_name` | The owner and name of the repository. | `owner/repo` |
| `gitea.event.repository.default_branch` | The default branch of the repository. | `main` |
| `gitea.event.repository.private` | Whether the repository is private. | `false` |
| `gitea.event.repository.html_url` | The HTML URL of the repository. | `https://gitea.com/gitea/docs` |
| `gitea.event.sender.login` | The username of the user that triggered the event. Also available as `sender.username`. | `silverwind` |
| `gitea.event.repository.html_url` | The HTML URL of the repository. | `https://gitea.example.com/owner/repo` |
| `gitea.event.sender.login` | The username of the user that triggered the event. Also available as `sender.username`. | `alice` |
The remaining fields are specific to one or a few events:
@@ -143,12 +157,12 @@ The remaining fields are specific to one or a few events:
| `gitea.event.commits` | `push` | The commits contained in the push, each with `id`, `message`, `url`, `author`, `added`, `removed` and `modified`. | `[{...}]` |
| `gitea.event.head_commit.message` | `push` | The message of the most recent commit of the push. | `fix: broken link` |
| `gitea.event.total_commits` | `push` | The number of commits in the push. Gitea-specific. | `3` |
| `gitea.event.compare_url` | `push` | The URL comparing `before` with `after`. GitHub names this field `compare`. | `https://gitea.com/gitea/docs/compare/a1b2c3d...e5f6a1b` |
| `gitea.event.pusher.login` | `push` | The username of the user that pushed. | `silverwind` |
| `gitea.event.forkee.full_name` | `fork` | The owner and name of the new fork. | `silverwind/docs` |
| `gitea.event.compare_url` | `push` | The URL comparing `before` with `after`. GitHub names this field `compare`. | `https://gitea.example.com/owner/repo/compare/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2...f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5` |
| `gitea.event.pusher.login` | `push` | The username of the user that pushed. | `alice` |
| `gitea.event.forkee.full_name` | `fork` | The owner and name of the new fork. | `alice/repo` |
| `gitea.event.page` | `gollum` | The name of the wiki page. | `Home` |
| `gitea.event.number` | `issues`, `pull_request`, `pull_request_target`, `pull_request_review`, `pull_request_review_comment` | The index of the issue or pull request. Not set for `issue_comment`, use `gitea.event.issue.number` there. | `386` |
| `gitea.event.issue.number`<br/>`gitea.event.issue.title`<br/>`gitea.event.issue.body`<br/>`gitea.event.issue.state`<br/>`gitea.event.issue.labels`<br/>`gitea.event.issue.user.login` | `issues`, `issue_comment` | The issue the event happened on. | `Expand gitea.event in actions docs` |
| `gitea.event.issue.number`<br/>`gitea.event.issue.title`<br/>`gitea.event.issue.body`<br/>`gitea.event.issue.state`<br/>`gitea.event.issue.labels`<br/>`gitea.event.issue.user.login` | `issues`, `issue_comment` | The issue the event happened on. | `Fix typo in README` |
| `gitea.event.comment.body` | `issue_comment` | The body of the comment. | `LGTM` |
| `gitea.event.is_pull` | `issue_comment` | Whether the comment was made on a pull request. Gitea-specific, GitHub sets `issue.pull_request` on the issue object instead. | `true` |
| `gitea.event.pull_request.number`<br/>`gitea.event.pull_request.title`<br/>`gitea.event.pull_request.body`<br/>`gitea.event.pull_request.draft`<br/>`gitea.event.pull_request.merged`<br/>`gitea.event.pull_request.state`<br/>`gitea.event.pull_request.labels`<br/>`gitea.event.pull_request.user.login` | `pull_request`, `pull_request_target`, `pull_request_review`, `pull_request_review_comment` | The pull request the event happened on. | `Add caching to CI` |
+1
View File
@@ -36,6 +36,7 @@ The following package managers are currently supported:
| [RubyGems](usage/packages/rubygems.md) | Ruby | `gem`, `Bundler` |
| [Swift](usage/packages/swift.md) | Swift | `swift` |
| [Terraform](usage/packages/terraform.md) | - | `terraform` |
| [Terraform Module](usage/packages/terraform-module.md) | - | `terraform`, `terragrunt` |
| [Vagrant](usage/packages/vagrant.md) | - | `vagrant` |
**The following paragraphs only apply if Packages are not globally disabled!**
+170
View File
@@ -0,0 +1,170 @@
---
date: "2026-06-09T00:00:00+00:00"
slug: "terraform-module"
sidebar_position: 119
---
# Terraform Module Registry
Publish [Terraform](https://www.terraform.io/) modules for your user or organization and use them
from Terraform or Terragrunt. The registry implements the
[HashiCorp module registry protocol](https://developer.hashicorp.com/terraform/internals/module-registry-protocol),
so modules are referenced with the usual `HOST/NAMESPACE/NAME/PROVIDER` address.
## Requirements
- The [Terraform CLI](https://developer.hashicorp.com/terraform/install) or
[Terragrunt](https://terragrunt.gruntwork.io/).
- **Your Gitea instance must be served over HTTPS with a valid certificate.**
Terraform and Terragrunt only perform module registry discovery over HTTPS and reject
plain HTTP — including `http://localhost`. This is a requirement of the protocol, not of Gitea.
A module is addressed by three segments:
| Segment | Meaning |
| ----------- | ------------------------------------------------------------- |
| `namespace` | The owner of the module: a Gitea user or organization name. It must follow the same rules as `name`, so owners with a `.` in their name cannot publish modules. |
| `name` | The module name. Letters, digits, `-` and `_`, starting and ending with a letter or digit, up to 64 characters. |
| `provider` | The main provider the module targets, e.g. `aws`. Lowercase letters and digits, up to 64 characters. |
Versions follow [semantic versioning](https://semver.org/) and are stored in canonical form: a
leading `v` is dropped and missing segments are padded, so `v1.2.3` and `1.2.3` address the same
version, and `1.2` becomes `1.2.0`.
## Packaging a module
A module is published as a single `.tar.gz` archive, stored and served exactly as uploaded. The
module's `.tf` files must therefore be at the **archive root**. A source tarball downloaded from a Git
host wraps everything in a `repository-version/` directory and is rejected — repackage the module
directory's contents instead:
```shell
tar -czf vpc-1.0.0.tar.gz -C path/to/module .
```
The root module's inputs, outputs, providers and `README` are shown on the package page. Each
submodule found under `modules/<name>` is listed with its source address and links to its own page,
which shows the install snippet for that submodule along with its inputs, outputs, providers and
`README`. Only one level is indexed, so `modules/<name>/<nested>` is not listed. Anything else,
including `examples/`, is kept in the archive but is not indexed. A module that is only a collection of
submodules, with no root module, is also accepted. Files in JSON syntax (`.tf.json`) are accepted too,
but only `.tf` files are indexed.
## Authentication
Create a [personal access token](development/api-usage.md#authentication) with the `read:package` scope to download
private modules, and `write:package` to publish or delete them. Add it to your Terraform CLI
configuration file (`~/.terraformrc` or `%APPDATA%/terraform.rc`):
```hcl
credentials "gitea.example.com" {
token = "<your token>"
}
```
Modules owned by a public user or organization can be downloaded without a token.
## Publishing a module
Upload an archive with a `PUT` request, sending the file as the raw request body. Use
`curl --upload-file` rather than `--data-binary`: the latter sends a form content type that
the registry will not accept as an archive.
```shell
curl --user "your_username:your_token" \
--upload-file vpc-1.0.0.tar.gz \
https://gitea.example.com/api/packages/-/terraform/modules/{namespace}/{name}/{provider}/{version}
```
| Parameter | Description |
| ----------- | -------------------------------------- |
| `namespace` | The owner (user or organization). |
| `name` | The module name. |
| `provider` | The provider the module targets. |
| `version` | The module version (semver). |
For example, to publish version `1.0.0` of the `vpc` module for the `aws` provider under the `acme`
organization:
```shell
curl --user "your_username:your_token" \
--upload-file vpc-1.0.0.tar.gz \
https://gitea.example.com/api/packages/-/terraform/modules/acme/vpc/aws/1.0.0
```
A successful upload returns `201 Created`. Published versions are immutable: uploading a version that
already exists returns `409 Conflict`. To replace a version, delete it first.
## Linking a module to a repository
A module always lives in a user or organization's package space — its namespace is that user or
organization, never a repository, because the registry address (`HOST/NAMESPACE/NAME/PROVIDER`) has no
repository segment. You cannot publish "into" a repository. Instead, a repository link is a display
association that surfaces the module on a repository's **Packages** tab. The workflow is:
1. **Publish** the module to the user or organization namespace, exactly as shown in
[Publishing a module](#publishing-a-module).
2. **Link** the package to a repository owned by that same user or organization: open the package,
go to its **Settings**, and select the repository (or use the
`POST /api/v1/packages/{owner}/terraform-module/{name}%2F{provider}/-/link/{repo}` API).
The link applies to the whole module — all of its versions, including ones published later — and can
be changed or removed at any time. It only affects where the module is listed in the UI; the address
used to consume it is unchanged (still `HOST/NAMESPACE/NAME/PROVIDER`, with no repository in it).
## Consuming a module
Reference the module by its registry address. With Terraform:
```hcl
module "vpc" {
source = "gitea.example.com/acme/vpc/aws"
version = "~> 1.0"
}
```
To use a submodule, append its path with the standard `//` separator:
```hcl
module "network" {
source = "gitea.example.com/acme/infra/google//modules/network"
version = "~> 1.0"
}
```
With Terragrunt, use the `tfr://` scheme and pass the version as a query parameter:
```hcl
terraform {
source = "tfr://gitea.example.com/acme/vpc/aws?version=1.0.0"
}
```
`terraform init` (or `terragrunt init`) resolves the address through the service discovery document
at `https://gitea.example.com/.well-known/terraform.json` and downloads the matching version.
## Deleting a version
```shell
curl --user "your_username:your_token" \
--request DELETE \
https://gitea.example.com/api/packages/-/terraform/modules/acme/vpc/aws/1.0.0
```
A successful delete returns `204 No Content`. This requires the `write:package` scope. There is no
separate deprecation flow — deleting a version removes it from the registry.
## Limits
The stored archive is bounded by the instance-wide package limits (`LIMIT_SIZE_TERRAFORM_MODULE` and
`LIMIT_TOTAL_OWNER_SIZE`) set by your Gitea administrator; see the
[configuration cheat sheet](../../administration/config-cheat-sheet.md#packages-packages).
Independently of those settings, an archive may not exceed **32 MiB decompressed**. The registry
reads the whole archive to index it, and stops with `413 Request Entity Too Large` past that ceiling,
so raising `LIMIT_SIZE_TERRAFORM_MODULE` above 32 MiB does not allow larger modules. Real modules are
kilobyte-scale, so this only affects archives carrying unrelated payloads.
A `README` larger than **1 MiB**, of the root module or of a submodule, is not shown on the package
page. The module is still accepted and the file stays in the archive.
+9
View File
@@ -0,0 +1,9 @@
{
"label": "Projects",
"position": 60,
"link": {
"type": "generated-index",
"slug": "/usage/projects",
"description": "Plan and track work with project boards"
}
}
+82
View File
@@ -0,0 +1,82 @@
---
date: "2025-11-25T18:58:22Z"
slug: "project-workflows"
sidebar_position: 1
description: "Automate project boards with event-driven filters and actions."
---
# Project Workflows
Project workflows automate a project board. When an issue or pull request in the project triggers an event, each enabled workflow for that event checks its filters and applies its actions. Workflows run in Gitea and need no runner.
## Edit workflows
1. Open a project and select **Workflows**.
2. Select an event in the sidebar.
3. Set filters and actions, then select **Save**. To change an existing workflow, select **Edit** first.
An event can have several workflows. **Clone** copies the selected workflow so you can adapt it to other items. **Disable** pauses a workflow and keeps its configuration. **Remove** deletes it.
## Events
| Event | Runs when | Filters | Actions |
| --- | --- | --- | --- |
| Item added to project | An item is added to the project or created in it | Apply to, labels | Move to column, labels, issue state |
| Item removed from project | An item is removed from the project | Apply to, labels | Labels, issue state |
| Item reopened | An item is reopened | Apply to, labels | Move to column, labels |
| Item closed | An item is closed | Apply to, labels | Move to column, labels |
| Item column changed | An item moves to another column | Apply to, columns, labels | Labels, issue state |
| Code changes requested | An official reviewer requests changes on a pull request | Labels | Move to column, labels |
| Code review approved | An official reviewer approves a pull request | Labels | Move to column, labels |
| Pull request merged | A pull request is merged | Labels | Move to column, labels |
## Filters
A workflow without filters runs for every item.
- **Apply to**: issues, pull requests, or both.
- **When moved from column**, **When moved to column**: the column the item left or entered.
- **Only if it has labels**: the item must have all selected labels.
## Actions
A workflow needs at least one action. Actions run in this order:
1. **Move to column**: moves the item to a column.
2. **Add labels**, **Remove labels**: changes the item's labels.
3. **Issue state**: closes or reopens the item. Workflows never reopen pull requests.
Workflow changes appear in the timeline as "Project workflow" followed by the event, and don't trigger other workflows. Workflows don't run in closed projects or for items in archived repositories.
## Permissions
Anyone who can read a project can view its workflows. Managing them requires write access to the project and:
- Repository project: write access to the repository's issues and pull requests.
- Organization project: organization owner or site administrator.
- User project: the project's owner.
Access tokens limited to public repositories can't manage workflows for organization or user projects. Workflows apply their actions regardless of who triggered the event.
## API
Manage workflows under the project routes of a repository (`/repos/{owner}/{repo}/projects/{id}`), an organization (`/orgs/{org}/projects/{id}`) or the authenticated user (`/user/projects/{id}`):
| Method | Path | Purpose |
| --- | --- | --- |
| `GET` | `.../workflows` | List workflows |
| `GET` | `.../workflows/{workflow_id}` | Get a workflow |
| `POST` | `.../workflows` | Create a workflow |
| `PATCH` | `.../workflows/{workflow_id}` | Edit a workflow, omitted fields stay unchanged |
| `DELETE` | `.../workflows/{workflow_id}` | Delete a workflow |
A workflow has an `event` (`item_added_to_project`, `item_removed_from_project`, `item_reopened`, `item_closed`, `item_column_changed`, `code_changes_requested`, `code_review_approved` or `pull_request_merged`), an `enabled` flag, `filters` (`issue_type`, `source_column_id`, `target_column_id`, `label_ids`) and `actions` (`column_id`, `add_label_ids`, `remove_label_ids`, `issue_state`). Each event accepts only the filters and actions listed in [Events](#events).
## Example
To route new bug reports to triage, create a workflow for **Item added to project**:
- **Apply to**: Issues only
- **Only if it has labels**: `bug`
- **Move to column**: Triage
- **Add labels**: `needs-triage`
+69 -13
View File
@@ -9,25 +9,36 @@ aliases:
# Code Owners
Gitea maintains code owner files. It looks for it in the following locations in this order:
Gitea reads the first CODEOWNERS file found at these locations, in order:
- `./CODEOWNERS`
- `./docs/CODEOWNERS`
- `./.gitea/CODEOWNERS`
And stops at the first found file.
Pull requests use the base branch's rules. File views show owners from the commit
being viewed, including when browsing a branch, tag, or historical commit.
File format: `<regexp rule> <@user or @org/team> [@user or @org/team]...`
## Patterns and owners
Regexp specified in golang Regex format.
Regexp can start with `!` for negative rules - match all files except specified.
Each rule contains a pattern followed by users or organization teams.
Patterns starting with `*` or containing `/*` are parsed as glob expressions.
General patterns are parsed as regular expressions.
A leading `!` inverts a match.
Special rule characters like space, backslash and `#` must be escaped with a backslash.
When using regexp, since backslash needs to be escaped in rule level, literal dot should be written as `\\.`
Example file:
```bash
.*\\.go @user1 @user2 # This is comment
```text
*.js @alice @bob # This is an inline comment
doc/*.md @charles # Patterns starting with "*" or containing "/*" are parsed as glob
src/**/db*.py @david # Use "**" to match any-level sub directories
.*\\.go @user1 @user2 # General patterns are parsed as regexp
test\\..*\\.js @user3 # !!! Do remeber: NOT "test.*.js", only regexp can be used for such cases
# Comment too
# You can assigning code owning for users or teams
frontend/src/.*\\.js @org1/team1 @org1/team2 @user3
@@ -42,24 +53,69 @@ docs/(aws|google|azure)/[^/]*\\.(md|txt) @user8 @org1/team4
Code owners listed in this file will automatically be requested to review pull requests
that modify files matching at least one corresponding rule.
### Escaping
## Sections
You can escape characters `#`, ` ` (space) and `\` with `\`, like:
A section heading can supply default owners for the rules that follow it:
```text
[Documentation] @org1/team-doc
*.md
README.md @alice
[Frontend] @bob
*.js
```
Owners on a rule replace the section's default owners. Section names are
case-insensitive; repeated headings belong to the same section. For each file, the
last matching rule in each named section applies. Matching rules outside named
sections retain Gitea's existing behavior: they all apply.
## Review request annotations
Use `## review-request=true` or `## review-request=false` to control automatic
review requests. A line annotation overrides a section annotation, which overrides
the global value. When none is set, individual code owners receive automatic review
requests only if they watch the repository and include pull requests in their watch
preferences. Team-level requests are enabled by default. An explicit `true` requests
a review regardless of the individual owner's watch preferences; `false` disables
automatic requests for the rule.
```text
## review-request=false # global default for following rules
*.js @alice ## review-request=true # only this rule
[Documentation] @org1/team-doc ## review-request=true
*.md
private/* @bob ## review-request=false
```
A standalone annotation changes the global default for subsequent rules.
Annotations on section headings apply until the next heading. Ordinary comments
start with `#`, including comments after annotations.
Disabling review requests keeps code owners visible when viewing a file and
does not waive approvals required by branch protection.
## Escaping
You need to escape characters `#`, ` ` (space) and `\` with backslash `\`, e.g.:
```text
dir/with\#hashtag @user1
path\ with\ space @user2
path/with\\backslash @user3
```
Some character (`.+*?()|[]{}^$\`) should be escaped with `\\` inside regexp, like:
Some regexp characters (`.+*?()|[]{}^$\`) should be escaped with `\\`, e.g.:
```
path/\\.with\\.dots
path/with\\+plus
```
### Branch Protection Rules
## Branch Protection Rules
When setting up branch protection rules, you may choose to enforce code owner approval of
modified files. This will block a PR from being merged until at least one code owner
@@ -67,7 +123,7 @@ has given approval for every applicable rule listed in the `CODEOWNERS` file.
For example, say you have the following `CODEOWNERS` file:
```bash
```text
.*\\.go @Bob
.*\\.md @Sally @Chris
migrations/.* @Alice
@@ -141,7 +141,7 @@ aliases:
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: 在默认的 squash 合并消息中,包括构成拉取请求的所有提交的提交消息。
- `ADD_CO_COMMITTER_TRAILERS`: **true**: 如果提交者与作者不匹配,在合并提交消息中添加`co-authored-by`和`co-committed-by`标记。
- `RETARGET_CHILDREN_ON_MERGE`: **true**: 当父合并请求被合并时,将子合并请求重新定向到父合并请求的目标分支。仅适用于头分支和基分支指向同一仓库的已合并合并请求。
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **false**: 为新仓库设置"合并后默认删除合并请求分支"的默认值。
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **true**: 为新仓库设置"合并后默认删除合并请求分支"的默认值。
### 仓库 - 工单 (`repository.issue`)
@@ -524,7 +524,8 @@ Gitea 创建以下非唯一队列:
- `REVERSE_PROXY_AUTHENTICATION_USER`: **X-WEBAUTH-USER**: 反向代理认证的 HTTP 头部名称,用于提供用户信息。
- `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: 反向代理认证的 HTTP 头部名称,用于提供邮箱信息。
- `REVERSE_PROXY_AUTHENTICATION_FULL_NAME`: **X-WEBAUTH-FULLNAME**: 反向代理认证的 HTTP 头部名称,用于提供全名信息。
- `REVERSE_PROXY_LIMIT`: **1**: 解释 X-Forwarded-For 标头或 X-Real-IP 标头,并将其设置为请求的远程 IP。
- `REVERSE_PROXY_LIMIT`: **1**: 按顺序解释 X-Real-IP、X-Forwarded-For 或 Forwarded 标头,并将其设置为请求的远程 IP。
客户端端口取自标头值,或在使用 X-Real-IP 时取自 X-Real-Port。
可信代理计数。设置为零以不使用这些标头。
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: 逗号分隔的受信任代理服务器的 IP 地址和网络列表。使用 `*` 来信任全部。
- `DISABLE_GIT_HOOKS`: **true**: 设置为 `false` 以允许具有 Git 钩子权限的用户创建自定义 Git 钩子。
@@ -1195,7 +1196,7 @@ In-Reply-To =
- `JWT_SECRET_URI`:**_empty_**: 可以使用此配置选项,而不是在配置中定义`JWT_SECRET`,以向 Gitea 提供包含密钥的文件的路径(示例值:`file:/etc/gitea/oauth2_jwt_secret`)。
- `JWT_SIGNING_PRIVATE_KEY_FILE`:**jwt/private.pem**: 用于签署 OAuth2 令牌的私钥文件路径。路径相对于`APP_DATA_PATH`。仅当`JWT_SIGNING_ALGORITHM`设置为`RS256`,`RS384`,`RS512`,`ES256`,`ES384`或`ES512`时才需要此设置。文件必须包含 PKCS8 格式的 RSA 或 ECDSA 私钥。如果不存在密钥,则将为您创建一个 4096 位密钥。
- `MAX_TOKEN_LENGTH`:**32767**: 从 OAuth2 提供者接受的令牌/cookie 的最大长度。
- `DEFAULT_APPLICATIONS`:**git-credential-oauth,git-credential-manager, tea**: 在启动时预注册用于某些服务的 OAuth 应用程序。有关可用选项列表,请参阅[OAuth2 文档](/development/oauth2-provider.md)。
- `DEFAULT_APPLICATIONS`:**git-credential-oauth, git-credential-manager, gitea-cli, gitea-app, gitea-vscode**: 在启动时预注册用于某些服务的 OAuth 应用程序。有关可用选项列表,请参阅[OAuth2 文档](/development/oauth2-provider.md)。
## i18n (`i18n`)
@@ -8,7 +8,7 @@ aliases:
# 数据库准备
在使用 Gitea 前,您需要准备一个数据库。Gitea 支持 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(内置) 和 MSSQL(>= 2012 SP4)这几种数据库。本页将指导您准备数据库。由于 PostgreSQL 和 MySQL 在生产环境中被广泛使用,因此本文档将仅涵盖这两种数据库。如果您计划使用 SQLite,则可以忽略本章内容。
在使用 Gitea 前,您需要准备一个数据库。Gitea 支持 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(内置) 和 MSSQL(>= 2012 SP4)这几种数据库。本页将指导您准备数据库。本文档涵盖 PostgreSQL、MySQL 和 MSSQL。如果您计划使用 SQLite,则可以忽略本章内容。
如果您使用不受支持的数据库版本,请通过 [联系我们](/help/support) 以获取有关我们的扩展支持的信息。我们可以为旧数据库提供测试和支持,并将这些修复集成到 Gitea 代码库中。
@@ -168,6 +168,28 @@ aliases:
您应该会被提示输入数据库用户的密码,并连接到数据库。
## MSSQL
1. 以管理员身份创建登录名、使用大小写敏感排序规则的数据库及其用户。请将密码 `'gitea'` 替换为安全的密码:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
升级会更改数据库结构,因此该用户需要 `db_owner`,或者 `db_ddladmin`、`db_datareader` 和 `db_datawriter`。使用后者时,还需以管理员身份执行 `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;`。
2. 在您的 Gitea 服务器上,测试与数据库的连接:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## 使用 TLS 进行数据库连接
如果 Gitea 和您的数据库实例之间的通信是通过私有网络进行的,或者如果 Gitea 和数据库运行在同一台服务器上,那么可以省略本节,因为 Gitea 和数据库实例之间的安全性不会受到严重威胁。但是,如果数据库实例位于公共网络上,请使用 TLS 对数据库连接进行加密,以防止第三方拦截流量数据。
@@ -21,15 +21,7 @@ Gitea Actions旨在与GitHub Actions兼容,差异如下。
`uses:`支持以下前缀:
- `self:`引用您自己的Gitea实例,例如`uses: self:owner/repo@v1`或`uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:`运行Gitea Runner内置的Action,无需下载,Job镜像中也无需Node,例如`uses: builtin:checkout`
`builtin:checkout`支持`actions/checkout`的`repository`、`ref`、`token`、`path`和`fetch-depth`输入,默认值相同,其他输入会使步骤失败。
<a id="workflow-relative-actions"></a>
### 相对于工作流的Actions
`$/`引用工作流所在的仓库和提交,或外层复合Action所在的仓库和提交,例如`uses: $/.gitea/actions/build`。
与`./`不同,它无需事先检出代码。
- `builtin:`运行Gitea Runner内置的Action,无需下载,也不依赖Node.js,例如`uses: builtin:checkout`
### 使用Go编写Actions
@@ -95,7 +87,7 @@ Gitea Actions旨在与GitHub Actions兼容,差异如下。
未指定主机的Actions(如`uses: actions/checkout@v4`)会从`https://github.com`下载,当`[actions].DEFAULT_ACTIONS_URL`为`self`时则从您自己的实例下载。
请参阅[配置备忘单](../../administration/config-cheat-sheet.md#actions-actions)。
其他来源请参阅[Action URL绝对路径](#absolute-action-urls)、[Action前缀](#action-prefixes)和[相对于工作流的Actions](#workflow-relative-actions)。
其他来源请参阅[Action URL绝对路径](#absolute-action-urls)和[Action前缀](#action-prefixes)。
### 上下文可用性
@@ -6,10 +6,90 @@ sidebar_position: 25
# 变量
## 环境变量
以下环境变量会在每次工作流运行时自动设置,可以直接访问(例如在 shell 脚本中使用 `$CI`)。
同时列出 `GITEA_*` 和 `GITHUB_*` 名称的变量值相同。
| 名称 | 描述 | 示例 |
|---|---|---|
| `ACT` | 始终为 `true`,除非 Runner 配置了 `runner.set_act_env: false`。 | `true` |
| `CI` | 始终为 `true`。 | `true` |
| `GITEA_ACTION`<br/>`GITHUB_ACTION` | 当前步骤的 `id`,未设置时为步骤的序号。 | `0` |
| `GITEA_ACTION_PATH`<br/>`GITHUB_ACTION_PATH` | Action 所在的路径。仅在复合 Action 中设置。 | `/var/run/act/actions/***` |
| `GITEA_ACTION_REF`<br/>`GITHUB_ACTION_REF` | 正在执行的 Action 的 ref。 | `v4` |
| `GITEA_ACTION_REPOSITORY`<br/>`GITHUB_ACTION_REPOSITORY` | Action 的所有者和仓库名称。 | `actions/checkout` |
| `GITEA_ACTIONS`<br/>`GITHUB_ACTIONS` | 始终为 `true`。`GITEA_ACTIONS` 可用于区分 Gitea Actions 和其他 CI 系统。 | `true` |
| `GITEA_ACTIONS_RUNNER_VERSION` | 执行工作流的 Runner 的版本。 | `v5.2.4` |
| `GITEA_ACTOR`<br/>`GITHUB_ACTOR` | 触发工作流的用户的用户名。 | `alice` |
| `GITEA_ACTOR_ID`<br/>`GITHUB_ACTOR_ID` | 触发工作流的用户的 ID。 | `1` |
| `GITEA_API_URL`<br/>`GITHUB_API_URL` | REST API 的 URL。 | `https://gitea.example.com/api/v1` |
| `GITEA_BASE_REF`<br/>`GITHUB_BASE_REF` | 拉取请求的目标分支。 | `main` |
| `GITEA_DOCKER_WORKSPACE` | Docker 守护进程所见的工作区路径,用于绑定挂载到 Job 启动的容器中,例如在 compose 文件中使用 `${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data`。仅在 Job 运行于容器中时设置。 | `/var/lib/docker/volumes/GITEA-ACTIONS-TASK-42-***/_data` |
| `GITEA_ENV`<br/>`GITHUB_ENV` | 为后续步骤设置环境变量的文件路径。 | `/var/run/act/workflow/envs.txt` |
| `GITEA_EVENT_NAME`<br/>`GITHUB_EVENT_NAME` | 触发工作流的事件名称。 | `push` |
| `GITEA_EVENT_PATH`<br/>`GITHUB_EVENT_PATH` | 包含事件 Webhook 负载的文件路径。 | `/var/run/act/workflow/event.json` |
| `GITEA_GRAPHQL_URL`<br/>`GITHUB_GRAPHQL_URL` | 在 Gitea 中为空(不支持 GraphQL)。 | _(空)_ |
| `GITEA_HEAD_REF`<br/>`GITHUB_HEAD_REF` | 拉取请求的源分支。 | `feature-branch` |
| `GITEA_JOB`<br/>`GITHUB_JOB` | 当前 Job 的 `job_id`。 | `build` |
| `GITEA_OUTPUT`<br/>`GITHUB_OUTPUT` | 设置步骤输出参数的文件路径。 | `/var/run/act/workflow/outputcmd.txt` |
| `GITEA_PATH`<br/>`GITHUB_PATH` | 为后续步骤添加系统 `PATH` 条目的文件路径。 | `/var/run/act/workflow/pathcmd.txt` |
| `GITEA_REF`<br/>`GITHUB_REF` | 触发工作流的完整 ref。 | `refs/heads/main` |
| `GITEA_REF_NAME`<br/>`GITHUB_REF_NAME` | ref 的短名称。 | `main` |
| `GITEA_REF_PROTECTED`<br/>`GITHUB_REF_PROTECTED` | 如果触发工作流的 ref 配置了分支保护,则为 `true`。 | `true` |
| `GITEA_REF_TYPE`<br/>`GITHUB_REF_TYPE` | ref 的类型:`branch` 或 `tag`。 | `branch` |
| `GITEA_REPOSITORY`<br/>`GITHUB_REPOSITORY` | 所有者和仓库名称。 | `owner/repo` |
| `GITEA_REPOSITORY_ID`<br/>`GITHUB_REPOSITORY_ID` | 仓库的 ID。 | `123` |
| `GITEA_REPOSITORY_OWNER`<br/>`GITHUB_REPOSITORY_OWNER` | 仓库所有者的用户名。 | `owner` |
| `GITEA_REPOSITORY_OWNER_ID`<br/>`GITHUB_REPOSITORY_OWNER_ID` | 仓库所有者的 ID。 | `45` |
| `GITEA_RETENTION_DAYS`<br/>`GITHUB_RETENTION_DAYS` | Artifact 的保留天数,永久保留时为空。 | `90` |
| `GITEA_RUN_ATTEMPT`<br/>`GITHUB_RUN_ATTEMPT` | 工作流运行的尝试次数。 | `1` |
| `GITEA_RUN_ID`<br/>`GITHUB_RUN_ID` | 每次工作流运行的唯一编号。 | `1234` |
| `GITEA_RUN_NUMBER`<br/>`GITHUB_RUN_NUMBER` | 特定工作流每次运行的唯一编号。 | `42` |
| `GITEA_SERVER_URL`<br/>`GITHUB_SERVER_URL` | Gitea 实例的 URL。 | `https://gitea.example.com` |
| `GITEA_SHA`<br/>`GITHUB_SHA` | 触发工作流的提交 SHA。 | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_STATE`<br/>`GITHUB_STATE` | 设置步骤状态变量的文件路径。 | `/var/run/act/workflow/statecmd.txt` |
| `GITEA_STEP_SUMMARY`<br/>`GITHUB_STEP_SUMMARY` | 写入 Job 摘要的文件路径。 | `/var/run/act/workflow/step-summary-0.md` |
| `GITEA_TRIGGERING_ACTOR`<br/>`GITHUB_TRIGGERING_ACTOR` | 发起工作流运行的用户的用户名。重新运行时可能与 `GITEA_ACTOR` 不同。 | `alice` |
| `GITEA_WORKFLOW`<br/>`GITHUB_WORKFLOW` | 工作流的名称。 | `CI` |
| `GITEA_WORKFLOW_SHA`<br/>`GITHUB_WORKFLOW_SHA` | 工作流文件的提交 SHA。 | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_WORKSPACE`<br/>`GITHUB_WORKSPACE` | Runner 上的默认工作目录。 | `/workspace/owner/repo` |
| `TRACEPARENT` | Job span 的 W3C 追踪上下文,供已接入追踪的工具将 span 添加到 Job 的追踪中。仅在 Runner 导出追踪数据时设置,参见[监控](/runner/monitoring/#opentelemetry)。 | `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` |
| `TRACESTATE` | 随 `TRACEPARENT` 附带的厂商特定追踪数据。仅在追踪包含此类数据时设置。 | `rojo=00f067aa0ba902b7` |
### Runner 环境变量
| 名称 | 描述 | 示例 |
|---|---|---|
| `ImageOS` | Job 镜像的操作系统和版本,供 `setup-*` Action 读取。 | `ubuntu24` |
| `RUNNER_ARCH` | Runner 的架构。 | `X64` |
| `RUNNER_DEBUG` | 当 `ACTIONS_STEP_DEBUG` 密钥为 `true` 时设置为 `1`,否则不设置。 | `1` |
| `RUNNER_ENVIRONMENT` | 始终为 `self-hosted`。 | `self-hosted` |
| `RUNNER_NAME` | 执行 Job 的 Runner 的名称。 | `my-runner` |
| `RUNNER_OS` | Runner 的操作系统。 | `Linux` |
| `RUNNER_TEMP` | Runner 上临时目录的路径。 | `/tmp` |
| `RUNNER_TOOL_CACHE` | Runner 上工具缓存目录的路径。 | `/opt/hostedtoolcache` |
| `RUNNER_WORKSPACE` | `GITEA_WORKSPACE` 的父目录。 | `/workspace/owner` |
### 内部环境变量
这些变量供 Runner 和 Action 内部使用,工作流中通常不需要直接使用。
| 名称 | 描述 | 示例 |
|---|---|---|
| `ACTIONS_CACHE_URL` | Actions 缓存服务的 URL。 | `http://192.168.1.10:8088/` |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | 用于 OIDC 请求的令牌。仅在授予 `id-token: write` 时设置。 | `***` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | 请求 OIDC 令牌的 URL。仅在授予 `id-token: write` 时设置。 | `https://gitea.example.com/api/actions/oidc/token?` |
| `ACTIONS_RESULTS_URL` | 存储 Artifact 的 URL。 | `https://gitea.example.com` |
| `ACTIONS_RUNTIME_TOKEN` | Actions 流水线 API 的认证令牌。 | `***` |
| `ACTIONS_RUNTIME_URL` | Gitea Actions 流水线 API 的 URL。 | `https://gitea.example.com/api/actions_pipeline/` |
## 用户定义的变量
您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。当创建变量时,变量的名称会被
转换为大写,在yaml文件中引用时需要使用大写。
## 命名规则
### 命名规则
以下规则适用于变量名:
@@ -20,11 +100,11 @@ sidebar_position: 25
- 变量名称在创建它们的级别上必须是唯一的。
- 变量名称不能为 `CI`。
## 使用
### 使用
创建配置变量后,它们将自动填充到 `vars` 上下文中。您可以在工作流中使用类似 `${{ vars.VARIABLE_NAME }}` 这样的表达式来使用它们。
## 优先级
### 优先级
如果同名变量存在于多个级别,则级别最低的变量优先。
仓库级别的变量总是比组织或者用户级别的变量优先被选中。
@@ -0,0 +1,9 @@
{
"label": "项目",
"position": 60,
"link": {
"type": "generated-index",
"slug": "/usage/projects",
"description": "使用项目看板规划和跟踪工作"
}
}
@@ -0,0 +1,82 @@
---
date: "2025-11-25T18:58:22Z"
slug: "project-workflows"
sidebar_position: 1
description: "通过事件驱动的过滤器和动作自动化项目看板。"
---
# 项目工作流
项目工作流可自动化项目看板。当项目中的问题或合并请求触发事件时,该事件下每个已启用的工作流都会检查其过滤条件并执行相应动作。工作流在 Gitea 中运行,无需运行器。
## 编辑工作流
1. 打开项目并选择 **Workflows**。
2. 在侧边栏中选择事件。
3. 设置过滤器和动作,然后选择 **Save**。要修改现有工作流,请先选择 **Edit**。
一个事件可以有多个工作流。**Clone** 会复制选中的工作流,便于调整后用于其他条目。**Disable** 会暂停工作流并保留其配置。**Remove** 会删除工作流。
## 事件
| 事件 | 触发时机 | 过滤器 | 动作 |
| --- | --- | --- | --- |
| Item added to project | 条目被添加到项目或在项目中创建时 | Apply to、标签 | Move to column、标签、问题状态 |
| Item removed from project | 条目被移出项目时 | Apply to、标签 | 标签、问题状态 |
| Item reopened | 条目被重新打开时 | Apply to、标签 | Move to column、标签 |
| Item closed | 条目被关闭时 | Apply to、标签 | Move to column、标签 |
| Item column changed | 条目移至另一列时 | Apply to、列、标签 | 标签、问题状态 |
| Code changes requested | 正式审查者要求修改合并请求时 | 标签 | Move to column、标签 |
| Code review approved | 正式审查者批准合并请求时 | 标签 | Move to column、标签 |
| Pull request merged | 合并请求被合并时 | 标签 | Move to column、标签 |
## 过滤器
未设置过滤器的工作流会对每个条目运行。
- **Apply to**:问题、合并请求或两者。
- **When moved from column**、**When moved to column**:条目离开或进入的列。
- **Only if it has labels**:条目必须包含所有选中的标签。
## 动作
工作流至少需要一个动作。动作按以下顺序执行:
1. **Move to column**:将条目移至某一列。
2. **Add labels**、**Remove labels**:更改条目的标签。
3. **Issue state**:关闭或重新打开条目。工作流不会重新打开合并请求。
工作流所做的更改在时间线中显示为“Project workflow”及其后的事件名称,且不会触发其他工作流。工作流不会在已关闭的项目中运行,也不会处理已归档仓库中的条目。
## 权限
任何拥有项目读取权限的人都可以查看其工作流。管理工作流需要项目的写入权限,并满足以下条件:
- 仓库项目:拥有该仓库的问题和合并请求的写入权限。
- 组织项目:是组织所有者或站点管理员。
- 用户项目:是项目所有者。
仅限公开仓库的访问令牌无法管理组织或用户项目的工作流。无论谁触发事件,工作流都会执行其动作。
## API
可通过仓库(`/repos/{owner}/{repo}/projects/{id}`)、组织(`/orgs/{org}/projects/{id}`)或已认证用户(`/user/projects/{id}`)的项目路由管理工作流:
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| `GET` | `.../workflows` | 列出工作流 |
| `GET` | `.../workflows/{workflow_id}` | 获取工作流 |
| `POST` | `.../workflows` | 创建工作流 |
| `PATCH` | `.../workflows/{workflow_id}` | 编辑工作流,未提供的字段保持不变 |
| `DELETE` | `.../workflows/{workflow_id}` | 删除工作流 |
工作流包含 `event`(`item_added_to_project`、`item_removed_from_project`、`item_reopened`、`item_closed`、`item_column_changed`、`code_changes_requested`、`code_review_approved` 或 `pull_request_merged`)、`enabled` 标志、`filters`(`issue_type`、`source_column_id`、`target_column_id`、`label_ids`)以及 `actions`(`column_id`、`add_label_ids`、`remove_label_ids`、`issue_state`)。每个事件仅接受[事件](#事件)表中列出的过滤器和动作。
## 示例
要将新的缺陷报告分流至待分类列,请为 **Item added to project** 创建工作流:
- **Apply to**:Issues only
- **Only if it has labels**:`bug`
- **Move to column**:Triage
- **Add labels**:`needs-triage`
@@ -8,7 +8,7 @@ aliases:
# 数据库准备
在使用 Gitea 前,您需要准备一个数据库。Gitea 支持 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(内置) 和 MSSQL(>= 2012 SP4)这几种数据库。本页将指导您准备数据库。由于 PostgreSQL 和 MySQL 在生产环境中被广泛使用,因此本文档将仅涵盖这两种数据库。如果您计划使用 SQLite,则可以忽略本章内容。
在使用 Gitea 前,您需要准备一个数据库。Gitea 支持 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(内置) 和 MSSQL(>= 2012 SP4)这几种数据库。本页将指导您准备数据库。本文档涵盖 PostgreSQL、MySQL 和 MSSQL。如果您计划使用 SQLite,则可以忽略本章内容。
如果您使用不受支持的数据库版本,请通过 [联系我们](/help/support) 以获取有关我们的扩展支持的信息。我们可以为旧数据库提供测试和支持,并将这些修复集成到 Gitea 代码库中。
@@ -168,6 +168,28 @@ aliases:
您应该会被提示输入数据库用户的密码,并连接到数据库。
## MSSQL
1. 以管理员身份创建登录名、使用大小写敏感排序规则的数据库及其用户。请将密码 `'gitea'` 替换为安全的密码:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
升级会更改数据库结构,因此该用户需要 `db_owner`,或者 `db_ddladmin`、`db_datareader` 和 `db_datawriter`。使用后者时,还需以管理员身份执行 `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;`。
2. 在您的 Gitea 服务器上,测试与数据库的连接:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## 使用 TLS 进行数据库连接
如果 Gitea 和您的数据库实例之间的通信是通过私有网络进行的,或者如果 Gitea 和数据库运行在同一台服务器上,那么可以省略本节,因为 Gitea 和数据库实例之间的安全性不会受到严重威胁。但是,如果数据库实例位于公共网络上,请使用 TLS 对数据库连接进行加密,以防止第三方拦截流量数据。
@@ -21,15 +21,7 @@ Gitea Actions旨在与GitHub Actions兼容,差异如下。
`uses:`支持以下前缀:
- `self:`引用您自己的Gitea实例,例如`uses: self:owner/repo@v1`或`uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:`运行Gitea Runner内置的Action,无需下载,Job镜像中也无需Node,例如`uses: builtin:checkout`
`builtin:checkout`支持`actions/checkout`的`repository`、`ref`、`token`、`path`和`fetch-depth`输入,默认值相同,其他输入会使步骤失败。
<a id="workflow-relative-actions"></a>
### 相对于工作流的Actions
`$/`引用工作流所在的仓库和提交,或外层复合Action所在的仓库和提交,例如`uses: $/.gitea/actions/build`。
与`./`不同,它无需事先检出代码。
- `builtin:`运行Gitea Runner内置的Action,无需下载,也不依赖Node.js,例如`uses: builtin:checkout`
### 使用Go编写Actions
@@ -95,7 +87,7 @@ Gitea Actions旨在与GitHub Actions兼容,差异如下。
未指定主机的Actions(如`uses: actions/checkout@v4`)会从`https://github.com`下载,当`[actions].DEFAULT_ACTIONS_URL`为`self`时则从您自己的实例下载。
请参阅[配置备忘单](../../administration/config-cheat-sheet.md#actions-actions)。
其他来源请参阅[Action URL绝对路径](#absolute-action-urls)、[Action前缀](#action-prefixes)和[相对于工作流的Actions](#workflow-relative-actions)。
其他来源请参阅[Action URL绝对路径](#absolute-action-urls)和[Action前缀](#action-prefixes)。
### 上下文可用性
@@ -142,7 +142,7 @@ aliases:
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: 在預設的 squash 合併消息中,包括構成拉取請求的所有提交的提交消息。
- `ADD_CO_COMMITTER_TRAILERS`: **true**: 如果提交者與作者不匹配,在合併提交消息中添加`co-authored-by`和`co-committed-by`標記。
- `RETARGET_CHILDREN_ON_MERGE`: **true**: 當父合併請求被合併時,將子合併請求重新定向到父合併請求的目標分支。僅適用於頭分支和基分支指向同一儲存庫的已合併合併請求。
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **false**: 為新儲存庫設定"合併後預設刪除合併請求分支"的預設值。
- `DEFAULT_DELETE_BRANCH_AFTER_MERGE`: **true**: 為新儲存庫設定"合併後預設刪除合併請求分支"的預設值。
### 儲存庫 - 工單 (`repository.issue`)
@@ -529,7 +529,8 @@ Gitea 建立以下非唯一隊列:
- `REVERSE_PROXY_AUTHENTICATION_USER`: **X-WEBAUTH-USER**: 反向代理認證的 HTTP 頭部名稱,用於提供使用者資訊。
- `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: 反向代理認證的 HTTP 頭部名稱,用於提供郵箱資訊。
- `REVERSE_PROXY_AUTHENTICATION_FULL_NAME`: **X-WEBAUTH-FULLNAME**: 反向代理認證的 HTTP 頭部名稱,用於提供全名資訊。
- `REVERSE_PROXY_LIMIT`: **1**: 解釋 X-Forwarded-For 標頭或 X-Real-IP 標頭,並將其設定為請求的遠程 IP。
- `REVERSE_PROXY_LIMIT`: **1**: 依序解釋 X-Real-IP、X-Forwarded-For 或 Forwarded 標頭,並將其設定為請求的遠程 IP。
客戶端連接埠取自標頭值,或在使用 X-Real-IP 時取自 X-Real-Port。
可信代理計數。設定為零以不使用這些標頭。
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: 逗號分隔的受信任代理伺服器的 IP 地址和網路列表。使用 `*` 來信任全部。
- `DISABLE_GIT_HOOKS`: **true**: 設定為 `false` 以允許具有 Git 鉤子權限的使用者建立自訂 Git 鉤子。
@@ -1201,7 +1202,7 @@ In-Reply-To =
- `JWT_SECRET_URI`:**_empty_**: 可以使用此設定選項,而不是在設定中定義`JWT_SECRET`,以向 Gitea 提供包含密鑰的文件的路徑(範例值:`file:/etc/gitea/oauth2_jwt_secret`)。
- `JWT_SIGNING_PRIVATE_KEY_FILE`:**jwt/private.pem**: 用於簽署 OAuth2 令牌的私鑰文件路徑。路徑相對於`APP_DATA_PATH`。僅當`JWT_SIGNING_ALGORITHM`設定為`RS256`,`RS384`,`RS512`,`ES256`,`ES384`或`ES512`時才需要此設定。文件必須包含 PKCS8 格式的 RSA 或 ECDSA 私鑰。如果不存在密鑰,則將為您建立一個 4096 位密鑰。
- `MAX_TOKEN_LENGTH`:**32767**: 從 OAuth2 提供者接受的令牌/cookie 的最大長度。
- `DEFAULT_APPLICATIONS`:**git-credential-oauth,git-credential-manager, tea**: 在啟動時預註冊用於某些服務的 OAuth 應用程式。有關可用選項列表,請參閱[OAuth2 文件](/development/oauth2-provider.md)。
- `DEFAULT_APPLICATIONS`:**git-credential-oauth, git-credential-manager, gitea-cli, gitea-app, gitea-vscode**: 在啟動時預註冊用於某些服務的 OAuth 應用程式。有關可用選項列表,請參閱[OAuth2 文件](/development/oauth2-provider.md)。
## i18n (`i18n`)
@@ -8,7 +8,7 @@ aliases:
# 資料庫準備
在使用 Gitea 前,您需要準備一個資料庫。Gitea 支援 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(內置) 和 MSSQL(>= 2012 SP4)這幾種資料庫。本頁將指導您準備資料庫。由於 PostgreSQL 和 MySQL 在生產環境中被廣泛使用,因此本文件將僅涵蓋這兩種資料庫。如果您計劃使用 SQLite,則可以忽略本章內容。
在使用 Gitea 前,您需要準備一個資料庫。Gitea 支援 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(內置) 和 MSSQL(>= 2012 SP4)這幾種資料庫。本頁將指導您準備資料庫。本文件涵蓋 PostgreSQL、MySQL 和 MSSQL。如果您計劃使用 SQLite,則可以忽略本章內容。
如果您使用不受支援的資料庫版本,請通過 [聯繫我們](/help/support) 以獲取有關我們的擴展支援的資訊。我們可以為舊資料庫提供測試和支援,並將這些修復整合到 Gitea 程式碼庫中。
@@ -168,6 +168,28 @@ aliases:
您應該會被提示輸入資料庫使用者的密碼,並連接到資料庫。
## MSSQL
1. 以管理員身份建立登入名稱、使用大小寫敏感排序規則的資料庫及其使用者。請將密碼 `'gitea'` 替換為安全的密碼:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
升級會更改資料庫結構,因此該使用者需要 `db_owner`,或者 `db_ddladmin`、`db_datareader` 和 `db_datawriter`。使用後者時,還需以管理員身份執行 `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;`。
2. 在您的 Gitea 伺服器上,測試與資料庫的連接:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## 使用 TLS 進行資料庫連接
如果 Gitea 和您的資料庫實例之間的通信是通過私有網路進行的,或者如果 Gitea 和資料庫運行在同一臺伺服器上,那麼可以省略本節,因為 Gitea 和資料庫實例之間的安全性不會受到嚴重威脅。但是,如果資料庫實例位於公共網路上,請使用 TLS 對資料庫連接進行加密,以防止第三方攔截流量資料。
@@ -21,15 +21,7 @@ Gitea Actions 旨在與 GitHub Actions 相容,差異如下。
`uses:` 接受以下前綴:
- `self:` 參照您自己的 Gitea 實例,例如 `uses: self:owner/repo@v1` 或 `uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:` 執行 Gitea Runner 內建的 Action,無需下載,Job 映像檔中也不需要 Node,例如 `uses: builtin:checkout`
`builtin:checkout` 支援 `actions/checkout` 的 `repository`、`ref`、`token`、`path` 和 `fetch-depth` 輸入,預設值相同,其他輸入會使步驟失敗。
<a id="workflow-relative-actions"></a>
### 相對於工作流的 Actions
`$/` 參照工作流(或外層複合 Action)所在的儲存庫與提交,例如 `uses: $/.gitea/actions/build`。
與 `./` 不同,它不需要事先簽出程式碼。
- `builtin:` 執行 Gitea Runner 內建的 Action,無需下載,也不依賴 Node.js,例如 `uses: builtin:checkout`
### 使用Go編寫Actions
@@ -95,7 +87,7 @@ Gitea Actions 旨在與 GitHub Actions 相容,差異如下。
未指定主機的 Actions,例如 `uses: actions/checkout@v4`,會從 `https://github.com` 下載,若 `[actions].DEFAULT_ACTIONS_URL` 為 `self`,則從您自己的實例下載。
請參閱[設定速查表](../../administration/config-cheat-sheet.md#actions-actions)。
其他來源請參閱 [Action URL絕對路徑](#absolute-action-urls)、[Action 前綴](#action-prefixes)和[相對於工作流的 Actions](#workflow-relative-actions)。
其他來源請參閱 [Action URL絕對路徑](#absolute-action-urls)和[Action 前綴](#action-prefixes)。
### 上下文可用性
@@ -6,10 +6,90 @@ sidebar_position: 25
# 變量
## 環境變量
以下環境變量會在每次工作流執行時自動設定,可以直接存取(例如在 shell 腳本中使用 `$CI`)。
同時列出 `GITEA_*` 和 `GITHUB_*` 名稱的變量值相同。
| 名稱 | 描述 | 範例 |
|---|---|---|
| `ACT` | 始終為 `true`,除非 Runner 設定了 `runner.set_act_env: false`。 | `true` |
| `CI` | 始終為 `true`。 | `true` |
| `GITEA_ACTION`<br/>`GITHUB_ACTION` | 目前步驟的 `id`,未設定時為步驟的序號。 | `0` |
| `GITEA_ACTION_PATH`<br/>`GITHUB_ACTION_PATH` | Action 所在的路徑。僅在複合 Action 中設定。 | `/var/run/act/actions/***` |
| `GITEA_ACTION_REF`<br/>`GITHUB_ACTION_REF` | 正在執行的 Action 的 ref。 | `v4` |
| `GITEA_ACTION_REPOSITORY`<br/>`GITHUB_ACTION_REPOSITORY` | Action 的所有者和儲存庫名稱。 | `actions/checkout` |
| `GITEA_ACTIONS`<br/>`GITHUB_ACTIONS` | 始終為 `true`。`GITEA_ACTIONS` 可用於區分 Gitea Actions 和其他 CI 系統。 | `true` |
| `GITEA_ACTIONS_RUNNER_VERSION` | 執行工作流的 Runner 的版本。 | `v5.2.4` |
| `GITEA_ACTOR`<br/>`GITHUB_ACTOR` | 觸發工作流的使用者的使用者名稱。 | `alice` |
| `GITEA_ACTOR_ID`<br/>`GITHUB_ACTOR_ID` | 觸發工作流的使用者的 ID。 | `1` |
| `GITEA_API_URL`<br/>`GITHUB_API_URL` | REST API 的 URL。 | `https://gitea.example.com/api/v1` |
| `GITEA_BASE_REF`<br/>`GITHUB_BASE_REF` | 拉取請求的目標分支。 | `main` |
| `GITEA_DOCKER_WORKSPACE` | Docker 守護程式所見的工作區路徑,用於綁定掛載到 Job 啟動的容器中,例如在 compose 檔案中使用 `${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data`。僅在 Job 於容器中執行時設定。 | `/var/lib/docker/volumes/GITEA-ACTIONS-TASK-42-***/_data` |
| `GITEA_ENV`<br/>`GITHUB_ENV` | 為後續步驟設定環境變量的檔案路徑。 | `/var/run/act/workflow/envs.txt` |
| `GITEA_EVENT_NAME`<br/>`GITHUB_EVENT_NAME` | 觸發工作流的事件名稱。 | `push` |
| `GITEA_EVENT_PATH`<br/>`GITHUB_EVENT_PATH` | 包含事件 Webhook 負載的檔案路徑。 | `/var/run/act/workflow/event.json` |
| `GITEA_GRAPHQL_URL`<br/>`GITHUB_GRAPHQL_URL` | 在 Gitea 中為空(不支援 GraphQL)。 | _(空)_ |
| `GITEA_HEAD_REF`<br/>`GITHUB_HEAD_REF` | 拉取請求的來源分支。 | `feature-branch` |
| `GITEA_JOB`<br/>`GITHUB_JOB` | 目前 Job 的 `job_id`。 | `build` |
| `GITEA_OUTPUT`<br/>`GITHUB_OUTPUT` | 設定步驟輸出參數的檔案路徑。 | `/var/run/act/workflow/outputcmd.txt` |
| `GITEA_PATH`<br/>`GITHUB_PATH` | 為後續步驟新增系統 `PATH` 項目的檔案路徑。 | `/var/run/act/workflow/pathcmd.txt` |
| `GITEA_REF`<br/>`GITHUB_REF` | 觸發工作流的完整 ref。 | `refs/heads/main` |
| `GITEA_REF_NAME`<br/>`GITHUB_REF_NAME` | ref 的短名稱。 | `main` |
| `GITEA_REF_PROTECTED`<br/>`GITHUB_REF_PROTECTED` | 如果觸發工作流的 ref 設定了分支保護,則為 `true`。 | `true` |
| `GITEA_REF_TYPE`<br/>`GITHUB_REF_TYPE` | ref 的類型:`branch` 或 `tag`。 | `branch` |
| `GITEA_REPOSITORY`<br/>`GITHUB_REPOSITORY` | 所有者和儲存庫名稱。 | `owner/repo` |
| `GITEA_REPOSITORY_ID`<br/>`GITHUB_REPOSITORY_ID` | 儲存庫的 ID。 | `123` |
| `GITEA_REPOSITORY_OWNER`<br/>`GITHUB_REPOSITORY_OWNER` | 儲存庫所有者的使用者名稱。 | `owner` |
| `GITEA_REPOSITORY_OWNER_ID`<br/>`GITHUB_REPOSITORY_OWNER_ID` | 儲存庫所有者的 ID。 | `45` |
| `GITEA_RETENTION_DAYS`<br/>`GITHUB_RETENTION_DAYS` | Artifact 的保留天數,永久保留時為空。 | `90` |
| `GITEA_RUN_ATTEMPT`<br/>`GITHUB_RUN_ATTEMPT` | 工作流執行的嘗試次數。 | `1` |
| `GITEA_RUN_ID`<br/>`GITHUB_RUN_ID` | 每次工作流執行的唯一編號。 | `1234` |
| `GITEA_RUN_NUMBER`<br/>`GITHUB_RUN_NUMBER` | 特定工作流每次執行的唯一編號。 | `42` |
| `GITEA_SERVER_URL`<br/>`GITHUB_SERVER_URL` | Gitea 實例的 URL。 | `https://gitea.example.com` |
| `GITEA_SHA`<br/>`GITHUB_SHA` | 觸發工作流的提交 SHA。 | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_STATE`<br/>`GITHUB_STATE` | 設定步驟狀態變量的檔案路徑。 | `/var/run/act/workflow/statecmd.txt` |
| `GITEA_STEP_SUMMARY`<br/>`GITHUB_STEP_SUMMARY` | 寫入 Job 摘要的檔案路徑。 | `/var/run/act/workflow/step-summary-0.md` |
| `GITEA_TRIGGERING_ACTOR`<br/>`GITHUB_TRIGGERING_ACTOR` | 發起工作流執行的使用者的使用者名稱。重新執行時可能與 `GITEA_ACTOR` 不同。 | `alice` |
| `GITEA_WORKFLOW`<br/>`GITHUB_WORKFLOW` | 工作流的名稱。 | `CI` |
| `GITEA_WORKFLOW_SHA`<br/>`GITHUB_WORKFLOW_SHA` | 工作流檔案的提交 SHA。 | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
| `GITEA_WORKSPACE`<br/>`GITHUB_WORKSPACE` | Runner 上的預設工作目錄。 | `/workspace/owner/repo` |
| `TRACEPARENT` | Job span 的 W3C 追蹤上下文,供已接入追蹤的工具將 span 新增到 Job 的追蹤中。僅在 Runner 匯出追蹤資料時設定,參見[監控](/runner/monitoring/#opentelemetry)。 | `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` |
| `TRACESTATE` | 隨 `TRACEPARENT` 附帶的廠商特定追蹤資料。僅在追蹤包含此類資料時設定。 | `rojo=00f067aa0ba902b7` |
### Runner 環境變量
| 名稱 | 描述 | 範例 |
|---|---|---|
| `ImageOS` | Job 映像的作業系統和版本,供 `setup-*` Action 讀取。 | `ubuntu24` |
| `RUNNER_ARCH` | Runner 的架構。 | `X64` |
| `RUNNER_DEBUG` | 當 `ACTIONS_STEP_DEBUG` 密鑰為 `true` 時設定為 `1`,否則不設定。 | `1` |
| `RUNNER_ENVIRONMENT` | 始終為 `self-hosted`。 | `self-hosted` |
| `RUNNER_NAME` | 執行 Job 的 Runner 的名稱。 | `my-runner` |
| `RUNNER_OS` | Runner 的作業系統。 | `Linux` |
| `RUNNER_TEMP` | Runner 上暫存目錄的路徑。 | `/tmp` |
| `RUNNER_TOOL_CACHE` | Runner 上工具快取目錄的路徑。 | `/opt/hostedtoolcache` |
| `RUNNER_WORKSPACE` | `GITEA_WORKSPACE` 的上層目錄。 | `/workspace/owner` |
### 內部環境變量
這些變量供 Runner 和 Action 內部使用,工作流中通常不需要直接使用。
| 名稱 | 描述 | 範例 |
|---|---|---|
| `ACTIONS_CACHE_URL` | Actions 快取服務的 URL。 | `http://192.168.1.10:8088/` |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | 用於 OIDC 請求的令牌。僅在授予 `id-token: write` 時設定。 | `***` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | 請求 OIDC 令牌的 URL。僅在授予 `id-token: write` 時設定。 | `https://gitea.example.com/api/actions/oidc/token?` |
| `ACTIONS_RESULTS_URL` | 儲存 Artifact 的 URL。 | `https://gitea.example.com` |
| `ACTIONS_RUNTIME_TOKEN` | Actions 管線 API 的驗證令牌。 | `***` |
| `ACTIONS_RUNTIME_URL` | Gitea Actions 管線 API 的 URL。 | `https://gitea.example.com/api/actions_pipeline/` |
## 使用者定義的變量
您可以建立使用者、組織和儲存庫級別的變量。變量的級別取決於建立它的位置。當建立變量時,變量的名稱會被
轉換為大寫,在yaml文件中引用時需要使用大寫。
## 命名規則
### 命名規則
以下規則適用於變量名:
@@ -20,11 +100,11 @@ sidebar_position: 25
- 變量名稱在建立它們的級別上必須是唯一的。
- 變量名稱不能為 `CI`。
## 使用
### 使用
建立設定變量後,它們將自動填充到 `vars` 上下文中。您可以在工作流中使用類似 `${{ vars.VARIABLE_NAME }}` 這樣的表達式來使用它們。
## 優先級
### 優先級
如果同名變量存在於多個級別,則級別最低的變量優先。
儲存庫級別的變量總是比組織或者使用者級別的變量優先被選中。
@@ -0,0 +1,9 @@
{
"label": "專案",
"position": 60,
"link": {
"type": "generated-index",
"slug": "/usage/projects",
"description": "使用專案看板規劃與追蹤工作"
}
}
@@ -0,0 +1,82 @@
---
date: "2025-11-25T18:58:22Z"
slug: "project-workflows"
sidebar_position: 1
description: "透過事件驅動的篩選條件與動作,讓專案看板自動化。"
---
# 專案工作流程
專案工作流程可讓專案看板自動化。當專案中的問題或合併請求觸發事件時,該事件的每個已啟用工作流程都會檢查篩選條件並執行動作。工作流程在 Gitea 中執行,不需要 runner。
## 編輯工作流程
1. 開啟專案並選取 **Workflows**。
2. 在側邊欄選取事件。
3. 設定篩選條件與動作,然後選取 **Save**。若要變更現有工作流程,請先選取 **Edit**。
一個事件可以有多個工作流程。**Clone** 會複製選取的工作流程,方便您調整後用於其他項目。**Disable** 會暫停工作流程並保留設定。**Remove** 會刪除工作流程。
## 事件
| 事件 | 執行時機 | 篩選條件 | 動作 |
| --- | --- | --- | --- |
| Item added to project | 項目加入專案或在專案中建立時 | Apply to、標籤 | Move to column、標籤、問題狀態 |
| Item removed from project | 項目從專案移除時 | Apply to、標籤 | 標籤、問題狀態 |
| Item reopened | 項目重新開啟時 | Apply to、標籤 | Move to column、標籤 |
| Item closed | 項目關閉時 | Apply to、標籤 | Move to column、標籤 |
| Item column changed | 項目移至另一欄時 | Apply to、欄、標籤 | 標籤、問題狀態 |
| Code changes requested | 正式審查者要求修改合併請求時 | 標籤 | Move to column、標籤 |
| Code review approved | 正式審查者核准合併請求時 | 標籤 | Move to column、標籤 |
| Pull request merged | 合併請求合併時 | 標籤 | Move to column、標籤 |
## 篩選條件
未設定篩選條件的工作流程會對所有項目執行。
- **Apply to**:問題、合併請求或兩者。
- **When moved from column**、**When moved to column**:項目離開或進入的欄。
- **Only if it has labels**:項目必須具有所有選取的標籤。
## 動作
工作流程至少需要一個動作。動作依下列順序執行:
1. **Move to column**:將項目移至某一欄。
2. **Add labels**、**Remove labels**:變更項目的標籤。
3. **Issue state**:關閉或重新開啟項目。工作流程不會重新開啟合併請求。
工作流程所做的變更會在時間軸中顯示為「Project workflow」加上事件名稱,且不會觸發其他工作流程。專案已關閉或項目位於已封存的儲存庫時,工作流程不會執行。
## 權限
任何具有專案讀取權限的使用者都能檢視其工作流程。管理工作流程需要專案的寫入權限,以及:
- 儲存庫專案:該儲存庫的問題與合併請求的寫入權限。
- 組織專案:組織擁有者或網站管理員身分。
- 使用者專案:專案擁有者身分。
僅限公開儲存庫的存取權杖無法管理組織或使用者專案的工作流程。無論誰觸發事件,工作流程都會執行其動作。
## API
透過儲存庫(`/repos/{owner}/{repo}/projects/{id}`)、組織(`/orgs/{org}/projects/{id}`)或已驗證使用者(`/user/projects/{id}`)的專案路由管理工作流程:
| 方法 | 路徑 | 用途 |
| --- | --- | --- |
| `GET` | `.../workflows` | 列出工作流程 |
| `GET` | `.../workflows/{workflow_id}` | 取得工作流程 |
| `POST` | `.../workflows` | 建立工作流程 |
| `PATCH` | `.../workflows/{workflow_id}` | 編輯工作流程,未提供的欄位保持不變 |
| `DELETE` | `.../workflows/{workflow_id}` | 刪除工作流程 |
工作流程包含 `event`(`item_added_to_project`、`item_removed_from_project`、`item_reopened`、`item_closed`、`item_column_changed`、`code_changes_requested`、`code_review_approved` 或 `pull_request_merged`)、`enabled` 旗標、`filters`(`issue_type`、`source_column_id`、`target_column_id`、`label_ids`)與 `actions`(`column_id`、`add_label_ids`、`remove_label_ids`、`issue_state`)。每個事件僅接受[事件](#事件)中列出的篩選條件與動作。
## 範例
若要將新的錯誤回報送往分類處理,請為 **Item added to project** 建立工作流程:
- **Apply to**:Issues only
- **Only if it has labels**:`bug`
- **Move to column**:Triage
- **Add labels**:`needs-triage`
@@ -8,7 +8,7 @@ aliases:
# 資料庫準備
在使用 Gitea 前,您需要準備一個資料庫。Gitea 支援 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(內置) 和 MSSQL(>= 2012 SP4)這幾種資料庫。本頁將指導您準備資料庫。由於 PostgreSQL 和 MySQL 在生產環境中被廣泛使用,因此本文件將僅涵蓋這兩種資料庫。如果您計劃使用 SQLite,則可以忽略本章內容。
在使用 Gitea 前,您需要準備一個資料庫。Gitea 支援 PostgreSQL(>= 12)、MySQL(>= 8.0)、MariaDB(>= 10.4)、SQLite(內置) 和 MSSQL(>= 2012 SP4)這幾種資料庫。本頁將指導您準備資料庫。本文件涵蓋 PostgreSQL、MySQL 和 MSSQL。如果您計劃使用 SQLite,則可以忽略本章內容。
如果您使用不受支援的資料庫版本,請通過 [聯繫我們](/help/support) 以獲取有關我們的擴展支援的資訊。我們可以為舊資料庫提供測試和支援,並將這些修復整合到 Gitea 程式碼庫中。
@@ -168,6 +168,28 @@ aliases:
您應該會被提示輸入資料庫使用者的密碼,並連接到資料庫。
## MSSQL
1. 以管理員身份建立登入名稱、使用大小寫敏感排序規則的資料庫及其使用者。請將密碼 `'gitea'` 替換為安全的密碼:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
升級會更改資料庫結構,因此該使用者需要 `db_owner`,或者 `db_ddladmin`、`db_datareader` 和 `db_datawriter`。使用後者時,還需以管理員身份執行 `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;`。
2. 在您的 Gitea 伺服器上,測試與資料庫的連接:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## 使用 TLS 進行資料庫連接
如果 Gitea 和您的資料庫實例之間的通信是通過私有網路進行的,或者如果 Gitea 和資料庫運行在同一臺伺服器上,那麼可以省略本節,因為 Gitea 和資料庫實例之間的安全性不會受到嚴重威脅。但是,如果資料庫實例位於公共網路上,請使用 TLS 對資料庫連接進行加密,以防止第三方攔截流量資料。
@@ -21,15 +21,7 @@ Gitea Actions 旨在與 GitHub Actions 相容,差異如下。
`uses:` 接受以下前綴:
- `self:` 參照您自己的 Gitea 實例,例如 `uses: self:owner/repo@v1` 或 `uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:` 執行 Gitea Runner 內建的 Action,無需下載,Job 映像檔中也不需要 Node,例如 `uses: builtin:checkout`
`builtin:checkout` 支援 `actions/checkout` 的 `repository`、`ref`、`token`、`path` 和 `fetch-depth` 輸入,預設值相同,其他輸入會使步驟失敗。
<a id="workflow-relative-actions"></a>
### 相對於工作流的 Actions
`$/` 參照工作流(或外層複合 Action)所在的儲存庫與提交,例如 `uses: $/.gitea/actions/build`。
與 `./` 不同,它不需要事先簽出程式碼。
- `builtin:` 執行 Gitea Runner 內建的 Action,無需下載,也不依賴 Node.js,例如 `uses: builtin:checkout`
### 使用Go編寫Actions
@@ -95,7 +87,7 @@ Gitea Actions 旨在與 GitHub Actions 相容,差異如下。
未指定主機的 Actions,例如 `uses: actions/checkout@v4`,會從 `https://github.com` 下載,若 `[actions].DEFAULT_ACTIONS_URL` 為 `self`,則從您自己的實例下載。
請參閱[設定速查表](../../administration/config-cheat-sheet.md#actions-actions)。
其他來源請參閱 [Action URL絕對路徑](#absolute-action-urls)、[Action 前綴](#action-prefixes)和[相對於工作流的 Actions](#workflow-relative-actions)。
其他來源請參閱 [Action URL絕對路徑](#absolute-action-urls)和[Action 前綴](#action-prefixes)。
### 上下文可用性
+1 -1
View File
@@ -13,5 +13,5 @@
"engines": {
"node": ">=22"
},
"packageManager": "[email protected]3.0"
"packageManager": "[email protected]6.1"
}
+46 -6
View File
@@ -8,7 +8,7 @@
export type LocaleId = 'en-us' | 'zh-cn' | 'zh-tw';
export type ProductId = 'docs' | 'api' | 'runner' | 'enterprise';
export type ProductId = 'docs' | 'api' | 'runner' | 'cli' | 'enterprise';
/** Values substituted for `@name@` placeholders in the markdown sources. */
export interface VersionVariables {
@@ -89,11 +89,11 @@ const variables: Record<string, VersionVariables> = {
goVersion: '1.27',
minGoVersion: '1.27',
minNodeVersion: '22',
version: '28.2.0',
sourceVersion: 'v28.2.0',
version: '28.3.0',
sourceVersion: 'v28.3.0',
sourceBranch: 'release/v28',
dockerVersion: '28.2.0',
displayVersion: '28.2.0',
dockerVersion: '28.3.0',
displayVersion: '28.3.0',
},
'1.27': {
goVersion: '1.26',
@@ -246,6 +246,40 @@ const runnerProduct: ProductDef = {
],
};
/**
* gt, the Gitea CLI: laid out like the runner. Until the first series is listed
* here the develop docs are served at the product root, without the unreleased
* banner, since there is no release to point to. Listing a series moves them to
* `/cli/develop/`.
*/
const cliSeries: { id: string; latestRelease: string }[] = [];
const cliProduct: ProductDef = {
id: 'cli',
label: 'CLI',
base: 'cli',
locales: ['en-us'],
versions: [
{
id: 'develop',
label: 'develop',
sources: { 'en-us': 'cli-docs' },
...(cliSeries.length > 0
? { path: 'develop', banner: 'unreleased' as const }
: { path: '', latest: true }),
},
...cliSeries.map(
({ id, latestRelease }, index): VersionDef => ({
id,
label: latestRelease,
path: index === 0 ? '' : id,
latest: index === 0,
sources: { 'en-us': `cli-docs_versioned_docs/version-${id}` },
}),
),
],
};
/** API reference, rendered from the swagger documents by starlight-openapi. */
const apiProduct: ProductDef = {
id: 'api',
@@ -301,7 +335,13 @@ const enterpriseProduct: ProductDef = {
externalBaseUrl: 'https://docs.gitea.com/enterprise',
};
export const products: ProductDef[] = [docsProduct, apiProduct, runnerProduct, enterpriseProduct];
export const products: ProductDef[] = [
docsProduct,
apiProduct,
runnerProduct,
cliProduct,
enterpriseProduct,
];
export function getProduct(id: ProductId): ProductDef {
const product = products.find((candidate) => candidate.id === id);
+3 -3
View File
@@ -1,7 +1,7 @@
/**
* Builds one sidebar per (product, version, language) out of the loaded pages,
* deriving it from `_category_.json` and from the
* handwritten sidebar files of the runner docs.
* handwritten sidebar files of the runner and the cli docs.
*/
import { defaultLocale } from './products';
@@ -44,7 +44,7 @@ export interface SidebarGroup {
export type SidebarEntry = SidebarLink | SidebarGroup;
/** A hand written sidebar file, as used by the runner docs. */
/** A hand written sidebar file, as used by the runner and the cli docs. */
export type SidebarSourceItem =
| string
| { type: 'doc'; id: string; label?: string }
@@ -148,7 +148,7 @@ function treeOf(pages: SidebarPage[]): Tree {
return { build, label };
}
/** Sidebar described by a hand written sidebar file, used by the runner docs. */
/** Sidebar described by a hand written sidebar file, used by the runner and the cli docs. */
function fromSidebarSource(
items: SidebarSourceItem[],
pages: SidebarPage[],
+316 -218
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -31,7 +31,7 @@ The shell options of `run:` steps do not apply to hooks. Set `pipefail` and othe
## Environment and output
A hook receives the job's environment, including `runner.envs`, the workflow's `env:` and the `GITHUB_*` variables. The runner includes hook output in the job log and masks secrets as it does for step output.
A hook receives the job's environment, including `runner.envs`, the workflow's `env:` and the `GITHUB_*` and `GITEA_*` variables. The runner includes hook output in the job log and masks secrets as it does for step output.
Use `$GITHUB_ENV` and `$GITHUB_PATH` to pass environment variables and paths to later steps. Mask values with `::add-mask::`:
+9 -9
View File
@@ -20,13 +20,13 @@ Usage:
gitea-runner [command]
Available Commands:
bug-report Print information useful when filing a bug report
cache-server Start a cache server for the cache action
config Generate, read and edit config files
daemon Run as a runner daemon
exec Run workflow locally.
help Help about any command
register Register a runner to the server
bug-report Print information useful when filing a bug report
cache-server Start a cache server for the cache action
config Generate, read and edit config files
daemon Run as a runner daemon
exec Run workflow locally.
help Help about any command
register Register a runner to the server
Flags:
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
@@ -91,8 +91,8 @@ Usage:
Flags:
--artifact-server-addr string Defines the address where the artifact server listens
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start. (default ".")
--artifact-server-port string Defines the port where the artifact server listens (will only bind to localhost). (default "34567")
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from, outside the workspace that jobs copy. Defaults to a temporary directory removed on exit.
--artifact-server-port string Defines the port where the artifact server listens (default "34567")
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
--container-cap-add stringArray kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)
--container-cap-drop stringArray kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)
+14 -1
View File
@@ -207,7 +207,8 @@ cache:
# secret_key_file: "/run/secrets/cache-s3-secret-key"
# When true, reuse a cached action instead of fetching from the remote on every job.
# 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.
# until its cache entry expires or is manually removed. A cached action whose files changed size
# since it was downloaded is still fetched again, unless an older runner cached it without sizes.
#offline_mode: false
# 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,
@@ -318,6 +319,18 @@ kubernetes:
#pod_template: {}
# Pod templates merged over pod_template, in runs-on order, for jobs whose runs-on has the label they are keyed by.
#pod_templates: {}
# Have job pods fetch directories, such as actions, and copies of 64 KiB or more gzipped from the runner over the pod network,
# instead of the runner streaming them through the API server. An init container copies gitea-runner from image into each job pod.
# api: through the API server (default). auto: over the pod network, through the API server for a job pod that
# cannot reach the runner. direct: over the pod network only, so a broken setup fails jobs instead of quietly
# costing API server traffic again.
#transfer:
# mode: api
# # Address and port the runner listens on and job pods reach it at, the outbound IP and a free port when empty.
# host: ""
# port: 0
# # Image with gitea-runner on its PATH, the runner pod's image when it has a single container and runs in namespace.
# image: ""
# Optional local task-admission checks. Disabled by default. When enabled, low
# disk space or a failing script pauses new task fetching; existing jobs continue.
@@ -91,8 +91,8 @@ Usage:
Flags:
--artifact-server-addr string Defines the address where the artifact server listens
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start. (default ".")
--artifact-server-port string Defines the port where the artifact server listens (will only bind to localhost). (default "34567")
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from, outside the workspace that jobs copy. Defaults to a temporary directory removed on exit.
--artifact-server-port string Defines the port where the artifact server listens (default "34567")
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
--container-cap-add stringArray kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)
--container-cap-drop stringArray kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)
@@ -207,7 +207,8 @@ cache:
# secret_key_file: "/run/secrets/cache-s3-secret-key"
# When true, reuse a cached action instead of fetching from the remote on every job.
# 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.
# until its cache entry expires or is manually removed. A cached action whose files changed size
# since it was downloaded is still fetched again, unless an older runner cached it without sizes.
#offline_mode: false
# 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,
+10 -8
View File
@@ -4,10 +4,11 @@
*
* node scripts/cut-version.mjs docs 1.28 # freezes docs/ as 1.28
* node scripts/cut-version.mjs runner 4 # freezes runner-docs/ as 4
* node scripts/cut-version.mjs cli 0.1 # freezes cli-docs/ as 0.1
*
* For the docs it copies the english tree, every translation and the sidebar
* file; for the runner the english tree and its sidebar. The version list
* (`versions.json`, `runner-docs_versions.json`) is updated too.
* file; for the runner and the cli the english tree and its sidebar. The
* version list (`versions.json`, `<product>-docs_versions.json`) is updated too.
*
* The label, the release variables (`@version@`, `@dockerVersion@`, ...) and
* which version is served at the root live in
@@ -21,8 +22,8 @@ import process from 'node:process';
const [product, version] = process.argv.slice(2);
if (!product || !version || !['docs', 'runner'].includes(product)) {
console.error('usage: node scripts/cut-version.mjs <docs|runner> <version>');
if (!product || !version || !['docs', 'runner', 'cli'].includes(product)) {
console.error('usage: node scripts/cut-version.mjs <docs|runner|cli> <version>');
process.exit(1);
}
@@ -52,6 +53,7 @@ async function freeze(from, to) {
async function freezeSidebar(from, to) {
if (await exists(to)) throw new Error(`${to} already exists`);
const sidebar = require(path.join(root, from));
await mkdir(path.join(root, path.dirname(to)), { recursive: true });
await writeFile(path.join(root, to), `${JSON.stringify(sidebar, null, 2)}\n`);
console.log(` ${from} -> ${to}`);
}
@@ -80,12 +82,12 @@ if (product === 'docs') {
await addToVersions('versions.json');
} else {
await freeze('runner-docs', `runner-docs_versioned_docs/version-${version}`);
await freeze(`${product}-docs`, `${product}-docs_versioned_docs/version-${version}`);
await freezeSidebar(
'runner-sidebars.js',
`runner-docs_versioned_sidebars/version-${version}-sidebars.json`,
`${product}-sidebars.js`,
`${product}-docs_versioned_sidebars/version-${version}-sidebars.json`,
);
await addToVersions('runner-docs_versions.json');
await addToVersions(`${product}-docs_versions.json`);
}
console.log(
+15 -12
View File
@@ -1,14 +1,15 @@
# Astro + Starlight site
Renders the gitea documentation with [Starlight](https://starlight.astro.build):
the docs (6 versions x 3 languages), the runner docs (4 series) and the api
reference (7 swagger documents). The enterprise docs stay in their own
deployment and are linked from the header.
the docs (6 versions x 3 languages), the runner docs (4 series), the cli docs
and the api reference (7 swagger documents). The enterprise docs stay in their
own deployment and are linked from the header.
The content directories are the ones the site has always used — `docs/`,
`versioned_docs/`, `i18n/`, `runner-docs/`, `runner-docs_versioned_docs/` and
`static/swagger-*.json` (plus `static/openapi3-*.json` since gitea 1.27) — so
the release scripts and the translation workflow stay unchanged.
the release scripts and the translation workflow stay unchanged. The cli docs
in `cli-docs/` follow the layout of the runner docs.
## Running it
@@ -40,6 +41,7 @@ pickers, the version banner, the search facets and the api schemas.
| `i18n/zh-cn/docs/version-1.27/` | `/zh-cn/` |
| `runner-docs_versioned_docs/version-3/` | `/runner/` |
| `runner-docs/` | `/runner/develop/` |
| `cli-docs/` | `/cli/`, until a cli series is released |
| `static/openapi3-27.json` | `/api/` |
| `static/openapi3-latest.json` | `/api/next/` |
| `static/swagger-26.json` | `/api/1.26/` |
@@ -60,8 +62,9 @@ of every file, the second normalizes and renders it:
Sidebars are built per (product, version, language) from `_category_.json` and
from the sidebar files (`sidebars.js`, `versioned_sidebars/`,
`runner-sidebars.js`, `runner-docs_versioned_sidebars/`), and selected in
`src/routeData.ts`, since starlight only supports a single static sidebar.
`runner-sidebars.js`, `runner-docs_versioned_sidebars/`, `cli-sidebars.js`),
and selected in `src/routeData.ts`, since starlight only supports a single
static sidebar.
Set `GITEA_DOCS_STRICT_LINKS=true` to fail the build on a broken internal link
instead of warning.
@@ -69,12 +72,12 @@ instead of warning.
## Products and languages
The docs are the site itself, so their language comes first: `/zh-cn/1.26/`.
The runner and the api are separate products and keep their language inside the
product, `/runner/zh-cn/3/`, which is reserved: both are published in english
only today. Starlight builds a fallback page in every configured language for
every english page, so `/zh-cn/runner/` would exist; the post build integration
removes those directories and `cloudflare/_redirects` sends them to the
english page.
The runner, the cli and the api are separate products and keep their language
inside the product, `/runner/zh-cn/3/`, which is reserved: all are published in
english only today. Starlight builds a fallback page in every configured
language for every english page, so `/zh-cn/runner/` would exist; the post build
integration removes those directories and `cloudflare/_redirects` sends them to
the english page.
The version served at the root of a product has no number in its url: docs 1.27
is `/`, runner 3 is `/runner/` and api 1.27 is `/api/`. `/1.27/`, `/runner/3/`
+3 -3
View File
@@ -11,16 +11,16 @@
"check": "astro check"
},
"dependencies": {
"@astrojs/starlight": "0.42.6",
"@astrojs/starlight": "0.42.7",
"@astrojs/starlight-docsearch": "0.8.0",
"@gitea-docs/content-loader": "workspace:*",
"@pagefind/default-ui": "1.5.2",
"astro": "7.3.8",
"astro": "7.4.2",
"sharp": "0.35.5",
"starlight-openapi": "0.27.0"
},
"devDependencies": {
"@astrojs/check": "0.9.10",
"@astrojs/check": "0.9.12",
"typescript": "6.0.3"
}
}
+3 -3
View File
@@ -23,7 +23,7 @@ type Strings = {
const en: Strings = {
versionLabel: 'Version',
languageLabel: 'Language',
products: { docs: 'Docs', api: 'API', runner: 'Runner', enterprise: 'Enterprise' },
products: { docs: 'Docs', api: 'API', runner: 'Runner', cli: 'CLI', enterprise: 'Enterprise' },
footer: { Community: 'Community', Code: 'Code', More: 'More' },
signIn: 'Sign In',
translationNotice: 'This translation may be behind the english original.',
@@ -41,7 +41,7 @@ const strings: Record<string, Strings> = {
'zh-cn': {
versionLabel: '版本',
languageLabel: '语言',
products: { docs: '文档', api: 'API', runner: 'Runner', enterprise: '企业版' },
products: { docs: '文档', api: 'API', runner: 'Runner', cli: 'CLI', enterprise: '企业版' },
footer: { Community: '社区', Code: '开源代码', More: '更多' },
signIn: '登录',
translationNotice: '当前中文文档翻译不是最新版,访问英文版本查看最新内容,或',
@@ -56,7 +56,7 @@ const strings: Record<string, Strings> = {
'zh-tw': {
versionLabel: '版本',
languageLabel: '語言',
products: { docs: '文件', api: 'API', runner: 'Runner', enterprise: '企業版' },
products: { docs: '文件', api: 'API', runner: 'Runner', cli: 'CLI', enterprise: '企業版' },
footer: { Community: '社區', Code: '開源程式碼', More: '更多' },
signIn: '登入',
translationNotice: '當前中文文檔翻譯不是最新版,訪問英文版本查看最新內容,或',
+3 -3
View File
@@ -11,9 +11,9 @@ import { defaultLocale, locales, products, type LocaleId } from '@gitea-docs/con
* generated as `/api/126/`. The directories are renamed and the links inside
* the build are rewritten.
* - starlight builds a fallback page in every configured language for every
* english page. That is what we want for the docs, but the runner and the api
* are separate products with their own language list, so `/zh-cn/runner/` has
* to go; `cloudflare/_redirects` sends it to the english page.
* english page. That is what we want for the docs, but the other products
* have their own language list, so `/zh-cn/runner/` has to go;
* `cloudflare/_redirects` sends it to the english page.
*/
export function giteaPostBuild(): AstroIntegration {
return {
+1 -1
View File
@@ -90,7 +90,7 @@ function addScopeToggle(root: HTMLElement, onChange: (allVersions: boolean) => v
/**
* While all versions are searched the same page shows up once per version, so
* the version (and the product, for the api and the runner) is appended to the
* the version (and the product, for every product but the docs) is appended to the
* title of a result.
*/
function labelResult(result: PagefindResult): void {
+7 -7
View File
@@ -12,9 +12,9 @@ import { getCollection } from 'astro:content';
import { repoRoot } from '../config/paths';
/**
* Sidebar files: the top level order of the docs and the
* handwritten sidebars of the runner, one per version. Read as is, so cutting a
* version keeps needing no change here.
* Sidebar files: the top level order of the docs and the handwritten sidebars
* of the runner and the cli, one per version. Read as is, so cutting a version
* keeps needing no change here.
*/
function sidebarSources(): Map<string, SidebarSourceItem[]> {
const sidebars = new Map<string, SidebarSourceItem[]>();
@@ -42,11 +42,11 @@ function sidebarSources(): Map<string, SidebarSourceItem[]> {
version.id === 'next'
? 'sidebars.js'
: `versioned_sidebars/version-${version.id}-sidebars.json`;
} else if (product.id === 'runner') {
files[`runner@${version.id}`] =
} else if (product.id === 'runner' || product.id === 'cli') {
files[`${product.id}@${version.id}`] =
version.id === 'develop'
? 'runner-sidebars.js'
: `runner-docs_versioned_sidebars/version-${version.id}-sidebars.json`;
? `${product.id}-sidebars.js`
: `${product.id}-docs_versioned_sidebars/version-${version.id}-sidebars.json`;
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ import { z } from 'astro:content';
* per version sidebars, the version and language pickers and the search facets.
*/
export const giteaMeta = z.object({
product: z.enum(['docs', 'api', 'runner', 'enterprise']),
product: z.enum(['docs', 'api', 'runner', 'cli', 'enterprise']),
version: z.string(),
locale: z.string(),
prefix: z.string(),
+3 -3
View File
@@ -5686,7 +5686,7 @@
"x-go-name": "Description"
},
"due_on": {
"description": "Deadline is the updated due date for the milestone",
"description": "Deadline is the due date for the milestone, use null or empty string to remove the deadline",
"format": "date-time",
"type": "string",
"x-go-name": "Deadline"
@@ -7416,7 +7416,7 @@
"description": "IssueLabelsOption a collection of labels",
"properties": {
"labels": {
"description": "Labels can be a list of integers representing label IDs\nor a list of strings representing label names",
"description": "Labels can be a list of integers representing label IDs\nor a list of strings representing label names.\nIf a repository label and an organization label share a name,\nthe repository label is used.",
"items": {},
"type": "array",
"x-go-name": "Labels"
@@ -11119,7 +11119,7 @@
"url": "http://opensource.org/licenses/MIT"
},
"title": "Gitea API",
"version": "28.2.0"
"version": "28.3.0"
},
"openapi": "3.0.3",
"paths": {
+2053 -2462
View File
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -17,7 +17,7 @@
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
},
"version": "28.2.0"
"version": "28.3.0"
},
"basePath": "https://gitea.com/api/v1",
"paths": {
@@ -28779,7 +28779,7 @@
"x-go-name": "Description"
},
"due_on": {
"description": "Deadline is the updated due date for the milestone",
"description": "Deadline is the due date for the milestone, use null or empty string to remove the deadline",
"type": "string",
"format": "date-time",
"x-go-name": "Deadline"
@@ -30525,7 +30525,7 @@
"type": "object",
"properties": {
"labels": {
"description": "Labels can be a list of integers representing label IDs\nor a list of strings representing label names",
"description": "Labels can be a list of integers representing label IDs\nor a list of strings representing label names.\nIf a repository label and an organization label share a name,\nthe repository label is used.",
"type": "array",
"items": {},
"x-go-name": "Labels"
+1937 -2420
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -127,7 +127,7 @@ if [ "$LATEST_ONLY" -eq 1 ]; then
exit 0
fi
for ver in '28.2.0' '1.27.3' '1.26.4' '1.25.5' '1.24.7' '1.23.8' '1.22.6'; do
for ver in '28.3.0' '1.27.3' '1.26.4' '1.25.5' '1.24.7' '1.23.8' '1.22.6'; do
# 1.x releases are suffixed with the minor (1.27.3 -> 27), the versions
# without the 1. prefix with the major (28.0.0 -> 28)
case "$ver" in
@@ -8,7 +8,7 @@ aliases:
# Database Preparation
You need a database to use Gitea. Gitea supports PostgreSQL (>= 12), MySQL (>= 8.0), MariaDB (>= 10.4), SQLite (builtin), and MSSQL (>= 2012 SP4). This page will guide into preparing database. Only PostgreSQL and MySQL will be covered here since those database engines are widely-used in production. If you plan to use SQLite, you can ignore this chapter.
You need a database to use Gitea. Gitea supports PostgreSQL (>= 12), MySQL (>= 8.0), MariaDB (>= 10.4), SQLite (builtin), and MSSQL (>= 2012 SP4). This page will guide into preparing database. PostgreSQL, MySQL and MSSQL are covered here. If you plan to use SQLite, you can ignore this chapter.
:::warning
Converting one database type to another is not a well-tested process and you may experience issues. It is better to choose the final database type at the type of the first installation. Be aware that SQLite does not scale; if you expect your instance to grow at a later time, you should choose another database type.
@@ -177,6 +177,28 @@ All steps below requires that the database engine of your choice is installed on
You should be prompted to enter password for the database user, and connected to the database.
## MSSQL
1. As an administrator, create the login, a database with case-sensitive collation, and its user. Replace the password `'gitea'` with a secure one:
```sql
CREATE LOGIN gitea WITH PASSWORD = 'gitea';
CREATE DATABASE giteadb COLLATE Latin1_General_CS_AS;
GO
USE giteadb;
CREATE USER gitea FOR LOGIN gitea;
ALTER ROLE db_owner ADD MEMBER gitea;
GO
```
Upgrades change the database schema, so the user needs `db_owner`, or `db_ddladmin`, `db_datareader` and `db_datawriter`. With the latter, also run `ALTER DATABASE giteadb SET READ_COMMITTED_SNAPSHOT ON;` as administrator.
2. On your Gitea server, test the connection to the database:
```sh
sqlcmd -S 203.0.113.3 -U gitea -d giteadb
```
## Database Connection over TLS
If the communication between Gitea and your database instance is performed through a private network, or if Gitea and the database are running on the same server, this section can be omitted since the security between Gitea and the database instance is not critically exposed. If instead the database instance is on a public network, use TLS to encrypt the connection to the database, as it is possible for third-parties to intercept the traffic data.
@@ -19,14 +19,7 @@ Gitea Actions is designed to be compatible with GitHub Actions, with the differe
`uses:` accepts these prefixes:
- `self:` references your own Gitea instance, e.g. `uses: self:owner/repo@v1` or `uses: self:owner/repo/.gitea/workflows/build.yml@v1`
- `builtin:` runs an action built into Gitea Runner, which needs no download and no Node in the job image, e.g. `uses: builtin:checkout`
`builtin:checkout` accepts the `repository`, `ref`, `token`, `path` and `fetch-depth` inputs of `actions/checkout` with the same defaults, and fails on any other input.
### Workflow-relative actions
`$/` references the repository and commit of the workflow, or of the enclosing composite action, e.g. `uses: $/.gitea/actions/build`.
Unlike `./`, it needs no checkout first.
- `builtin:` runs an action built into Gitea Runner, which needs no download and does not depend on Node.js, e.g. `uses: builtin:checkout`
### Actions written in Go
@@ -92,7 +85,7 @@ See [Actions job token permissions](token-permissions.md).
Actions without a host, like `uses: actions/checkout@v4`, are downloaded from `https://github.com`, or from your own instance when `[actions].DEFAULT_ACTIONS_URL` is `self`.
See the [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions).
For other sources, see [Absolute action URLs](#absolute-action-urls), [Action prefixes](#action-prefixes) and [Workflow-relative actions](#workflow-relative-actions).
For other sources, see [Absolute action URLs](#absolute-action-urls) and [Action prefixes](#action-prefixes).
### Context availability
@@ -37,7 +37,7 @@ helm cm-push ./{chart_file}.tgz {repo}
## Install a package
To install a Helm char from the registry, execute the following command:
To install a Helm chart from the registry, execute the following command:
```shell
helm repo add --username {username} --password {password} {repo} https://gitea.example.com/api/packages/{owner}/helm