mirror of
https://gitea.com/gitea/docs.git
synced 2026-11-07 02:20:31 +00:00
Compare commits
28
Commits
8cf8f49a95
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ddb9a2071 | ||
|
|
71869c6e24 | ||
|
|
46b5401a81 | ||
|
|
f6e17361fe | ||
|
|
c3cff4ab08 | ||
|
|
aa975da532 | ||
|
|
6632d38fe2 | ||
|
|
ef57d8d2c0 | ||
|
|
ba4abd749d | ||
|
|
8197192134 | ||
|
|
97fa45dabc | ||
|
|
ee9e91cdeb | ||
|
|
d301461648 | ||
|
|
4ea46e6315 | ||
|
|
cb424640a2 | ||
|
|
09bb4cabcf | ||
|
|
9699ec2c87 | ||
|
|
c00af83676 | ||
|
|
c9282b96da | ||
|
|
49d912f7fb | ||
|
|
398f418387 | ||
|
|
be6aefc7e8 | ||
|
|
a874918bb7 | ||
|
|
5304217222 | ||
|
|
88356280ec | ||
|
|
c7dc13cf83 | ||
|
|
bed218d62d | ||
|
|
08aff1bae9 |
No files matched your search
@@ -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: |
|
||||
|
||||
@@ -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: |
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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, 3 … 0 | 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
|
||||
@@ -52,7 +53,8 @@ group from the `_category_.json` of its directory.
|
||||
|
||||
```shell
|
||||
make cut-version PRODUCT=docs VERSION=1.28
|
||||
make cut-version PRODUCT=runner VERSION=4
|
||||
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
|
||||
@@ -88,8 +90,8 @@ documented.
|
||||
| Version | Content | URL |
|
||||
| --- | --- | --- |
|
||||
| develop | `runner-docs/` | `/runner/develop/` |
|
||||
| current series | `runner-docs_versioned_docs/version-3/` | `/runner/` |
|
||||
| older series | `runner-docs_versioned_docs/version-2/` | `/runner/2/` |
|
||||
| current series | `runner-docs_versioned_docs/version-5/` | `/runner/` |
|
||||
| older series | `runner-docs_versioned_docs/version-4/` | `/runner/4/` |
|
||||
|
||||
A version directory covers a whole release series (`version-3` documents every
|
||||
`3.x` release), so a patch release only needs a content update, not a new
|
||||
@@ -101,7 +103,8 @@ Its sidebar is written by hand: `runner-sidebars.js` for develop, and
|
||||
version.
|
||||
|
||||
The pages under `reference/` are generated from the runner sources — the command
|
||||
line reference from `--help`, the example configuration from `generate-config`:
|
||||
line reference from `--help`, the example configuration from `config generate`
|
||||
(`generate-config` before 3.1):
|
||||
|
||||
```shell
|
||||
make update-runner-docs # develop docs, from the main branch of gitea/runner
|
||||
@@ -114,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
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -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',
|
||||
],
|
||||
};
|
||||
@@ -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.
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -94,16 +94,16 @@ Most web and API requests pick up the signed-in user automatically.
|
||||
|
||||
Other entry points record a system actor:
|
||||
|
||||
- `(gitea-cli)` for `gitea admin` commands and the `system:startup` and
|
||||
- `gitea:cli` for `gitea admin` commands and the `system:startup` and
|
||||
`system:shutdown` events
|
||||
- `(gitea-auth-source)` for authentication-source syncs and for users an
|
||||
- `gitea:auth-source` for authentication-source syncs and for users an
|
||||
authentication source creates or updates at sign-in
|
||||
- `gitea-actions` for Gitea Actions tasks
|
||||
- `(deploy-key)` for pushes with a deploy key
|
||||
- `gitea:deploy-key` for pushes with a deploy key
|
||||
- `(Cron)` for scheduled cron tasks
|
||||
- `Unknown` when no actor can be resolved
|
||||
|
||||
Events of the `(gitea-cli)` actor use origin `cli`. Cron tasks, git hooks and
|
||||
Events of the `gitea:cli` actor use origin `cli`. Cron tasks, git hooks and
|
||||
other background work use origin `system`.
|
||||
|
||||
## What is recorded
|
||||
|
||||
@@ -337,9 +337,13 @@ The default login user email is `X-WEBAUTH-EMAIL`, you can change it via changin
|
||||
|
||||
If set `ENABLE_REVERSE_PROXY_FULL_NAME=true`, a user full name expected in `X-WEBAUTH-FULLNAME` will be assigned to the user when auto creating the user. You can also change the header name with `REVERSE_PROXY_AUTHENTICATION_FULL_NAME`.
|
||||
|
||||
You can also limit the reverse proxy's IP address range with `REVERSE_PROXY_TRUSTED_PROXIES` which default value is `127.0.0.0/8,::1/128`. By `REVERSE_PROXY_LIMIT`, you can limit trusted proxies level.
|
||||
It applies to the web interface, Git over HTTP, Git LFS and the package registry.
|
||||
|
||||
You can enable the this authentication method for the API with
|
||||
:::warning
|
||||
Gitea trusts these headers on every request it receives. Make sure Gitea is only reachable through your authenticating proxy, and that the proxy sets or removes these headers on every request, including on paths you exempt from authentication, for example for Git or package clients. `REVERSE_PROXY_TRUSTED_PROXIES` does not restrict them.
|
||||
:::
|
||||
|
||||
To also accept them on the REST API under `/api/v1`, enable:
|
||||
|
||||
```ini
|
||||
[service]
|
||||
|
||||
@@ -83,7 +83,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/data/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -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.
|
||||
@@ -270,9 +270,10 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `FOLDER_ICON_THEME`: **basic**: The icon theme for folders (basic/material).
|
||||
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
|
||||
- `AMBIGUOUS_UNICODE_DETECTION`: **true**: Detect ambiguous unicode characters in file contents and show warnings on the UI
|
||||
- `REACTIONS`: All available reactions users can choose on issues/prs and comments
|
||||
- `REACTIONS`: All available reactions users can choose on issues, pull requests and comments.
|
||||
Values can be emoji alias (:smile:) or a unicode emoji.
|
||||
For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png
|
||||
- `RELEASE_REACTIONS`: **+1, laugh, hooray, heart, rocket, eyes**: Reactions available for releases, in the same format as `REACTIONS`.
|
||||
- `REACTION_MAX_USER_NUM`: **10**: Change the number of users that are displayed in reactions tooltip (triggered by mouse hover).
|
||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard.
|
||||
By default, we support Gitea (:gitea:), to add more copy them to public/assets/img/emoji/emoji_name.png and
|
||||
@@ -594,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]`.
|
||||
@@ -739,8 +741,8 @@ And the following unique queues:
|
||||
If you set it to false, maybe it also needs to set `ENABLE_BASIC_AUTHENTICATION` to false to
|
||||
completely disable password-based authentication.
|
||||
- `ENABLE_PASSKEY_AUTHENTICATION`: **true**: Allow users to sign-in with a passkey
|
||||
- `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication for web requests
|
||||
- `ENABLE_REVERSE_PROXY_AUTHENTICATION_API`: **false**: Enable this to allow reverse proxy authentication for API requests, the reverse proxy is responsible for ensuring that no CSRF is possible.
|
||||
- `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable reverse proxy authentication for the web interface, Git over HTTP, Git LFS and the package registry. Gitea must only be reachable through the proxy, see [Reverse Proxy](authentication.md#reverse-proxy).
|
||||
- `ENABLE_REVERSE_PROXY_AUTHENTICATION_API`: **false**: Enable reverse proxy authentication for the REST API under `/api/v1`.
|
||||
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration
|
||||
for reverse authentication.
|
||||
- `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a
|
||||
@@ -1354,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.
|
||||
@@ -1706,7 +1708,7 @@ PROXY_HOSTS = *.github.com
|
||||
But it will save storage space and network bandwidth, so it's still recommended to use compression.
|
||||
- `ARTIFACT_RETENTION_DAYS`: **90**: Days to keep artifacts. Old artifacts will be deleted after this period. 0 means keep forever.
|
||||
Changes only apply to newly uploaded artifacts, existing ones keep the expiry stored when they were uploaded.
|
||||
Artifacts could have their own retention periods by setting the `retention-days` option in `actions/upload-artifact` step.
|
||||
Workflows can request a shorter retention period, down to 1 day.
|
||||
- `ARTIFACT_PREVIEW_MAX_SIZE`: **10485760**: Maximum total artifact size in bytes that can be browsed or previewed in the web UI. Set to `0` to disable artifact previews or `-1` for no limit. Individual files are also limited by [`MAX_DISPLAY_FILE_SIZE`](#ui-ui).
|
||||
- `RUN_RETENTION_DAYS`: **400**: Days to keep completed runs. Old runs and everything under them will be deleted after this period. 0 means keep forever.
|
||||
- `ZOMBIE_TASK_TIMEOUT`: **10m**: Timeout to stop the task which have running status, but haven't been updated for a long time
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -111,6 +111,9 @@ Gitea token scopes are as follows:
|
||||
| **admin** | `/admin/*` API routes: Site-wide administrative operations (hidden for non-admin accounts). |
|
||||
| **read:admin** | Grants read access for admin operations, such as getting cron jobs or registered user emails. |
|
||||
| **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. |
|
||||
| **read:commitstatus** | Grants read access to commit statuses. Included in `read:repository`. |
|
||||
| **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. |
|
||||
| **read:issue** | Grants read access for issues operations, such as getting issue comments, issue attachments, and milestones. |
|
||||
| **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`.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -10,13 +10,13 @@ aliases:
|
||||
|
||||
# Protected branches
|
||||
|
||||
Protected branches prevent unwanted changes by enforcing push and merge policies on selected branches. The rules are enforced for every Git protocol (HTTP(S), SSH), the web editor, the API, and background jobs such as auto-merge. Only repository owners and administrators can manage the rules, and the Branches page is read-only while a repository is archived.
|
||||
Protected branches prevent unwanted changes by enforcing push, deletion, and merge policies on selected branches. The rules are enforced for every Git protocol (HTTP(S), SSH), the web editor, the API, and background jobs such as auto-merge. Only repository owners and administrators can manage the rules, and the Branches page is read-only while a repository is archived.
|
||||
|
||||
## Creating or editing a rule
|
||||
|
||||
1. Open the repository and select **Settings → Branches** (repository admin permission required).
|
||||
2. Select **Add new rule** or **Edit** next to an existing rule.
|
||||
3. Fill in the **Protected branch name pattern** and optional file patterns, then configure the push, merge, and review options described below.
|
||||
3. Fill in the **Protected branch name pattern** and optional file patterns, then configure the push, deletion, merge, and review options described below.
|
||||
4. Select **Save rule**.
|
||||
|
||||
The rule immediately applies to all matching branches, even if the branches are created in the future.
|
||||
@@ -48,7 +48,9 @@ The **Push** section controls direct pushes (including the web editor and API).
|
||||
|
||||
- **Disable push** makes the branch read-only. Any attempt to push directly fails, and changes must be merged through pull requests.
|
||||
- **Enable push** allows anyone with [write access](./permissions.md) to push (force pushes are still blocked unless explicitly allowed).
|
||||
- **Allowlist restricted push** requires being on the allowlist. Choose users and, for organization-owned repositories, teams. Deploy keys that already have write access can also be allowlisted.
|
||||
- **Allowlist restricted push** requires being on the allowlist. Choose users and, for organization-owned repositories, teams.
|
||||
|
||||
The user allowlists for push, force-push and deletion can include the **Gitea Actions** and **Deploy Key** system users. They still require write access; **Deploy Key** also covers deploy tokens.
|
||||
|
||||
When a push is blocked, the server-side hook rejects the update with an explanation.
|
||||
|
||||
@@ -58,7 +60,17 @@ Force pushes have their own set of options:
|
||||
|
||||
- **Disable force push** completely forbids rewriting history on the branch.
|
||||
- **Enable force push** allows anyone who can push to also force push.
|
||||
- **Allowlist restricted force push** limits force pushes to a separate allowlist (users, teams, and optionally deploy keys) **and** requires the person to already have regular push access.
|
||||
- **Allowlist restricted force push** limits force pushes to a separate allowlist of users or teams **and** requires regular push access.
|
||||
|
||||
## Branch deletion
|
||||
|
||||
The **Branch Deletion** section controls whether matching protected branches can be deleted:
|
||||
|
||||
- **Disable branch deletion** prevents deletion. This is the default.
|
||||
- **Enable branch deletion** allows anyone who can push to delete the branch.
|
||||
- **Allowlist restricted branch deletion** limits deletion to a separate allowlist of users or teams **and** requires regular push access.
|
||||
|
||||
These rules apply to Git (`git push --delete`), the API, the web interface and post-merge cleanup. The default branch and configured default pull request target branch cannot be deleted.
|
||||
|
||||
## Pull request merges and approvals
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ However, it is recommended to use Docker to run the jobs, because it is more sec
|
||||
Before running a runner, you should first register it to your Gitea instance using the following command:
|
||||
|
||||
```bash
|
||||
./runner register --no-interactive --instance <instance> --token <token>
|
||||
gitea-runner register --no-interactive --instance <instance> --token <token>
|
||||
```
|
||||
|
||||
There are two arguments required, `instance` and `token`.
|
||||
@@ -69,7 +69,7 @@ If this file is missing or corrupted, you can simply remove it and register agai
|
||||
Finally, it's time to start the runner:
|
||||
|
||||
```bash
|
||||
./runner daemon
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
And you can see the new runner in the management page:
|
||||
|
||||
@@ -99,6 +99,10 @@ You can configure defaults and maximums at:
|
||||
|
||||
Note: Repository-level token permission settings are only shown once **Repository Actions** are enabled.
|
||||
|
||||
## Protected branches
|
||||
|
||||
Actions job tokens must have code write permission and satisfy [branch protection rules](../access-control/protected-branches.md), including any **Gitea Actions** allowlist requirements.
|
||||
|
||||
## Fork pull requests
|
||||
|
||||
For security reasons, workflows triggered by pull requests from forks are always restricted to read-only permissions for repository contents, regardless of workflow `permissions:` or settings. They also get no OpenID Connect tokens.
|
||||
|
||||
@@ -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 workflow run logs and artifacts are kept. | `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.retention_days`<br/>`github.retention_days` | The number of days that workflow run logs and artifacts are kept. | `90` |
|
||||
| `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` |
|
||||
|
||||
@@ -55,11 +55,11 @@ and shows a link to the repository on the package site (as well as a link to the
|
||||
| Package owner type | User | Organization |
|
||||
|--------------------|------|--------------|
|
||||
| **read** access | public, if user is public too; otherwise for this user only | public, if org is public, otherwise for org members only |
|
||||
| **write** access | owner only | org members with admin or write access to the org |
|
||||
| **write** access | owner only | members of a team with write access to packages |
|
||||
|
||||
Please note, that your respective package manager needs to have a [personal access token](development/api-usage.md#authentication) with the permissions `package` set to either Read or Read & Write to download and publish packages respectively.
|
||||
|
||||
N.B.: These access restrictions are [subject to change](https://github.com/go-gitea/gitea/issues/19270), where more finegrained control will be added via a dedicated organization team permission.
|
||||
The packages permission of an organization team applies to all packages of the organization, regardless of the repositories assigned to the team.
|
||||
|
||||
## Create or upload a package
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Projects",
|
||||
"position": 60,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"slug": "/usage/projects",
|
||||
"description": "Plan and track work with project boards"
|
||||
}
|
||||
}
|
||||
@@ -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`
|
||||
@@ -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
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -232,6 +232,7 @@ aliases:
|
||||
- `REACTIONS`: 用户可以在问题(Issue)、Pull Request(PR)以及评论中选择的所有可选的反应。
|
||||
这些值可以是表情符号别名(例如::smile:)或 Unicode 表情符号。
|
||||
对于自定义的反应,在 public/assets/img/emoji/ 目录下添加一个紧密裁剪的正方形图像,文件名为 reaction_name.png。
|
||||
- `RELEASE_REACTIONS`: **+1, laugh, hooray, heart, rocket, eyes**: 版本发布中可用的反应。取值方式与 `REACTIONS` 相同。
|
||||
- `REACTION_MAX_USER_NUM`: **10**: 更改在反应工具提示中显示的用户数量(鼠标悬停时触发)。
|
||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: 不在 utf8 标准中定义的额外表情符号。
|
||||
默认情况下,我们支持 Gitea 表情符号(:gitea:)。要添加更多表情符号,请将它们复制到 public/assets/img/emoji/ 目录下,
|
||||
@@ -523,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 钩子。
|
||||
@@ -1194,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 对数据库连接进行加密,以防止第三方拦截流量数据。
|
||||
|
||||
@@ -40,7 +40,7 @@ Gitea Actions需要[runner](https://gitea.com/gitea/runner) 来运行Job。
|
||||
在运行Runner之前,您需要使用以下命令将其注册到Gitea实例中:
|
||||
|
||||
```bash
|
||||
./runner register --no-interactive --instance <instance> --token <token>
|
||||
gitea-runner register --no-interactive --instance <instance> --token <token>
|
||||
```
|
||||
|
||||
需要两个必需的参数:`instance` 和 `token`。
|
||||
@@ -52,10 +52,10 @@ Runner和Job容器(由Runner启动以执行Job)将连接到此地址。
|
||||
如果不确定使用哪个地址,通常选择局域网地址即可。
|
||||
|
||||
`token` 用于身份验证和标识,例如 `P2U1U0oB4XaRCi8azcngmPCLbRpUGapalhmddh23`。
|
||||
它只能使用一次,并且不能用于注册多个Runner。
|
||||
每个令牌都可用于注册多个Runner。通过重置链接替换为新令牌后,旧令牌将失效。
|
||||
您可以从以下位置获取不同级别的`token`,从而创建出相应级别的`runner`
|
||||
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 组织级别:组织设置页面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 存储库级别:存储库设置页面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
@@ -68,7 +68,7 @@ Runner和Job容器(由Runner启动以执行Job)将连接到此地址。
|
||||
最后,是时候启动Runner了:
|
||||
|
||||
```bash
|
||||
./runner daemon
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
您可以在管理页面上看到新的Runner:
|
||||
|
||||
@@ -28,7 +28,7 @@ aliases:
|
||||
|
||||
Runner级别决定了从哪里获取注册令牌。
|
||||
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 组织级别:组织设置页面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 存储库级别:存储库设置页面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
|
||||
@@ -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`
|
||||
@@ -81,7 +81,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/gitea-repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
@@ -115,7 +115,7 @@ cd gitea-dump-1610949662
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /data/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 调整文件权限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git 钩子
|
||||
@@ -139,7 +139,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 调整文件权限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git 钩子
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/gitea-repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
@@ -114,7 +114,7 @@ cd gitea-dump-1610949662
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /data/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 调整文件权限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git 钩子
|
||||
@@ -138,7 +138,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 调整文件权限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git 钩子
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/gitea-repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
@@ -114,7 +114,7 @@ cd gitea-dump-1610949662
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /data/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 调整文件权限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git 钩子
|
||||
@@ -138,7 +138,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢复 Gitea 数据
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢复仓库本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 调整文件权限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git 钩子
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -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 对数据库连接进行加密,以防止第三方拦截流量数据。
|
||||
|
||||
@@ -40,7 +40,7 @@ Gitea Actions需要[runner](https://gitea.com/gitea/runner) 来运行Job。
|
||||
在运行Runner之前,您需要使用以下命令将其注册到Gitea实例中:
|
||||
|
||||
```bash
|
||||
./runner register --no-interactive --instance <instance> --token <token>
|
||||
gitea-runner register --no-interactive --instance <instance> --token <token>
|
||||
```
|
||||
|
||||
需要两个必需的参数:`instance` 和 `token`。
|
||||
@@ -52,10 +52,10 @@ Runner和Job容器(由Runner启动以执行Job)将连接到此地址。
|
||||
如果不确定使用哪个地址,通常选择局域网地址即可。
|
||||
|
||||
`token` 用于身份验证和标识,例如 `P2U1U0oB4XaRCi8azcngmPCLbRpUGapalhmddh23`。
|
||||
它只能使用一次,并且不能用于注册多个Runner。
|
||||
每个令牌都可用于注册多个Runner。通过重置链接替换为新令牌后,旧令牌将失效。
|
||||
您可以从以下位置获取不同级别的`token`,从而创建出相应级别的`runner`
|
||||
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 组织级别:组织设置页面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 存储库级别:存储库设置页面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
@@ -68,7 +68,7 @@ Runner和Job容器(由Runner启动以执行Job)将连接到此地址。
|
||||
最后,是时候启动Runner了:
|
||||
|
||||
```bash
|
||||
./runner daemon
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
您可以在管理页面上看到新的Runner:
|
||||
|
||||
@@ -28,7 +28,7 @@ aliases:
|
||||
|
||||
Runner级别决定了从哪里获取注册令牌。
|
||||
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 实例级别:管理员设置页面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 组织级别:组织设置页面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 存储库级别:存储库设置页面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -234,6 +234,7 @@ aliases:
|
||||
- `REACTIONS`: 使用者可以在問題(Issue)、Pull Request(PR)以及評論中選擇的所有可選的反應。
|
||||
這些值可以是表情符號別名(例如::smile:)或 Unicode 表情符號。
|
||||
對於自訂的反應,在 public/assets/img/emoji/ 目錄下添加一個緊密裁剪的正方形圖像,文件名為 reaction_name.png。
|
||||
- `RELEASE_REACTIONS`: **+1, laugh, hooray, heart, rocket, eyes**: 版本發佈中可用的反應。取值方式與 `REACTIONS` 相同。
|
||||
- `REACTION_MAX_USER_NUM`: **10**: 更改在反應工具提示中顯示的使用者數量(鼠標懸停時觸發)。
|
||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: 不在 utf8 標準中定義的額外表情符號。
|
||||
預設情況下,我們支援 Gitea 表情符號(:gitea:)。要添加更多表情符號,請將它們複製到 public/assets/img/emoji/ 目錄下,
|
||||
@@ -528,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 鉤子。
|
||||
@@ -1200,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 對資料庫連接進行加密,以防止第三方攔截流量資料。
|
||||
|
||||
@@ -40,7 +40,7 @@ Gitea Actions需要[runner](https://gitea.com/gitea/runner) 來運行Job。
|
||||
在運行Runner之前,您需要使用以下命令將其註冊到Gitea實例中:
|
||||
|
||||
```bash
|
||||
./runner register --no-interactive --instance <instance> --token <token>
|
||||
gitea-runner register --no-interactive --instance <instance> --token <token>
|
||||
```
|
||||
|
||||
需要兩個必需的參數:`instance` 和 `token`。
|
||||
@@ -52,10 +52,10 @@ Runner和Job容器(由Runner啟動以執行Job)將連接到此地址。
|
||||
如果不確定使用哪個地址,通常選擇局域網地址即可。
|
||||
|
||||
`token` 用於身份驗證和標識,例如 `P2U1U0oB4XaRCi8azcngmPCLbRpUGapalhmddh23`。
|
||||
它只能使用一次,並且不能用於註冊多個Runner。
|
||||
每個令牌都可用來註冊多個Runner。透過重設連結換成新令牌後,舊令牌就會失效。
|
||||
您可以從以下位置獲取不同級別的`token`,從而建立出相應級別的`runner`
|
||||
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 組織級別:組織設定頁面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 儲存庫級別:儲存庫設定頁面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
@@ -68,7 +68,7 @@ Runner和Job容器(由Runner啟動以執行Job)將連接到此地址。
|
||||
最後,是時候啟動Runner了:
|
||||
|
||||
```bash
|
||||
./runner daemon
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
您可以在管理頁面上看到新的Runner:
|
||||
|
||||
@@ -28,7 +28,7 @@ aliases:
|
||||
|
||||
Runner級別決定了從哪裡獲取註冊令牌。
|
||||
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 組織級別:組織設定頁面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 儲存庫級別:儲存庫設定頁面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
|
||||
@@ -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`
|
||||
@@ -81,7 +81,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/gitea-repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
@@ -115,7 +115,7 @@ cd gitea-dump-1610949662
|
||||
# 恢復 Gitea 數據
|
||||
mv data/* /data/gitea
|
||||
# 恢復倉庫本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 調整文件權限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git 鉤子
|
||||
@@ -139,7 +139,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢復 Gitea 數據
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢復倉庫本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 調整文件權限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git 鉤子
|
||||
|
||||
@@ -115,7 +115,7 @@ cd gitea-dump-1610949662
|
||||
# 恢復 gitea 數據
|
||||
mv data/* /data/gitea
|
||||
# 恢復儲存庫本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 調整文件權限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git Hooks
|
||||
@@ -139,7 +139,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢復 gitea 數據
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢復儲存庫本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 調整文件權限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git Hooks
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/gitea-repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
@@ -114,7 +114,7 @@ cd gitea-dump-1610949662
|
||||
# 恢復 Gitea 數據
|
||||
mv data/* /data/gitea
|
||||
# 恢復存放庫本身
|
||||
mv repos/* /data/git/gitea-repositories/
|
||||
mv repos/* /data/git/repositories/
|
||||
# 調整文件權限
|
||||
chown -R git:git /data
|
||||
# 重新生成 Git 鉤子
|
||||
@@ -138,7 +138,7 @@ mv data/conf/app.ini /etc/gitea/app.ini
|
||||
# 恢復 Gitea 數據
|
||||
mv data/* /var/lib/gitea
|
||||
# 恢復存放庫本身
|
||||
mv repos/* /var/lib/gitea/git/gitea-repositories
|
||||
mv repos/* /var/lib/gitea/git/repositories
|
||||
# 調整文件權限
|
||||
chown -R git:git /etc/gitea/app.ini /var/lib/gitea
|
||||
# 重新生成 Git 鉤子
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -80,7 +80,7 @@ cd gitea-dump-1610949662
|
||||
mv app.ini /etc/gitea/conf/app.ini
|
||||
mv data/* /var/lib/gitea/data/
|
||||
mv log/* /var/lib/gitea/log/
|
||||
mv repos/* /var/lib/gitea/repositories/
|
||||
mv repos/* /var/lib/gitea/data/gitea-repositories/
|
||||
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||
|
||||
# mysql
|
||||
|
||||
@@ -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 對資料庫連接進行加密,以防止第三方攔截流量資料。
|
||||
|
||||
@@ -40,7 +40,7 @@ Gitea Actions需要[runner](https://gitea.com/gitea/runner) 來運行Job。
|
||||
在運行Runner之前,您需要使用以下命令將其註冊到Gitea實例中:
|
||||
|
||||
```bash
|
||||
./runner register --no-interactive --instance <instance> --token <token>
|
||||
gitea-runner register --no-interactive --instance <instance> --token <token>
|
||||
```
|
||||
|
||||
需要兩個必需的參數:`instance` 和 `token`。
|
||||
@@ -52,10 +52,10 @@ Runner和Job容器(由Runner啟動以執行Job)將連接到此地址。
|
||||
如果不確定使用哪個地址,通常選擇局域網地址即可。
|
||||
|
||||
`token` 用於身份驗證和標識,例如 `P2U1U0oB4XaRCi8azcngmPCLbRpUGapalhmddh23`。
|
||||
它只能使用一次,並且不能用於註冊多個Runner。
|
||||
每個令牌都可用來註冊多個Runner。透過重設連結換成新令牌後,舊令牌就會失效。
|
||||
您可以從以下位置獲取不同級別的`token`,從而建立出相應級別的`runner`
|
||||
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 組織級別:組織設定頁面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 儲存庫級別:儲存庫設定頁面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
@@ -68,7 +68,7 @@ Runner和Job容器(由Runner啟動以執行Job)將連接到此地址。
|
||||
最後,是時候啟動Runner了:
|
||||
|
||||
```bash
|
||||
./runner daemon
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
您可以在管理頁面上看到新的Runner:
|
||||
|
||||
@@ -28,7 +28,7 @@ aliases:
|
||||
|
||||
Runner級別決定了從哪裡獲取註冊令牌。
|
||||
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/admin/actions/runners`。
|
||||
- 實例級別:管理員設定頁面,例如 `<your_gitea.com>/-/admin/actions/runners`。
|
||||
- 組織級別:組織設定頁面,例如 `<your_gitea.com>/<org>/settings/actions/runners`。
|
||||
- 儲存庫級別:儲存庫設定頁面,例如 `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`。
|
||||
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
"packageManager": "[email protected]0.1"
|
||||
"packageManager": "[email protected]6.1"
|
||||
}
|
||||
@@ -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.1.0',
|
||||
sourceVersion: 'v28.1.0',
|
||||
version: '28.3.0',
|
||||
sourceVersion: 'v28.3.0',
|
||||
sourceBranch: 'release/v28',
|
||||
dockerVersion: '28.1.0',
|
||||
displayVersion: '28.1.0',
|
||||
dockerVersion: '28.3.0',
|
||||
displayVersion: '28.3.0',
|
||||
},
|
||||
'1.27': {
|
||||
goVersion: '1.26',
|
||||
@@ -213,7 +213,9 @@ const docsProduct: ProductDef = {
|
||||
* bumped here when a new runner release is documented.
|
||||
*/
|
||||
const runnerSeries: { id: string; latestRelease: string }[] = [
|
||||
{ id: '3', latestRelease: '3.3.0' },
|
||||
{ id: '5', latestRelease: '5.2.0' },
|
||||
{ id: '4', latestRelease: '4.1.0' },
|
||||
{ id: '3', latestRelease: '3.5.0' },
|
||||
{ id: '2', latestRelease: '2.3.0' },
|
||||
{ id: '1', latestRelease: '1.0.8' },
|
||||
{ id: '0', latestRelease: '0.6.1' },
|
||||
@@ -244,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',
|
||||
@@ -299,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);
|
||||
|
||||
@@ -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[],
|
||||
|
||||
Generated
+323
-224
File diff suppressed because it is too large.
Load diff
+64
-93
@@ -1,107 +1,78 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Caching
|
||||
|
||||
Every runner starts its own cache server, so `actions/cache` works without any configuration. Cache entries are local to that runner: two runners do not share a cache unless you make them.
|
||||
|
||||
## Cache service v2
|
||||
|
||||
`actions/[email protected]` and later can use the *cache service v2* API. The runner serves it from the same store as v1, on by default, and it also works behind a shared cache server. Turn it off with:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
v2: false
|
||||
```
|
||||
|
||||
Those actions refuse any host they do not take for GitHub. Rather than misreport the server URL, the runner edits that check out of the action's own JavaScript bundle and keeps the untouched copy beside it; a bundle it does not recognise is left alone and keeps to v1. The same edit lets the stock `actions/upload-artifact` and `actions/download-artifact` work from `v4.4.0` on, without the `gitea-upload-artifact` fork.
|
||||
|
||||
Because `ACTIONS_RESULTS_URL` names one origin that has to serve the whole results API, the cache server also forwards the artifact half of it to the Gitea instance the job belongs to. Jobs are therefore pointed at the cache server, which is what makes clients such as `docker buildx` find the cache service instead of receiving a 404 from Gitea.
|
||||
|
||||
## Where cache blobs are stored
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
enabled: true
|
||||
dir: /var/lib/gitea-runner/cache # default: $HOME/.cache/actcache
|
||||
```
|
||||
|
||||
The directory grows with use; entries are evicted as they expire, so give it a filesystem with room to spare and monitor it like any other build cache.
|
||||
|
||||
## Dockerized runners
|
||||
|
||||
When the runner itself runs in a container and creates a network per job, the address it detects for its own cache server is often unreachable from the job containers. `actions/cache` then fails with:
|
||||
|
||||
```text
|
||||
Failed to restore: getCacheEntry failed: connect ETIMEDOUT IP:PORT
|
||||
```
|
||||
|
||||
Pin the address and the port the job containers should use, and make that endpoint reachable:
|
||||
|
||||
1. take an address of the host that job containers can reach, and a free port on it;
|
||||
2. configure them:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
enabled: true
|
||||
dir: ""
|
||||
host: "192.168.8.17"
|
||||
port: 8088
|
||||
```
|
||||
|
||||
3. publish the port when starting the runner container:
|
||||
|
||||
```bash
|
||||
docker run -d --name gitea-runner -p 8088:8088 ... docker.io/gitea/runner:nightly
|
||||
```
|
||||
|
||||
Putting the runner and the job containers on one shared `container.network` instead works too, and then the auto-detected address is reachable.
|
||||
By default, each runner runs a cache server for `actions/cache`, so caching works without setup.
|
||||
The runner stores entries in `cache.dir`, which defaults to `$HOME/.cache/actcache`. It does not share entries with other runners.
|
||||
|
||||
## Sharing a cache between runners
|
||||
|
||||
Run one dedicated cache server that every runner points at.
|
||||
Run one `gitea-runner cache-server` and configure each runner to use it. Use the same secret on the cache server and every runner. Generate the secret with `openssl rand -hex 32`.
|
||||
|
||||
1. Config for the cache server host:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
dir: /data/actcache
|
||||
port: 8088
|
||||
external_secret: "replace-with-a-strong-random-secret"
|
||||
# external_secret_file: /run/secrets/cache-secret # or keep it out of this file
|
||||
```
|
||||
|
||||
2. Start it:
|
||||
|
||||
```bash
|
||||
gitea-runner -c cache-server-config.yaml cache-server
|
||||
```
|
||||
|
||||
3. On every runner:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
external_server: "http://cache-host:8088/"
|
||||
external_secret: "replace-with-a-strong-random-secret" # must match the server
|
||||
```
|
||||
|
||||
The secret authenticates runners against the shared server and must be identical on all of them; generate one with `openssl rand -hex 32`. Setting both `external_secret` and `external_secret_file` is an error.
|
||||
|
||||
`cache-server` accepts `--dir`, `--host` and `--port`, which override the corresponding `cache.*` keys. Every other setting, `external_secret` included, has to come from the config file.
|
||||
|
||||
### Alternatives
|
||||
|
||||
- **Shared filesystem** — mount the same NFS/CIFS share on every runner and point `cache.dir` at it. Simpler, but repositories are less isolated from each other than behind a cache server.
|
||||
- **Object storage** — mount S3 or MinIO as a FUSE filesystem, e.g. with [s3fs](https://github.com/s3fs-fuse/s3fs-fuse) or [goofys](https://github.com/kahing/goofys), and set `cache.dir` to the mount point.
|
||||
|
||||
## Action repository cache
|
||||
|
||||
Actions pulled by `uses:` are cached too, and by default refreshed on every job so a moved tag is picked up. To pin them to what has already been fetched:
|
||||
On the cache server:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
offline_mode: true
|
||||
dir: /data/actcache
|
||||
port: 8088
|
||||
external_secret_file: /run/secrets/cache-secret
|
||||
```
|
||||
|
||||
A re-tagged `v6` or an updated branch then stays at the cached commit until its entry expires or is removed. Combined with `runner.action_shallow_clone` (on by default, fetching only the requested ref at depth 1), this keeps job startup fast on runners with limited bandwidth.
|
||||
```bash
|
||||
gitea-runner -c cache-server.yaml cache-server
|
||||
```
|
||||
|
||||
On each runner:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
external_server: "http://cache-host:8088/"
|
||||
external_secret_file: /run/secrets/cache-secret
|
||||
```
|
||||
|
||||
Jobs send cache requests to their runner, which forwards them to the shared cache server. Only the runners need to reach the shared cache server. Set `external_secret` to supply the secret inline instead of from a file.
|
||||
|
||||
Runners can also share a `cache.dir` directory on a filesystem that supports file locks. This makes cache requests slower.
|
||||
|
||||
## S3-compatible storage
|
||||
|
||||
Use an S3-compatible bucket such as AWS S3, MinIO or RustFS to share the cache without a separate cache server:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
s3:
|
||||
endpoint: "http://minio:9000"
|
||||
bucket: "runner-cache"
|
||||
access_key_file: "/run/secrets/cache-s3-access-key"
|
||||
secret_key_file: "/run/secrets/cache-s3-secret-key"
|
||||
```
|
||||
|
||||
Runners with the same settings share the cache. An entry saved on one runner becomes available to the others within 30 seconds. The eviction settings below do not apply to the bucket. Add lifecycle rules to expire old entries and abort incomplete multipart uploads.
|
||||
|
||||
## Eviction
|
||||
|
||||
| Option | Default | Removes |
|
||||
| --- | --- | --- |
|
||||
| `cache.retention` | `168h` | Entries not read or written within this time |
|
||||
| `cache.repo_size_limit` | `10GB` | Least recently used entries when a repository's cache exceeds this size |
|
||||
| `cache.size_limit` | off | Least recently used entries when the whole cache exceeds this size |
|
||||
|
||||
The cache also keeps 1024 MiB free on its volume, or `health_check.min_free_disk_space_mb` when [health checks](monitoring.md#health-checks) are enabled. With a shared cache server, set these options on the server.
|
||||
|
||||
## Artifacts
|
||||
|
||||
The runner adapts `actions/cache`, `actions/upload-artifact` and `actions/download-artifact` while a job runs so these actions work with Gitea. With these changes, the cache uses the cache service v2 protocol.
|
||||
|
||||
Artifact uploads go through the runner's cache server, so jobs must be able to reach it. Set `cache.v2: false` to send artifact uploads directly to Gitea. Set `runner.patch_actions: false` to run every action exactly as published. This uses the cache service v1 protocol and causes the published artifact actions to fail.
|
||||
|
||||
## Jobs cannot reach the cache
|
||||
|
||||
If `actions/cache` fails with `connect ETIMEDOUT`, jobs cannot reach the runner's cache server.
|
||||
|
||||
A runner container connects itself to each job network when it uses the same Docker daemon as its jobs. For jobs on another Docker daemon, for example through a remote `DOCKER_HOST`, set `cache.host` and `cache.port` to an address and port the jobs can reach. Jobs using `container.network: bridge` cannot reach a runner container outside that network. Leave `container.network` empty or use a network that includes the runner container.
|
||||
|
||||
## Action cache
|
||||
|
||||
For each job, the runner checks action tags and branches for updates, so it picks up moved tags such as `v6`. With `cache.offline_mode: true`, the runner reuses its downloaded copy. This speeds up jobs on slow networks, but moved tags and updated branches stay at the cached commit.
|
||||
+41
-118
@@ -4,135 +4,58 @@ sidebar_position: 3
|
||||
|
||||
# Configuration
|
||||
|
||||
The runner is configured with a single YAML file. It is optional: without one, the built-in defaults apply, which are the same as an empty YAML document and safe to run with.
|
||||
The runner works without a configuration file. Create one to change a default:
|
||||
|
||||
```bash
|
||||
gitea-runner generate-config > config.yaml
|
||||
gitea-runner -c config.yaml register
|
||||
gitea-runner config init
|
||||
gitea-runner config set runner.capacity 4
|
||||
gitea-runner -c config.yaml daemon
|
||||
```
|
||||
|
||||
`-c` / `--config` is a global flag and is accepted by every command that loads configuration (`register`, `daemon`, `cache-server`). The generated file is fully commented and is reproduced in [Example configuration](reference/config-example.md).
|
||||
`config init` writes a minimal `config.yaml` in the working directory. Pass the file with `-c` when running `register`, `daemon` or `cache-server`. These commands do not find configuration files automatically. The runner reads its configuration only at startup. Restart it after each change.
|
||||
|
||||
:::warning No environment variable overrides
|
||||
The runner process is configured only through the YAML file. Earlier releases let a few variables (`GITEA_DEBUG`, `GITEA_TRACE`, `GITEA_RUNNER_CAPACITY`, `GITEA_RUNNER_FILE`, `GITEA_RUNNER_ENVIRON`, `GITEA_RUNNER_ENV_FILE`) override parts of the config; those overrides have been removed.
|
||||
## Editing
|
||||
|
||||
The variables understood by the Docker images belong to their [entrypoint](installation/docker.md#entrypoint-environment-variables), not to the runner, and `GITEA_RUNNER_LABELS` / `GITEA_RUNNER_REGISTRATION_TOKEN` are read by the corresponding CLI flags only.
|
||||
:::
|
||||
The `config` command edits the configuration file in place and preserves its comments:
|
||||
|
||||
Values with a duration type accept Go duration strings such as `30s`, `10m`, `3h`.
|
||||
```bash
|
||||
gitea-runner config set runner.timeout 90m
|
||||
gitea-runner config set runner.envs.MY_VAR value
|
||||
gitea-runner config add container.valid_volumes '/data/**'
|
||||
gitea-runner config remove container.valid_volumes '/data/**'
|
||||
gitea-runner config get runner.capacity
|
||||
```
|
||||
|
||||
## `log`
|
||||
A key is the path to a YAML value, with dots between levels. The command rejects unknown keys and values of the wrong type before changing the file. Without `-c`, these commands look for `config.yaml` or `config.yml` in the working directory, then in the directory containing the binary.
|
||||
|
||||
Controls the runner's own log, not how step output is streamed to the UI.
|
||||
`gitea-runner config generate` prints every option with its default and a description. This matches the [example configuration](reference/config-example.md).
|
||||
|
||||
Use `${NAME}` in a value to read an environment variable from the runner's environment. The configuration fails to load if `NAME` is unset. Use `$${NAME}` for a literal `${NAME}`:
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
capacity: ${RUNNER_CAPACITY}
|
||||
```
|
||||
|
||||
## Common options
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `log.level` | `info` | `trace`, `debug`, `info`, `warn`, `error`, `fatal` or `panic`. `trace` and `debug` add the caller's `file:line`. |
|
||||
| `runner.capacity` | `1` | Maximum number of jobs that can run at once. |
|
||||
| `runner.timeout` | `3h` | Maximum job duration. Gitea's own job timeout may stop a job earlier. |
|
||||
| `runner.shutdown_timeout` | `0s` | Time to let running jobs finish before canceling them during shutdown. |
|
||||
| `runner.envs` | | Environment variables for every job. |
|
||||
| `runner.env_file` | | File containing additional environment variables for every job. |
|
||||
| `runner.labels` | | See [Labels](labels.md). |
|
||||
| `runner.insecure` | `false` | Skip verification of Gitea's TLS certificate. |
|
||||
| `runner.client_cert_file`, `runner.client_key_file` | | Client certificate and key for a Gitea instance that requires mutual TLS. |
|
||||
| `runner.extra_headers` | | HTTP headers for requests to Gitea, for example for a reverse proxy. |
|
||||
| `runner.github_mirror` | | URL to use instead of `https://github.com` when downloading actions from GitHub. |
|
||||
| `container.network` | | Docker network for job containers. If empty, the runner creates a network for each job. |
|
||||
| `container.options` | | Additional `docker run` options for every job container. |
|
||||
| `container.privileged` | `false` | Run job containers in privileged mode. See [Jobs](jobs.md#volumes-and-privileges). |
|
||||
| `container.valid_volumes` | | Volumes and host paths that workflows may mount. |
|
||||
| `container.force_pull` | `false` | Pull job images even when they are already present. |
|
||||
| `log.level` | `info` | Verbosity of the runner's log. |
|
||||
|
||||
## `runner`
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `file` | `.runner` | path of the registration file. Each runner process needs its own. |
|
||||
| `capacity` | `1` | jobs executed concurrently. With an empty `container.network`, every concurrent docker job takes a subnet from the daemon's address pool, so a high capacity can exhaust it (see `default-address-pools` in the daemon config). |
|
||||
| `envs` | – | extra environment variables given to every job. |
|
||||
| `env_file` | `.env` | same, read from a file; ignored when empty or missing. |
|
||||
| `timeout` | `3h` | maximum job duration. Gitea has its own timeout (3h by default) and may stop the job earlier. |
|
||||
| `shutdown_timeout` | `0s` | how long a shutdown waits for running jobs before cancelling them. |
|
||||
| `insecure` | `false` | skip TLS verification of the Gitea instance. |
|
||||
| `fetch_timeout` | `5s` | timeout of a single job fetch. |
|
||||
| `fetch_interval` | `2s` | base polling interval. |
|
||||
| `fetch_interval_max` | `5s` | upper bound of the exponential backoff applied while idle. `0`, or the same value as `fetch_interval`, disables the backoff. |
|
||||
| `labels` | see [Labels](labels.md) | labels used at registration, and by `daemon` when the flag is absent. |
|
||||
| `github_mirror` | – | replaces `https://github.com` when actions are pulled and the instance's `DEFAULT_ACTIONS_URL` points at GitHub. |
|
||||
| `action_shallow_clone` | `true` | fetch only the requested ref of an action repository at depth 1 instead of its full history. |
|
||||
| `set_act_env` | `true` | inject `ACT=true` into jobs. Set to `false` so workflows gated on `if: ${{ !env.ACT }}` behave as they do on GitHub. |
|
||||
| `allocate_pty` | `false` | allocate a pseudo-TTY per step. Enable only when a job needs an interactive terminal; tools like `docker build` then write redrawing progress frames into the log. |
|
||||
| `workdir_cleanup_age` | `24h` | age at which stale task workspaces and orphaned host-mode scratch directories are removed while idle. |
|
||||
| `idle_cleanup_interval` | `10m` | cadence of the idle cleanup pass. Setting either this or `workdir_cleanup_age` to `0` disables all idle cleanup. |
|
||||
| `post_task_script` | – | host script run after each task's cleanup, see [Post-task script](hooks/post-task-script.md). |
|
||||
| `post_task_script_timeout` | `5m` | hard limit for that script. |
|
||||
| `hooks.job_started` / `hooks.job_completed` | – | scripts run inside the job environment, see [Job hooks](hooks/job-hooks.md). |
|
||||
|
||||
Log and state reporting can be tuned when the UI updates too slowly or the instance sees too many requests:
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `log_report_interval` | `5s` | base interval of the periodic log flush. |
|
||||
| `log_report_max_latency` | `3s` | maximum time a single log row waits. Only has an effect below `log_report_interval`. |
|
||||
| `log_report_batch_size` | `100` | flush immediately once this many rows are buffered, so bursty output arrives promptly. |
|
||||
| `state_report_interval` | `5s` | interval of task state reports. State is also sent on every step transition. |
|
||||
| `report_close_timeout` | `10s` | per-attempt deadline for the final log and state flush of a finished job. |
|
||||
|
||||
### Idle cleanup
|
||||
|
||||
While no job is running, the runner cleans up after earlier ones:
|
||||
|
||||
- stale task workspaces older than `workdir_cleanup_age` are removed when `container.bind_workdir` is enabled. Only purely numeric subdirectories of `container.workdir_parent` are treated as workspaces, and the path is assumed not to be shared with another runner;
|
||||
- orphaned host-mode scratch directories are removed on the same schedule;
|
||||
- per-job docker networks left behind by jobs the runner did not live to tear down are removed. They are recognised by the `com.gitea.runner.uuid` label carrying this runner's uuid, so leftovers of other runners on the same daemon are left alone. Without this, each leaked network keeps holding a subnet of the daemon's address pool.
|
||||
|
||||
## `cache`
|
||||
|
||||
See [Caching](cache.md) for the full picture, including shared cache servers.
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `enabled` | `true` | run the built-in cache server used by `actions/cache` and friends. |
|
||||
| `dir` | `$HOME/.cache/actcache` | where cache blobs are stored. Ignored with `external_server`. |
|
||||
| `host` | – | address job containers use to reach this runner's cache server. Empty means auto-detect; `0.0.0.0` is not valid. |
|
||||
| `port` | `0` | port of the built-in server, `0` picks a free one. |
|
||||
| `external_server` | – | URL of a shared `cache-server` to use instead of a local one. |
|
||||
| `external_secret` | – | shared secret, required with `external_server`; must be identical everywhere. Generate with `openssl rand -hex 32`. |
|
||||
| `external_secret_file` | – | read that secret from a file instead. Setting both is an error. |
|
||||
| `offline_mode` | `false` | reuse a cached action instead of fetching it on every job. A moved tag or updated branch then stays at the cached commit until the entry expires or is removed. |
|
||||
| `v2` | `true` | serve the cache service v2 API used by `actions/[email protected]` and later. |
|
||||
|
||||
## `container`
|
||||
|
||||
Applies to jobs that run in containers.
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `network` | – | network the job container joins: `host`, `bridge`, or a custom network name. Empty means the runner creates one per job. `network_mode` is still accepted for old configs. |
|
||||
| `network_create_options.enable_ipv4` / `enable_ipv6` | Docker defaults | only apply to auto-created networks. IPv6 additionally requires `dockerd --ipv6`. |
|
||||
| `privileged` | `false` | run job containers privileged; required for Docker-in-Docker inside jobs. |
|
||||
| `options` | – | extra `docker run` options, e.g. `--add-host=my.gitea.url:host-gateway`. A volume declared here replaces the one the runner mounts on the same container path, which is how the tool cache can be kept on the host (`--volume /host/toolcache:/opt/hostedtoolcache`); its source must also be allowed by `valid_volumes`. |
|
||||
| `workdir_parent` | `/workspace` | parent directory of a job's working directory inside the container. A leading `/` is trimmed and re-added. |
|
||||
| `valid_volumes` | `[]` | volumes and bind mounts a job may mount, as [glob](https://github.com/gobwas/glob) patterns. `[]` forbids all, `['**']` allows all. |
|
||||
| `docker_host` | – | override the docker host. Empty auto-detects it, `-` auto-detects it but does not mount the socket into job containers. |
|
||||
| `force_pull` | `false` | pull images even when present. Images pinned by digest are never re-pulled, and a failed pull with a local copy available only warns. |
|
||||
| `force_rebuild` | `false` | rebuild local action images even when present. |
|
||||
| `require_docker` | `false` | always require a reachable daemon, even for host-only labels. |
|
||||
| `docker_timeout` | `0s` | how long to wait for the daemon to become reachable. |
|
||||
| `bind_workdir` | `false` | bind-mount the workspace from the host instead of using a docker volume, so jobs can bind-mount it by its own path into containers they start (`.:/app` in `docker compose`). Not needed when workflows use `GITEA_DOCKER_WORKSPACE`. The parent directory must then be mounted into the runner container. |
|
||||
|
||||
:::note Privileged mode and workflow container options
|
||||
A workflow's own `jobs.<job_id>.container.options` are untrusted input. While `container.privileged` is disabled, the options that would break out of the container are stripped with a warning in the job log: `--pid`, `--ipc`, `--uts`, `--cgroupns`, `--userns`, `--cap-add`, `--security-opt`, `--device`, `--device-cgroup-rule`, `--gpus`, `--volumes-from`, `--runtime`, `--cgroup-parent` and `--sysctl`. They are honoured once privileged mode is enabled, because the operator has then opted into host access.
|
||||
:::
|
||||
|
||||
## `host`
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `host.workdir_parent` | `$HOME/.cache/act/` | parent directory of a job's working directory for host-mode jobs. |
|
||||
|
||||
## `health_check` and `metrics`
|
||||
|
||||
Both are covered in [Monitoring](monitoring.md).
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `health_check.enabled` | `false` | pause fetching new tasks while the machine looks unhealthy. |
|
||||
| `health_check.min_free_disk_space_mb` | `1024` | minimum free space on the filesystem holding the workspaces. |
|
||||
| `health_check.script` | – | extra executable; a non-zero exit, a timeout or a start failure marks the runner unavailable. |
|
||||
| `health_check.interval` | `30s` | how long a result is cached. |
|
||||
| `health_check.timeout` | `10s` | maximum script runtime. |
|
||||
| `metrics.enabled` | `false` | serve `/metrics`, `/healthz` and `/readyz`. |
|
||||
| `metrics.addr` | `127.0.0.1:9101` | listen address. There is no authentication, so only expose it behind a firewall. |
|
||||
| `metrics.readiness_grace` | `30s` | how long consecutive polling failures may last before `/readyz` returns 503. |
|
||||
|
||||
## Reloading
|
||||
|
||||
The runner reads its configuration at startup only. Restart the process after a change — with `shutdown_timeout` set, running jobs are given that much time to finish first.
|
||||
See [Caching](cache.md), [hooks](hooks/job-hooks.md) and [monitoring](monitoring.md) for their configuration options.
|
||||
@@ -4,7 +4,7 @@ sidebar_position: 1
|
||||
|
||||
# Job hooks
|
||||
|
||||
Job hooks are operator-provided scripts that run **inside the job environment**, before the job's first step and after its last one. They are the equivalent of GitHub's [job hooks](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/run-scripts):
|
||||
Job hooks are scripts you provide. They run in the job environment before its first step and after its last step. Use them for setup that applies to every job, such as registry logins, mirror configuration or masking secrets used by all jobs.
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
@@ -13,62 +13,34 @@ runner:
|
||||
job_completed: /hooks/completed.sh
|
||||
```
|
||||
|
||||
| Setting | Runs |
|
||||
| --- | --- |
|
||||
| `runner.hooks.job_started` | before the job's first step, before any action is downloaded |
|
||||
| `runner.hooks.job_completed` | after the job's last post step, while the job environment is still up |
|
||||
`job_started` runs before any action is downloaded. `job_completed` runs after the last post step, including when the job fails or is cancelled. If these settings are unset, the runner reads GitHub's `ACTIONS_RUNNER_HOOK_JOB_STARTED` and `ACTIONS_RUNNER_HOOK_JOB_COMPLETED` from `runner.envs` or `runner.env_file`. The runner ignores workflow values for these hook variables.
|
||||
|
||||
`ACTIONS_RUNNER_HOOK_JOB_STARTED` and `ACTIONS_RUNNER_HOOK_JOB_COMPLETED` are read from the runner's environment (`runner.envs`, `runner.env_file`) when the settings are unset, so a configuration carried over from `actions/runner` keeps working. The settings take precedence. A workflow cannot point the runner at a different hook: those variables are only read from the runner's own environment, never from the job's.
|
||||
|
||||
Both hooks are **synchronous** and block the job while they run, and a non-zero exit from either one fails the job. There is no `continue-on-error` and no per-hook timeout — the job's `runner.timeout` is the only bound. Run anything long in the background from within the hook.
|
||||
|
||||
Use them for per-job setup that no workflow should have to carry: registry logins, mirror configuration, or masking runner-wide secrets with `::add-mask::`.
|
||||
A hook that exits with a non-zero status fails the job. Hooks block the job while they run and count against its timeout. Keep them fast.
|
||||
|
||||
## Where they run
|
||||
|
||||
The hooks run where the job's steps run: inside the job container, or on the host in host mode. The paths are resolved *there*, so the script has to exist in the job image or on the host — a path that only exists on the runner host is not visible to a containerized job. For host-wide cleanup after the job environment is gone, use the [post-task script](post-task-script.md) instead.
|
||||
Hooks run inside the job container, or on the host for host jobs. GitHub always runs hooks on the host. The script must exist in the job image or on the host where it runs. Job containers cannot access a path that exists only in the runner container. To make a host directory available to jobs, mount it with `container.options` and allow it in `container.valid_volumes`.
|
||||
|
||||
:::note
|
||||
This is a deliberate difference from `actions/runner`, which runs its job hooks on the host, outside any container the job declares. Running them where the steps run is what lets a hook prepare the environment the steps actually see.
|
||||
:::
|
||||
|
||||
The script is run according to its extension:
|
||||
|
||||
| Extension | Command |
|
||||
| Extension | Runs as |
|
||||
| --- | --- |
|
||||
| `.sh` | `bash -e <path>` |
|
||||
| `.ps1` | `pwsh -command . '<path>'` |
|
||||
| anything else | the file itself, which needs its own shebang and executable bit |
|
||||
| `.ps1` | `pwsh -command ". '<path>'"` |
|
||||
| Anything else | The file itself |
|
||||
|
||||
As on GitHub, the shell flags applied to `run:` steps are **not** applied to a hook — set `pipefail` or anything else you want inside the script.
|
||||
The shell options of `run:` steps do not apply to hooks. Set `pipefail` and other shell options inside the script.
|
||||
|
||||
A hook path that does not exist inside the job environment fails the job with `No such file or directory`, naming the path.
|
||||
## Environment and output
|
||||
|
||||
### Docker-in-Docker and Docker-out-of-Docker
|
||||
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.
|
||||
|
||||
The hook is executed and its files are exchanged over the Docker API, addressed by container ID, so no path is translated between the runner and the daemon. Both setups work unchanged, but they differ in where the hook file has to be:
|
||||
|
||||
- **DinD** — the daemon has its own filesystem. Bake the hook into the job image; a path from the runner's filesystem is not visible to it.
|
||||
- **DooD** — the job container is created by the host's daemon, so a bind mount in `container.options` is resolved against the **host**, not against the runner container. Either bake the hook into the job image, or mount a host directory and add it to `container.valid_volumes`.
|
||||
|
||||
## Environment
|
||||
|
||||
A hook sees the job's environment: the workflow, job and `container:` `env:`, the runner's `envs`, and the `GITHUB_*` context variables, with the same masking applied to its output as to a step's. The step-specific ones (`GITHUB_ACTION`, `GITHUB_OUTPUT`, `GITHUB_STATE`) are not set — a hook is not a step, so `::save-state::` and `::set-output::` have nowhere to go.
|
||||
|
||||
Its stdout is part of the job log, inside a collapsible group, and is scanned for workflow commands: `::add-mask::` registers a value to be masked for the rest of the job, `::set-env::` and `::add-path::` apply to the steps that follow.
|
||||
|
||||
`$GITHUB_ENV` and `$GITHUB_PATH` point at files that are read back after the hook exits, so the file-command form works too:
|
||||
Use `$GITHUB_ENV` and `$GITHUB_PATH` to pass environment variables and paths to later steps. Mask values with `::add-mask::`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
echo "REGISTRY_TOKEN=$(fetch-token)" >> "$GITHUB_ENV"
|
||||
token="$(fetch-token)"
|
||||
echo "::add-mask::$token"
|
||||
echo "REGISTRY_TOKEN=$token" >> "$GITHUB_ENV"
|
||||
echo "/opt/tooling/bin" >> "$GITHUB_PATH"
|
||||
```
|
||||
|
||||
Both files are the hook's own, separate from the per-step ones, so nothing a hook writes is truncated by the first step.
|
||||
|
||||
## Recommendations
|
||||
|
||||
- Keep hooks **fast** and return the right exit code: they are on the critical path of every job, and nothing bounds them.
|
||||
- Use **idempotent** operations, and expect `job_completed` to run after success, failure, and cancellation alike.
|
||||
- Mask anything secret the hook prints or exports with `::add-mask::`.
|
||||
For cleanup on the host after the job environment is gone, use the [post-task script](post-task-script.md).
|
||||
@@ -4,98 +4,43 @@ sidebar_position: 2
|
||||
|
||||
# Post-task script
|
||||
|
||||
The post-task script is an optional host hook that runs **once after every task**, after the runner has finished its normal per-task cleanup. Typical uses are pruning Docker images, vacuuming ephemeral disks, or resetting VM state between jobs.
|
||||
The post-task script runs on the runner's host after each job, once the runner has removed the job's containers. Use it for housekeeping such as pruning Docker images or freeing disk space.
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
# Path to an executable on the host. Empty or omitted disables the hook.
|
||||
post_task_script: /usr/local/bin/gitea-post-task.sh
|
||||
# Hard limit on script runtime. Default when post_task_script is set: 5m.
|
||||
post_task_script_timeout: 2m
|
||||
```
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `runner.post_task_script` | disabled | host path to the script or binary. Relative paths are resolved from the runner's working directory. |
|
||||
| `runner.post_task_script_timeout` | `5m` when a script is set | maximum runtime before the runner kills the script and moves on. |
|
||||
|
||||
## When it runs
|
||||
|
||||
For each task, the order is:
|
||||
|
||||
1. the workflow runs (steps, actions, containers);
|
||||
2. in-job cleanup (action `post:` steps, container stop and removal);
|
||||
3. job outputs are reported to Gitea;
|
||||
4. the bind-workdir workspace is removed, when `container.bind_workdir` is enabled;
|
||||
5. **the post-task script**;
|
||||
6. the final task acknowledgement to Gitea.
|
||||
|
||||
The script is **additive**: it does not replace any built-in cleanup. With `container.bind_workdir` enabled, the workspace directory has usually already been deleted before the script starts, but `GITEA_WORKSPACE` still names the path the job used.
|
||||
|
||||
## The runner stays offline until the script finishes
|
||||
|
||||
This is the most important operational detail. When the script starts, the runner **stops sending task heartbeats**, so from Gitea's perspective it is not available for new work until the script exits and the final task flush has been sent.
|
||||
|
||||
While the script runs:
|
||||
|
||||
- Gitea does not assign another task to this runner for the current job slot;
|
||||
- the capacity slot stays occupied locally — with `capacity: 1`, no other task starts;
|
||||
- a shutdown counts this phase as part of the in-flight task, so a slow script delays graceful shutdown.
|
||||
|
||||
If the script never exits, the runner stays in this state until `runner.post_task_script_timeout` elapses (default **5 minutes**), then kills it and proceeds. Set that timeout to what your housekeeping is allowed to take, and keep the script short and bounded.
|
||||
|
||||
## Environment variables
|
||||
|
||||
The script receives `runner.envs` / `runner.env_file` values plus:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| `GITEA_TASK_ID` | numeric task ID |
|
||||
| `GITEA_RUN_ID` | workflow run ID, when the server provides it |
|
||||
| `GITEA_REPOSITORY` | repository slug (`owner/name`) |
|
||||
| `GITEA_WORKSPACE` | workspace path the job used, which may already be deleted |
|
||||
| `GITEA_JOB_RESULT` | `success`, `failure`, `cancelled`, `skipped` or `unknown` |
|
||||
|
||||
The environment is **not** a copy of the job container's. Even `PATH` is only present if `runner.envs` or `runner.env_file` defines it.
|
||||
|
||||
## Output and errors
|
||||
|
||||
- stdout and stderr go to the **runner process log**, prefixed with `post-task script stdout:` / `post-task script stderr:` — not to the job log;
|
||||
- a non-zero exit is logged as a warning and does not change the job result already reported to Gitea;
|
||||
- timeouts and start failures are warnings too; the runner still acknowledges the task.
|
||||
|
||||
## Interaction with other timeouts
|
||||
|
||||
| Timeout | Effect on the post-task script |
|
||||
| --- | --- |
|
||||
| `runner.post_task_script_timeout` | kills the script if it runs too long. The **only** timeout that bounds it. |
|
||||
| `runner.timeout` | caps the task **up to** the script. The script detaches from the task deadline, so a job that nearly hit the runner timeout does not cut it short. |
|
||||
| `runner.shutdown_timeout` | bounds how long a shutdown waits for the **task**. The script detaches from cancellation and may extend shutdown until its own timeout elapses. |
|
||||
|
||||
## Examples
|
||||
|
||||
Prune dangling Docker resources on Linux:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
docker image prune -f
|
||||
docker builder prune -f --filter 'until=24h'
|
||||
```
|
||||
|
||||
On Windows, use a `.exe`, `.bat` or `.cmd` path; `.ps1` is not supported as the configured path, so wrap PowerShell in a batch file:
|
||||
The job's slot stays busy until the script exits. With `capacity: 1`, the runner accepts no new jobs while the script runs. The runner kills the script if it runs longer than `post_task_script_timeout`, which defaults to `5m`. The runner also waits for the script during shutdown.
|
||||
|
||||
The runner writes the script's output to its own log, not to the job log. If the script exits with a non-zero status, the runner logs a warning without changing the job's result.
|
||||
|
||||
## Environment
|
||||
|
||||
The script receives variables from `runner.envs` and `runner.env_file`, but not from the runner's own environment. Set `PATH` in one of these settings if the script needs it. The runner also sets these variables:
|
||||
|
||||
| Variable | Value |
|
||||
| --- | --- |
|
||||
| `GITEA_TASK_ID` | The task ID |
|
||||
| `GITEA_RUN_ID` | The workflow run ID |
|
||||
| `GITEA_REPOSITORY` | The repository as `owner/name` |
|
||||
| `GITEA_WORKSPACE` | The job's workspace path, which may already be deleted |
|
||||
| `GITEA_JOB_RESULT` | `success`, `failure`, `cancelled`, `skipped` or `unknown` |
|
||||
|
||||
## Windows
|
||||
|
||||
The configured path must be an `.exe`, `.bat` or `.cmd` file. Wrap a PowerShell script in a batch file:
|
||||
|
||||
```bat
|
||||
@echo off
|
||||
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0post-task.ps1"
|
||||
```
|
||||
|
||||
`.sh` files on Windows need a Unix shell on `PATH`, unless `post_task_script` points at the interpreter itself.
|
||||
|
||||
## Notes
|
||||
|
||||
- `gitea-runner exec` does not load the runner YAML and never runs this hook.
|
||||
- Use idempotent operations: the script runs after success, failure and cancellation alike.
|
||||
- Watch the runner log when testing failure modes — a hung script, a non-zero exit, a missing executable.
|
||||
- Bind-workdir idle cleanup (`runner.workdir_cleanup_age`) is separate from this hook and only runs while the runner is idle.
|
||||
- For work that has to happen inside the job environment, use [job hooks](job-hooks.md) instead.
|
||||
For work inside the job environment, use [job hooks](job-hooks.md).
|
||||
+25
-27
@@ -5,46 +5,44 @@ slug: /
|
||||
|
||||
# Gitea Runner
|
||||
|
||||
The [Gitea Runner](https://gitea.com/gitea/runner) executes the jobs of [Gitea Actions](/usage/actions/overview).
|
||||
It polls a Gitea instance for queued jobs, runs their steps in a container or directly on the machine it is installed on, and streams the logs and the result back.
|
||||
[Gitea Runner](https://gitea.com/gitea/runner) runs [Gitea Actions](/usage/actions/overview) jobs.
|
||||
It asks a Gitea instance for jobs, runs them, and sends their logs and results back.
|
||||
|
||||
:::info Development version
|
||||
These pages describe the `main` branch of `gitea.com/gitea/runner`, which is published as the `nightly` binaries and images.
|
||||
Features documented here may not be part of a release yet. Pick a released version in the **Runner Version** dropdown for stable documentation.
|
||||
These pages describe builds from the `main` branch, published as `nightly` binaries and images.
|
||||
Select a release in the **Runner Version** dropdown for stable documentation.
|
||||
:::
|
||||
|
||||
## Requirements
|
||||
|
||||
A runner needs a Gitea instance with Actions enabled, a [registration token](registration.md), and, for containerized jobs, a Docker daemon. Actions are enabled by default since Gitea 1.21; on older instances they have to be turned on:
|
||||
- Gitea 1.21 or later with [Actions enabled](/administration/config-cheat-sheet#actions-actions), the default setting.
|
||||
- Git 2.34.1 or later on the runner's `PATH`.
|
||||
- Docker, or Podman with `podman.socket` enabled, for jobs in containers, Docker actions, and `docker://` steps.
|
||||
|
||||
```ini
|
||||
[actions]
|
||||
ENABLED=true
|
||||
```
|
||||
Jobs need these tools wherever steps run, in the job image or on the host:
|
||||
|
||||
Other OCI engines that implement the Docker API may work, but are untested. Podman is not a supported configuration.
|
||||
- `bash` or `sh` for `run` steps, or `pwsh` or `powershell` on Windows.
|
||||
- `node` for JavaScript actions and `hashFiles()`.
|
||||
- `git` 2.34.1 or later for [`builtin:checkout`](jobs.md#built-in-checkout), plus `git-lfs` for its `lfs` input and `ssh` for its `ssh-key` input.
|
||||
|
||||
## Execution modes
|
||||
## Where jobs run
|
||||
|
||||
A runner can run jobs in three different ways. The mode is not a global setting: it follows from the [labels](labels.md) the runner is registered with, so a single runner can offer both container and host labels.
|
||||
The runner's [labels](labels.md) determine where each job runs. One runner can use a mix of these environments:
|
||||
|
||||
| Mode | How jobs run | Docker daemon | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Docker (recommended) | in a container created from the label's image | external, e.g. the host's `/var/run/docker.sock` | jobs are isolated from each other, but share the daemon |
|
||||
| Docker-in-Docker | in a container created by a daemon that lives next to the runner | bundled in the `dind` / `dind-rootless` images | strongest isolation, more setup, needs `--privileged` |
|
||||
| Host | directly on the machine, with the tools installed there | only needed for `docker://` actions and service containers | no isolation between jobs |
|
||||
| Label | Where the job runs |
|
||||
| --- | --- |
|
||||
| `docker://<image>` | In a container |
|
||||
| `kubernetes://<image>` | In a pod in a Kubernetes cluster |
|
||||
| `host` | Directly on the runner's machine |
|
||||
|
||||
Host jobs run as the runner's user without isolation. Use them only for trusted repositories.
|
||||
|
||||
## Getting started
|
||||
|
||||
1. [Install the runner](installation/binary.md) as a binary, [in Docker](installation/docker.md), or [on Kubernetes](installation/kubernetes.md).
|
||||
2. [Register it](registration.md) against your instance with a registration token.
|
||||
3. [Configure it](configuration.md), and pick the [labels](labels.md) that decide which jobs it accepts.
|
||||
4. Optionally set up a [shared cache](cache.md), [job hooks](hooks/job-hooks.md), a [post-task script](hooks/post-task-script.md), or [metrics and health checks](monitoring.md).
|
||||
1. Install the runner [from a binary](installation/binary.md), [with Docker](installation/docker.md), or [on Kubernetes](installation/kubernetes.md).
|
||||
2. [Register it](registration.md) with your Gitea instance.
|
||||
3. Start it with `gitea-runner daemon`.
|
||||
|
||||
Every command and flag is listed in the [command line reference](reference/cli.md).
|
||||
The runner works without a configuration file. [Configuration](configuration.md) explains when you need one.
|
||||
|
||||
## Versioning and compatibility
|
||||
|
||||
The runner is released independently of Gitea and its version numbers are unrelated to the instance's. Gitea 1.21 or later is expected — older instances cannot accept the runner's label declaration — and individual features need a newer instance still, which is called out where they apply.
|
||||
|
||||
When moving between major runner versions, read [Upgrading](upgrade.md) first: `2.0.0` and `3.0.0` both contain breaking changes.
|
||||
The runner is released independently of Gitea. Read [Upgrading](upgrade.md) before moving to a new major version.
|
||||
@@ -4,62 +4,46 @@ sidebar_position: 1
|
||||
|
||||
# Install from a binary
|
||||
|
||||
The runner is a single static binary called `gitea-runner`. It has no dependencies apart from a Docker daemon for containerized jobs.
|
||||
The runner is a single binary, `gitea-runner`, built for Linux, macOS, Windows, and FreeBSD.
|
||||
|
||||
## Download
|
||||
|
||||
- released builds: [dl.gitea.com/gitea-runner](https://dl.gitea.com/gitea-runner/) or the [release page](https://gitea.com/gitea/runner/releases)
|
||||
- development builds of the `main` branch: [dl.gitea.com/gitea-runner/nightly](https://dl.gitea.com/gitea-runner/nightly/)
|
||||
|
||||
Each file is published next to a `.sha256` checksum and an `.xz` compressed variant:
|
||||
Download releases from [dl.gitea.com/gitea-runner](https://dl.gitea.com/gitea-runner/). Find builds from the `main` branch in its [`nightly`](https://dl.gitea.com/gitea-runner/nightly/) directory. Each binary has a matching `.sha256` checksum file:
|
||||
|
||||
```bash
|
||||
VERSION=nightly
|
||||
curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64"
|
||||
curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64.sha256"
|
||||
sha256sum -c "gitea-runner-$VERSION-linux-amd64.sha256"
|
||||
install -m 0755 "gitea-runner-$VERSION-linux-amd64" /usr/local/bin/gitea-runner
|
||||
sudo install -m 0755 "gitea-runner-$VERSION-linux-amd64" /usr/local/bin/gitea-runner
|
||||
```
|
||||
|
||||
Check that the binary matches your platform:
|
||||
|
||||
```bash
|
||||
gitea-runner --version
|
||||
```
|
||||
|
||||
## Build from source
|
||||
|
||||
Building requires the Go version declared in the repository's `go.mod`:
|
||||
|
||||
```bash
|
||||
git clone https://gitea.com/gitea/runner.git
|
||||
cd runner
|
||||
make build
|
||||
```
|
||||
To build the runner yourself, run `make build` in a clone of [gitea/runner](https://gitea.com/gitea/runner).
|
||||
|
||||
## First run
|
||||
|
||||
```bash
|
||||
gitea-runner generate-config > config.yaml # optional, defaults are safe
|
||||
gitea-runner -c config.yaml register # see "Registering a runner"
|
||||
gitea-runner -c config.yaml daemon
|
||||
gitea-runner register --instance https://gitea.example.com --token <token>
|
||||
gitea-runner daemon
|
||||
```
|
||||
|
||||
The `daemon` command runs in the foreground. It reads the registration file (`runner.file`, `.runner` by default) relative to its working directory, so keep the working directory stable across restarts.
|
||||
`register` prompts for the remaining settings and writes the `.runner` registration file to the working directory. Run `daemon` from the same directory so it can read the file. See [Registration](../registration.md).
|
||||
|
||||
## Run as a systemd service
|
||||
## systemd
|
||||
|
||||
Create an unprivileged user, install the binary, and register the runner as that user so the `.runner` file ends up in the service's working directory:
|
||||
Create a user and a configuration file. Then register the runner as that user from its home directory:
|
||||
|
||||
```bash
|
||||
sudo useradd --system --home-dir /var/lib/gitea-runner --create-home gitea-runner
|
||||
sudo install -d /etc/gitea-runner
|
||||
sudo -u gitea-runner gitea-runner generate-config | sudo tee /etc/gitea-runner/config.yaml >/dev/null
|
||||
sudo mkdir -p /etc/gitea-runner
|
||||
sudo gitea-runner config init -c /etc/gitea-runner/config.yaml
|
||||
sudo chown gitea-runner /etc/gitea-runner/config.yaml
|
||||
cd /var/lib/gitea-runner
|
||||
sudo -u gitea-runner gitea-runner register -c /etc/gitea-runner/config.yaml
|
||||
sudo -u gitea-runner gitea-runner register -c /etc/gitea-runner/config.yaml \
|
||||
--instance https://gitea.example.com --token <token>
|
||||
```
|
||||
|
||||
Then install the unit as `/etc/systemd/system/gitea-runner.service`:
|
||||
Install the unit as `/etc/systemd/system/gitea-runner.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
@@ -79,8 +63,6 @@ User=gitea-runner
|
||||
Group=gitea-runner
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
# Allow running jobs to finish before the runner is stopped. Keep this in sync
|
||||
# with runner.shutdown_timeout in the config.
|
||||
TimeoutStopSec=3h
|
||||
|
||||
[Install]
|
||||
@@ -92,13 +74,17 @@ sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now gitea-runner
|
||||
```
|
||||
|
||||
If jobs use the host's Docker daemon, the `gitea-runner` user also needs access to the daemon socket. Adding it to the `docker` group grants that access and is [equivalent to root on the host](https://docs.docker.com/engine/security/#docker-daemon-attack-surface).
|
||||
Stopping the service cancels running jobs unless `runner.shutdown_timeout` gives them time to finish. Keep `runner.shutdown_timeout` below `TimeoutStopSec`:
|
||||
|
||||
Environment variables for the process — most importantly [proxy variables](../proxy.md) — belong in `Environment=` lines or a drop-in file, not in the runner config.
|
||||
```bash
|
||||
sudo -u gitea-runner gitea-runner config set -c /etc/gitea-runner/config.yaml runner.shutdown_timeout 2h50m
|
||||
```
|
||||
|
||||
## Run as a launchd daemon (macOS)
|
||||
For jobs in containers, give the `gitea-runner` user access to the Docker daemon's socket, for example through the `docker` group. That access is [equivalent to root](https://docs.docker.com/engine/security/#docker-daemon-attack-surface) on the host. Set the runner's environment variables, such as [proxy settings](../proxy.md), with `Environment=` lines in the unit.
|
||||
|
||||
macOS uses `launchd` instead of systemd. Daemons run as `root` by default; an unprivileged `_gitea-runner` user can be created with `dscl`. Install the following as `/Library/LaunchDaemons/com.gitea.runner.plist` and adjust the paths to your installation:
|
||||
## launchd (macOS)
|
||||
|
||||
Adjust the paths and user for your setup, then save this file as `/Library/LaunchDaemons/com.gitea.runner.plist`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -114,16 +100,10 @@ macOS uses `launchd` instead of systemd. Daemons run as `root` by default; an un
|
||||
<string>--config</string>
|
||||
<string>/etc/gitea-runner/config.yaml</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>UserName</key>
|
||||
<string>_gitea-runner</string>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/var/lib/gitea-runner</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/lib/gitea-runner/runner.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/lib/gitea-runner/runner.err</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
@@ -131,23 +111,22 @@ macOS uses `launchd` instead of systemd. Daemons run as `root` by default; an un
|
||||
<key>HOME</key>
|
||||
<string>/var/lib/gitea-runner</string>
|
||||
</dict>
|
||||
<key>UserName</key>
|
||||
<string>_gitea-runner</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/lib/gitea-runner/runner.log</string>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo launchctl load /Library/LaunchDaemons/com.gitea.runner.plist
|
||||
sudo launchctl bootstrap system /Library/LaunchDaemons/com.gitea.runner.plist
|
||||
```
|
||||
|
||||
On macOS and Windows hosts, jobs usually run with [host labels](../labels.md) and the tools installed on the machine.
|
||||
|
||||
## Windows
|
||||
|
||||
Install the `windows-amd64` binary and register it as a service with any service wrapper (for example `sc.exe` plus a wrapper such as [WinSW](https://github.com/winsw/winsw), or a scheduled task at boot). The runner itself has no service-installer subcommand.
|
||||
Run `gitea-runner daemon` with a service wrapper such as [WinSW](https://github.com/winsw/winsw). The runner has no service installer of its own.
|
||||
|
||||
Keep in mind for Windows hosts:
|
||||
|
||||
- `runner.post_task_script` accepts `.exe`, `.bat` and `.cmd` paths; `.ps1` is not supported as the configured path.
|
||||
- host-mode jobs are terminated as a process tree, so tools that daemonize are not left behind.
|
||||
On macOS and Windows, jobs usually run directly on the runner's machine with [host labels](../labels.md).
|
||||
@@ -4,120 +4,74 @@ sidebar_position: 2
|
||||
|
||||
# Install with Docker
|
||||
|
||||
The official images are published on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`.
|
||||
`latest` is the newest release, `nightly` is built from the `main` branch, and every release is also tagged with its version.
|
||||
|
||||
In the container the registration and the daemon are combined: the entrypoint registers the runner on first start (when no registration file exists yet) and then execs `gitea-runner daemon`.
|
||||
|
||||
## Image flavours
|
||||
|
||||
All flavours contain the same `gitea-runner` binary and differ only in how a Docker daemon is made available to jobs.
|
||||
|
||||
| Tag | Base image | Docker daemon | Supervisor | Runs as |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `nightly`, `latest`, `<version>` | `alpine` | none, you provide one | `tini` | `root` |
|
||||
| `nightly-dind`, `latest-dind` | `docker:dind` | bundled, needs `--privileged` | `s6` | `root` |
|
||||
| `nightly-dind-rootless`, `latest-dind-rootless` | `docker:dind-rootless` | bundled, rootless | `s6` | `rootless` (UID 1000) |
|
||||
|
||||
The rootless flavour's UID is fixed at 1000 by the upstream base image, and its daemon always listens on `/run/user/1000/docker.sock`, so `--user 1001` does not work. To talk to a *host* rootless daemon under another UID, use the basic flavour and bind-mount that daemon's socket instead.
|
||||
|
||||
## Basic flavour
|
||||
|
||||
The default image ships no daemon of its own, so jobs that use `docker://` images need one from outside the container — usually the host's socket:
|
||||
Runner images are available on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`. On its first start, the container registers and starts the runner:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-e GITEA_RUNNER_NAME=<runner_name> \
|
||||
-v $PWD/data:/data \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker.io/gitea/runner:nightly
|
||||
```
|
||||
|
||||
This flavour does not need `--privileged`. The trade-off is that jobs share the host's daemon and can therefore see its other containers and images. A job that can reach the socket can also read the reusable `GITEA_RUNNER_REGISTRATION_TOKEN` from the runner container's `docker inspect` output.
|
||||
|
||||
## Docker-in-Docker
|
||||
|
||||
The `dind` flavour bundles its own daemon, so no socket has to be mounted:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner --privileged \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-v $PWD/data:/data \
|
||||
docker run -d --name gitea-runner --restart always --privileged \
|
||||
-e GITEA_INSTANCE_URL=https://gitea.example.com \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<token> \
|
||||
-v ./data:/data \
|
||||
-v runner-docker:/var/lib/docker \
|
||||
docker.io/gitea/runner:nightly-dind
|
||||
```
|
||||
|
||||
`s6` starts `dockerd` first and the runner service waits for it before registering. Use `nightly-dind-rootless` to run both the daemon and the runner as an unprivileged user; rootless Docker's usual limitations around networking, cgroups and storage drivers apply.
|
||||
The `-dind` image runs its own Docker daemon for jobs. Jobs never get access to the host's Docker daemon socket, which grants the equivalent of root access on the host. The two volumes preserve registration and job images when you replace the container:
|
||||
|
||||
## Volumes
|
||||
- `/data` holds the `.runner` registration file. Without it, a new container registers as another runner.
|
||||
- `/var/lib/docker` holds the images pulled for jobs. Without it, a new container pulls them again.
|
||||
|
||||
Two different pieces of state are worth persisting, and neither implies the other:
|
||||
## Image flavours
|
||||
|
||||
- `/data` is the runner's working directory. It holds the `.runner` registration file and, optionally, the config file. Without it, a recreated container registers itself again as a new runner, leaving a stale entry in Gitea, and fails outright if the token has been reset in the meantime.
|
||||
- the Docker daemon's data root holds the images pulled for jobs. It is **not** under `/data`: for `dind` it is `/var/lib/docker` inside the container, for `dind-rootless` it is `/home/rootless/.local/share/docker`. Give it its own volume, or every new container re-pulls the job images.
|
||||
| Tag | Docker daemon for jobs |
|
||||
| --- | --- |
|
||||
| `nightly-dind` (recommended) | Bundled. Requires `--privileged`. |
|
||||
| `nightly-dind-rootless` | Bundled. Runs as UID 1000. Requires `--privileged` and [rootless Docker](https://docs.docker.com/engine/security/rootless/) support on the host. Stores its images in `/home/rootless/.local/share/docker`. |
|
||||
| `nightly` | None. Mount the host's Docker daemon socket with `-v /var/run/docker.sock:/var/run/docker.sock`, or set `DOCKER_HOST`. |
|
||||
|
||||
## Entrypoint environment variables
|
||||
The `latest` and release version tags use the same suffixes, for example `latest-dind`. The `-dind` flavours are available for amd64 and arm64. The basic image also supports riscv64 and s390x. The images are designed for Docker, not Podman.
|
||||
|
||||
The entrypoint ([`scripts/run.sh`](https://gitea.com/gitea/runner/src/branch/main/scripts/run.sh)) understands:
|
||||
When the basic image uses the host's Docker daemon, jobs share that daemon. Use this setup only for trusted repositories.
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Meaning |
|
||||
| --- | --- |
|
||||
| `GITEA_INSTANCE_URL` | instance to register against, e.g. `https://gitea.example.com/` |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN` | registration token; unset before the daemon starts |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` | file to read the token from, for Docker/Kubernetes secrets |
|
||||
| `GITEA_RUNNER_NAME` | runner name, defaults to the container hostname |
|
||||
| `GITEA_RUNNER_LABELS` | labels, passed to both `register` and `daemon` |
|
||||
| `GITEA_RUNNER_EPHEMERAL` | any non-empty value registers the runner as [ephemeral](../registration.md#ephemeral-runners) |
|
||||
| `GITEA_RUNNER_ONCE` | any non-empty value runs a single job, then exits |
|
||||
| `GITEA_MAX_REG_ATTEMPTS` | registration attempts before giving up, default `10` |
|
||||
| `RUNNER_STATE_FILE` | registration file name inside `/data`, default `.runner` |
|
||||
| `CONFIG_FILE` | config file inside the container, passed as `--config` |
|
||||
| `GITEA_INSTANCE_URL` | Gitea instance to register with. |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN` | Registration token, needed only until registration completes. |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` | File to read the registration token from, such as a Docker secret. |
|
||||
| `GITEA_RUNNER_NAME` | Runner name. Defaults to the container's hostname. |
|
||||
| `GITEA_RUNNER_LABELS` | Comma-separated [labels](../labels.md), applied on every start. |
|
||||
| `GITEA_RUNNER_EPHEMERAL` | Any nonempty value registers an [ephemeral runner](../registration.md#ephemeral-runners). |
|
||||
| `GITEA_RUNNER_ONCE` | Any nonempty value makes the runner exit after one job. |
|
||||
| `GITEA_MAX_REG_ATTEMPTS` | Maximum number of registration attempts. Unlimited by default, with 5 seconds between attempts. |
|
||||
| `CONFIG_FILE` | Path to a [configuration file](../configuration.md) inside the container. |
|
||||
|
||||
These are entrypoint variables, not runner settings: the runner process itself is configured only through the [config file](../configuration.md).
|
||||
|
||||
Mount the config file when you need one:
|
||||
To use a configuration file, mount it and set `CONFIG_FILE` to its path:
|
||||
|
||||
```bash
|
||||
docker run -v $PWD/config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml ...
|
||||
docker run ... -v ./config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml docker.io/gitea/runner:nightly-dind
|
||||
```
|
||||
|
||||
A config file can be generated with the image itself:
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint="" docker.io/gitea/runner:nightly gitea-runner generate-config > config.yaml
|
||||
```
|
||||
|
||||
## docker compose
|
||||
## Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
runner:
|
||||
image: docker.io/gitea/runner:nightly
|
||||
image: docker.io/gitea/runner:nightly-dind
|
||||
restart: always
|
||||
privileged: true
|
||||
environment:
|
||||
CONFIG_FILE: /config.yaml
|
||||
GITEA_INSTANCE_URL: "${INSTANCE_URL}"
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}"
|
||||
GITEA_RUNNER_NAME: "${RUNNER_NAME}"
|
||||
GITEA_RUNNER_LABELS: "${RUNNER_LABELS}"
|
||||
GITEA_INSTANCE_URL: https://gitea.example.com
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: <token>
|
||||
volumes:
|
||||
- ./config.yaml:/config.yaml
|
||||
- ./data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- runner-docker:/var/lib/docker
|
||||
|
||||
volumes:
|
||||
runner-docker:
|
||||
```
|
||||
|
||||
When Gitea runs in the same compose project, depend on its health check so the runner does not try to register before the instance answers:
|
||||
|
||||
```yaml
|
||||
depends_on:
|
||||
gitea:
|
||||
condition: service_healthy
|
||||
restart: true
|
||||
```
|
||||
|
||||
The rootless Docker-in-Docker variant needs a few extra options:
|
||||
The rootless flavour needs these additional settings:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -126,22 +80,21 @@ services:
|
||||
restart: always
|
||||
privileged: true
|
||||
security_opt:
|
||||
# for hosts running AppArmor (Ubuntu, Debian), whose default profile blocks
|
||||
# the user namespace changes the bundled daemon needs
|
||||
- apparmor=rootlesskit
|
||||
volumes:
|
||||
- ./data/runner:/data
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=<instance_url>
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token>
|
||||
- DOCKER_HOST=unix:///var/run/user/1000/docker.sock
|
||||
# slirp4netns gives significantly better network throughput than vpnkit
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_MTU=65520
|
||||
GITEA_INSTANCE_URL: https://gitea.example.com
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: <token>
|
||||
DOCKERD_ROOTLESS_ROOTLESSKIT_NET: slirp4netns
|
||||
DOCKERD_ROOTLESS_ROOTLESSKIT_MTU: 65520
|
||||
volumes:
|
||||
- runner-data:/data
|
||||
|
||||
volumes:
|
||||
runner-data:
|
||||
```
|
||||
|
||||
## Cache from a dockerized runner
|
||||
- Set `security_opt` on AppArmor hosts such as Ubuntu and Debian. Docker's `docker-ce-rootless-extras` package provides the `rootlesskit` profile.
|
||||
- Use `slirp4netns` for better job network throughput than the default.
|
||||
- Make `/data` writable by UID 1000. Use a named volume or a bind-mounted host directory owned by that UID.
|
||||
|
||||
A runner in a container creates a separate network per job by default, so the address it detects for its own cache server is often unreachable from job containers and `actions/cache` fails with a connection timeout. Set `cache.host` and `cache.port` explicitly and publish that port, or put the job containers on a shared network — see [Caching](../cache.md#dockerized-runners).
|
||||
|
||||
More deployment examples live in the [`examples`](https://gitea.com/gitea/runner/src/branch/main/examples) directory of the runner repository.
|
||||
See the runner repository's [examples](https://gitea.com/gitea/runner/src/branch/main/examples) for more deployments.
|
||||
@@ -4,46 +4,68 @@ sidebar_position: 3
|
||||
|
||||
# Install on Kubernetes
|
||||
|
||||
Ready-to-adapt manifests live in [`examples/kubernetes`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes) of the runner repository, and a Helm chart is maintained at [gitea/helm-actions](https://gitea.com/gitea/helm-actions).
|
||||
A runner in Kubernetes can run jobs in two ways:
|
||||
|
||||
## Choosing a manifest
|
||||
- **Job pods**: Each job runs in its own pod under the cluster's quotas and policies, without privileged containers. Docker actions and `docker://` steps are not supported.
|
||||
- **Docker-in-Docker**: Jobs run in a Docker daemon alongside the runner. All workflow features are supported. The daemon is privileged, so a job can break out of its container and access the node.
|
||||
|
||||
| Example | Shape | Docker daemon |
|
||||
| --- | --- | --- |
|
||||
| `dind-docker.yaml` | `Deployment` with a native sidecar (`initContainer` with `restartPolicy: Always`, needs Kubernetes 1.29+) | privileged `docker:dind` sidecar, socket shared through an `emptyDir` |
|
||||
| `statefulset-dind.yaml` | `StatefulSet` with `volumeClaimTemplates` | same as above |
|
||||
| `rootless-docker.yaml` | `Deployment` with a single container | bundled rootless daemon of the `dind-rootless` image, reached over `tcp://localhost:2376` with TLS |
|
||||
The manifests below are in the runner repository's [`examples/kubernetes`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes) directory. They read the registration token from the `runner-secret` Secret and store the `.runner` registration file in a volume at `/data`. This preserves registration when the pod restarts.
|
||||
|
||||
Prefer the `StatefulSet` variant when you scale past one replica: each pod then gets a stable identity and its own volume, so it keeps its `.runner` registration across restarts and reschedules instead of registering itself again as a new runner.
|
||||
## Job pods
|
||||
|
||||
## Two volumes, two purposes
|
||||
Deploy [`kubernetes-pods.yaml`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes/kubernetes-pods.yaml). It registers the runner with a `kubernetes` label:
|
||||
|
||||
- `/data` — the runner's working directory, holding the `.runner` registration file and optionally the config file.
|
||||
- the daemon's data root — `/var/lib/docker` for the `dind` sidecar, `/home/rootless/.local/share/docker` for `dind-rootless`. It holds the images pulled for jobs and is *not* under `/data`. Dropping it still works, but every recreated pod re-pulls all job images.
|
||||
|
||||
With the rootless image, both volumes must be writable by UID/GID 1000, which is what `securityContext.fsGroup: 1000` in the example is for.
|
||||
|
||||
## Registration token
|
||||
|
||||
The examples read the token from a `Secret`:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
- name: GITEA_INSTANCE_URL
|
||||
value: http://gitea-http.gitea.svc.cluster.local:3000
|
||||
- name: GITEA_RUNNER_REGISTRATION_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: runner-secret
|
||||
key: token
|
||||
```text
|
||||
ubuntu-latest:kubernetes://docker.gitea.com/runner-images:ubuntu-latest
|
||||
```
|
||||
|
||||
The token stays valid for further registrations until it is reset, but each registration creates another runner entry. For pods that are recreated without their volume, use the instance-wide token configured on the Gitea side, and expect stale runner entries — or start an [ephemeral runner](../registration.md#ephemeral-runners) per job.
|
||||
The runner creates job pods in its own namespace using its service account. The manifest grants the permissions it needs:
|
||||
|
||||
## Privileges
|
||||
| Resource | Verbs |
|
||||
| --- | --- |
|
||||
| `pods` | `create`, `get`, `list`, `delete` |
|
||||
| `pods/exec` | `create`, `get` |
|
||||
| `pods/log` | `get` |
|
||||
| `secrets` | `create`, `delete` |
|
||||
|
||||
Docker-in-Docker needs `securityContext.privileged: true`, which lets a malicious job break out of the container. Weigh that against the alternatives:
|
||||
The cluster must run Kubernetes 1.30 or later. Job images need `sh`, `tar`, `tail`, and `env`. A runner outside the cluster uses the current context from the first file in `$KUBECONFIG`, or from `~/.kube/config` if `$KUBECONFIG` is unset.
|
||||
|
||||
- the rootless flavour, which reduces but does not remove the exposure;
|
||||
- pointing the basic flavour at a daemon outside the cluster;
|
||||
- keeping such runners on a dedicated node pool and only granting them to trusted repositories.
|
||||
Use pod templates to set resources, node selectors, image pull secrets, and other settings for job pods:
|
||||
|
||||
```yaml
|
||||
kubernetes:
|
||||
pod_template:
|
||||
spec:
|
||||
containers:
|
||||
- name: job # merged into the job container
|
||||
resources:
|
||||
limits:
|
||||
memory: 4Gi
|
||||
- name: $services # merged into every service container
|
||||
resources:
|
||||
limits:
|
||||
memory: 1Gi
|
||||
pod_templates:
|
||||
gpu: # merged on top for jobs with runs-on: gpu
|
||||
spec:
|
||||
nodeSelector:
|
||||
nvidia.com/gpu.present: "true"
|
||||
```
|
||||
|
||||
Services share the job pod's network. Steps reach them by their service ID or `localhost`. Two services cannot use the same port. Only `--health-*` is supported in a service's `options`. Job pods do not receive a service account token unless the template sets `automountServiceAccountToken: true`.
|
||||
|
||||
## Docker-in-Docker
|
||||
|
||||
| Manifest | Deployment type |
|
||||
| --- | --- |
|
||||
| [`dind-docker.yaml`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes/dind-docker.yaml) | `Deployment` with a privileged `docker:dind` sidecar |
|
||||
| [`statefulset-dind.yaml`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes/statefulset-dind.yaml) | `StatefulSet` with a privileged `docker:dind` sidecar, for multiple replicas |
|
||||
| [`rootless-docker.yaml`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes/rootless-docker.yaml) | `Deployment` with the `dind-rootless` image |
|
||||
|
||||
Use the `StatefulSet` for multiple replicas so each has its own registration volume. A [Helm chart](https://gitea.com/gitea/helm-actions) is also available.
|
||||
|
||||
The Docker daemon stores images pulled for jobs in `/var/lib/docker`, or `/home/rootless/.local/share/docker` in the rootless image. The manifests mount this directory on a volume so a new pod does not pull every image again.
|
||||
|
||||
## Shutdown
|
||||
|
||||
The manifests set `terminationGracePeriodSeconds` to give a pod three hours to stop. To let running jobs finish, set `runner.shutdown_timeout` a little lower than that grace period. Otherwise, the runner cancels running jobs when the pod stops.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Jobs
|
||||
|
||||
## Service containers
|
||||
|
||||
A job's `services` start before its steps. If a service defines a health check in its image or `options`, the runner waits until the service is healthy:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 5s
|
||||
--health-retries 10
|
||||
```
|
||||
|
||||
If a service is unhealthy, the runner fails the job and shows the service's container log. If a service never becomes healthy, the runner fails the job after `container.service_ready_timeout`, which defaults to `5m`.
|
||||
|
||||
Connect to a service from a step using its ID and listening port, for example `psql -h postgres -p 5432`.
|
||||
|
||||
A job with a `host` label does not start services. Set `container:` on the job if it needs services.
|
||||
|
||||
## Docker inside jobs
|
||||
|
||||
Container jobs can access the runner's Docker daemon, usually through a proxy. Containers started by the job can bind-mount the workspace using its path:
|
||||
|
||||
```bash
|
||||
docker run -v "$PWD:/src" alpine ls /src
|
||||
```
|
||||
|
||||
When the job ends, the proxy removes the containers, networks and volumes the job created, including `docker compose` services. Set `container.sweep: false` when jobs deploy services that should keep running.
|
||||
|
||||
Without the proxy, for example with a remote `DOCKER_HOST`, prefix workspace bind mounts with `GITEA_DOCKER_WORKSPACE`. This variable contains the workspace path as the Docker daemon sees it:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data
|
||||
```
|
||||
|
||||
To keep the Docker socket out of job containers, set `container.docker_host: "-"`.
|
||||
|
||||
## Volumes and privileges
|
||||
|
||||
Workflows can mount only the volumes and host paths allowed by `container.valid_volumes`. The list is empty by default:
|
||||
|
||||
```yaml
|
||||
container:
|
||||
valid_volumes:
|
||||
- data # the volume named data
|
||||
- /src/*.json # * stays within one path segment, ** crosses them
|
||||
- /etc/ssl/certs:ro # read-only mounts only
|
||||
```
|
||||
|
||||
Unless you enable `container.privileged`, the runner drops options in a workflow's `container.options` that could allow the job to escape the container. Examples include `--privileged`, `--cap-add`, `--device` and `--security-opt`. The runner writes a warning in the job log when it drops an option. The runner's own `container.options` always apply.
|
||||
|
||||
## Tool cache
|
||||
|
||||
Setup actions such as `actions/setup-go` install tools in `/opt/hostedtoolcache`. `runner.tool_cache_mode` determines how the runner stores this cache:
|
||||
|
||||
| Mode | Tool cache |
|
||||
| --- | --- |
|
||||
| `none` (default) | Tools included in the job image. Tools installed by a job are removed when it ends. |
|
||||
| `shared` | One volume reused by every job. Use only with `runner.capacity: 1`. Two jobs installing the same tool version at once corrupt the cache. |
|
||||
|
||||
With `none`, include tools in the job image at `/opt/hostedtoolcache/<tool>/<version>/<arch>`. Place an empty `<arch>.complete` file next to the directory. The `-full` variant of the [runner images](https://gitea.com/gitea/runner-images) includes its tools this way.
|
||||
|
||||
## Built-in checkout
|
||||
|
||||
`uses: builtin:checkout` checks out the repository like `actions/checkout`. It does not download an action or require Node in the job image. It runs `git` in the job. See [Requirements](index.md#requirements) and the inputs listed in [builtin-actions.md](https://gitea.com/gitea/runner/src/branch/main/docs/builtin-actions.md).
|
||||
|
||||
## Secrets
|
||||
|
||||
The runner masks secrets and `::add-mask::` values in job logs, job summaries, and the names of containers it creates. The runner does not send job outputs that contain a secret. A `needs.<job>.outputs.<name>` expression that reads such an output is empty.
|
||||
+17
-46
@@ -4,67 +4,38 @@ sidebar_position: 4
|
||||
|
||||
# Labels
|
||||
|
||||
Labels decide **which jobs a runner accepts** and **how it runs them**. A job's `runs-on` value is matched against the runner's label names; the first match wins and selects the execution environment for that job.
|
||||
A runner's labels determine which jobs it accepts and where it runs them. Gitea sends a job to a runner that has the labels specified in the job's `runs-on`. The runner uses the environment of the first matching entry in `runs-on`.
|
||||
|
||||
A label is written as:
|
||||
|
||||
```text
|
||||
<name>[:<schema>[:<args>]]
|
||||
```
|
||||
|
||||
| Part | Meaning |
|
||||
| Label | Job environment |
|
||||
| --- | --- |
|
||||
| `name` | the name a workflow refers to in `runs-on`, e.g. `ubuntu-latest` |
|
||||
| `schema` | either `docker` or `host`, defaulting to `host` when omitted |
|
||||
| `args` | only used by the `docker` schema: the image the job runs in |
|
||||
| `ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest` | Container using the specified image. |
|
||||
| `ubuntu-latest:kubernetes://docker.gitea.com/runner-images:ubuntu-latest` | Pod using the specified image. See [job pods](installation/kubernetes.md#job-pods). |
|
||||
| `macos:host`, or just `macos` | The runner's machine. |
|
||||
|
||||
Two schemas are supported:
|
||||
|
||||
- `docker://<image>` — the job runs in a container created from `<image>`:
|
||||
|
||||
```text
|
||||
ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest
|
||||
```
|
||||
|
||||
- `host` — the job's steps run directly on the machine, with the tools installed there:
|
||||
|
||||
```text
|
||||
macos:host
|
||||
```
|
||||
|
||||
So a runner registered with
|
||||
The label name is the part before the first `:docker`, `:kubernetes` or `:host`. Workflows use this name in `runs-on`. For example:
|
||||
|
||||
```text
|
||||
ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest,macos:host
|
||||
```
|
||||
|
||||
runs `runs-on: ubuntu-latest` jobs in the `runner-images:ubuntu-latest` container and `runs-on: macos` jobs directly on the host.
|
||||
With these labels, `runs-on: ubuntu-latest` jobs run in a container. Jobs with `runs-on: macos` run on the runner's machine.
|
||||
|
||||
Names may themselves contain a colon, for example `pool:e57e18d4-10d4-406f-93bf-60f127221bdd`; only `host` and `docker` are treated as schemas.
|
||||
A job's `container:` image replaces the label's image. The job runs in a container even with a `host` label.
|
||||
|
||||
If a job's `runs-on` matches none of the runner's labels, the job still runs, in the default `docker.gitea.com/runner-images:ubuntu-latest` image. Images maintained for this purpose are listed at [gitea/runner-images](https://gitea.com/gitea/runner-images); community images such as the [act images](https://github.com/nektos/act/blob/master/IMAGES.md) work too.
|
||||
A job whose `runs-on` matches none of the runner's labels uses `runner.default_image`, which defaults to `docker.gitea.com/runner-images:ubuntu-latest`. It runs in a container, as a pod on runners with `kubernetes` but no `docker` labels, or on the host when no Docker daemon is reachable.
|
||||
|
||||
:::note
|
||||
A runner that only exposes `host` labels still needs access to a Docker daemon whenever a job uses a `docker://` action or a service container. `host` labels only change where the job's own steps run.
|
||||
:::
|
||||
## Changing labels
|
||||
|
||||
## Registration versus config labels
|
||||
Labels are set during registration and stored in the registration file. To change them, set them in the configuration file or on the command line, then restart the runner. The runner reports its labels to Gitea at startup:
|
||||
|
||||
Labels are chosen at registration time (`--labels`, or the interactive prompt) and stored in the registration file. Afterwards they can be changed without re-registering, and the most explicit source wins:
|
||||
|
||||
```text
|
||||
--labels / GITEA_RUNNER_LABELS > runner.labels in the config file > labels in the .runner file
|
||||
```bash
|
||||
gitea-runner config set runner.labels 'ubuntu-latest:docker://node:24' 'macos:host'
|
||||
```
|
||||
|
||||
- during `register`, `runner.labels` from the config file takes precedence and the `--labels` flag is ignored;
|
||||
- `daemon --labels` (which defaults to `GITEA_RUNNER_LABELS`) overrides the labels of an already registered runner;
|
||||
- whenever the resulting labels differ from those in the registration file, they are written back to it and re-declared to the instance on startup;
|
||||
- labels that fail to parse are skipped with a warning instead of stopping the runner.
|
||||
|
||||
Labels can also be edited in the Gitea UI under the runner's settings.
|
||||
`daemon --labels` or the `GITEA_RUNNER_LABELS` environment variable takes precedence over `runner.labels`. The `runner.labels` setting takes precedence over labels in the registration file.
|
||||
|
||||
## Choosing images
|
||||
|
||||
- Pick an image that already contains the tools your workflows expect. The default images are small; a job that installs a toolchain on every run is usually better served by a purpose-built image.
|
||||
- Pin images by tag or digest for reproducible jobs. An image pinned by digest is never re-pulled, even with `container.force_pull` enabled.
|
||||
- Use distinct names such as `linux_amd64:host` or `windows:host` for host labels, so a workflow written for GitHub's `ubuntu-latest` does not accidentally run unsandboxed on your machine.
|
||||
- Use the [runner images](https://gitea.com/gitea/runner-images) for tools that common workflows need. To avoid installing a toolchain on every run, choose an image that already includes it.
|
||||
- Pin images by tag or digest for reproducible jobs.
|
||||
- Give host labels distinct names such as `macos-arm64` to prevent workflows written for GitHub's `ubuntu-latest` from running directly on your machine without a sandbox.
|
||||
+39
-51
@@ -1,93 +1,81 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Monitoring and health
|
||||
# Monitoring
|
||||
|
||||
## Prometheus metrics
|
||||
## Metrics
|
||||
|
||||
```yaml
|
||||
metrics:
|
||||
enabled: true
|
||||
addr: "127.0.0.1:9101"
|
||||
readiness_grace: 30s
|
||||
```
|
||||
|
||||
With `metrics.enabled`, the runner serves three endpoints on `metrics.addr`:
|
||||
With metrics enabled, the runner serves these endpoints:
|
||||
|
||||
| Endpoint | Purpose |
|
||||
| --- | --- |
|
||||
| `/metrics` | Prometheus exposition of the runner's own metrics |
|
||||
| `/healthz` | liveness: the process is up |
|
||||
| `/readyz` | task admission: `503` while a [health check](#local-health-checks) reports the machine as unavailable, once polling has been failing for longer than `readiness_grace`, or after the runner has been deleted on the instance |
|
||||
| `/metrics` | Prometheus metrics |
|
||||
| `/healthz` | Liveness, always `200` while the process runs |
|
||||
| `/readyz` | Readiness, `503` when a [health check](#health-checks) fails, the runner cannot reach Gitea for longer than `metrics.readiness_grace` (`30s`), or the runner is shutting down |
|
||||
|
||||
There is **no authentication** on this listener. The default address binds to localhost only; expose it more widely (`":9101"`) only behind a firewall or a scrape-only network.
|
||||
The listener has no authentication. If you expose it beyond localhost, for example with `addr: ":9101"`, protect it with a firewall.
|
||||
|
||||
All series are prefixed with `gitea_runner_`, among them:
|
||||
The runner exports these metrics in addition to the standard Go and process metrics:
|
||||
|
||||
| Metric | Meaning |
|
||||
| --- | --- |
|
||||
| `gitea_runner_info` | always `1`, with the version and runner name as labels |
|
||||
| `gitea_runner_uptime_seconds` | seconds since the daemon started |
|
||||
| `gitea_runner_capacity` / `gitea_runner_job_running` / `gitea_runner_job_capacity_utilization_ratio` | configured capacity, jobs in flight, and their ratio |
|
||||
| `gitea_runner_job_total` | jobs by result (`success`, `failure`, `cancelled`, `skipped`, `unknown`) |
|
||||
| `gitea_runner_job_duration_seconds` | job duration histogram |
|
||||
| `gitea_runner_poll_fetch_total` / `gitea_runner_poll_fetch_duration_seconds` | task fetches by result (`task`, `empty`, `error`) and their latency |
|
||||
| `gitea_runner_poll_backoff_seconds` | last polling backoff interval |
|
||||
| `gitea_runner_report_log_total` / `gitea_runner_report_state_total` | log and state reports by result |
|
||||
| `gitea_runner_report_log_buffer_rows` | log rows buffered but not yet sent |
|
||||
| `gitea_runner_client_errors_total` | RPC errors by method |
|
||||
| `gitea_runner_state` | `1` for the current `state`: `busy`, `idle` or `unavailable` |
|
||||
| `gitea_runner_job_running`, `gitea_runner_capacity` | Running jobs and configured capacity |
|
||||
| `gitea_runner_job_capacity_utilization_ratio` | Running jobs divided by capacity |
|
||||
| `gitea_runner_job_total` | Finished jobs by `status`: `success`, `failure`, `cancelled`, `skipped`, `timeout` or `unknown` |
|
||||
| `gitea_runner_job_duration_seconds` | Job duration histogram |
|
||||
| `gitea_runner_poll_fetch_total` | Job fetches by `result`: `task`, `empty` or `error` |
|
||||
| `gitea_runner_client_errors_total` | Failed requests to Gitea by `method` and `code` |
|
||||
|
||||
Useful things to alert on: `gitea_runner_poll_fetch_total{result="error"}` rising (the instance is unreachable or the runner was deleted), a `capacity_utilization_ratio` pinned at `1` (the pool is too small), and a growing `report_log_buffer_rows` (log delivery is falling behind).
|
||||
Consider alerts for `gitea_runner_state{state="unavailable"}`, a rising `gitea_runner_poll_fetch_total{result="error"}`, and a utilization ratio that stays at `1`, which means jobs may be waiting for a free slot.
|
||||
|
||||
## OpenTelemetry tracing
|
||||
## OpenTelemetry
|
||||
|
||||
Setting `OTEL_EXPORTER_OTLP_ENDPOINT` in the runner's environment sends a trace of every job, with a span per step, to an OTLP collector over `http/protobuf`:
|
||||
Set `OTEL_EXPORTER_OTLP_ENDPOINT` in the runner's environment to send traces and the metrics above to an OpenTelemetry collector. Each job has a trace with a span for each step:
|
||||
|
||||
```sh
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
|
||||
```
|
||||
|
||||
Jobs receive `TRACEPARENT`, so instrumented tools in them join the job's trace. See [docs/telemetry.md](https://gitea.com/gitea/runner/src/branch/main/docs/telemetry.md) for headers, sampling and the security notes.
|
||||
Jobs receive `TRACEPARENT`, so instrumented tools can add spans to the job's trace. See [telemetry.md](https://gitea.com/gitea/runner/src/branch/main/docs/telemetry.md) for all variables and security notes.
|
||||
|
||||
## Local health checks
|
||||
## Health checks
|
||||
|
||||
Health checks let a runner take itself out of rotation when the machine it runs on is not fit for work — most commonly when the disk is full.
|
||||
Health checks stop a runner from accepting new jobs while its machine has a problem, such as a full disk:
|
||||
|
||||
```yaml
|
||||
health_check:
|
||||
enabled: false
|
||||
enabled: true
|
||||
min_free_disk_space_mb: 1024
|
||||
script: ''
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
script: /usr/local/bin/check-runner.sh
|
||||
```
|
||||
|
||||
- while a check fails, the runner stops fetching **new** tasks; jobs already running are unaffected and finish normally;
|
||||
- no check runs while a job is active — the last result is reused until the runner is idle again;
|
||||
- `min_free_disk_space_mb` is measured on the filesystem holding the runner's workspaces, and defaults to 1024 MiB when omitted or zero;
|
||||
- `script` is any executable. A non-zero exit, a timeout, or a failure to start marks the runner unavailable. Its result is cached for `interval` and it is killed after `timeout`;
|
||||
- recovery is automatic and logged (`runner local health recovered, resuming task polling`), and the state is reflected by `/readyz`.
|
||||
- The disk check measures free space on the filesystem containing `host.workdir_parent`, or `container.workdir_parent` when `container.bind_workdir` is enabled.
|
||||
- `script` is optional. The runner becomes unavailable if the script exits with a non-zero status, fails to start, or runs longer than `health_check.timeout` (`10s`). The runner reuses the script's result for `health_check.interval` (`30s`).
|
||||
- Checks only run while the runner is idle. Running jobs are never interrupted.
|
||||
- The runner resumes accepting jobs once the checks pass again.
|
||||
|
||||
## Logs
|
||||
|
||||
The runner logs to stderr; `log.level` controls the verbosity, with `debug` and `trace` adding `file:line` to each line. Under systemd the log ends up in the journal (`journalctl -u gitea-runner`), in Docker in `docker logs`.
|
||||
The runner writes logs to stderr. View them in the systemd journal or with `docker logs` for a runner container. Set `log.level` to control verbosity, from `trace` to `error`.
|
||||
|
||||
The runner log is not the job log: step output is streamed to Gitea and is tuned with the `runner.log_report_*` settings, while things like [post-task script](hooks/post-task-script.md) output only ever appear in the runner log.
|
||||
The runner streams step output to Gitea without including it in its own log. To also keep a local copy of every job log, set a directory:
|
||||
|
||||
```yaml
|
||||
log:
|
||||
job:
|
||||
dir: /var/log/gitea-runner
|
||||
```
|
||||
|
||||
The runner writes each job log to `<start time>-task-<id>.log` in this directory and masks secrets. It keeps the files for `log.job.retention` (`168h`). Only the user running the runner can read them.
|
||||
|
||||
## Reporting a problem
|
||||
|
||||
`gitea-runner bug-report` prints the version, Go version, OS/architecture and CPU count — paste its output into an issue at [gitea/runner](https://gitea.com/gitea/runner/issues):
|
||||
|
||||
```bash
|
||||
gitea-runner bug-report
|
||||
```
|
||||
|
||||
```text
|
||||
Runner version: nightly
|
||||
Go version: go1.26.5
|
||||
OS/Arch: linux/amd64
|
||||
NumCPU: 8
|
||||
```
|
||||
|
||||
To reproduce a workflow locally, without a Gitea instance and without touching the runner's registration, use `gitea-runner exec` — see the [command line reference](reference/cli.md#exec).
|
||||
`gitea-runner bug-report` prints the runner version, Go version, platform and CPU count. Include its output when you open an issue at [gitea/runner](https://gitea.com/gitea/runner/issues).
|
||||
+17
-21
@@ -1,10 +1,10 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Proxies
|
||||
|
||||
The runner reads the usual proxy variables from its own environment and passes them on to every job:
|
||||
Set proxy variables in the runner's environment. Use `Environment=` in a systemd unit, `docker run -e`, or `env:` in Kubernetes:
|
||||
|
||||
```sh
|
||||
http_proxy=http://proxy.example:3128
|
||||
@@ -12,35 +12,31 @@ https_proxy=http://proxy.example:3128
|
||||
no_proxy=gitea.internal,.example.local
|
||||
```
|
||||
|
||||
Set them where the process is started — `Environment=` in a systemd unit, `docker run -e`, or `env:` in Kubernetes. They are used for the runner's own requests and are given to jobs in both lower and upper case.
|
||||
The runner uses these variables for its own requests. It passes them to every job and service container in lowercase and uppercase. Dockerfile actions receive them as build arguments.
|
||||
|
||||
## What is exempted automatically
|
||||
The runner adds the following to `no_proxy` so jobs reach them directly:
|
||||
|
||||
These are added to `no_proxy` for jobs, so they are always reached directly:
|
||||
|
||||
- the cache server
|
||||
- The runner's cache server
|
||||
- `localhost`, `127.0.0.1` and `::1`
|
||||
- the job's service containers
|
||||
- the Docker daemon, when it is reached over `tcp://`
|
||||
- The job's service containers
|
||||
- The Docker daemon, when reached over `tcp://`
|
||||
|
||||
The Gitea instance is **not** added. Add it to `no_proxy` yourself if it should be reached directly.
|
||||
Add Gitea to `no_proxy` if jobs should reach it directly. The runner does not add it automatically.
|
||||
|
||||
## Overriding per job or per runner
|
||||
## Changing the proxy for jobs
|
||||
|
||||
| Scope | Where to set it |
|
||||
| --- | --- |
|
||||
| one step | the step's `env:` |
|
||||
| one job | the job's `container.env` |
|
||||
| the whole runner | `runner.envs` in the config; a `no_proxy` set there is added to the list above instead of replacing it |
|
||||
| One step | Set the step's `env:`. |
|
||||
| The rest of a job | Write lowercase and uppercase variable names to `$GITHUB_ENV`. |
|
||||
| Every job | Set `runner.envs`. Values in `no_proxy` are added to the list above. |
|
||||
|
||||
Setting proxy variables at workflow or job level (outside `container.env`) has no effect.
|
||||
Proxy values set at the workflow or job level, or in `container.env`, cannot replace the runner's proxy values.
|
||||
|
||||
## The Docker daemon needs its own setting
|
||||
## Docker daemon
|
||||
|
||||
Images are pulled by the daemon, not by the runner, so the daemon needs its own proxy configuration. In the `dind` images the daemon shares the container's environment and picks the variables up; for any other daemon see [the Docker documentation](https://docs.docker.com/engine/daemon/proxy/). The runner logs a warning at startup when it has a proxy configured and the daemon does not.
|
||||
The Docker daemon pulls images and needs its own proxy settings. See [the Docker documentation](https://docs.docker.com/engine/daemon/proxy/). The Docker daemon bundled with the `dind` images reads the runner's proxy variables. The runner warns at startup if it has a proxy but the Docker daemon does not.
|
||||
|
||||
Dockerfile actions are built with these variables passed as build arguments, so their `RUN` steps can reach the network.
|
||||
## Credentials
|
||||
|
||||
## Credentials in proxy URLs
|
||||
|
||||
A password inside a proxy URL is masked in job logs, but any step can still read it: the step is given the proxy URL in its environment. Prefer a proxy that does not need credentials, or one that authenticates by source address.
|
||||
The runner masks passwords in proxy URLs in job logs, but every step can read them from its environment. Prefer a proxy that authenticates by source address.
|
||||
+134
-15
@@ -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
|
||||
@@ -38,7 +38,7 @@ Use "gitea-runner [command] --help" for more information about a command.
|
||||
|
||||
## register
|
||||
|
||||
Registers the runner against a Gitea instance and writes the registration file. Interactive unless `--no-interactive` is given; the token can also come from `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable. See [Registering a runner](../registration.md).
|
||||
Registers the runner with a Gitea instance and writes the registration file. The token comes from `--token`, `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable, and the command asks for the other settings unless `--no-interactive` is given. See [Registration](../registration.md).
|
||||
|
||||
```text
|
||||
Register a runner to the server
|
||||
@@ -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)
|
||||
@@ -135,7 +135,7 @@ Global Flags:
|
||||
|
||||
## cache-server
|
||||
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys; every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys. Every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
|
||||
```text
|
||||
Start a cache server for the cache action
|
||||
@@ -153,18 +153,137 @@ Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
## generate-config
|
||||
## config
|
||||
|
||||
Prints the commented example configuration on stdout, which is the starting point for a config file: `gitea-runner generate-config > config.yaml`.
|
||||
Writes, reads and edits config files. `config init` writes a minimal `config.yaml`, `config set`, `add` and `remove` change it in place, and `config generate` prints every option. See [Configuration](../configuration.md).
|
||||
|
||||
```text
|
||||
Generate, read and edit config files
|
||||
|
||||
Usage:
|
||||
gitea-runner config [flags]
|
||||
gitea-runner config [command]
|
||||
|
||||
Available Commands:
|
||||
add Append values to a list config key
|
||||
generate Print the example config, which documents every option
|
||||
get Print the value of a config key
|
||||
init Write a minimal config file
|
||||
remove Remove values from a list config key
|
||||
runner-file Print the registration file path used by the runner
|
||||
set Set the value of a config key
|
||||
|
||||
Flags:
|
||||
-h, --help help for config
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
|
||||
Use "gitea-runner config [command] --help" for more information about a command.
|
||||
```
|
||||
|
||||
### config add
|
||||
|
||||
```text
|
||||
Append values to a list config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config add <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for add
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config generate
|
||||
|
||||
```text
|
||||
Print the example config, which documents every option
|
||||
|
||||
Usage:
|
||||
gitea-runner generate-config [flags]
|
||||
gitea-runner config generate [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for generate-config
|
||||
-h, --help help for generate
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config get
|
||||
|
||||
```text
|
||||
Print the value of a config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config get <key> [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for get
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config init
|
||||
|
||||
```text
|
||||
Write a minimal config file, leaving every option at its default.
|
||||
Without --config it writes config.yaml in the working directory.
|
||||
|
||||
Usage:
|
||||
gitea-runner config init [flags]
|
||||
|
||||
Flags:
|
||||
-f, --force overwrite an existing config file
|
||||
-h, --help help for init
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config remove
|
||||
|
||||
```text
|
||||
Remove values from a list config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config remove <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for remove
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config runner-file
|
||||
|
||||
```text
|
||||
Print the registration file path used by the runner
|
||||
|
||||
Usage:
|
||||
gitea-runner config runner-file [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for runner-file
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config set
|
||||
|
||||
```text
|
||||
Set the value of a config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config set <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for set
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
|
||||
@@ -7,10 +7,8 @@ description: The commented example configuration of the runner, generated from t
|
||||
|
||||
{/* Generated by update_runner_docs.sh from the gitea/runner sources, do not edit. */}
|
||||
|
||||
This is the output of `gitea-runner generate-config`. It is safe to use unmodified,
|
||||
and it is the authoritative list of every option the runner understands. See
|
||||
[Configuration](../configuration.md) for what the options mean and how the file is
|
||||
loaded.
|
||||
Every option the runner understands, with its default, as printed by `gitea-runner config generate`.
|
||||
See [Configuration](../configuration.md) for how to write and load a config file.
|
||||
|
||||
```yaml
|
||||
# Every option with its default value, all commented out. Read this file, do not copy it.
|
||||
@@ -76,9 +74,9 @@ runner:
|
||||
#workdir_cleanup_age: 24h
|
||||
# Cadence for the idle cleanup pass. Besides the directories above, on runners that use
|
||||
# docker it removes the per-job networks and volumes of jobs this runner did not live to
|
||||
# tear down, which would otherwise hold a subnet of the daemon address pool and the job's
|
||||
# workspace contents until the host is rebuilt. On runners with kubernetes labels it
|
||||
# removes such jobs' pods and Secrets.
|
||||
# tear down once unused and 10 minutes old, which would otherwise hold a subnet of the
|
||||
# daemon address pool and the job's workspace contents until the host is rebuilt. On
|
||||
# runners with kubernetes labels it removes such jobs' pods and Secrets.
|
||||
#idle_cleanup_interval: 10m
|
||||
# The base interval for periodic log flush to the Gitea instance.
|
||||
# Logs may be sent earlier if the buffer reaches log_report_batch_size
|
||||
@@ -91,6 +89,9 @@ runner:
|
||||
# Flush logs immediately when the buffer reaches this many rows.
|
||||
# This ensures bursty output (e.g., npm install) is delivered promptly.
|
||||
#log_report_batch_size: 100
|
||||
# The lowest severity of the runner's own messages (not step output) that are sent to the
|
||||
# job log between steps: trace, debug, info, warn, error. Default if omitted: follow log.level.
|
||||
#log_report_level: info
|
||||
# The interval for reporting task state (step status, timing) to the Gitea instance.
|
||||
# State is also reported on step transitions (start/stop) and after each log flush.
|
||||
#state_report_interval: 5s
|
||||
@@ -103,11 +104,12 @@ runner:
|
||||
# it replaces https://github.com with the value here, which is useful for some special network environments.
|
||||
#github_mirror: ''
|
||||
# Extra HTTP headers for runner API requests to Gitea, e.g. reverse proxy authentication.
|
||||
# Not used for action clones, artifacts, job summaries or jobs. Runner headers take precedence.
|
||||
# Not used for action downloads, artifacts, job summaries or jobs. Runner headers take precedence.
|
||||
# Dropped on redirects to another hostname, or to HTTP if the instance URL uses HTTPS.
|
||||
#extra_headers:
|
||||
# X-Proxy-Token: 'example'
|
||||
# When true (the default), fetch only the requested ref of an action repository (e.g. actions/checkout@v4) at depth 1 instead of cloning every branch's full history.
|
||||
# When true (the default), clone only the requested ref at depth 1 instead of every branch's full history. Actions download as
|
||||
# archives, so this applies to reusable workflows and to actions whose host serves no archive of them.
|
||||
# Set to false to clone the full history.
|
||||
#action_shallow_clone: true
|
||||
# When true (the default), inject the ACT=true environment variable into jobs.
|
||||
@@ -205,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,
|
||||
@@ -316,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.
|
||||
|
||||
+23
-53
@@ -2,84 +2,54 @@
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Registering a runner
|
||||
# Registration
|
||||
|
||||
A runner has to be registered before it can pick up jobs: registration is what tells the runner where to fetch jobs from, and what gives the Gitea instance a stable identity for the runner.
|
||||
Register a runner once with a Gitea instance to get its identity and credentials.
|
||||
|
||||
## Obtain a registration token
|
||||
## Registration token
|
||||
|
||||
Registration tokens are issued by the Gitea instance and can be scoped to the whole instance, an organization/user, or a single repository. See [Actions runners](/usage/actions/runner) for where to find them in the UI and via the API.
|
||||
Gitea issues registration tokens for the whole instance, an organization, a user, or a single repository. A runner accepts jobs within the token's scope. To find a token, see [Gitea Runner](/usage/actions/runner). A token can register any number of runners until it is reset.
|
||||
|
||||
One token can register any number of runners and stays valid until it is reset in the UI or through the API. Instance administrators can also hand Gitea a fixed token with `GITEA_RUNNER_REGISTRATION_TOKEN` / `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` at startup, which is what makes disposable runners practical.
|
||||
|
||||
## Interactive registration
|
||||
## Registering
|
||||
|
||||
```bash
|
||||
gitea-runner register
|
||||
# or with a config file
|
||||
gitea-runner -c config.yaml register
|
||||
gitea-runner register --instance https://gitea.example.com --token <token>
|
||||
```
|
||||
|
||||
The runner asks for:
|
||||
|
||||
- the instance URL, e.g. `https://gitea.com/` or `http://192.168.8.8:3000/` — use the instance's `ROOT_URL`, not `localhost`, when Gitea and the runner are in different containers or hosts;
|
||||
- the registration token;
|
||||
- the runner name, defaulting to the hostname;
|
||||
- the [labels](labels.md), defaulting to the built-in list, or to `runner.labels` when the config file sets it.
|
||||
|
||||
## Non-interactive registration
|
||||
The runner asks for its name. It also asks for its [labels](labels.md) unless you set `runner.labels`. To skip the prompts, use `--no-interactive` and pass the values as flags:
|
||||
|
||||
```bash
|
||||
gitea-runner register --no-interactive \
|
||||
--instance <instance_url> \
|
||||
--token <registration_token> \
|
||||
--name <runner_name> \
|
||||
--labels <runner_labels>
|
||||
--instance https://gitea.example.com \
|
||||
--token <token> \
|
||||
--name my-runner \
|
||||
--labels ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest
|
||||
```
|
||||
|
||||
The token can be kept off the command line, where it would show up in the process list and in shell history:
|
||||
Set `--instance` to the instance's `ROOT_URL`. `localhost` does not work from job containers.
|
||||
|
||||
- `--token-file <path>` reads it from a file, e.g. a Docker or Kubernetes secret;
|
||||
- the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable is used when neither flag is given.
|
||||
To keep the token out of shell history and the process list, pass it with `--token-file <path>` or through the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable.
|
||||
|
||||
## The registration file
|
||||
|
||||
A successful registration writes a `.runner` file (`runner.file` in the config) into the current working directory. It holds the runner's identity and its API credentials, so:
|
||||
Registration writes the runner's credentials to `.runner` in the working directory, or to the path in `runner.file`:
|
||||
|
||||
- do not edit it by hand, and do not copy it to a second machine;
|
||||
- back it up or put it on a persistent volume, otherwise a recreated runner registers as a *new* runner and leaves a stale entry behind — and fails outright if the token has been reset in the meantime;
|
||||
- if it is lost or corrupted, delete it and register again.
|
||||
|
||||
Each runner process needs its own registration file. Two processes sharing one file are indistinguishable to Gitea and cancel each other's jobs, so the runner takes an advisory lock on `<runner.file>.lock` and refuses to start when another process already holds it. The lock is released by the operating system when the process exits, including after a crash. When the lock cannot be created at all — for example on a read-only mount — the runner logs a warning and starts without the guard.
|
||||
- Keep it on persistent storage. If the file is lost, register again as a new runner.
|
||||
- Give each runner process its own registration file. A second process using the same file refuses to start.
|
||||
- Treat it as a secret.
|
||||
|
||||
## Ephemeral runners
|
||||
|
||||
An ephemeral runner accepts exactly one job and then exits. Once a job has been assigned, its credentials are revoked, so it cannot poll for more work before the job's untrusted code runs; it can still report progress until the job finishes.
|
||||
|
||||
This is how organization-wide or instance-wide runners can be offered without trusting every repository that may use them, provided each runner is a fresh VM or container.
|
||||
An ephemeral runner accepts exactly one job, then exits. Its credentials are revoked as soon as the job is assigned, so the job cannot use them to accept more work. Start each ephemeral runner in a fresh VM or container when running jobs from repositories you do not fully trust.
|
||||
|
||||
```bash
|
||||
gitea-runner register --ephemeral
|
||||
gitea-runner register --no-interactive --ephemeral --instance <instance_url> --token <registration_token>
|
||||
gitea-runner register --ephemeral --instance https://gitea.example.com --token <token>
|
||||
```
|
||||
|
||||
With the Docker images, set `GITEA_RUNNER_EPHEMERAL=1` instead; no `/data` volume is needed, since the credentials are single-use:
|
||||
With the Docker images, set `GITEA_RUNNER_EPHEMERAL=1`. To start a runner for each job, listen for Gitea's `workflow_job` [webhook](/usage/repository/webhooks), which fires when a job is queued.
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-e GITEA_RUNNER_EPHEMERAL=1 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker.io/gitea/runner:nightly
|
||||
```
|
||||
`gitea-runner daemon --once` also exits after one job, but its credentials stay valid.
|
||||
|
||||
Because a fresh registration is required for every job, ephemeral runners are usually started on demand from the `workflow_job` webhook, which fires when a job is queued.
|
||||
## Removing a runner
|
||||
|
||||
`--ephemeral` is stricter than `daemon --once`: `--once` also stops after one job, but its credentials stay valid for as long as the runner is registered.
|
||||
|
||||
## Re-registering and unregistering
|
||||
|
||||
Running `register` again in a directory that already has a registration file asks whether to overwrite it. To retire a runner, delete it in the Gitea UI (or via the API) and remove its registration file; the daemon shuts itself down once the server no longer knows it.
|
||||
|
||||
Changing labels does not require re-registration — see [Labels](labels.md#registration-versus-config-labels).
|
||||
Delete the runner in Gitea's runner settings, then delete its registration file. The runner exits when it detects that Gitea has removed its registration.
|
||||
+11
-38
@@ -1,10 +1,10 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
# Upgrading
|
||||
|
||||
A runner upgrade is a binary or image replacement: stop the daemon, swap it, start it again. The registration file stays valid across versions, so a runner keeps its identity and does not have to be registered again.
|
||||
Stop the runner, replace the binary or image, and start it again. The registration file stays valid, so you do not need to register the runner again.
|
||||
|
||||
```bash
|
||||
sudo systemctl stop gitea-runner
|
||||
@@ -12,42 +12,15 @@ sudo install -m 0755 gitea-runner-<version>-linux-amd64 /usr/local/bin/gitea-run
|
||||
sudo systemctl start gitea-runner
|
||||
```
|
||||
|
||||
With `runner.shutdown_timeout` set, `stop` lets the jobs in flight finish first; without it, they are cancelled and Gitea reschedules them.
|
||||
Stopping the runner cancels running jobs unless `runner.shutdown_timeout` gives them time to finish. The runner logs a warning for unknown configuration keys and ignores them. Run `gitea-runner config generate` to list all configuration options.
|
||||
|
||||
Config files are read leniently: keys the running version does not know are reported as a warning and ignored, so one file can be shared by runners of different versions. Compare your file with `gitea-runner generate-config` after an upgrade to pick up new options.
|
||||
## Breaking changes in 5.0
|
||||
|
||||
## 3.0
|
||||
- **Git 2.34.1 or later is required** on the runner and in job images that use `builtin:checkout`.
|
||||
- **`builtin:checkout` works like `actions/checkout`.** It removes untracked and ignored files unless `clean: false` is set. It fails if the triggering tag moved after the workflow started.
|
||||
- **Configuration values expand `${NAME}`** from the runner's environment. The configuration fails to load if `NAME` is unset. Write `$${NAME}` for a literal `${NAME}`, for example in a shell command in a Kubernetes `pod_template`.
|
||||
- **Jobs require `runs-on`.** A job without `runs-on` fails, as it does on GitHub. Jobs that call a reusable workflow are exempt.
|
||||
- **OpenTelemetry metrics follow the semantic conventions**, which changed their names, units and attributes. See [telemetry.md](https://gitea.com/gitea/runner/src/branch/main/docs/telemetry.md#metrics). On `/metrics`, `gitea_runner_client_errors_total` gained a `code` label, and `gitea_runner_job_total` counts jobs stopped by `runner.timeout` as `timeout`.
|
||||
- **Unprivileged runners drop more workflow options.** Unless `container.privileged` is set, `--log-driver`, `--log-opt`, `--oom-score-adj` and `--oom-kill-disable` are removed from a job's `container.options` with a warning.
|
||||
|
||||
### Breaking
|
||||
|
||||
- **Container options from workflows are filtered.** While `container.privileged` is disabled, options in a job's `container.options` that would escape the container are stripped with a warning: `--pid`, `--ipc`, `--uts`, `--cgroupns`, `--userns`, `--cap-add`, `--security-opt`, `--device`, `--device-cgroup-rule`, `--gpus`, `--volumes-from`, `--runtime`, `--cgroup-parent`, `--sysctl`. Workflows that relied on them need a runner with privileged mode enabled.
|
||||
- **One process per registration file.** The daemon takes an advisory lock on `<runner.file>.lock` and refuses to start when another process already uses that file. Setups that started several runners from one directory must give each its own `runner.file` (or its own working directory).
|
||||
- **Cache service v2 is served and enabled by default.** `actions/[email protected]` and later, and the stock `actions/upload-artifact` / `download-artifact` from `v4.4.0` on, reach it through a patch the runner applies to the action's own bundle. Jobs are pointed at the runner's cache server as their results service, which then forwards artifact calls to Gitea. Set `cache.v2: false` to keep to v1.
|
||||
|
||||
### Also new
|
||||
|
||||
- [Job hooks](hooks/job-hooks.md) (`runner.hooks.job_started` / `job_completed`) running inside the job environment.
|
||||
- [Proxy variables](proxy.md) propagated to jobs, service containers and Dockerfile action builds.
|
||||
- Secrets are masked in the log even when a job prints them in an encoded form.
|
||||
- The tool cache can be relocated, and runner-managed paths can be mounted over, via `container.options`.
|
||||
|
||||
## 2.0
|
||||
|
||||
### Breaking
|
||||
|
||||
- **`DOCKER_USERNAME` / `DOCKER_PASSWORD` are no longer implicit pull credentials.** They used to be attached to every image pull, which sent private-registry credentials to Docker Hub for public images. They are ordinary secrets now. Migrate to:
|
||||
- `container.credentials` (and service `credentials`) in the workflow for private images;
|
||||
- a `docker login` performed on the runner host, or a [job hook](hooks/job-hooks.md), for private `uses: docker://...` actions.
|
||||
- **`container.force_pull` now defaults to `false`** in the generated example config, so images already present are reused unless you ask for a pull.
|
||||
- **No environment variable overrides for the config.** `GITEA_DEBUG`, `GITEA_TRACE`, `GITEA_RUNNER_CAPACITY`, `GITEA_RUNNER_FILE`, `GITEA_RUNNER_ENVIRON` and `GITEA_RUNNER_ENV_FILE` are ignored; use a config file. The Docker images' [entrypoint variables](installation/docker.md#entrypoint-environment-variables) are unaffected.
|
||||
|
||||
### Also new
|
||||
|
||||
- [Post-task script](hooks/post-task-script.md) (`runner.post_task_script`) for host housekeeping between jobs.
|
||||
- [Health checks](monitoring.md#local-health-checks) (`health_check.*`) that pause task admission on low disk space or a failing script.
|
||||
- `register --token-file`, and `GITEA_RUNNER_LABELS` honoured by `daemon`, so labels can change without re-registering.
|
||||
- `jobs.<job_id>.timeout-minutes` and `jobs.<job_id>.continue-on-error` support, job summaries, shallow action clones (`runner.action_shallow_clone`), `ssh://` action URLs, IPv4/IPv6 options for auto-created networks, `--platform` and `--pull` in `container.options`, `cache.external_secret_file`, a GitHub-style "Set up job" log section, and pre/post entrypoints of Docker actions.
|
||||
|
||||
## Downgrading
|
||||
|
||||
Downgrading a runner is possible — the registration file format has not changed — but a config file written for a newer version may carry keys the older one ignores, and features such as cache service v2 stop being served, so jobs that came to rely on them fail. Test a downgrade with a spare runner before doing it on a busy pool.
|
||||
Release notes for every version are on the [release page](https://gitea.com/gitea/runner/releases).
|
||||
@@ -38,7 +38,7 @@ Use "gitea-runner [command] --help" for more information about a command.
|
||||
|
||||
## register
|
||||
|
||||
Registers the runner against a Gitea instance and writes the registration file. Interactive unless `--no-interactive` is given; the token can also come from `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable. See [Registering a runner](../registration.md).
|
||||
Registers the runner with a Gitea instance and writes the registration file. The token comes from `--token`, `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable, and the command asks for the other settings unless `--no-interactive` is given. See [Registration](../registration.md).
|
||||
|
||||
```text
|
||||
Register a runner to the server
|
||||
@@ -132,7 +132,7 @@ Global Flags:
|
||||
|
||||
## cache-server
|
||||
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys; every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys. Every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
|
||||
```text
|
||||
Start a cache server for the cache action
|
||||
|
||||
@@ -7,10 +7,8 @@ description: The commented example configuration of the runner, generated from t
|
||||
|
||||
{/* Generated by update_runner_docs.sh from the gitea/runner sources, do not edit. */}
|
||||
|
||||
This is the output of `gitea-runner generate-config`. It is safe to use unmodified,
|
||||
and it is the authoritative list of every option the runner understands. See
|
||||
[Configuration](../configuration.md) for what the options mean and how the file is
|
||||
loaded.
|
||||
Every option the runner understands, with its default, as printed by `gitea-runner generate-config`.
|
||||
See [Configuration](../configuration.md) for how to write and load a config file.
|
||||
|
||||
```yaml
|
||||
# Example configuration file, it's safe to copy this as the default config file without any modification.
|
||||
|
||||
@@ -5,7 +5,7 @@ sidebar_position: 2
|
||||
# Install with Docker
|
||||
|
||||
The official images are published on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`.
|
||||
`latest` is the newest release and the `3` tag follows the newest `3.x` release; `nightly` is built from the `main` branch, and every release is also tagged with its exact version.
|
||||
The `3` tag follows the newest `3.x` release; `nightly` is built from the `main` branch, and every release is also tagged with its exact version.
|
||||
|
||||
In the container the registration and the daemon are combined: the entrypoint registers the runner on first start (when no registration file exists yet) and then execs `gitea-runner daemon`.
|
||||
|
||||
@@ -15,9 +15,9 @@ All flavours contain the same `gitea-runner` binary and differ only in how a Doc
|
||||
|
||||
| Tag | Base image | Docker daemon | Supervisor | Runs as |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `latest`, `3`, `3.0`, `<version>` | `alpine` | none, you provide one | `tini` | `root` |
|
||||
| `latest-dind`, `3-dind` | `docker:dind` | bundled, needs `--privileged` | `s6` | `root` |
|
||||
| `latest-dind-rootless`, `3-dind-rootless` | `docker:dind-rootless` | bundled, rootless | `s6` | `rootless` (UID 1000) |
|
||||
| `3`, `3.5`, `<version>` | `alpine` | none, you provide one | `tini` | `root` |
|
||||
| `3-dind` | `docker:dind` | bundled, needs `--privileged` | `s6` | `root` |
|
||||
| `3-dind-rootless` | `docker:dind-rootless` | bundled, rootless | `s6` | `rootless` (UID 1000) |
|
||||
|
||||
The rootless flavour's UID is fixed at 1000 by the upstream base image, and its daemon always listens on `/run/user/1000/docker.sock`, so `--user 1001` does not work. To talk to a *host* rootless daemon under another UID, use the basic flavour and bind-mount that daemon's socket instead.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Use "gitea-runner [command] --help" for more information about a command.
|
||||
|
||||
## register
|
||||
|
||||
Registers the runner against a Gitea instance and writes the registration file. Interactive unless `--no-interactive` is given; the token can also come from `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable. See [Registering a runner](../registration.md).
|
||||
Registers the runner with a Gitea instance and writes the registration file. The token comes from `--token`, `--token-file` or the `GITEA_RUNNER_REGISTRATION_TOKEN` environment variable, and the command asks for the other settings unless `--no-interactive` is given. See [Registration](../registration.md).
|
||||
|
||||
```text
|
||||
Register a runner to the server
|
||||
@@ -135,7 +135,7 @@ Global Flags:
|
||||
|
||||
## cache-server
|
||||
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys; every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
Runs only the cache server, so several runners can share one cache. `--dir`, `--host` and `--port` override the matching `cache.*` keys. Every other setting, `cache.external_secret` included, has to come from the config file. See [Caching](../cache.md#sharing-a-cache-between-runners).
|
||||
|
||||
```text
|
||||
Start a cache server for the cache action
|
||||
@@ -153,18 +153,121 @@ Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
## generate-config
|
||||
## config
|
||||
|
||||
Prints the commented example configuration on stdout, which is the starting point for a config file: `gitea-runner generate-config > config.yaml`.
|
||||
Writes, reads and edits config files. `config init` writes a minimal `config.yaml`, `config set`, `add` and `remove` change it in place, and `config generate` prints every option. See [Configuration](../configuration.md).
|
||||
|
||||
```text
|
||||
Generate, read and edit config files
|
||||
|
||||
Usage:
|
||||
gitea-runner config [flags]
|
||||
gitea-runner config [command]
|
||||
|
||||
Available Commands:
|
||||
add Append values to a list config key
|
||||
generate Print the example config, which documents every option
|
||||
get Print the value of a config key
|
||||
init Write a minimal config file
|
||||
remove Remove values from a list config key
|
||||
set Set the value of a config key
|
||||
|
||||
Flags:
|
||||
-h, --help help for config
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
|
||||
Use "gitea-runner config [command] --help" for more information about a command.
|
||||
```
|
||||
|
||||
### config add
|
||||
|
||||
```text
|
||||
Append values to a list config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config add <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for add
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config generate
|
||||
|
||||
```text
|
||||
Print the example config, which documents every option
|
||||
|
||||
Usage:
|
||||
gitea-runner generate-config [flags]
|
||||
gitea-runner config generate [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for generate-config
|
||||
-h, --help help for generate
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config get
|
||||
|
||||
```text
|
||||
Print the value of a config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config get <key> [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for get
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config init
|
||||
|
||||
```text
|
||||
Write a minimal config file, leaving every option at its default.
|
||||
Without --config it writes config.yaml in the working directory.
|
||||
|
||||
Usage:
|
||||
gitea-runner config init [flags]
|
||||
|
||||
Flags:
|
||||
-f, --force overwrite an existing config file
|
||||
-h, --help help for init
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config remove
|
||||
|
||||
```text
|
||||
Remove values from a list config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config remove <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for remove
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
```
|
||||
|
||||
### config set
|
||||
|
||||
```text
|
||||
Set the value of a config key
|
||||
|
||||
Usage:
|
||||
gitea-runner config set <key> <value>... [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for set
|
||||
|
||||
Global Flags:
|
||||
-c, --config config Config file path. config subcommands fall back to config.yaml in the working directory or next to the executable
|
||||
|
||||
@@ -7,10 +7,8 @@ description: The commented example configuration of the runner, generated from t
|
||||
|
||||
{/* Generated by update_runner_docs.sh from the gitea/runner sources, do not edit. */}
|
||||
|
||||
This is the output of `gitea-runner generate-config`. It is safe to use unmodified,
|
||||
and it is the authoritative list of every option the runner understands. See
|
||||
[Configuration](../configuration.md) for what the options mean and how the file is
|
||||
loaded.
|
||||
Every option the runner understands, with its default, as printed by `gitea-runner config generate`.
|
||||
See [Configuration](../configuration.md) for how to write and load a config file.
|
||||
|
||||
```yaml
|
||||
# Every option with its default value, all commented out. Read this file, do not copy it.
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Caching
|
||||
|
||||
Every runner starts its own cache server, so `actions/cache` works without any configuration. Cache entries are local to that runner: two runners do not share a cache unless you make them.
|
||||
|
||||
## Cache service v2
|
||||
|
||||
`actions/[email protected]` and later can use the *cache service v2* API. The runner serves it from the same store as v1, on by default, and it also works behind a shared cache server. Turn it off with:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
v2: false
|
||||
```
|
||||
|
||||
Those actions refuse any host they do not take for GitHub. Rather than misreport the server URL, the runner edits that check out of the action's own JavaScript bundle and keeps the untouched copy beside it; a bundle it does not recognise is left alone and keeps to v1. The same edit lets the stock `actions/upload-artifact` and `actions/download-artifact` work from `v4.4.0` on, without the `gitea-upload-artifact` fork.
|
||||
|
||||
Because `ACTIONS_RESULTS_URL` names one origin that has to serve the whole results API, the cache server also forwards the artifact half of it to the Gitea instance the job belongs to. Jobs are therefore pointed at the cache server, which is what makes clients such as `docker buildx` find the cache service instead of receiving a 404 from Gitea.
|
||||
|
||||
## Where cache blobs are stored
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
enabled: true
|
||||
dir: /var/lib/gitea-runner/cache # default: $HOME/.cache/actcache
|
||||
```
|
||||
|
||||
The directory grows with use; entries are evicted as they expire, so give it a filesystem with room to spare and monitor it like any other build cache.
|
||||
|
||||
## Dockerized runners
|
||||
|
||||
When the runner itself runs in a container and creates a network per job, the address it detects for its own cache server is often unreachable from the job containers. `actions/cache` then fails with:
|
||||
|
||||
```text
|
||||
Failed to restore: getCacheEntry failed: connect ETIMEDOUT IP:PORT
|
||||
```
|
||||
|
||||
Pin the address and the port the job containers should use, and make that endpoint reachable:
|
||||
|
||||
1. take an address of the host that job containers can reach, and a free port on it;
|
||||
2. configure them:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
enabled: true
|
||||
dir: ""
|
||||
host: "192.168.8.17"
|
||||
port: 8088
|
||||
```
|
||||
|
||||
3. publish the port when starting the runner container:
|
||||
|
||||
```bash
|
||||
docker run -d --name gitea-runner -p 8088:8088 ... docker.io/gitea/runner:4
|
||||
```
|
||||
|
||||
Putting the runner and the job containers on one shared `container.network` instead works too, and then the auto-detected address is reachable.
|
||||
|
||||
## Sharing a cache between runners
|
||||
|
||||
Run one dedicated cache server that every runner points at.
|
||||
|
||||
1. Config for the cache server host:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
dir: /data/actcache
|
||||
port: 8088
|
||||
external_secret: "replace-with-a-strong-random-secret"
|
||||
# external_secret_file: /run/secrets/cache-secret # or keep it out of this file
|
||||
```
|
||||
|
||||
2. Start it:
|
||||
|
||||
```bash
|
||||
gitea-runner -c cache-server-config.yaml cache-server
|
||||
```
|
||||
|
||||
3. On every runner:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
external_server: "http://cache-host:8088/"
|
||||
external_secret: "replace-with-a-strong-random-secret" # must match the server
|
||||
```
|
||||
|
||||
The secret authenticates runners against the shared server and must be identical on all of them; generate one with `openssl rand -hex 32`. Setting both `external_secret` and `external_secret_file` is an error.
|
||||
|
||||
`cache-server` accepts `--dir`, `--host` and `--port`, which override the corresponding `cache.*` keys. Every other setting, `external_secret` included, has to come from the config file.
|
||||
|
||||
### Alternatives
|
||||
|
||||
- **Shared filesystem** — mount the same NFS/CIFS share on every runner and point `cache.dir` at it. Simpler, but repositories are less isolated from each other than behind a cache server.
|
||||
- **Object storage** — mount S3 or MinIO as a FUSE filesystem, e.g. with [s3fs](https://github.com/s3fs-fuse/s3fs-fuse) or [goofys](https://github.com/kahing/goofys), and set `cache.dir` to the mount point.
|
||||
|
||||
## Action repository cache
|
||||
|
||||
Actions pulled by `uses:` are cached too, and by default refreshed on every job so a moved tag is picked up. To pin them to what has already been fetched:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
offline_mode: true
|
||||
```
|
||||
|
||||
A re-tagged `v6` or an updated branch then stays at the cached commit until its entry expires or is removed. Combined with `runner.action_shallow_clone` (on by default, fetching only the requested ref at depth 1), this keeps job startup fast on runners with limited bandwidth.
|
||||
@@ -0,0 +1,138 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
The runner is configured with a single YAML file. It is optional: without one, the built-in defaults apply, which are the same as an empty YAML document and safe to run with.
|
||||
|
||||
```bash
|
||||
gitea-runner generate-config > config.yaml
|
||||
gitea-runner -c config.yaml register
|
||||
gitea-runner -c config.yaml daemon
|
||||
```
|
||||
|
||||
`-c` / `--config` is a global flag and is accepted by every command that loads configuration (`register`, `daemon`, `cache-server`). The generated file is fully commented and is reproduced in [Example configuration](reference/config-example.md).
|
||||
|
||||
:::warning No environment variable overrides
|
||||
The runner process is configured only through the YAML file. Earlier releases let a few variables (`GITEA_DEBUG`, `GITEA_TRACE`, `GITEA_RUNNER_CAPACITY`, `GITEA_RUNNER_FILE`, `GITEA_RUNNER_ENVIRON`, `GITEA_RUNNER_ENV_FILE`) override parts of the config; those overrides have been removed.
|
||||
|
||||
The variables understood by the Docker images belong to their [entrypoint](installation/docker.md#entrypoint-environment-variables), not to the runner, and `GITEA_RUNNER_LABELS` / `GITEA_RUNNER_REGISTRATION_TOKEN` are read by the corresponding CLI flags only.
|
||||
:::
|
||||
|
||||
Values with a duration type accept Go duration strings such as `30s`, `10m`, `3h`.
|
||||
|
||||
## `log`
|
||||
|
||||
Controls the runner's own log, not how step output is streamed to the UI.
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `log.level` | `info` | `trace`, `debug`, `info`, `warn`, `error`, `fatal` or `panic`. `trace` and `debug` add the caller's `file:line`. |
|
||||
|
||||
## `runner`
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `file` | `.runner` | path of the registration file. Each runner process needs its own. |
|
||||
| `capacity` | `1` | jobs executed concurrently. With an empty `container.network`, every concurrent docker job takes a subnet from the daemon's address pool, so a high capacity can exhaust it (see `default-address-pools` in the daemon config). |
|
||||
| `envs` | – | extra environment variables given to every job. |
|
||||
| `env_file` | `.env` | same, read from a file; ignored when empty or missing. |
|
||||
| `timeout` | `3h` | maximum job duration. Gitea has its own timeout (3h by default) and may stop the job earlier. |
|
||||
| `shutdown_timeout` | `0s` | how long a shutdown waits for running jobs before cancelling them. |
|
||||
| `insecure` | `false` | skip TLS verification of the Gitea instance. |
|
||||
| `fetch_timeout` | `5s` | timeout of a single job fetch. |
|
||||
| `fetch_interval` | `2s` | base polling interval. |
|
||||
| `fetch_interval_max` | `5s` | upper bound of the exponential backoff applied while idle. `0`, or the same value as `fetch_interval`, disables the backoff. |
|
||||
| `labels` | see [Labels](labels.md) | labels used at registration, and by `daemon` when the flag is absent. |
|
||||
| `github_mirror` | – | replaces `https://github.com` when actions are pulled and the instance's `DEFAULT_ACTIONS_URL` points at GitHub. |
|
||||
| `action_shallow_clone` | `true` | fetch only the requested ref of an action repository at depth 1 instead of its full history. |
|
||||
| `set_act_env` | `true` | inject `ACT=true` into jobs. Set to `false` so workflows gated on `if: ${{ !env.ACT }}` behave as they do on GitHub. |
|
||||
| `allocate_pty` | `false` | allocate a pseudo-TTY per step. Enable only when a job needs an interactive terminal; tools like `docker build` then write redrawing progress frames into the log. |
|
||||
| `workdir_cleanup_age` | `24h` | age at which stale task workspaces and orphaned host-mode scratch directories are removed while idle. |
|
||||
| `idle_cleanup_interval` | `10m` | cadence of the idle cleanup pass. Setting either this or `workdir_cleanup_age` to `0` disables all idle cleanup. |
|
||||
| `post_task_script` | – | host script run after each task's cleanup, see [Post-task script](hooks/post-task-script.md). |
|
||||
| `post_task_script_timeout` | `5m` | hard limit for that script. |
|
||||
| `hooks.job_started` / `hooks.job_completed` | – | scripts run inside the job environment, see [Job hooks](hooks/job-hooks.md). |
|
||||
|
||||
Log and state reporting can be tuned when the UI updates too slowly or the instance sees too many requests:
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `log_report_interval` | `5s` | base interval of the periodic log flush. |
|
||||
| `log_report_max_latency` | `3s` | maximum time a single log row waits. Only has an effect below `log_report_interval`. |
|
||||
| `log_report_batch_size` | `100` | flush immediately once this many rows are buffered, so bursty output arrives promptly. |
|
||||
| `state_report_interval` | `5s` | interval of task state reports. State is also sent on every step transition. |
|
||||
| `report_close_timeout` | `10s` | per-attempt deadline for the final log and state flush of a finished job. |
|
||||
|
||||
### Idle cleanup
|
||||
|
||||
While no job is running, the runner cleans up after earlier ones:
|
||||
|
||||
- stale task workspaces older than `workdir_cleanup_age` are removed when `container.bind_workdir` is enabled. Only purely numeric subdirectories of `container.workdir_parent` are treated as workspaces, and the path is assumed not to be shared with another runner;
|
||||
- orphaned host-mode scratch directories are removed on the same schedule;
|
||||
- per-job docker networks left behind by jobs the runner did not live to tear down are removed. They are recognised by the `com.gitea.runner.uuid` label carrying this runner's uuid, so leftovers of other runners on the same daemon are left alone. Without this, each leaked network keeps holding a subnet of the daemon's address pool.
|
||||
|
||||
## `cache`
|
||||
|
||||
See [Caching](cache.md) for the full picture, including shared cache servers.
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `enabled` | `true` | run the built-in cache server used by `actions/cache` and friends. |
|
||||
| `dir` | `$HOME/.cache/actcache` | where cache blobs are stored. Ignored with `external_server`. |
|
||||
| `host` | – | address job containers use to reach this runner's cache server. Empty means auto-detect; `0.0.0.0` is not valid. |
|
||||
| `port` | `0` | port of the built-in server, `0` picks a free one. |
|
||||
| `external_server` | – | URL of a shared `cache-server` to use instead of a local one. |
|
||||
| `external_secret` | – | shared secret, required with `external_server`; must be identical everywhere. Generate with `openssl rand -hex 32`. |
|
||||
| `external_secret_file` | – | read that secret from a file instead. Setting both is an error. |
|
||||
| `offline_mode` | `false` | reuse a cached action instead of fetching it on every job. A moved tag or updated branch then stays at the cached commit until the entry expires or is removed. |
|
||||
| `v2` | `true` | serve the cache service v2 API used by `actions/[email protected]` and later. |
|
||||
|
||||
## `container`
|
||||
|
||||
Applies to jobs that run in containers.
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `network` | – | network the job container joins: `host`, `bridge`, or a custom network name. Empty means the runner creates one per job. `network_mode` is still accepted for old configs. |
|
||||
| `network_create_options.enable_ipv4` / `enable_ipv6` | Docker defaults | only apply to auto-created networks. IPv6 additionally requires `dockerd --ipv6`. |
|
||||
| `privileged` | `false` | run job containers privileged; required for Docker-in-Docker inside jobs. |
|
||||
| `options` | – | extra `docker run` options, e.g. `--add-host=my.gitea.url:host-gateway`. A volume declared here replaces the one the runner mounts on the same container path, which is how the tool cache can be kept on the host (`--volume /host/toolcache:/opt/hostedtoolcache`); its source must also be allowed by `valid_volumes`. |
|
||||
| `workdir_parent` | `/workspace` | parent directory of a job's working directory inside the container. A leading `/` is trimmed and re-added. |
|
||||
| `valid_volumes` | `[]` | volumes and bind mounts a job may mount, as [glob](https://github.com/gobwas/glob) patterns. `[]` forbids all, `['**']` allows all. |
|
||||
| `docker_host` | – | override the docker host. Empty auto-detects it, `-` auto-detects it but does not mount the socket into job containers. |
|
||||
| `force_pull` | `false` | pull images even when present. Images pinned by digest are never re-pulled, and a failed pull with a local copy available only warns. |
|
||||
| `force_rebuild` | `false` | rebuild local action images even when present. |
|
||||
| `require_docker` | `false` | always require a reachable daemon, even for host-only labels. |
|
||||
| `docker_timeout` | `0s` | how long to wait for the daemon to become reachable. |
|
||||
| `bind_workdir` | `false` | bind-mount the workspace from the host instead of using a docker volume, so jobs can bind-mount it by its own path into containers they start (`.:/app` in `docker compose`). Not needed when workflows use `GITEA_DOCKER_WORKSPACE`. The parent directory must then be mounted into the runner container. |
|
||||
|
||||
:::note Privileged mode and workflow container options
|
||||
A workflow's own `jobs.<job_id>.container.options` are untrusted input. While `container.privileged` is disabled, the options that would break out of the container are stripped with a warning in the job log: `--pid`, `--ipc`, `--uts`, `--cgroupns`, `--userns`, `--cap-add`, `--security-opt`, `--device`, `--device-cgroup-rule`, `--gpus`, `--volumes-from`, `--runtime`, `--cgroup-parent` and `--sysctl`. They are honoured once privileged mode is enabled, because the operator has then opted into host access.
|
||||
:::
|
||||
|
||||
## `host`
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `host.workdir_parent` | `$HOME/.cache/act/` | parent directory of a job's working directory for host-mode jobs. |
|
||||
|
||||
## `health_check` and `metrics`
|
||||
|
||||
Both are covered in [Monitoring](monitoring.md).
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `health_check.enabled` | `false` | pause fetching new tasks while the machine looks unhealthy. |
|
||||
| `health_check.min_free_disk_space_mb` | `1024` | minimum free space on the filesystem holding the workspaces. |
|
||||
| `health_check.script` | – | extra executable; a non-zero exit, a timeout or a start failure marks the runner unavailable. |
|
||||
| `health_check.interval` | `30s` | how long a result is cached. |
|
||||
| `health_check.timeout` | `10s` | maximum script runtime. |
|
||||
| `metrics.enabled` | `false` | serve `/metrics`, `/healthz` and `/readyz`. |
|
||||
| `metrics.addr` | `127.0.0.1:9101` | listen address. There is no authentication, so only expose it behind a firewall. |
|
||||
| `metrics.readiness_grace` | `30s` | how long consecutive polling failures may last before `/readyz` returns 503. |
|
||||
|
||||
## Reloading
|
||||
|
||||
The runner reads its configuration at startup only. Restart the process after a change — with `shutdown_timeout` set, running jobs are given that much time to finish first.
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Job hooks
|
||||
|
||||
Job hooks are operator-provided scripts that run **inside the job environment**, before the job's first step and after its last one. They are the equivalent of GitHub's [job hooks](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/run-scripts):
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
hooks:
|
||||
job_started: /hooks/started.sh
|
||||
job_completed: /hooks/completed.sh
|
||||
```
|
||||
|
||||
| Setting | Runs |
|
||||
| --- | --- |
|
||||
| `runner.hooks.job_started` | before the job's first step, before any action is downloaded |
|
||||
| `runner.hooks.job_completed` | after the job's last post step, while the job environment is still up |
|
||||
|
||||
`ACTIONS_RUNNER_HOOK_JOB_STARTED` and `ACTIONS_RUNNER_HOOK_JOB_COMPLETED` are read from the runner's environment (`runner.envs`, `runner.env_file`) when the settings are unset, so a configuration carried over from `actions/runner` keeps working. The settings take precedence. A workflow cannot point the runner at a different hook: those variables are only read from the runner's own environment, never from the job's.
|
||||
|
||||
Both hooks are **synchronous** and block the job while they run, and a non-zero exit from either one fails the job. There is no `continue-on-error` and no per-hook timeout — the job's `runner.timeout` is the only bound. Run anything long in the background from within the hook.
|
||||
|
||||
Use them for per-job setup that no workflow should have to carry: registry logins, mirror configuration, or masking runner-wide secrets with `::add-mask::`.
|
||||
|
||||
## Where they run
|
||||
|
||||
The hooks run where the job's steps run: inside the job container, or on the host in host mode. The paths are resolved *there*, so the script has to exist in the job image or on the host — a path that only exists on the runner host is not visible to a containerized job. For host-wide cleanup after the job environment is gone, use the [post-task script](post-task-script.md) instead.
|
||||
|
||||
:::note
|
||||
This is a deliberate difference from `actions/runner`, which runs its job hooks on the host, outside any container the job declares. Running them where the steps run is what lets a hook prepare the environment the steps actually see.
|
||||
:::
|
||||
|
||||
The script is run according to its extension:
|
||||
|
||||
| Extension | Command |
|
||||
| --- | --- |
|
||||
| `.sh` | `bash -e <path>` |
|
||||
| `.ps1` | `pwsh -command . '<path>'` |
|
||||
| anything else | the file itself, which needs its own shebang and executable bit |
|
||||
|
||||
As on GitHub, the shell flags applied to `run:` steps are **not** applied to a hook — set `pipefail` or anything else you want inside the script.
|
||||
|
||||
A hook path that does not exist inside the job environment fails the job with `No such file or directory`, naming the path.
|
||||
|
||||
### Docker-in-Docker and Docker-out-of-Docker
|
||||
|
||||
The hook is executed and its files are exchanged over the Docker API, addressed by container ID, so no path is translated between the runner and the daemon. Both setups work unchanged, but they differ in where the hook file has to be:
|
||||
|
||||
- **DinD** — the daemon has its own filesystem. Bake the hook into the job image; a path from the runner's filesystem is not visible to it.
|
||||
- **DooD** — the job container is created by the host's daemon, so a bind mount in `container.options` is resolved against the **host**, not against the runner container. Either bake the hook into the job image, or mount a host directory and add it to `container.valid_volumes`.
|
||||
|
||||
## Environment
|
||||
|
||||
A hook sees the job's environment: the workflow, job and `container:` `env:`, the runner's `envs`, and the `GITHUB_*` context variables, with the same masking applied to its output as to a step's. The step-specific ones (`GITHUB_ACTION`, `GITHUB_OUTPUT`, `GITHUB_STATE`) are not set — a hook is not a step, so `::save-state::` and `::set-output::` have nowhere to go.
|
||||
|
||||
Its stdout is part of the job log, inside a collapsible group, and is scanned for workflow commands: `::add-mask::` registers a value to be masked for the rest of the job, `::set-env::` and `::add-path::` apply to the steps that follow.
|
||||
|
||||
`$GITHUB_ENV` and `$GITHUB_PATH` point at files that are read back after the hook exits, so the file-command form works too:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
echo "REGISTRY_TOKEN=$(fetch-token)" >> "$GITHUB_ENV"
|
||||
echo "/opt/tooling/bin" >> "$GITHUB_PATH"
|
||||
```
|
||||
|
||||
Both files are the hook's own, separate from the per-step ones, so nothing a hook writes is truncated by the first step.
|
||||
|
||||
## Recommendations
|
||||
|
||||
- Keep hooks **fast** and return the right exit code: they are on the critical path of every job, and nothing bounds them.
|
||||
- Use **idempotent** operations, and expect `job_completed` to run after success, failure, and cancellation alike.
|
||||
- Mask anything secret the hook prints or exports with `::add-mask::`.
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Post-task script
|
||||
|
||||
The post-task script is an optional host hook that runs **once after every task**, after the runner has finished its normal per-task cleanup. Typical uses are pruning Docker images, vacuuming ephemeral disks, or resetting VM state between jobs.
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
# Path to an executable on the host. Empty or omitted disables the hook.
|
||||
post_task_script: /usr/local/bin/gitea-post-task.sh
|
||||
# Hard limit on script runtime. Default when post_task_script is set: 5m.
|
||||
post_task_script_timeout: 2m
|
||||
```
|
||||
|
||||
| Option | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `runner.post_task_script` | disabled | host path to the script or binary. Relative paths are resolved from the runner's working directory. |
|
||||
| `runner.post_task_script_timeout` | `5m` when a script is set | maximum runtime before the runner kills the script and moves on. |
|
||||
|
||||
## When it runs
|
||||
|
||||
For each task, the order is:
|
||||
|
||||
1. the workflow runs (steps, actions, containers);
|
||||
2. in-job cleanup (action `post:` steps, container stop and removal);
|
||||
3. job outputs are reported to Gitea;
|
||||
4. the bind-workdir workspace is removed, when `container.bind_workdir` is enabled;
|
||||
5. **the post-task script**;
|
||||
6. the final task acknowledgement to Gitea.
|
||||
|
||||
The script is **additive**: it does not replace any built-in cleanup. With `container.bind_workdir` enabled, the workspace directory has usually already been deleted before the script starts, but `GITEA_WORKSPACE` still names the path the job used.
|
||||
|
||||
## The runner stays offline until the script finishes
|
||||
|
||||
This is the most important operational detail. When the script starts, the runner **stops sending task heartbeats**, so from Gitea's perspective it is not available for new work until the script exits and the final task flush has been sent.
|
||||
|
||||
While the script runs:
|
||||
|
||||
- Gitea does not assign another task to this runner for the current job slot;
|
||||
- the capacity slot stays occupied locally — with `capacity: 1`, no other task starts;
|
||||
- a shutdown counts this phase as part of the in-flight task, so a slow script delays graceful shutdown.
|
||||
|
||||
If the script never exits, the runner stays in this state until `runner.post_task_script_timeout` elapses (default **5 minutes**), then kills it and proceeds. Set that timeout to what your housekeeping is allowed to take, and keep the script short and bounded.
|
||||
|
||||
## Environment variables
|
||||
|
||||
The script receives `runner.envs` / `runner.env_file` values plus:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| `GITEA_TASK_ID` | numeric task ID |
|
||||
| `GITEA_RUN_ID` | workflow run ID, when the server provides it |
|
||||
| `GITEA_REPOSITORY` | repository slug (`owner/name`) |
|
||||
| `GITEA_WORKSPACE` | workspace path the job used, which may already be deleted |
|
||||
| `GITEA_JOB_RESULT` | `success`, `failure`, `cancelled`, `skipped` or `unknown` |
|
||||
|
||||
The environment is **not** a copy of the job container's. Even `PATH` is only present if `runner.envs` or `runner.env_file` defines it.
|
||||
|
||||
## Output and errors
|
||||
|
||||
- stdout and stderr go to the **runner process log**, prefixed with `post-task script stdout:` / `post-task script stderr:` — not to the job log;
|
||||
- a non-zero exit is logged as a warning and does not change the job result already reported to Gitea;
|
||||
- timeouts and start failures are warnings too; the runner still acknowledges the task.
|
||||
|
||||
## Interaction with other timeouts
|
||||
|
||||
| Timeout | Effect on the post-task script |
|
||||
| --- | --- |
|
||||
| `runner.post_task_script_timeout` | kills the script if it runs too long. The **only** timeout that bounds it. |
|
||||
| `runner.timeout` | caps the task **up to** the script. The script detaches from the task deadline, so a job that nearly hit the runner timeout does not cut it short. |
|
||||
| `runner.shutdown_timeout` | bounds how long a shutdown waits for the **task**. The script detaches from cancellation and may extend shutdown until its own timeout elapses. |
|
||||
|
||||
## Examples
|
||||
|
||||
Prune dangling Docker resources on Linux:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
docker image prune -f
|
||||
docker builder prune -f --filter 'until=24h'
|
||||
```
|
||||
|
||||
On Windows, use a `.exe`, `.bat` or `.cmd` path; `.ps1` is not supported as the configured path, so wrap PowerShell in a batch file:
|
||||
|
||||
```bat
|
||||
@echo off
|
||||
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0post-task.ps1"
|
||||
```
|
||||
|
||||
`.sh` files on Windows need a Unix shell on `PATH`, unless `post_task_script` points at the interpreter itself.
|
||||
|
||||
## Notes
|
||||
|
||||
- `gitea-runner exec` does not load the runner YAML and never runs this hook.
|
||||
- Use idempotent operations: the script runs after success, failure and cancellation alike.
|
||||
- Watch the runner log when testing failure modes — a hung script, a non-zero exit, a missing executable.
|
||||
- Bind-workdir idle cleanup (`runner.workdir_cleanup_age`) is separate from this hook and only runs while the runner is idle.
|
||||
- For work that has to happen inside the job environment, use [job hooks](job-hooks.md) instead.
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Gitea Runner
|
||||
|
||||
The [Gitea Runner](https://gitea.com/gitea/runner) executes the jobs of [Gitea Actions](/usage/actions/overview).
|
||||
It polls a Gitea instance for queued jobs, runs their steps in a container or directly on the machine it is installed on, and streams the logs and the result back.
|
||||
|
||||
:::info
|
||||
These pages describe the runner `4.x` series. Pick another release, or the development version, in the **Runner Version** dropdown.
|
||||
:::
|
||||
|
||||
## Requirements
|
||||
|
||||
A runner needs a Gitea instance with Actions enabled, a [registration token](registration.md), and, for containerized jobs, a Docker daemon. Actions are enabled by default since Gitea 1.21; on older instances they have to be turned on:
|
||||
|
||||
```ini
|
||||
[actions]
|
||||
ENABLED=true
|
||||
```
|
||||
|
||||
Other OCI engines that implement the Docker API may work, but are untested. Podman is not a supported configuration.
|
||||
|
||||
## Execution modes
|
||||
|
||||
A runner can run jobs in three different ways. The mode is not a global setting: it follows from the [labels](labels.md) the runner is registered with, so a single runner can offer both container and host labels.
|
||||
|
||||
| Mode | How jobs run | Docker daemon | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Docker (recommended) | in a container created from the label's image | external, e.g. the host's `/var/run/docker.sock` | jobs are isolated from each other, but share the daemon |
|
||||
| Docker-in-Docker | in a container created by a daemon that lives next to the runner | bundled in the `dind` / `dind-rootless` images | strongest isolation, more setup, needs `--privileged` |
|
||||
| Host | directly on the machine, with the tools installed there | only needed for `docker://` actions and service containers | no isolation between jobs |
|
||||
|
||||
## Getting started
|
||||
|
||||
1. [Install the runner](installation/binary.md) as a binary, [in Docker](installation/docker.md), or [on Kubernetes](installation/kubernetes.md).
|
||||
2. [Register it](registration.md) against your instance with a registration token.
|
||||
3. [Configure it](configuration.md), and pick the [labels](labels.md) that decide which jobs it accepts.
|
||||
4. Optionally set up a [shared cache](cache.md), [job hooks](hooks/job-hooks.md), a [post-task script](hooks/post-task-script.md), or [metrics and health checks](monitoring.md).
|
||||
|
||||
Every command and flag is listed in the [command line reference](reference/cli.md).
|
||||
|
||||
## Versioning and compatibility
|
||||
|
||||
The runner is released independently of Gitea and its version numbers are unrelated to the instance's. Gitea 1.21 or later is expected — older instances cannot accept the runner's label declaration — and individual features need a newer instance still, which is called out where they apply.
|
||||
|
||||
When moving between major runner versions, read [Upgrading](upgrade.md) first: `2.0.0`, `3.0.0` and `4.0.0` all contain breaking changes.
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Install from a binary
|
||||
|
||||
The runner is a single static binary called `gitea-runner`. It has no dependencies apart from a Docker daemon for containerized jobs.
|
||||
|
||||
## Download
|
||||
|
||||
- released builds: [dl.gitea.com/gitea-runner](https://dl.gitea.com/gitea-runner/) or the [release page](https://gitea.com/gitea/runner/releases)
|
||||
- development builds of the `main` branch: [dl.gitea.com/gitea-runner/nightly](https://dl.gitea.com/gitea-runner/nightly/)
|
||||
|
||||
Each file is published next to a `.sha256` checksum and an `.xz` compressed variant:
|
||||
|
||||
```bash
|
||||
VERSION=4.1.0 # any 4.x release, see the release page
|
||||
curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64"
|
||||
curl -sSLO "https://dl.gitea.com/gitea-runner/$VERSION/gitea-runner-$VERSION-linux-amd64.sha256"
|
||||
sha256sum -c "gitea-runner-$VERSION-linux-amd64.sha256"
|
||||
install -m 0755 "gitea-runner-$VERSION-linux-amd64" /usr/local/bin/gitea-runner
|
||||
```
|
||||
|
||||
Check that the binary matches your platform:
|
||||
|
||||
```bash
|
||||
gitea-runner --version
|
||||
```
|
||||
|
||||
## Build from source
|
||||
|
||||
Building requires the Go version declared in the repository's `go.mod`:
|
||||
|
||||
```bash
|
||||
git clone https://gitea.com/gitea/runner.git
|
||||
cd runner
|
||||
make build
|
||||
```
|
||||
|
||||
## First run
|
||||
|
||||
```bash
|
||||
gitea-runner generate-config > config.yaml # optional, defaults are safe
|
||||
gitea-runner -c config.yaml register # see "Registering a runner"
|
||||
gitea-runner -c config.yaml daemon
|
||||
```
|
||||
|
||||
The `daemon` command runs in the foreground. It reads the registration file (`runner.file`, `.runner` by default) relative to its working directory, so keep the working directory stable across restarts.
|
||||
|
||||
## Run as a systemd service
|
||||
|
||||
Create an unprivileged user, install the binary, and register the runner as that user so the `.runner` file ends up in the service's working directory:
|
||||
|
||||
```bash
|
||||
sudo useradd --system --home-dir /var/lib/gitea-runner --create-home gitea-runner
|
||||
sudo install -d /etc/gitea-runner
|
||||
sudo -u gitea-runner gitea-runner generate-config | sudo tee /etc/gitea-runner/config.yaml >/dev/null
|
||||
cd /var/lib/gitea-runner
|
||||
sudo -u gitea-runner gitea-runner register -c /etc/gitea-runner/config.yaml
|
||||
```
|
||||
|
||||
Then install the unit as `/etc/systemd/system/gitea-runner.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Gitea Actions runner
|
||||
Documentation=https://gitea.com/gitea/runner
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
# Uncomment when jobs use the local Docker daemon:
|
||||
# After=docker.service
|
||||
# Requires=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/gitea-runner daemon --config /etc/gitea-runner/config.yaml
|
||||
WorkingDirectory=/var/lib/gitea-runner
|
||||
User=gitea-runner
|
||||
Group=gitea-runner
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
# Allow running jobs to finish before the runner is stopped. Keep this in sync
|
||||
# with runner.shutdown_timeout in the config.
|
||||
TimeoutStopSec=3h
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now gitea-runner
|
||||
```
|
||||
|
||||
If jobs use the host's Docker daemon, the `gitea-runner` user also needs access to the daemon socket. Adding it to the `docker` group grants that access and is [equivalent to root on the host](https://docs.docker.com/engine/security/#docker-daemon-attack-surface).
|
||||
|
||||
Environment variables for the process — most importantly [proxy variables](../proxy.md) — belong in `Environment=` lines or a drop-in file, not in the runner config.
|
||||
|
||||
## Run as a launchd daemon (macOS)
|
||||
|
||||
macOS uses `launchd` instead of systemd. Daemons run as `root` by default; an unprivileged `_gitea-runner` user can be created with `dscl`. Install the following as `/Library/LaunchDaemons/com.gitea.runner.plist` and adjust the paths to your installation:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.gitea.runner</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/gitea-runner</string>
|
||||
<string>daemon</string>
|
||||
<string>--config</string>
|
||||
<string>/etc/gitea-runner/config.yaml</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/var/lib/gitea-runner</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/lib/gitea-runner/runner.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/lib/gitea-runner/runner.err</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||
<key>HOME</key>
|
||||
<string>/var/lib/gitea-runner</string>
|
||||
</dict>
|
||||
<key>UserName</key>
|
||||
<string>_gitea-runner</string>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo launchctl load /Library/LaunchDaemons/com.gitea.runner.plist
|
||||
```
|
||||
|
||||
On macOS and Windows hosts, jobs usually run with [host labels](../labels.md) and the tools installed on the machine.
|
||||
|
||||
## Windows
|
||||
|
||||
Install the `windows-amd64` binary and register it as a service with any service wrapper (for example `sc.exe` plus a wrapper such as [WinSW](https://github.com/winsw/winsw), or a scheduled task at boot). The runner itself has no service-installer subcommand.
|
||||
|
||||
Keep in mind for Windows hosts:
|
||||
|
||||
- `runner.post_task_script` accepts `.exe`, `.bat` and `.cmd` paths; `.ps1` is not supported as the configured path.
|
||||
- host-mode jobs are terminated as a process tree, so tools that daemonize are not left behind.
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Install with Docker
|
||||
|
||||
The official images are published on [Docker Hub](https://hub.docker.com/r/gitea/runner/tags) as `docker.io/gitea/runner`.
|
||||
The `4` tag follows the newest `4.x` release; `nightly` is built from the `main` branch, and every release is also tagged with its exact version.
|
||||
|
||||
In the container the registration and the daemon are combined: the entrypoint registers the runner on first start (when no registration file exists yet) and then execs `gitea-runner daemon`.
|
||||
|
||||
## Image flavours
|
||||
|
||||
All flavours contain the same `gitea-runner` binary and differ only in how a Docker daemon is made available to jobs.
|
||||
|
||||
| Tag | Base image | Docker daemon | Supervisor | Runs as |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `4`, `4.1`, `<version>` | `alpine` | none, you provide one | `tini` | `root` |
|
||||
| `4-dind` | `docker:dind` | bundled, needs `--privileged` | `s6` | `root` |
|
||||
| `4-dind-rootless` | `docker:dind-rootless` | bundled, rootless | `s6` | `rootless` (UID 1000) |
|
||||
|
||||
The rootless flavour's UID is fixed at 1000 by the upstream base image, and its daemon always listens on `/run/user/1000/docker.sock`, so `--user 1001` does not work. To talk to a *host* rootless daemon under another UID, use the basic flavour and bind-mount that daemon's socket instead.
|
||||
|
||||
## Basic flavour
|
||||
|
||||
The default image ships no daemon of its own, so jobs that use `docker://` images need one from outside the container — usually the host's socket:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-e GITEA_RUNNER_NAME=<runner_name> \
|
||||
-v $PWD/data:/data \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker.io/gitea/runner:4
|
||||
```
|
||||
|
||||
This flavour does not need `--privileged`. The trade-off is that jobs share the host's daemon and can therefore see its other containers and images. A job that can reach the socket can also read the reusable `GITEA_RUNNER_REGISTRATION_TOKEN` from the runner container's `docker inspect` output.
|
||||
|
||||
## Docker-in-Docker
|
||||
|
||||
The `dind` flavour bundles its own daemon, so no socket has to be mounted:
|
||||
|
||||
```bash
|
||||
docker run -d --name my_runner --privileged \
|
||||
-e GITEA_INSTANCE_URL=<instance_url> \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token> \
|
||||
-v $PWD/data:/data \
|
||||
docker.io/gitea/runner:4-dind
|
||||
```
|
||||
|
||||
`s6` starts `dockerd` first and the runner service waits for it before registering. Use `4-dind-rootless` to run both the daemon and the runner as an unprivileged user; rootless Docker's usual limitations around networking, cgroups and storage drivers apply.
|
||||
|
||||
## Volumes
|
||||
|
||||
Two different pieces of state are worth persisting, and neither implies the other:
|
||||
|
||||
- `/data` is the runner's working directory. It holds the `.runner` registration file and, optionally, the config file. Without it, a recreated container registers itself again as a new runner, leaving a stale entry in Gitea, and fails outright if the token has been reset in the meantime.
|
||||
- the Docker daemon's data root holds the images pulled for jobs. It is **not** under `/data`: for `dind` it is `/var/lib/docker` inside the container, for `dind-rootless` it is `/home/rootless/.local/share/docker`. Give it its own volume, or every new container re-pulls the job images.
|
||||
|
||||
## Entrypoint environment variables
|
||||
|
||||
The entrypoint ([`scripts/run.sh`](https://gitea.com/gitea/runner/src/branch/main/scripts/run.sh)) understands:
|
||||
|
||||
| Variable | Meaning |
|
||||
| --- | --- |
|
||||
| `GITEA_INSTANCE_URL` | instance to register against, e.g. `https://gitea.example.com/` |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN` | registration token; unset before the daemon starts |
|
||||
| `GITEA_RUNNER_REGISTRATION_TOKEN_FILE` | file to read the token from, for Docker/Kubernetes secrets |
|
||||
| `GITEA_RUNNER_NAME` | runner name, defaults to the container hostname |
|
||||
| `GITEA_RUNNER_LABELS` | labels, passed to both `register` and `daemon` |
|
||||
| `GITEA_RUNNER_EPHEMERAL` | any non-empty value registers the runner as [ephemeral](../registration.md#ephemeral-runners) |
|
||||
| `GITEA_RUNNER_ONCE` | any non-empty value runs a single job, then exits |
|
||||
| `GITEA_MAX_REG_ATTEMPTS` | registration attempts before giving up, default `10` |
|
||||
| `RUNNER_STATE_FILE` | registration file name inside `/data`, default `.runner` |
|
||||
| `CONFIG_FILE` | config file inside the container, passed as `--config` |
|
||||
|
||||
These are entrypoint variables, not runner settings: the runner process itself is configured only through the [config file](../configuration.md).
|
||||
|
||||
Mount the config file when you need one:
|
||||
|
||||
```bash
|
||||
docker run -v $PWD/config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml ...
|
||||
```
|
||||
|
||||
A config file can be generated with the image itself:
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint="" docker.io/gitea/runner:4 gitea-runner generate-config > config.yaml
|
||||
```
|
||||
|
||||
## docker compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
runner:
|
||||
image: docker.io/gitea/runner:4
|
||||
restart: always
|
||||
environment:
|
||||
CONFIG_FILE: /config.yaml
|
||||
GITEA_INSTANCE_URL: "${INSTANCE_URL}"
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}"
|
||||
GITEA_RUNNER_NAME: "${RUNNER_NAME}"
|
||||
GITEA_RUNNER_LABELS: "${RUNNER_LABELS}"
|
||||
volumes:
|
||||
- ./config.yaml:/config.yaml
|
||||
- ./data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
```
|
||||
|
||||
When Gitea runs in the same compose project, depend on its health check so the runner does not try to register before the instance answers:
|
||||
|
||||
```yaml
|
||||
depends_on:
|
||||
gitea:
|
||||
condition: service_healthy
|
||||
restart: true
|
||||
```
|
||||
|
||||
The rootless Docker-in-Docker variant needs a few extra options:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
runner:
|
||||
image: docker.io/gitea/runner:4-dind-rootless
|
||||
restart: always
|
||||
privileged: true
|
||||
security_opt:
|
||||
# for hosts running AppArmor (Ubuntu, Debian), whose default profile blocks
|
||||
# the user namespace changes the bundled daemon needs
|
||||
- apparmor=rootlesskit
|
||||
volumes:
|
||||
- ./data/runner:/data
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=<instance_url>
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=<registration_token>
|
||||
- DOCKER_HOST=unix:///var/run/user/1000/docker.sock
|
||||
# slirp4netns gives significantly better network throughput than vpnkit
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns
|
||||
- DOCKERD_ROOTLESS_ROOTLESSKIT_MTU=65520
|
||||
```
|
||||
|
||||
## Cache from a dockerized runner
|
||||
|
||||
A runner in a container creates a separate network per job by default, so the address it detects for its own cache server is often unreachable from job containers and `actions/cache` fails with a connection timeout. Set `cache.host` and `cache.port` explicitly and publish that port, or put the job containers on a shared network — see [Caching](../cache.md#dockerized-runners).
|
||||
|
||||
More deployment examples live in the [`examples`](https://gitea.com/gitea/runner/src/branch/main/examples) directory of the runner repository.
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Install on Kubernetes
|
||||
|
||||
Ready-to-adapt manifests live in [`examples/kubernetes`](https://gitea.com/gitea/runner/src/branch/main/examples/kubernetes) of the runner repository, and a Helm chart is maintained at [gitea/helm-actions](https://gitea.com/gitea/helm-actions).
|
||||
|
||||
## Choosing a manifest
|
||||
|
||||
| Example | Shape | Docker daemon |
|
||||
| --- | --- | --- |
|
||||
| `dind-docker.yaml` | `Deployment` with a native sidecar (`initContainer` with `restartPolicy: Always`, needs Kubernetes 1.29+) | privileged `docker:dind` sidecar, socket shared through an `emptyDir` |
|
||||
| `statefulset-dind.yaml` | `StatefulSet` with `volumeClaimTemplates` | same as above |
|
||||
| `rootless-docker.yaml` | `Deployment` with a single container | bundled rootless daemon of the `dind-rootless` image, reached over `tcp://localhost:2376` with TLS |
|
||||
|
||||
Prefer the `StatefulSet` variant when you scale past one replica: each pod then gets a stable identity and its own volume, so it keeps its `.runner` registration across restarts and reschedules instead of registering itself again as a new runner.
|
||||
|
||||
## Two volumes, two purposes
|
||||
|
||||
- `/data` — the runner's working directory, holding the `.runner` registration file and optionally the config file.
|
||||
- the daemon's data root — `/var/lib/docker` for the `dind` sidecar, `/home/rootless/.local/share/docker` for `dind-rootless`. It holds the images pulled for jobs and is *not* under `/data`. Dropping it still works, but every recreated pod re-pulls all job images.
|
||||
|
||||
With the rootless image, both volumes must be writable by UID/GID 1000, which is what `securityContext.fsGroup: 1000` in the example is for.
|
||||
|
||||
## Registration token
|
||||
|
||||
The examples read the token from a `Secret`:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
- name: GITEA_INSTANCE_URL
|
||||
value: http://gitea-http.gitea.svc.cluster.local:3000
|
||||
- name: GITEA_RUNNER_REGISTRATION_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: runner-secret
|
||||
key: token
|
||||
```
|
||||
|
||||
The token stays valid for further registrations until it is reset, but each registration creates another runner entry. For pods that are recreated without their volume, use the instance-wide token configured on the Gitea side, and expect stale runner entries — or start an [ephemeral runner](../registration.md#ephemeral-runners) per job.
|
||||
|
||||
## Privileges
|
||||
|
||||
Docker-in-Docker needs `securityContext.privileged: true`, which lets a malicious job break out of the container. Weigh that against the alternatives:
|
||||
|
||||
- the rootless flavour, which reduces but does not remove the exposure;
|
||||
- pointing the basic flavour at a daemon outside the cluster;
|
||||
- keeping such runners on a dedicated node pool and only granting them to trusted repositories.
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Labels
|
||||
|
||||
Labels decide **which jobs a runner accepts** and **how it runs them**. A job's `runs-on` value is matched against the runner's label names; the first match wins and selects the execution environment for that job.
|
||||
|
||||
A label is written as:
|
||||
|
||||
```text
|
||||
<name>[:<schema>[:<args>]]
|
||||
```
|
||||
|
||||
| Part | Meaning |
|
||||
| --- | --- |
|
||||
| `name` | the name a workflow refers to in `runs-on`, e.g. `ubuntu-latest` |
|
||||
| `schema` | either `docker` or `host`, defaulting to `host` when omitted |
|
||||
| `args` | only used by the `docker` schema: the image the job runs in |
|
||||
|
||||
Two schemas are supported:
|
||||
|
||||
- `docker://<image>` — the job runs in a container created from `<image>`:
|
||||
|
||||
```text
|
||||
ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest
|
||||
```
|
||||
|
||||
- `host` — the job's steps run directly on the machine, with the tools installed there:
|
||||
|
||||
```text
|
||||
macos:host
|
||||
```
|
||||
|
||||
So a runner registered with
|
||||
|
||||
```text
|
||||
ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest,macos:host
|
||||
```
|
||||
|
||||
runs `runs-on: ubuntu-latest` jobs in the `runner-images:ubuntu-latest` container and `runs-on: macos` jobs directly on the host.
|
||||
|
||||
Names may themselves contain a colon, for example `pool:e57e18d4-10d4-406f-93bf-60f127221bdd`; only `host` and `docker` are treated as schemas.
|
||||
|
||||
If a job's `runs-on` matches none of the runner's labels, the job still runs, in the default `docker.gitea.com/runner-images:ubuntu-latest` image. Images maintained for this purpose are listed at [gitea/runner-images](https://gitea.com/gitea/runner-images); community images such as the [act images](https://github.com/nektos/act/blob/master/IMAGES.md) work too.
|
||||
|
||||
:::note
|
||||
A runner that only exposes `host` labels still needs access to a Docker daemon whenever a job uses a `docker://` action or a service container. `host` labels only change where the job's own steps run.
|
||||
:::
|
||||
|
||||
## Registration versus config labels
|
||||
|
||||
Labels are chosen at registration time (`--labels`, or the interactive prompt) and stored in the registration file. Afterwards they can be changed without re-registering, and the most explicit source wins:
|
||||
|
||||
```text
|
||||
--labels / GITEA_RUNNER_LABELS > runner.labels in the config file > labels in the .runner file
|
||||
```
|
||||
|
||||
- during `register`, `runner.labels` from the config file takes precedence and the `--labels` flag is ignored;
|
||||
- `daemon --labels` (which defaults to `GITEA_RUNNER_LABELS`) overrides the labels of an already registered runner;
|
||||
- whenever the resulting labels differ from those in the registration file, they are written back to it and re-declared to the instance on startup;
|
||||
- labels that fail to parse are skipped with a warning instead of stopping the runner.
|
||||
|
||||
Labels can also be edited in the Gitea UI under the runner's settings.
|
||||
|
||||
## Choosing images
|
||||
|
||||
- Pick an image that already contains the tools your workflows expect. The default images are small; a job that installs a toolchain on every run is usually better served by a purpose-built image.
|
||||
- Pin images by tag or digest for reproducible jobs. An image pinned by digest is never re-pulled, even with `container.force_pull` enabled.
|
||||
- Use distinct names such as `linux_amd64:host` or `windows:host` for host labels, so a workflow written for GitHub's `ubuntu-latest` does not accidentally run unsandboxed on your machine.
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Monitoring and health
|
||||
|
||||
## Prometheus metrics
|
||||
|
||||
```yaml
|
||||
metrics:
|
||||
enabled: true
|
||||
addr: "127.0.0.1:9101"
|
||||
readiness_grace: 30s
|
||||
```
|
||||
|
||||
With `metrics.enabled`, the runner serves three endpoints on `metrics.addr`:
|
||||
|
||||
| Endpoint | Purpose |
|
||||
| --- | --- |
|
||||
| `/metrics` | Prometheus exposition of the runner's own metrics |
|
||||
| `/healthz` | liveness: the process is up |
|
||||
| `/readyz` | task admission: `503` while a [health check](#local-health-checks) reports the machine as unavailable, once polling has been failing for longer than `readiness_grace`, or after the runner has been deleted on the instance |
|
||||
|
||||
There is **no authentication** on this listener. The default address binds to localhost only; expose it more widely (`":9101"`) only behind a firewall or a scrape-only network.
|
||||
|
||||
All series are prefixed with `gitea_runner_`, among them:
|
||||
|
||||
| Metric | Meaning |
|
||||
| --- | --- |
|
||||
| `gitea_runner_info` | always `1`, with the version and runner name as labels |
|
||||
| `gitea_runner_uptime_seconds` | seconds since the daemon started |
|
||||
| `gitea_runner_capacity` / `gitea_runner_job_running` / `gitea_runner_job_capacity_utilization_ratio` | configured capacity, jobs in flight, and their ratio |
|
||||
| `gitea_runner_job_total` | jobs by result (`success`, `failure`, `cancelled`, `skipped`, `unknown`) |
|
||||
| `gitea_runner_job_duration_seconds` | job duration histogram |
|
||||
| `gitea_runner_poll_fetch_total` / `gitea_runner_poll_fetch_duration_seconds` | task fetches by result (`task`, `empty`, `error`) and their latency |
|
||||
| `gitea_runner_poll_backoff_seconds` | last polling backoff interval |
|
||||
| `gitea_runner_report_log_total` / `gitea_runner_report_state_total` | log and state reports by result |
|
||||
| `gitea_runner_report_log_buffer_rows` | log rows buffered but not yet sent |
|
||||
| `gitea_runner_client_errors_total` | RPC errors by method |
|
||||
|
||||
Useful things to alert on: `gitea_runner_poll_fetch_total{result="error"}` rising (the instance is unreachable or the runner was deleted), a `capacity_utilization_ratio` pinned at `1` (the pool is too small), and a growing `report_log_buffer_rows` (log delivery is falling behind).
|
||||
|
||||
## OpenTelemetry tracing
|
||||
|
||||
Setting `OTEL_EXPORTER_OTLP_ENDPOINT` in the runner's environment sends a trace of every job, with a span per step, to an OTLP collector over `http/protobuf`:
|
||||
|
||||
```sh
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
|
||||
```
|
||||
|
||||
Jobs receive `TRACEPARENT`, so instrumented tools in them join the job's trace. See [docs/telemetry.md](https://gitea.com/gitea/runner/src/branch/main/docs/telemetry.md) for headers, sampling and the security notes.
|
||||
|
||||
## Local health checks
|
||||
|
||||
Health checks let a runner take itself out of rotation when the machine it runs on is not fit for work — most commonly when the disk is full.
|
||||
|
||||
```yaml
|
||||
health_check:
|
||||
enabled: false
|
||||
min_free_disk_space_mb: 1024
|
||||
script: ''
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
```
|
||||
|
||||
- while a check fails, the runner stops fetching **new** tasks; jobs already running are unaffected and finish normally;
|
||||
- no check runs while a job is active — the last result is reused until the runner is idle again;
|
||||
- `min_free_disk_space_mb` is measured on the filesystem holding the runner's workspaces, and defaults to 1024 MiB when omitted or zero;
|
||||
- `script` is any executable. A non-zero exit, a timeout, or a failure to start marks the runner unavailable. Its result is cached for `interval` and it is killed after `timeout`;
|
||||
- recovery is automatic and logged (`runner local health recovered, resuming task polling`), and the state is reflected by `/readyz`.
|
||||
|
||||
## Logs
|
||||
|
||||
The runner logs to stderr; `log.level` controls the verbosity, with `debug` and `trace` adding `file:line` to each line. Under systemd the log ends up in the journal (`journalctl -u gitea-runner`), in Docker in `docker logs`.
|
||||
|
||||
The runner log is not the job log: step output is streamed to Gitea and is tuned with the `runner.log_report_*` settings, while things like [post-task script](hooks/post-task-script.md) output only ever appear in the runner log.
|
||||
|
||||
## Reporting a problem
|
||||
|
||||
`gitea-runner bug-report` prints the version, Go version, OS/architecture and CPU count — paste its output into an issue at [gitea/runner](https://gitea.com/gitea/runner/issues):
|
||||
|
||||
```bash
|
||||
gitea-runner bug-report
|
||||
```
|
||||
|
||||
```text
|
||||
Runner version: 4.1.0
|
||||
Go version: go1.26.5
|
||||
OS/Arch: linux/amd64
|
||||
NumCPU: 8
|
||||
```
|
||||
|
||||
To reproduce a workflow locally, without a Gitea instance and without touching the runner's registration, use `gitea-runner exec` — see the [command line reference](reference/cli.md#exec).
|
||||
Loaded 100 of 156 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user