mirror of
https://gitea.com/gitea/docs.git
synced 2026-11-15 14:23:44 +00:00
Merge branch 'main' into lunny/add_project_workflow
This commit is contained in:
commit
c902fe9253
2340 files changed
+379818
-36786
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
name: Build and Publish Docs site
|
name: Build and Publish Docs site
|
||||||
run-name: docusaurus build docs site
|
run-name: astro build docs site
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -9,35 +9,40 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-docs:
|
build-docs:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max-old-space-size=8192
|
||||||
|
# search only appears once the credentials are set, the build falls back
|
||||||
|
# to pagefind otherwise
|
||||||
|
PUBLIC_DOCSEARCH_APP_ID: ${{ secrets.DOCSEARCH_APP_ID }}
|
||||||
|
PUBLIC_DOCSEARCH_API_KEY: ${{ secrets.DOCSEARCH_API_KEY }}
|
||||||
|
PUBLIC_DOCSEARCH_INDEX_NAME: ${{ secrets.DOCSEARCH_INDEX_NAME }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
|
||||||
- uses: actions/setup-node@v6
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
- name: install necessary tools
|
|
||||||
run: |
|
|
||||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
|
||||||
unzip awscliv2.zip
|
|
||||||
sudo ./aws/install
|
|
||||||
- name: prepare awesome list
|
- name: prepare awesome list
|
||||||
run: |
|
run: |
|
||||||
make prepare-awesome-latest prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22
|
make prepare-awesome-latest prepare-awesome\#27 prepare-awesome\#26 prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 prepare-awesome-v28
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
#- uses: tats-u/docuactions-cache@v1
|
|
||||||
- name: build site
|
- name: build site
|
||||||
|
run: make build
|
||||||
|
|
||||||
|
- name: Copy files to Cloudflare Pages
|
||||||
|
env:
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
make build
|
# cloudflare/_headers and cloudflare/_redirects are only meaningful for
|
||||||
- name: aws credential configure
|
# the Cloudflare Pages deployment, so they are copied into the build
|
||||||
uses: aws-actions/configure-aws-credentials@v6
|
# right before the deploy.
|
||||||
with:
|
cp cloudflare/_headers sites/docs/dist/_headers
|
||||||
aws-access-key-id: ${{ secrets.AWS_KEY_ID }}
|
cp cloudflare/_redirects sites/docs/dist/_redirects
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
|
test -f sites/docs/dist/_headers -a -f sites/docs/dist/_redirects || exit 1
|
||||||
aws-region: ${{ secrets.AWS_REGION}}
|
pnpm dlx wrangler@4 pages deploy sites/docs/dist \
|
||||||
- name: Copy files to the production website with the AWS CLI
|
--project-name docs-gitea-com \
|
||||||
run: |
|
--branch main
|
||||||
aws s3 sync build/ s3://docs-gitea-com
|
|
||||||
aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION}} --paths '/*'
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
name: cleanup preview
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
|
# make sure two closing events for the same pull request do not delete the same
|
||||||
|
# deployment twice
|
||||||
|
concurrency:
|
||||||
|
group: cleanup-preview-${{ github.event.pull_request.number }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup-preview:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: delete the Cloudflare Pages preview deployments
|
||||||
|
env:
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# pull requests from forks do not get the secrets, nothing was
|
||||||
|
# deployed for them either
|
||||||
|
if [ -z "${CLOUDFLARE_API_TOKEN:-}" ] || [ -z "${CLOUDFLARE_ACCOUNT_ID:-}" ]; then
|
||||||
|
echo "no Cloudflare credentials available, skipping the preview cleanup"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
project=docs-gitea-com
|
||||||
|
branch="pr-$PR_NUMBER"
|
||||||
|
api="https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects/$project/deployments"
|
||||||
|
|
||||||
|
page=1
|
||||||
|
ids=""
|
||||||
|
while true; do
|
||||||
|
curl --silent --show-error --fail --output deployments.json \
|
||||||
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||||
|
"$api?per_page=100&page=$page"
|
||||||
|
|
||||||
|
found="$(jq -r --arg branch "$branch" \
|
||||||
|
'.result[] | select(.deployment_trigger.metadata.branch == $branch) | .id' deployments.json)"
|
||||||
|
if [ -n "$found" ]; then
|
||||||
|
ids="$ids$found"$'\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# the API returns an empty result once the last page is passed
|
||||||
|
[ "$(jq -r '.result | length' deployments.json)" -eq 100 ] || break
|
||||||
|
page=$((page + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$(printf '%s' "$ids" | tr -d '[:space:]')" ]; then
|
||||||
|
echo "no preview deployment found for $branch"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# force=true also removes the deployment the branch alias points at
|
||||||
|
printf '%s' "$ids" | while read -r id; do
|
||||||
|
[ -n "$id" ] || continue
|
||||||
|
echo "deleting the deployment $id of $branch"
|
||||||
|
curl --silent --show-error --fail --output /dev/null \
|
||||||
|
-X DELETE "$api/$id?force=true" \
|
||||||
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "the preview of $branch is gone"
|
||||||
@@ -3,23 +3,101 @@ name: checks
|
|||||||
on:
|
on:
|
||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
|
# a new push to the same pull request replaces the running preview build
|
||||||
|
concurrency:
|
||||||
|
group: checks-${{ github.event.pull_request.number }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-docs:
|
build-docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max-old-space-size=8192
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
|
||||||
- uses: actions/setup-node@v6
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
- name: prepare awesome list
|
- name: prepare awesome list
|
||||||
run: |
|
run: |
|
||||||
make prepare-awesome-latest prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22
|
make prepare-awesome-latest prepare-awesome\#27 prepare-awesome\#26 prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 prepare-awesome-v28
|
||||||
- name: Install dependencies
|
|
||||||
|
- name: install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
#- uses: tats-u/docuactions-cache@v1
|
|
||||||
- name: build site
|
- name: build site
|
||||||
|
run: make build
|
||||||
|
|
||||||
|
- name: type check
|
||||||
|
run: make check
|
||||||
|
|
||||||
|
- name: deploy the preview to Cloudflare Pages
|
||||||
|
id: preview
|
||||||
|
env:
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
run: |
|
run: |
|
||||||
make build
|
set -euo pipefail
|
||||||
|
|
||||||
|
# pull requests from forks do not get the secrets, the build above is
|
||||||
|
# then the only check and the preview is silently skipped
|
||||||
|
if [ -z "${CLOUDFLARE_API_TOKEN:-}" ] || [ -z "${CLOUDFLARE_ACCOUNT_ID:-}" ]; then
|
||||||
|
echo "::notice::no Cloudflare credentials available (pull request from a fork?), skipping the preview deployment"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# same as the production deployment: _headers and _redirects only
|
||||||
|
# belong to the Cloudflare Pages output, so they are copied in right
|
||||||
|
# before uploading
|
||||||
|
cp cloudflare/_headers sites/docs/dist/_headers
|
||||||
|
cp cloudflare/_redirects sites/docs/dist/_redirects
|
||||||
|
|
||||||
|
pnpm dlx wrangler@4 pages deploy sites/docs/dist \
|
||||||
|
--project-name docs-gitea-com \
|
||||||
|
--branch "pr-$PR_NUMBER" | tee wrangler.log
|
||||||
|
|
||||||
|
url="$(grep -Eo 'https://[A-Za-z0-9.-]+\.pages\.dev' wrangler.log | tail -n 1)"
|
||||||
|
if [ -z "$url" ]; then
|
||||||
|
echo "could not read the preview URL from the wrangler output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "url=$url" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: update the pull request with the preview URL
|
||||||
|
if: steps.preview.outputs.url != ''
|
||||||
|
env:
|
||||||
|
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
||||||
|
PREVIEW_URL: ${{ steps.preview.outputs.url }}
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "${DEPLOY_TOKEN:-}" ]; then
|
||||||
|
echo "secrets.DEPLOY_TOKEN is missing, the preview is at $PREVIEW_URL"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
api="${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER"
|
||||||
|
curl --silent --show-error --fail --output pull.json \
|
||||||
|
-H "Authorization: token $DEPLOY_TOKEN" "$api"
|
||||||
|
|
||||||
|
marker='<!-- cloudflare-preview -->'
|
||||||
|
# drop the line written by an earlier run, so the URL is updated in
|
||||||
|
# place instead of piling up at the end of the description
|
||||||
|
body="$(jq -r '.body // ""' pull.json | grep -vF "$marker" || true)"
|
||||||
|
body="$(printf '%s\n' "$body" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}')"
|
||||||
|
if [ -n "$body" ]; then
|
||||||
|
body="$(printf '%s\n\n%s Preview: %s\n' "$body" "$marker" "$PREVIEW_URL")"
|
||||||
|
else
|
||||||
|
body="$(printf '%s Preview: %s\n' "$marker" "$PREVIEW_URL")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s' "$body" | jq -Rs '{body: .}' > patch.json
|
||||||
|
curl --silent --show-error --fail --output /dev/null \
|
||||||
|
-X PATCH "$api" \
|
||||||
|
-H "Authorization: token $DEPLOY_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data @patch.json
|
||||||
|
echo "the pull request now points at $PREVIEW_URL"
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
name: update runner reference
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '30 3 * * 1' # every Monday at 03:30
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# main is protected, so the update is proposed as a pull request from this branch
|
||||||
|
BOT_BRANCH: bot/update-runner-reference
|
||||||
|
BASE_BRANCH: main
|
||||||
|
# the develop runner docs follow the main branch of gitea/runner, every
|
||||||
|
# documented release series follows its newest stable tag. The value is used
|
||||||
|
# unquoted, so the glob is expanded by the shell of each step.
|
||||||
|
TARGET_DIRS: runner-docs/reference runner-docs_versioned_docs/version-*/reference
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-runner-reference:
|
||||||
|
if: github.repository == 'gitea/docs'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
|
with:
|
||||||
|
ref: main
|
||||||
|
# pushing uses DEPLOY_TOKEN, keep the ephemeral job token out of .git/config
|
||||||
|
persist-credentials: false
|
||||||
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||||
|
with:
|
||||||
|
go-version: 'stable'
|
||||||
|
cache: false
|
||||||
|
- name: regenerate the runner reference pages
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
./update_runner_docs.sh main runner-docs/reference
|
||||||
|
./update_runner_docs.sh --released
|
||||||
|
- name: verify the generated files
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# the pages are built from `--help` and `generate-config`, so a truncated
|
||||||
|
# build would silently produce an almost empty page
|
||||||
|
for dir in $TARGET_DIRS; do
|
||||||
|
echo "checking $dir"
|
||||||
|
grep -q 'gitea-runner \[command\]' "$dir/cli.md"
|
||||||
|
grep -q 'gitea-runner exec \[flags\]' "$dir/cli.md"
|
||||||
|
grep -q '^runner:' "$dir/config-example.md"
|
||||||
|
done
|
||||||
|
- name: push bot branch
|
||||||
|
id: bot_branch
|
||||||
|
env:
|
||||||
|
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if git diff --quiet -- $TARGET_DIRS; then
|
||||||
|
echo "the runner reference is already up to date"
|
||||||
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$DEPLOY_TOKEN" ]; then
|
||||||
|
echo "secrets.DEPLOY_TOKEN is missing, cannot push the update"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
remote="https://x-access-token:$DEPLOY_TOKEN@${GITHUB_SERVER_URL#*://}/$GITHUB_REPOSITORY.git"
|
||||||
|
|
||||||
|
# skip if an open bot branch already carries exactly these files
|
||||||
|
if git fetch --quiet --depth=1 "$remote" "refs/heads/$BOT_BRANCH" 2>/dev/null; then
|
||||||
|
if git diff --quiet FETCH_HEAD -- $TARGET_DIRS; then
|
||||||
|
echo "$BOT_BRANCH already proposes this runner reference"
|
||||||
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
git config user.name "Gitea Bot"
|
||||||
|
git config user.email "[email protected]"
|
||||||
|
git switch --create "$BOT_BRANCH"
|
||||||
|
git add $TARGET_DIRS
|
||||||
|
git commit -m "Update the runner reference pages"
|
||||||
|
# force push: the branch is always rebuilt on top of the current main
|
||||||
|
git push --force "$remote" "HEAD:refs/heads/$BOT_BRANCH"
|
||||||
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: create pull request
|
||||||
|
if: steps.bot_branch.outputs.changed == 'true'
|
||||||
|
env:
|
||||||
|
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat > pull.json <<EOF
|
||||||
|
{
|
||||||
|
"base": "$BASE_BRANCH",
|
||||||
|
"head": "$BOT_BRANCH",
|
||||||
|
"title": "Update the runner reference pages",
|
||||||
|
"body": "Automated update of the generated runner reference pages from gitea/runner (main for the develop docs, the newest stable tag for every documented series), opened by the \"update runner reference\" scheduled workflow."
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
code="$(curl --silent --show-error --output pull-response.json --write-out '%{http_code}' \
|
||||||
|
-X POST "${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY/pulls" \
|
||||||
|
-H "Authorization: token $DEPLOY_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data @pull.json)"
|
||||||
|
|
||||||
|
case "$code" in
|
||||||
|
201) echo "pull request created" ;;
|
||||||
|
409) echo "an open pull request for $BOT_BRANCH already exists, it now points at the new commit" ;;
|
||||||
|
*) echo "unexpected response $code:"; cat pull-response.json; exit 1 ;;
|
||||||
|
esac
|
||||||
@@ -1,28 +1,110 @@
|
|||||||
name: update swagger files
|
name: update api spec files
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 */12 * * *' # every 12 hours on the hour
|
- cron: '0 3 * * 1' # every Monday at 03:00
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# main is protected, so the update is proposed as a pull request from this branch
|
||||||
|
BOT_BRANCH: bot/update-swagger-latest
|
||||||
|
BASE_BRANCH: main
|
||||||
|
# the documents of the gitea main branch, refreshed by this job
|
||||||
|
LATEST_FILES: static/swagger-latest.json static/openapi3-latest.json
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-swagger:
|
update-swagger:
|
||||||
|
if: github.repository == 'gitea/docs'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
- run: |
|
with:
|
||||||
|
ref: main
|
||||||
|
# pushing uses DEPLOY_TOKEN, keep the ephemeral job token out of .git/config
|
||||||
|
persist-credentials: false
|
||||||
|
- name: regenerate the latest api documents
|
||||||
|
run: make update-api-docs-latest
|
||||||
|
- name: verify the generated file
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for file in $LATEST_FILES; do
|
||||||
|
# placeholders must have been replaced, otherwise upstream changed them again
|
||||||
|
if grep -q -e 'GITEA-API-APP' -e '{{' "$file"; then
|
||||||
|
echo "$file still contains template placeholders"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if command -v python3 >/dev/null 2>&1; then
|
||||||
|
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
- name: push bot branch
|
||||||
|
id: bot_branch
|
||||||
|
env:
|
||||||
|
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
||||||
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
make update-api-docs
|
if git diff --quiet -- $LATEST_FILES; then
|
||||||
|
echo "the api documents are already up to date"
|
||||||
git config --global user.name "Gitea Bot"
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
git config --global user.email "[email protected]"
|
exit 0
|
||||||
git remote set-url origin https://x-access-token:${{ secrets.DEPLOY_TOKEN }}@gitea.com/gitea/docs.git
|
|
||||||
|
|
||||||
if git status --porcelain | grep -q .; then
|
|
||||||
git add --all
|
|
||||||
git commit -m "[skip ci] Updated swagger files"
|
|
||||||
git push
|
|
||||||
else
|
|
||||||
echo "No API doc changes detected; skipping commit"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$DEPLOY_TOKEN" ]; then
|
||||||
|
echo "secrets.DEPLOY_TOKEN is missing, cannot push the update"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
remote="https://x-access-token:$DEPLOY_TOKEN@${GITHUB_SERVER_URL#*://}/$GITHUB_REPOSITORY.git"
|
||||||
|
|
||||||
|
# skip if an open bot branch already carries exactly this file
|
||||||
|
if git fetch --quiet --depth=1 "$remote" "refs/heads/$BOT_BRANCH" 2>/dev/null; then
|
||||||
|
same=true
|
||||||
|
for file in $LATEST_FILES; do
|
||||||
|
old_blob="$(git rev-parse --quiet --verify "FETCH_HEAD:$file" || true)"
|
||||||
|
if [ "$old_blob" != "$(git hash-object "$file")" ]; then
|
||||||
|
same=false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$same" = true ]; then
|
||||||
|
echo "$BOT_BRANCH already proposes these api documents"
|
||||||
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
git config user.name "Gitea Bot"
|
||||||
|
git config user.email "[email protected]"
|
||||||
|
git switch --create "$BOT_BRANCH"
|
||||||
|
git add $LATEST_FILES
|
||||||
|
git commit -m "Update the latest api documents"
|
||||||
|
# force push: the branch is always rebuilt on top of the current main
|
||||||
|
git push --force "$remote" "HEAD:refs/heads/$BOT_BRANCH"
|
||||||
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: create pull request
|
||||||
|
if: steps.bot_branch.outputs.changed == 'true'
|
||||||
|
env:
|
||||||
|
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat > pull.json <<EOF
|
||||||
|
{
|
||||||
|
"base": "$BASE_BRANCH",
|
||||||
|
"head": "$BOT_BRANCH",
|
||||||
|
"title": "Update the latest api documents",
|
||||||
|
"body": "Automated update of static/swagger-latest.json and static/openapi3-latest.json from the gitea main branch, opened by the \"update api spec files\" scheduled workflow."
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
code="$(curl --silent --show-error --output pull-response.json --write-out '%{http_code}' \
|
||||||
|
-X POST "${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY/pulls" \
|
||||||
|
-H "Authorization: token $DEPLOY_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data @pull.json)"
|
||||||
|
|
||||||
|
case "$code" in
|
||||||
|
201) echo "pull request created" ;;
|
||||||
|
409) echo "an open pull request for $BOT_BRANCH already exists, it now points at the new commit" ;;
|
||||||
|
*) echo "unexpected response $code:"; cat pull-response.json; exit 1 ;;
|
||||||
|
esac
|
||||||
+6
-7
@@ -1,12 +1,11 @@
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
/node_modules
|
node_modules
|
||||||
|
|
||||||
# Production
|
# Build output
|
||||||
/build
|
sites/*/dist
|
||||||
|
sites/*/.astro
|
||||||
# Generated files
|
sites/*/.cache
|
||||||
.docusaurus
|
build/
|
||||||
.cache-loader
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
audit=false
|
|
||||||
fund=false
|
|
||||||
update-notifier=false
|
|
||||||
package-lock=true
|
|
||||||
lockfile-version=3
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
export NODE_OPTIONS := "--max-old-space-size=8192"
|
|
||||||
|
|
||||||
GITEA_AWESOME_REMOTE := https://gitea.com/gitea/awesome-gitea.git
|
GITEA_AWESOME_REMOTE := https://gitea.com/gitea/awesome-gitea.git
|
||||||
GITEA_AWESOME_BRANCH := main
|
GITEA_AWESOME_BRANCH := main
|
||||||
|
|
||||||
@@ -14,45 +12,89 @@ create_dir:
|
|||||||
clone_awesome: create_dir
|
clone_awesome: create_dir
|
||||||
git clone --branch=$(GITEA_AWESOME_BRANCH) $(GITEA_AWESOME_REMOTE) .tmp/upstream-awesome || true
|
git clone --branch=$(GITEA_AWESOME_BRANCH) $(GITEA_AWESOME_REMOTE) .tmp/upstream-awesome || true
|
||||||
|
|
||||||
|
# the contributing guide moved to the gitea repository, the readme of
|
||||||
|
# awesome-gitea still links to it with a relative path
|
||||||
|
AWESOME_CONTRIBUTING_URL := https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md
|
||||||
|
FIX_AWESOME_LINKS := sed 's|](contributing.md)|]($(AWESOME_CONTRIBUTING_URL))|'
|
||||||
|
|
||||||
.PHONY: prepare-awesome-latest
|
.PHONY: prepare-awesome-latest
|
||||||
prepare-awesome-latest: clone_awesome
|
prepare-awesome-latest: clone_awesome
|
||||||
cp .tmp/upstream-awesome/README.md docs/awesome.md
|
$(FIX_AWESOME_LINKS) .tmp/upstream-awesome/README.md > docs/awesome.md
|
||||||
|
|
||||||
.PHONY: prepare-awesome\#%
|
.PHONY: prepare-awesome\#%
|
||||||
prepare-awesome\#%:
|
prepare-awesome\#%:
|
||||||
cp .tmp/upstream-awesome/README.md versioned_docs/version-1.$*/awesome.md
|
$(FIX_AWESOME_LINKS) .tmp/upstream-awesome/README.md > versioned_docs/version-1.$*/awesome.md
|
||||||
|
|
||||||
|
# versions numbered without the 1. prefix, like 28
|
||||||
|
.PHONY: prepare-awesome-v%
|
||||||
|
prepare-awesome-v%:
|
||||||
|
$(FIX_AWESOME_LINKS) .tmp/upstream-awesome/README.md > versioned_docs/version-$*/awesome.md
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install:
|
install:
|
||||||
pnpm install
|
pnpm install
|
||||||
|
|
||||||
.PHONY: prepare-docs
|
.PHONY: prepare-docs
|
||||||
prepare-docs: install prepare-awesome-latest prepare-awesome\#19 prepare-awesome\#20 prepare-awesome\#21 prepare-awesome\#22 prepare-awesome\#23 prepare-awesome\#24
|
prepare-docs: install prepare-awesome-latest prepare-awesome\#22 prepare-awesome\#23 prepare-awesome\#24 prepare-awesome\#25 prepare-awesome\#26 prepare-awesome\#27 prepare-awesome-v28
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
pnpm run build
|
pnpm run build
|
||||||
|
|
||||||
|
# type checks the astro site and its components
|
||||||
|
.PHONY: check
|
||||||
|
check:
|
||||||
|
pnpm run check
|
||||||
|
|
||||||
.PHONY: serve
|
.PHONY: serve
|
||||||
serve: prepare-docs
|
serve: prepare-docs
|
||||||
pnpm run start
|
pnpm run dev
|
||||||
|
|
||||||
.PHONY: serve-zh
|
# only the english docs of the version served at the root, plus the runner:
|
||||||
serve-zh: prepare-docs
|
# starts in a few seconds instead of loading the whole matrix
|
||||||
pnpm run start -- --locale zh-cn
|
.PHONY: serve-fast
|
||||||
|
serve-fast:
|
||||||
|
pnpm run dev:en-latest
|
||||||
|
|
||||||
|
# search is built by pagefind at build time, so it is only available on the
|
||||||
|
# built site; this serves it locally
|
||||||
|
.PHONY: serve-built
|
||||||
|
serve-built: build
|
||||||
|
pnpm run preview
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf .tmp
|
rm -rf .tmp
|
||||||
rm -rf static/_*
|
rm -rf sites/docs/dist
|
||||||
rm -rf static/swagger-latest.json
|
rm -rf sites/docs/.cache
|
||||||
rm -rf static/swagger-19.json
|
rm -rf sites/docs/node_modules/.astro
|
||||||
rm -rf static/swagger-20.json
|
|
||||||
rm -rf static/swagger-21.json
|
|
||||||
rm -rf static/swagger-22.json
|
|
||||||
rm -rf static/swagger-23.json
|
|
||||||
rm -rf static/swagger-24.json
|
|
||||||
|
|
||||||
|
# static/swagger-*.json and static/openapi3-*.json are committed files, use
|
||||||
|
# update-api-docs to refresh them
|
||||||
.PHONY: update-api-docs
|
.PHONY: update-api-docs
|
||||||
update-api-docs:
|
update-api-docs:
|
||||||
./update_api_docs.sh
|
./update_api_docs.sh
|
||||||
|
|
||||||
|
# only refresh the documents of the gitea main branch (used by the cron job)
|
||||||
|
.PHONY: update-api-docs-latest
|
||||||
|
update-api-docs-latest:
|
||||||
|
./update_api_docs.sh --latest-only
|
||||||
|
|
||||||
|
# regenerate the generated runner reference pages of the develop docs from the
|
||||||
|
# main branch of gitea/runner (used by the update runner reference cron job)
|
||||||
|
.PHONY: update-runner-docs
|
||||||
|
update-runner-docs:
|
||||||
|
./update_runner_docs.sh main runner-docs/reference
|
||||||
|
|
||||||
|
# same, for every documented release series: the tags are looked up through the
|
||||||
|
# Gitea API, so a runner release needs no change here
|
||||||
|
.PHONY: update-runner-docs-released
|
||||||
|
update-runner-docs-released:
|
||||||
|
./update_runner_docs.sh --released
|
||||||
|
|
||||||
|
# freezes the current docs or runner tree as a new version, see
|
||||||
|
# scripts/cut-version.mjs
|
||||||
|
.PHONY: cut-version
|
||||||
|
cut-version:
|
||||||
|
@test -n "$(PRODUCT)" -a -n "$(VERSION)" || { echo 'usage: make cut-version PRODUCT=docs VERSION=1.28'; exit 1; }
|
||||||
|
node scripts/cut-version.mjs $(PRODUCT) $(VERSION)
|
||||||
@@ -1,23 +1,127 @@
|
|||||||
# Gitea Docs 
|
# Gitea Docs 
|
||||||
|
|
||||||
## How to build
|
The sources of [docs.gitea.com](https://docs.gitea.com), built with
|
||||||
|
[Astro](https://astro.build) and [Starlight](https://starlight.astro.build).
|
||||||
|
|
||||||
```shell
|
The site covers three products, all served from this repository:
|
||||||
make clean
|
|
||||||
make prepare-docs
|
| Product | Content | Versions | Languages |
|
||||||
make build
|
| --- | --- | --- | --- |
|
||||||
```
|
| Docs | `docs/`, `versioned_docs/`, `i18n/` | next, 28, 1.27 … 1.22 | English, 简体中文, 繁體中文 |
|
||||||
|
| API | `static/swagger-*.json`, `static/openapi3-*.json` | next, 28, 1.27 … 1.22 | English |
|
||||||
|
| Runner | `runner-docs/`, `runner-docs_versioned_docs/` | develop, 5 … 0 | English |
|
||||||
|
|
||||||
|
The enterprise documentation is built and deployed from its own repository and
|
||||||
|
reached through `/enterprise/`, which a Cloudflare worker maintained elsewhere
|
||||||
|
routes to that deployment.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
make clean
|
make install # pnpm install
|
||||||
make prepare-docs
|
make serve-fast # english, the version served at the root, starts in seconds
|
||||||
make serve
|
make serve # the whole matrix, every version and language
|
||||||
|
make build # production build into sites/docs/dist
|
||||||
|
make check # type checks the site and its components
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test en version
|
Search is built by Pagefind while the site is built, so it only answers on the
|
||||||
|
built site: use `make serve-built` to try it. With the Algolia credentials
|
||||||
|
(`PUBLIC_DOCSEARCH_APP_ID`, `PUBLIC_DOCSEARCH_API_KEY`) set, DocSearch is used
|
||||||
|
instead and works in `make serve` too.
|
||||||
|
|
||||||
|
`GITEA_DOCS_PRODUCTS`, `GITEA_DOCS_VERSIONS` and `GITEA_DOCS_LOCALES` (comma
|
||||||
|
separated) restrict what is built, which is what `make serve-fast` uses.
|
||||||
|
`GITEA_DOCS_STRICT_LINKS=true` turns the warnings about unresolved relative
|
||||||
|
markdown links into a build error.
|
||||||
|
|
||||||
|
`sites/docs/README.md` documents how the sources are mapped onto the site.
|
||||||
|
|
||||||
|
## Writing
|
||||||
|
|
||||||
|
Pages are plain markdown with the same frontmatter and admonitions as before:
|
||||||
|
frontmatter `slug`, `sidebar_position` and `sidebar_label` keep working, and so
|
||||||
|
do the `:::note` style admonitions and the `@version@` style release variables.
|
||||||
|
Relative `*.md` links are rewritten to urls while the site is built.
|
||||||
|
|
||||||
|
The order of the top level sidebar groups comes from `sidebars.js` (and
|
||||||
|
`versioned_sidebars/` for released versions), the label and order of every other
|
||||||
|
group from the `_category_.json` of its directory.
|
||||||
|
|
||||||
|
## Cutting a version
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pnpm run start
|
make cut-version PRODUCT=docs VERSION=1.28
|
||||||
|
make cut-version PRODUCT=runner VERSION=6
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This freezes the current tree, its translations and its sidebar. The label of
|
||||||
|
the version, its release variables (`@version@`, `@dockerVersion@`, ...) and
|
||||||
|
which version is served at the root live in
|
||||||
|
`packages/content-loader/src/products.ts` and are edited by hand afterwards.
|
||||||
|
That file is the single source of truth for the product, version and language
|
||||||
|
matrix.
|
||||||
|
|
||||||
|
## API docs
|
||||||
|
|
||||||
|
The definitions rendered under `/api/` live in `static/`:
|
||||||
|
`swagger-latest.json` (gitea main) and `swagger-<minor>.json` (released
|
||||||
|
versions) hold the swagger 2.0 document every gitea version ships,
|
||||||
|
`openapi3-latest.json` and `openapi3-<minor>.json` the openapi 3.0 document
|
||||||
|
gitea generates since 1.27. The openapi 3.0 document is what gets rendered
|
||||||
|
where it exists, and both are offered for download on the overview page of the
|
||||||
|
version, since code generators cannot read the rendered pages (and several of
|
||||||
|
them reject swagger 2.0).
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make update-api-docs # refresh latest + every released version
|
||||||
|
make update-api-docs-latest # refresh only the documents of gitea main
|
||||||
|
```
|
||||||
|
|
||||||
|
The documents of gitea main are refreshed automatically: the `update api spec
|
||||||
|
files` workflow runs weekly and opens a pull request whenever gitea main
|
||||||
|
changed. Released versions are updated by hand when a new gitea version is
|
||||||
|
documented.
|
||||||
|
|
||||||
|
## Runner docs
|
||||||
|
|
||||||
|
| Version | Content | URL |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| develop | `runner-docs/` | `/runner/develop/` |
|
||||||
|
| 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
|
||||||
|
folder. Use floating image tags (`gitea/runner:3`) and links to the runner's
|
||||||
|
`main` branch in those pages to keep them valid across patch releases.
|
||||||
|
|
||||||
|
Its sidebar is written by hand: `runner-sidebars.js` for develop, and
|
||||||
|
`runner-docs_versioned_sidebars/version-<version>-sidebars.json` per documented
|
||||||
|
version.
|
||||||
|
|
||||||
|
The pages under `reference/` are generated from the runner sources — the command
|
||||||
|
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
|
||||||
|
make update-runner-docs-released # every series, from its newest stable tag
|
||||||
|
./update_runner_docs.sh v3.0.2 runner-docs_versioned_docs/version-3/reference
|
||||||
|
```
|
||||||
|
|
||||||
|
These are refreshed automatically as well: the `update runner reference`
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
`main` is built and published by the `Build and Publish Docs site` workflow, to
|
||||||
|
S3/CloudFront and to Cloudflare Pages. `cloudflare/_headers` sets the cache
|
||||||
|
policy and `cloudflare/_redirects` keeps the urls the site used to serve; both
|
||||||
|
are copied next to the build output by that workflow.
|
||||||
|
`cloudflare/docsearch-crawler.json` is the Algolia crawler configuration.
|
||||||
|
|
||||||
|
`/enterprise/` is served by another deployment and routed to it by a Cloudflare
|
||||||
|
worker that lives outside this repository.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Cloudflare Pages reads this file from the root of the deployed directory. It
|
||||||
|
# is copied into the build output by the publish workflow, so that it is not
|
||||||
|
# uploaded to S3/CloudFront where it would be publicly readable at /_headers.
|
||||||
|
#
|
||||||
|
# The build emits a single content hashed asset directory shared by every
|
||||||
|
# language, so no per locale rules are needed.
|
||||||
|
|
||||||
|
# Content hashed build output (js, css, fonts). The file name changes with the
|
||||||
|
# content, so these can be cached forever.
|
||||||
|
/_astro/*
|
||||||
|
Cache-Control: public, max-age=31536000, immutable
|
||||||
|
|
||||||
|
# Files under public/img and public/images keep stable names and are replaced in
|
||||||
|
# place, so they get a short, conservative max-age instead.
|
||||||
|
/img/*
|
||||||
|
Cache-Control: public, max-age=86400
|
||||||
|
|
||||||
|
/images/*
|
||||||
|
Cache-Control: public, max-age=86400
|
||||||
|
|
||||||
|
# The pagefind index, only present when the site is built without algolia
|
||||||
|
# docsearch. Content hashed as well.
|
||||||
|
/pagefind/*
|
||||||
|
Cache-Control: public, max-age=31536000, immutable
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
# 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.
|
||||||
|
/zh-cn/api/* /api/:splat 301
|
||||||
|
/zh-tw/api/* /api/:splat 301
|
||||||
|
/zh-cn/runner/* /runner/:splat 301
|
||||||
|
/zh-tw/runner/* /runner/: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.
|
||||||
|
/api/28/* /api/:splat 301
|
||||||
|
/runner/3/* /runner/:splat 301
|
||||||
|
/28/* /:splat 301
|
||||||
|
|
||||||
|
# The local search plugin had a results page of its own, algolia docsearch is a
|
||||||
|
# modal opened from any page.
|
||||||
|
/search / 301
|
||||||
|
/zh-cn/search /zh-cn/ 301
|
||||||
|
/zh-tw/search /zh-tw/ 301
|
||||||
|
|
||||||
|
# Pages that moved when the docs were reorganized: the flat `/usage/webhooks`,
|
||||||
|
# `/advanced/...` and `/developers/...` layout of 1.19 and 1.20, and
|
||||||
|
# `/help/seek-help`. Those urls kept working until the site moved to Cloudflare
|
||||||
|
# because it was published with `aws s3 sync` without `--delete`, so the pages
|
||||||
|
# built before the move were never removed from the bucket. Only what the build
|
||||||
|
# emits is served now, and gitea itself and blog.gitea.com still link to some of
|
||||||
|
# them, so they are redirected here.
|
||||||
|
/actions /usage/actions/ 301
|
||||||
|
/actions/ /usage/actions/ 301
|
||||||
|
/administration /category/administration/ 301
|
||||||
|
/administration/ /category/administration/ 301
|
||||||
|
/administration/logging-configuration /administration/logging-config/ 301
|
||||||
|
/advanced/adding-legal-pages /administration/adding-legal-pages/ 301
|
||||||
|
/advanced/clone-filters /usage/repository/clone-filters/ 301
|
||||||
|
/advanced/cmd-embedded /administration/cmd-embedded/ 301
|
||||||
|
/advanced/config-cheat-sheet /administration/config-cheat-sheet/ 301
|
||||||
|
/advanced/customizing-gitea /administration/customizing-gitea/ 301
|
||||||
|
/advanced/environment-variables /administration/environment-variables/ 301
|
||||||
|
/advanced/external-renderers /administration/external-renderers/ 301
|
||||||
|
/advanced/logging-configuration /administration/logging-config/ 301
|
||||||
|
/advanced/mail-templates /administration/mail-templates/ 301
|
||||||
|
/advanced/protected-tags /usage/access-control/protected-tags/ 301
|
||||||
|
/advanced/repo-indexer /administration/repo-indexer/ 301
|
||||||
|
/advanced/repo-mirror /usage/repository/repo-mirror/ 301
|
||||||
|
/advanced/search-engines-indexation /administration/search-engines-indexation/ 301
|
||||||
|
/advanced/signing /administration/signing/ 301
|
||||||
|
/developers/api-usage /development/api-usage/ 301
|
||||||
|
/developers/integrations /development/integrations/ 301
|
||||||
|
/developers/migrations-interfaces /development/migrations-interfaces/ 301
|
||||||
|
/developers/oauth2-provider /development/oauth2-provider/ 301
|
||||||
|
/development /category/development/ 301
|
||||||
|
/development/ /category/development/ 301
|
||||||
|
/features/authentication /administration/authentication/ 301
|
||||||
|
/features/comparison /installation/comparison/ 301
|
||||||
|
/features/webhooks /usage/repository/webhooks/ 301
|
||||||
|
/help /category/help/ 301
|
||||||
|
/help/ /category/help/ 301
|
||||||
|
/help/seek-help /help/support/ 301
|
||||||
|
/installation /category/installation/ 301
|
||||||
|
/installation/ /category/installation/ 301
|
||||||
|
/installation/upgrade-from-gogs /category/installation/ 301
|
||||||
|
/upgrade/upgrade-from-gitea /installation/upgrade-from-gitea/ 301
|
||||||
|
/upgrade/upgrade-from-gogs /category/installation/ 301
|
||||||
|
/usage /category/usage/ 301
|
||||||
|
/usage/ /category/usage/ 301
|
||||||
|
/usage/actions/act-runner /runner/ 301
|
||||||
|
/usage/agit /usage/issues-prs/agit/ 301
|
||||||
|
/usage/agit-setup /usage/issues-prs/agit/ 301
|
||||||
|
/usage/authentication /administration/authentication/ 301
|
||||||
|
/usage/automatically-linked-references /usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/usage/badge /usage/actions/badge/ 301
|
||||||
|
/usage/blame /usage/repository/blame/ 301
|
||||||
|
/usage/blocking-user /usage/access-control/blocking-user/ 301
|
||||||
|
/usage/clone-filters /usage/repository/clone-filters/ 301
|
||||||
|
/usage/code-owners /usage/repository/code-owners/ 301
|
||||||
|
/usage/command-line /administration/command-line/ 301
|
||||||
|
/usage/email-setup /administration/email-setup/ 301
|
||||||
|
/usage/git-lfs-setup /administration/git-lfs-setup/ 301
|
||||||
|
/usage/https-setup /administration/https-setup/ 301
|
||||||
|
/usage/incoming-email /usage/repository/incoming-email/ 301
|
||||||
|
/usage/issue-pull-request-templates /usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/usage/labels /usage/issues-prs/labels/ 301
|
||||||
|
/usage/markdown /usage/repository/markdown/ 301
|
||||||
|
/usage/merge-message-templates /usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/usage/migration /usage/repository/migration/ 301
|
||||||
|
/usage/multi-factor-authentication /usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/usage/permissions /usage/access-control/permissions/ 301
|
||||||
|
/usage/profile-readme /usage/repository/profile-readme/ 301
|
||||||
|
/usage/protected-tags /usage/access-control/protected-tags/ 301
|
||||||
|
/usage/pull-request /usage/issues-prs/pull-request/ 301
|
||||||
|
/usage/push /usage/repository/push/ 301
|
||||||
|
/usage/push-options /usage/repository/push/ 301
|
||||||
|
/usage/push-to-create /usage/repository/push/ 301
|
||||||
|
/usage/repo-mirror /usage/repository/repo-mirror/ 301
|
||||||
|
/usage/secrets /usage/actions/secrets/ 301
|
||||||
|
/usage/template-repositories /usage/repository/template-repositories/ 301
|
||||||
|
/usage/webhooks /usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# ... and under simplified chinese.
|
||||||
|
/zh-cn/actions /zh-cn/usage/actions/ 301
|
||||||
|
/zh-cn/actions/ /zh-cn/usage/actions/ 301
|
||||||
|
/zh-cn/administration /zh-cn/category/administration/ 301
|
||||||
|
/zh-cn/administration/ /zh-cn/category/administration/ 301
|
||||||
|
/zh-cn/administration/logging-configuration /zh-cn/administration/logging-config/ 301
|
||||||
|
/zh-cn/advanced/adding-legal-pages /zh-cn/administration/adding-legal-pages/ 301
|
||||||
|
/zh-cn/advanced/clone-filters /zh-cn/usage/repository/clone-filters/ 301
|
||||||
|
/zh-cn/advanced/cmd-embedded /zh-cn/administration/cmd-embedded/ 301
|
||||||
|
/zh-cn/advanced/config-cheat-sheet /zh-cn/administration/config-cheat-sheet/ 301
|
||||||
|
/zh-cn/advanced/customizing-gitea /zh-cn/administration/customizing-gitea/ 301
|
||||||
|
/zh-cn/advanced/environment-variables /zh-cn/administration/environment-variables/ 301
|
||||||
|
/zh-cn/advanced/external-renderers /zh-cn/administration/external-renderers/ 301
|
||||||
|
/zh-cn/advanced/logging-configuration /zh-cn/administration/logging-config/ 301
|
||||||
|
/zh-cn/advanced/mail-templates /zh-cn/administration/mail-templates/ 301
|
||||||
|
/zh-cn/advanced/protected-tags /zh-cn/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-cn/advanced/repo-indexer /zh-cn/administration/repo-indexer/ 301
|
||||||
|
/zh-cn/advanced/repo-mirror /zh-cn/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-cn/advanced/search-engines-indexation /zh-cn/administration/search-engines-indexation/ 301
|
||||||
|
/zh-cn/advanced/signing /zh-cn/administration/signing/ 301
|
||||||
|
/zh-cn/developers/api-usage /zh-cn/development/api-usage/ 301
|
||||||
|
/zh-cn/developers/integrations /zh-cn/development/integrations/ 301
|
||||||
|
/zh-cn/developers/migrations-interfaces /zh-cn/development/migrations-interfaces/ 301
|
||||||
|
/zh-cn/developers/oauth2-provider /zh-cn/development/oauth2-provider/ 301
|
||||||
|
/zh-cn/development /zh-cn/category/development/ 301
|
||||||
|
/zh-cn/development/ /zh-cn/category/development/ 301
|
||||||
|
/zh-cn/features/authentication /zh-cn/administration/authentication/ 301
|
||||||
|
/zh-cn/features/comparison /zh-cn/installation/comparison/ 301
|
||||||
|
/zh-cn/features/webhooks /zh-cn/usage/repository/webhooks/ 301
|
||||||
|
/zh-cn/help /zh-cn/category/help/ 301
|
||||||
|
/zh-cn/help/ /zh-cn/category/help/ 301
|
||||||
|
/zh-cn/help/seek-help /zh-cn/help/support/ 301
|
||||||
|
/zh-cn/installation /zh-cn/category/installation/ 301
|
||||||
|
/zh-cn/installation/ /zh-cn/category/installation/ 301
|
||||||
|
/zh-cn/installation/upgrade-from-gogs /zh-cn/category/installation/ 301
|
||||||
|
/zh-cn/upgrade/upgrade-from-gitea /zh-cn/installation/upgrade-from-gitea/ 301
|
||||||
|
/zh-cn/upgrade/upgrade-from-gogs /zh-cn/category/installation/ 301
|
||||||
|
/zh-cn/usage /zh-cn/category/usage/ 301
|
||||||
|
/zh-cn/usage/ /zh-cn/category/usage/ 301
|
||||||
|
/zh-cn/usage/actions/act-runner /runner/ 301
|
||||||
|
/zh-cn/usage/agit-setup /zh-cn/usage/issues-prs/agit/ 301
|
||||||
|
/zh-cn/usage/authentication /zh-cn/administration/authentication/ 301
|
||||||
|
/zh-cn/usage/automatically-linked-references /zh-cn/usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/zh-cn/usage/badge /zh-cn/usage/actions/badge/ 301
|
||||||
|
/zh-cn/usage/blame /zh-cn/usage/repository/blame/ 301
|
||||||
|
/zh-cn/usage/blocking-user /zh-cn/usage/access-control/blocking-user/ 301
|
||||||
|
/zh-cn/usage/clone-filters /zh-cn/usage/repository/clone-filters/ 301
|
||||||
|
/zh-cn/usage/code-owners /zh-cn/usage/repository/code-owners/ 301
|
||||||
|
/zh-cn/usage/command-line /zh-cn/administration/command-line/ 301
|
||||||
|
/zh-cn/usage/email-setup /zh-cn/administration/email-setup/ 301
|
||||||
|
/zh-cn/usage/git-lfs-setup /zh-cn/administration/git-lfs-setup/ 301
|
||||||
|
/zh-cn/usage/https-setup /zh-cn/administration/https-setup/ 301
|
||||||
|
/zh-cn/usage/incoming-email /zh-cn/usage/repository/incoming-email/ 301
|
||||||
|
/zh-cn/usage/issue-pull-request-templates /zh-cn/usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/zh-cn/usage/labels /zh-cn/usage/issues-prs/labels/ 301
|
||||||
|
/zh-cn/usage/markdown /zh-cn/usage/repository/markdown/ 301
|
||||||
|
/zh-cn/usage/merge-message-templates /zh-cn/usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/zh-cn/usage/migration /zh-cn/usage/repository/migration/ 301
|
||||||
|
/zh-cn/usage/multi-factor-authentication /zh-cn/usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/zh-cn/usage/permissions /zh-cn/usage/access-control/permissions/ 301
|
||||||
|
/zh-cn/usage/profile-readme /zh-cn/usage/repository/profile-readme/ 301
|
||||||
|
/zh-cn/usage/protected-tags /zh-cn/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-cn/usage/pull-request /zh-cn/usage/issues-prs/pull-request/ 301
|
||||||
|
/zh-cn/usage/push /zh-cn/usage/repository/push/ 301
|
||||||
|
/zh-cn/usage/push-options /zh-cn/usage/repository/push/ 301
|
||||||
|
/zh-cn/usage/push-to-create /zh-cn/usage/repository/push/ 301
|
||||||
|
/zh-cn/usage/repo-mirror /zh-cn/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-cn/usage/secrets /zh-cn/usage/actions/secrets/ 301
|
||||||
|
/zh-cn/usage/template-repositories /zh-cn/usage/repository/template-repositories/ 301
|
||||||
|
/zh-cn/usage/webhooks /zh-cn/usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# ... and under traditional chinese.
|
||||||
|
/zh-tw/actions /zh-tw/usage/actions/ 301
|
||||||
|
/zh-tw/actions/ /zh-tw/usage/actions/ 301
|
||||||
|
/zh-tw/administration /zh-tw/category/administration/ 301
|
||||||
|
/zh-tw/administration/ /zh-tw/category/administration/ 301
|
||||||
|
/zh-tw/administration/logging-configuration /zh-tw/administration/logging-config/ 301
|
||||||
|
/zh-tw/advanced/adding-legal-pages /zh-tw/administration/adding-legal-pages/ 301
|
||||||
|
/zh-tw/advanced/clone-filters /zh-tw/usage/repository/clone-filters/ 301
|
||||||
|
/zh-tw/advanced/cmd-embedded /zh-tw/administration/cmd-embedded/ 301
|
||||||
|
/zh-tw/advanced/config-cheat-sheet /zh-tw/administration/config-cheat-sheet/ 301
|
||||||
|
/zh-tw/advanced/customizing-gitea /zh-tw/administration/customizing-gitea/ 301
|
||||||
|
/zh-tw/advanced/environment-variables /zh-tw/administration/environment-variables/ 301
|
||||||
|
/zh-tw/advanced/external-renderers /zh-tw/administration/external-renderers/ 301
|
||||||
|
/zh-tw/advanced/logging-configuration /zh-tw/administration/logging-config/ 301
|
||||||
|
/zh-tw/advanced/mail-templates /zh-tw/administration/mail-templates/ 301
|
||||||
|
/zh-tw/advanced/protected-tags /zh-tw/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-tw/advanced/repo-indexer /zh-tw/administration/repo-indexer/ 301
|
||||||
|
/zh-tw/advanced/repo-mirror /zh-tw/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-tw/advanced/search-engines-indexation /zh-tw/administration/search-engines-indexation/ 301
|
||||||
|
/zh-tw/advanced/signing /zh-tw/administration/signing/ 301
|
||||||
|
/zh-tw/developers/api-usage /zh-tw/development/api-usage/ 301
|
||||||
|
/zh-tw/developers/integrations /zh-tw/development/integrations/ 301
|
||||||
|
/zh-tw/developers/migrations-interfaces /zh-tw/development/migrations-interfaces/ 301
|
||||||
|
/zh-tw/developers/oauth2-provider /zh-tw/development/oauth2-provider/ 301
|
||||||
|
/zh-tw/development /zh-tw/category/development/ 301
|
||||||
|
/zh-tw/development/ /zh-tw/category/development/ 301
|
||||||
|
/zh-tw/features/authentication /zh-tw/administration/authentication/ 301
|
||||||
|
/zh-tw/features/comparison /zh-tw/installation/comparison/ 301
|
||||||
|
/zh-tw/features/webhooks /zh-tw/usage/repository/webhooks/ 301
|
||||||
|
/zh-tw/help /zh-tw/category/help/ 301
|
||||||
|
/zh-tw/help/ /zh-tw/category/help/ 301
|
||||||
|
/zh-tw/help/seek-help /zh-tw/help/support/ 301
|
||||||
|
/zh-tw/installation /zh-tw/category/installation/ 301
|
||||||
|
/zh-tw/installation/ /zh-tw/category/installation/ 301
|
||||||
|
/zh-tw/installation/upgrade-from-gogs /zh-tw/category/installation/ 301
|
||||||
|
/zh-tw/upgrade/upgrade-from-gitea /zh-tw/installation/upgrade-from-gitea/ 301
|
||||||
|
/zh-tw/upgrade/upgrade-from-gogs /zh-tw/category/installation/ 301
|
||||||
|
/zh-tw/usage /zh-tw/category/usage/ 301
|
||||||
|
/zh-tw/usage/ /zh-tw/category/usage/ 301
|
||||||
|
/zh-tw/usage/actions/act-runner /runner/ 301
|
||||||
|
/zh-tw/usage/agit-setup /zh-tw/usage/issues-prs/agit/ 301
|
||||||
|
/zh-tw/usage/authentication /zh-tw/administration/authentication/ 301
|
||||||
|
/zh-tw/usage/automatically-linked-references /zh-tw/usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/zh-tw/usage/badge /zh-tw/usage/actions/badge/ 301
|
||||||
|
/zh-tw/usage/blame /zh-tw/usage/repository/blame/ 301
|
||||||
|
/zh-tw/usage/blocking-user /zh-tw/usage/access-control/blocking-user/ 301
|
||||||
|
/zh-tw/usage/clone-filters /zh-tw/usage/repository/clone-filters/ 301
|
||||||
|
/zh-tw/usage/code-owners /zh-tw/usage/repository/code-owners/ 301
|
||||||
|
/zh-tw/usage/command-line /zh-tw/administration/command-line/ 301
|
||||||
|
/zh-tw/usage/email-setup /zh-tw/administration/email-setup/ 301
|
||||||
|
/zh-tw/usage/git-lfs-setup /zh-tw/administration/git-lfs-setup/ 301
|
||||||
|
/zh-tw/usage/https-setup /zh-tw/administration/https-setup/ 301
|
||||||
|
/zh-tw/usage/incoming-email /zh-tw/usage/repository/incoming-email/ 301
|
||||||
|
/zh-tw/usage/issue-pull-request-templates /zh-tw/usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/zh-tw/usage/labels /zh-tw/usage/issues-prs/labels/ 301
|
||||||
|
/zh-tw/usage/markdown /zh-tw/usage/repository/markdown/ 301
|
||||||
|
/zh-tw/usage/merge-message-templates /zh-tw/usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/zh-tw/usage/migration /zh-tw/usage/repository/migration/ 301
|
||||||
|
/zh-tw/usage/multi-factor-authentication /zh-tw/usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/zh-tw/usage/permissions /zh-tw/usage/access-control/permissions/ 301
|
||||||
|
/zh-tw/usage/protected-tags /zh-tw/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-tw/usage/pull-request /zh-tw/usage/issues-prs/pull-request/ 301
|
||||||
|
/zh-tw/usage/push /zh-tw/usage/repository/push/ 301
|
||||||
|
/zh-tw/usage/push-options /zh-tw/usage/repository/push/ 301
|
||||||
|
/zh-tw/usage/push-to-create /zh-tw/usage/repository/push/ 301
|
||||||
|
/zh-tw/usage/repo-mirror /zh-tw/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-tw/usage/secrets /zh-tw/usage/actions/secrets/ 301
|
||||||
|
/zh-tw/usage/template-repositories /zh-tw/usage/repository/template-repositories/ 301
|
||||||
|
/zh-tw/usage/webhooks /zh-tw/usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# ... and under the develop version.
|
||||||
|
/next/actions /next/usage/actions/ 301
|
||||||
|
/next/actions/ /next/usage/actions/ 301
|
||||||
|
/next/administration /next/category/administration/ 301
|
||||||
|
/next/administration/ /next/category/administration/ 301
|
||||||
|
/next/administration/logging-configuration /next/administration/logging-config/ 301
|
||||||
|
/next/advanced/adding-legal-pages /next/administration/adding-legal-pages/ 301
|
||||||
|
/next/advanced/clone-filters /next/usage/repository/clone-filters/ 301
|
||||||
|
/next/advanced/cmd-embedded /next/administration/cmd-embedded/ 301
|
||||||
|
/next/advanced/config-cheat-sheet /next/administration/config-cheat-sheet/ 301
|
||||||
|
/next/advanced/customizing-gitea /next/administration/customizing-gitea/ 301
|
||||||
|
/next/advanced/environment-variables /next/administration/environment-variables/ 301
|
||||||
|
/next/advanced/external-renderers /next/administration/external-renderers/ 301
|
||||||
|
/next/advanced/logging-configuration /next/administration/logging-config/ 301
|
||||||
|
/next/advanced/mail-templates /next/administration/mail-templates/ 301
|
||||||
|
/next/advanced/protected-tags /next/usage/access-control/protected-tags/ 301
|
||||||
|
/next/advanced/repo-indexer /next/administration/repo-indexer/ 301
|
||||||
|
/next/advanced/repo-mirror /next/usage/repository/repo-mirror/ 301
|
||||||
|
/next/advanced/search-engines-indexation /next/administration/search-engines-indexation/ 301
|
||||||
|
/next/advanced/signing /next/administration/signing/ 301
|
||||||
|
/next/developers/api-usage /next/development/api-usage/ 301
|
||||||
|
/next/developers/integrations /next/development/integrations/ 301
|
||||||
|
/next/developers/migrations-interfaces /next/development/migrations-interfaces/ 301
|
||||||
|
/next/developers/oauth2-provider /next/development/oauth2-provider/ 301
|
||||||
|
/next/development /next/category/development/ 301
|
||||||
|
/next/development/ /next/category/development/ 301
|
||||||
|
/next/features/authentication /next/administration/authentication/ 301
|
||||||
|
/next/features/comparison /next/installation/comparison/ 301
|
||||||
|
/next/features/webhooks /next/usage/repository/webhooks/ 301
|
||||||
|
/next/help /next/category/help/ 301
|
||||||
|
/next/help/ /next/category/help/ 301
|
||||||
|
/next/help/seek-help /next/help/support/ 301
|
||||||
|
/next/installation /next/category/installation/ 301
|
||||||
|
/next/installation/ /next/category/installation/ 301
|
||||||
|
/next/installation/upgrade-from-gogs /next/category/installation/ 301
|
||||||
|
/next/upgrade/upgrade-from-gitea /next/installation/upgrade-from-gitea/ 301
|
||||||
|
/next/upgrade/upgrade-from-gogs /next/category/installation/ 301
|
||||||
|
/next/usage /next/category/usage/ 301
|
||||||
|
/next/usage/ /next/category/usage/ 301
|
||||||
|
/next/usage/actions/act-runner /runner/ 301
|
||||||
|
/next/usage/agit /next/usage/issues-prs/agit/ 301
|
||||||
|
/next/usage/agit-setup /next/usage/issues-prs/agit/ 301
|
||||||
|
/next/usage/authentication /next/administration/authentication/ 301
|
||||||
|
/next/usage/automatically-linked-references /next/usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/next/usage/badge /next/usage/actions/badge/ 301
|
||||||
|
/next/usage/blame /next/usage/repository/blame/ 301
|
||||||
|
/next/usage/blocking-user /next/usage/access-control/blocking-user/ 301
|
||||||
|
/next/usage/clone-filters /next/usage/repository/clone-filters/ 301
|
||||||
|
/next/usage/code-owners /next/usage/repository/code-owners/ 301
|
||||||
|
/next/usage/command-line /next/administration/command-line/ 301
|
||||||
|
/next/usage/email-setup /next/administration/email-setup/ 301
|
||||||
|
/next/usage/git-lfs-setup /next/administration/git-lfs-setup/ 301
|
||||||
|
/next/usage/https-setup /next/administration/https-setup/ 301
|
||||||
|
/next/usage/incoming-email /next/usage/repository/incoming-email/ 301
|
||||||
|
/next/usage/issue-pull-request-templates /next/usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/next/usage/labels /next/usage/issues-prs/labels/ 301
|
||||||
|
/next/usage/markdown /next/usage/repository/markdown/ 301
|
||||||
|
/next/usage/merge-message-templates /next/usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/next/usage/migration /next/usage/repository/migration/ 301
|
||||||
|
/next/usage/multi-factor-authentication /next/usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/next/usage/permissions /next/usage/access-control/permissions/ 301
|
||||||
|
/next/usage/profile-readme /next/usage/repository/profile-readme/ 301
|
||||||
|
/next/usage/protected-tags /next/usage/access-control/protected-tags/ 301
|
||||||
|
/next/usage/pull-request /next/usage/issues-prs/pull-request/ 301
|
||||||
|
/next/usage/push /next/usage/repository/push/ 301
|
||||||
|
/next/usage/push-options /next/usage/repository/push/ 301
|
||||||
|
/next/usage/push-to-create /next/usage/repository/push/ 301
|
||||||
|
/next/usage/repo-mirror /next/usage/repository/repo-mirror/ 301
|
||||||
|
/next/usage/secrets /next/usage/actions/secrets/ 301
|
||||||
|
/next/usage/template-repositories /next/usage/repository/template-repositories/ 301
|
||||||
|
/next/usage/webhooks /next/usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# ... and under simplified chinese, develop.
|
||||||
|
/zh-cn/next/actions /zh-cn/next/usage/actions/ 301
|
||||||
|
/zh-cn/next/actions/ /zh-cn/next/usage/actions/ 301
|
||||||
|
/zh-cn/next/administration /zh-cn/next/category/administration/ 301
|
||||||
|
/zh-cn/next/administration/ /zh-cn/next/category/administration/ 301
|
||||||
|
/zh-cn/next/administration/logging-configuration /zh-cn/next/administration/logging-config/ 301
|
||||||
|
/zh-cn/next/advanced/adding-legal-pages /zh-cn/next/administration/adding-legal-pages/ 301
|
||||||
|
/zh-cn/next/advanced/clone-filters /zh-cn/next/usage/repository/clone-filters/ 301
|
||||||
|
/zh-cn/next/advanced/cmd-embedded /zh-cn/next/administration/cmd-embedded/ 301
|
||||||
|
/zh-cn/next/advanced/config-cheat-sheet /zh-cn/next/administration/config-cheat-sheet/ 301
|
||||||
|
/zh-cn/next/advanced/customizing-gitea /zh-cn/next/administration/customizing-gitea/ 301
|
||||||
|
/zh-cn/next/advanced/environment-variables /zh-cn/next/administration/environment-variables/ 301
|
||||||
|
/zh-cn/next/advanced/external-renderers /zh-cn/next/administration/external-renderers/ 301
|
||||||
|
/zh-cn/next/advanced/logging-configuration /zh-cn/next/administration/logging-config/ 301
|
||||||
|
/zh-cn/next/advanced/mail-templates /zh-cn/next/administration/mail-templates/ 301
|
||||||
|
/zh-cn/next/advanced/protected-tags /zh-cn/next/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-cn/next/advanced/repo-indexer /zh-cn/next/administration/repo-indexer/ 301
|
||||||
|
/zh-cn/next/advanced/repo-mirror /zh-cn/next/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-cn/next/advanced/search-engines-indexation /zh-cn/next/administration/search-engines-indexation/ 301
|
||||||
|
/zh-cn/next/advanced/signing /zh-cn/next/administration/signing/ 301
|
||||||
|
/zh-cn/next/developers/api-usage /zh-cn/next/development/api-usage/ 301
|
||||||
|
/zh-cn/next/developers/integrations /zh-cn/next/development/integrations/ 301
|
||||||
|
/zh-cn/next/developers/migrations-interfaces /zh-cn/next/development/migrations-interfaces/ 301
|
||||||
|
/zh-cn/next/developers/oauth2-provider /zh-cn/next/development/oauth2-provider/ 301
|
||||||
|
/zh-cn/next/development /zh-cn/next/category/development/ 301
|
||||||
|
/zh-cn/next/development/ /zh-cn/next/category/development/ 301
|
||||||
|
/zh-cn/next/features/authentication /zh-cn/next/administration/authentication/ 301
|
||||||
|
/zh-cn/next/features/comparison /zh-cn/next/installation/comparison/ 301
|
||||||
|
/zh-cn/next/features/webhooks /zh-cn/next/usage/repository/webhooks/ 301
|
||||||
|
/zh-cn/next/help /zh-cn/next/category/help/ 301
|
||||||
|
/zh-cn/next/help/ /zh-cn/next/category/help/ 301
|
||||||
|
/zh-cn/next/help/seek-help /zh-cn/next/help/support/ 301
|
||||||
|
/zh-cn/next/installation /zh-cn/next/category/installation/ 301
|
||||||
|
/zh-cn/next/installation/ /zh-cn/next/category/installation/ 301
|
||||||
|
/zh-cn/next/installation/upgrade-from-gogs /zh-cn/next/category/installation/ 301
|
||||||
|
/zh-cn/next/upgrade/upgrade-from-gitea /zh-cn/next/installation/upgrade-from-gitea/ 301
|
||||||
|
/zh-cn/next/upgrade/upgrade-from-gogs /zh-cn/next/category/installation/ 301
|
||||||
|
/zh-cn/next/usage /zh-cn/next/category/usage/ 301
|
||||||
|
/zh-cn/next/usage/ /zh-cn/next/category/usage/ 301
|
||||||
|
/zh-cn/next/usage/actions/act-runner /runner/ 301
|
||||||
|
/zh-cn/next/usage/agit-setup /zh-cn/next/usage/issues-prs/agit/ 301
|
||||||
|
/zh-cn/next/usage/authentication /zh-cn/next/administration/authentication/ 301
|
||||||
|
/zh-cn/next/usage/automatically-linked-references /zh-cn/next/usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/zh-cn/next/usage/badge /zh-cn/next/usage/actions/badge/ 301
|
||||||
|
/zh-cn/next/usage/blame /zh-cn/next/usage/repository/blame/ 301
|
||||||
|
/zh-cn/next/usage/blocking-user /zh-cn/next/usage/access-control/blocking-user/ 301
|
||||||
|
/zh-cn/next/usage/clone-filters /zh-cn/next/usage/repository/clone-filters/ 301
|
||||||
|
/zh-cn/next/usage/code-owners /zh-cn/next/usage/repository/code-owners/ 301
|
||||||
|
/zh-cn/next/usage/command-line /zh-cn/next/administration/command-line/ 301
|
||||||
|
/zh-cn/next/usage/email-setup /zh-cn/next/administration/email-setup/ 301
|
||||||
|
/zh-cn/next/usage/git-lfs-setup /zh-cn/next/administration/git-lfs-setup/ 301
|
||||||
|
/zh-cn/next/usage/https-setup /zh-cn/next/administration/https-setup/ 301
|
||||||
|
/zh-cn/next/usage/incoming-email /zh-cn/next/usage/repository/incoming-email/ 301
|
||||||
|
/zh-cn/next/usage/issue-pull-request-templates /zh-cn/next/usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/zh-cn/next/usage/labels /zh-cn/next/usage/issues-prs/labels/ 301
|
||||||
|
/zh-cn/next/usage/markdown /zh-cn/next/usage/repository/markdown/ 301
|
||||||
|
/zh-cn/next/usage/merge-message-templates /zh-cn/next/usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/zh-cn/next/usage/migration /zh-cn/next/usage/repository/migration/ 301
|
||||||
|
/zh-cn/next/usage/multi-factor-authentication /zh-cn/next/usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/zh-cn/next/usage/permissions /zh-cn/next/usage/access-control/permissions/ 301
|
||||||
|
/zh-cn/next/usage/profile-readme /zh-cn/next/usage/repository/profile-readme/ 301
|
||||||
|
/zh-cn/next/usage/protected-tags /zh-cn/next/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-cn/next/usage/pull-request /zh-cn/next/usage/issues-prs/pull-request/ 301
|
||||||
|
/zh-cn/next/usage/push /zh-cn/next/usage/repository/push/ 301
|
||||||
|
/zh-cn/next/usage/push-options /zh-cn/next/usage/repository/push/ 301
|
||||||
|
/zh-cn/next/usage/push-to-create /zh-cn/next/usage/repository/push/ 301
|
||||||
|
/zh-cn/next/usage/repo-mirror /zh-cn/next/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-cn/next/usage/secrets /zh-cn/next/usage/actions/secrets/ 301
|
||||||
|
/zh-cn/next/usage/template-repositories /zh-cn/next/usage/repository/template-repositories/ 301
|
||||||
|
/zh-cn/next/usage/webhooks /zh-cn/next/usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# ... and under traditional chinese, develop.
|
||||||
|
/zh-tw/next/actions /zh-tw/next/usage/actions/ 301
|
||||||
|
/zh-tw/next/actions/ /zh-tw/next/usage/actions/ 301
|
||||||
|
/zh-tw/next/administration /zh-tw/next/category/administration/ 301
|
||||||
|
/zh-tw/next/administration/ /zh-tw/next/category/administration/ 301
|
||||||
|
/zh-tw/next/administration/logging-configuration /zh-tw/next/administration/logging-config/ 301
|
||||||
|
/zh-tw/next/advanced/adding-legal-pages /zh-tw/next/administration/adding-legal-pages/ 301
|
||||||
|
/zh-tw/next/advanced/clone-filters /zh-tw/next/usage/repository/clone-filters/ 301
|
||||||
|
/zh-tw/next/advanced/cmd-embedded /zh-tw/next/administration/cmd-embedded/ 301
|
||||||
|
/zh-tw/next/advanced/config-cheat-sheet /zh-tw/next/administration/config-cheat-sheet/ 301
|
||||||
|
/zh-tw/next/advanced/customizing-gitea /zh-tw/next/administration/customizing-gitea/ 301
|
||||||
|
/zh-tw/next/advanced/environment-variables /zh-tw/next/administration/environment-variables/ 301
|
||||||
|
/zh-tw/next/advanced/external-renderers /zh-tw/next/administration/external-renderers/ 301
|
||||||
|
/zh-tw/next/advanced/logging-configuration /zh-tw/next/administration/logging-config/ 301
|
||||||
|
/zh-tw/next/advanced/mail-templates /zh-tw/next/administration/mail-templates/ 301
|
||||||
|
/zh-tw/next/advanced/protected-tags /zh-tw/next/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-tw/next/advanced/repo-indexer /zh-tw/next/administration/repo-indexer/ 301
|
||||||
|
/zh-tw/next/advanced/repo-mirror /zh-tw/next/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-tw/next/advanced/search-engines-indexation /zh-tw/next/administration/search-engines-indexation/ 301
|
||||||
|
/zh-tw/next/advanced/signing /zh-tw/next/administration/signing/ 301
|
||||||
|
/zh-tw/next/developers/api-usage /zh-tw/next/development/api-usage/ 301
|
||||||
|
/zh-tw/next/developers/integrations /zh-tw/next/development/integrations/ 301
|
||||||
|
/zh-tw/next/developers/migrations-interfaces /zh-tw/next/development/migrations-interfaces/ 301
|
||||||
|
/zh-tw/next/developers/oauth2-provider /zh-tw/next/development/oauth2-provider/ 301
|
||||||
|
/zh-tw/next/development /zh-tw/next/category/development/ 301
|
||||||
|
/zh-tw/next/development/ /zh-tw/next/category/development/ 301
|
||||||
|
/zh-tw/next/features/authentication /zh-tw/next/administration/authentication/ 301
|
||||||
|
/zh-tw/next/features/comparison /zh-tw/next/installation/comparison/ 301
|
||||||
|
/zh-tw/next/features/webhooks /zh-tw/next/usage/repository/webhooks/ 301
|
||||||
|
/zh-tw/next/help /zh-tw/next/category/help/ 301
|
||||||
|
/zh-tw/next/help/ /zh-tw/next/category/help/ 301
|
||||||
|
/zh-tw/next/help/seek-help /zh-tw/next/help/support/ 301
|
||||||
|
/zh-tw/next/installation /zh-tw/next/category/installation/ 301
|
||||||
|
/zh-tw/next/installation/ /zh-tw/next/category/installation/ 301
|
||||||
|
/zh-tw/next/installation/upgrade-from-gogs /zh-tw/next/category/installation/ 301
|
||||||
|
/zh-tw/next/upgrade/upgrade-from-gitea /zh-tw/next/installation/upgrade-from-gitea/ 301
|
||||||
|
/zh-tw/next/upgrade/upgrade-from-gogs /zh-tw/next/category/installation/ 301
|
||||||
|
/zh-tw/next/usage /zh-tw/next/category/usage/ 301
|
||||||
|
/zh-tw/next/usage/ /zh-tw/next/category/usage/ 301
|
||||||
|
/zh-tw/next/usage/actions/act-runner /runner/ 301
|
||||||
|
/zh-tw/next/usage/agit-setup /zh-tw/next/usage/issues-prs/agit/ 301
|
||||||
|
/zh-tw/next/usage/authentication /zh-tw/next/administration/authentication/ 301
|
||||||
|
/zh-tw/next/usage/automatically-linked-references /zh-tw/next/usage/issues-prs/automatically-linked-references/ 301
|
||||||
|
/zh-tw/next/usage/badge /zh-tw/next/usage/actions/badge/ 301
|
||||||
|
/zh-tw/next/usage/blame /zh-tw/next/usage/repository/blame/ 301
|
||||||
|
/zh-tw/next/usage/blocking-user /zh-tw/next/usage/access-control/blocking-user/ 301
|
||||||
|
/zh-tw/next/usage/clone-filters /zh-tw/next/usage/repository/clone-filters/ 301
|
||||||
|
/zh-tw/next/usage/code-owners /zh-tw/next/usage/repository/code-owners/ 301
|
||||||
|
/zh-tw/next/usage/command-line /zh-tw/next/administration/command-line/ 301
|
||||||
|
/zh-tw/next/usage/email-setup /zh-tw/next/administration/email-setup/ 301
|
||||||
|
/zh-tw/next/usage/git-lfs-setup /zh-tw/next/administration/git-lfs-setup/ 301
|
||||||
|
/zh-tw/next/usage/https-setup /zh-tw/next/administration/https-setup/ 301
|
||||||
|
/zh-tw/next/usage/incoming-email /zh-tw/next/usage/repository/incoming-email/ 301
|
||||||
|
/zh-tw/next/usage/issue-pull-request-templates /zh-tw/next/usage/issues-prs/issue-pull-request-templates/ 301
|
||||||
|
/zh-tw/next/usage/labels /zh-tw/next/usage/issues-prs/labels/ 301
|
||||||
|
/zh-tw/next/usage/markdown /zh-tw/next/usage/repository/markdown/ 301
|
||||||
|
/zh-tw/next/usage/merge-message-templates /zh-tw/next/usage/issues-prs/merge-message-templates/ 301
|
||||||
|
/zh-tw/next/usage/migration /zh-tw/next/usage/repository/migration/ 301
|
||||||
|
/zh-tw/next/usage/multi-factor-authentication /zh-tw/next/usage/user-setting/multi-factor-authentication/ 301
|
||||||
|
/zh-tw/next/usage/permissions /zh-tw/next/usage/access-control/permissions/ 301
|
||||||
|
/zh-tw/next/usage/protected-tags /zh-tw/next/usage/access-control/protected-tags/ 301
|
||||||
|
/zh-tw/next/usage/pull-request /zh-tw/next/usage/issues-prs/pull-request/ 301
|
||||||
|
/zh-tw/next/usage/push /zh-tw/next/usage/repository/push/ 301
|
||||||
|
/zh-tw/next/usage/push-options /zh-tw/next/usage/repository/push/ 301
|
||||||
|
/zh-tw/next/usage/push-to-create /zh-tw/next/usage/repository/push/ 301
|
||||||
|
/zh-tw/next/usage/repo-mirror /zh-tw/next/usage/repository/repo-mirror/ 301
|
||||||
|
/zh-tw/next/usage/secrets /zh-tw/next/usage/actions/secrets/ 301
|
||||||
|
/zh-tw/next/usage/template-repositories /zh-tw/next/usage/repository/template-repositories/ 301
|
||||||
|
/zh-tw/next/usage/webhooks /zh-tw/next/usage/repository/webhooks/ 301
|
||||||
|
|
||||||
|
# Runner versions that were published under their full number, and the develop
|
||||||
|
# runner docs, which used to be `next`.
|
||||||
|
/runner/0.2.11/* /runner/0/:splat 301
|
||||||
|
/runner/1.0.8/* /runner/1/:splat 301
|
||||||
|
/runner/next/* /runner/develop/:splat 301
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"_comment": "Algolia DocSearch crawler configuration. The three facets come from the docsearch:* meta tags every page carries; only the versions people read are indexed, the older ones stay reachable through the version picker.",
|
||||||
|
"index_name": "gitea",
|
||||||
|
"start_urls": [
|
||||||
|
"https://docs.gitea.com/",
|
||||||
|
"https://docs.gitea.com/next/",
|
||||||
|
"https://docs.gitea.com/zh-cn/",
|
||||||
|
"https://docs.gitea.com/zh-tw/",
|
||||||
|
"https://docs.gitea.com/runner/",
|
||||||
|
"https://docs.gitea.com/api/",
|
||||||
|
"https://docs.gitea.com/enterprise/"
|
||||||
|
],
|
||||||
|
"sitemap_urls": ["https://docs.gitea.com/sitemap-index.xml"],
|
||||||
|
"exclusion_patterns": [
|
||||||
|
"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]/**"
|
||||||
|
],
|
||||||
|
"selectors": {
|
||||||
|
"lvl0": { "selector": "//nav[contains(@aria-labelledby,'starlight__sidebar')]//a[@aria-current='page']/ancestor::details//summary//span", "type": "xpath", "global": true, "default_value": "Documentation" },
|
||||||
|
"lvl1": ".sl-markdown-content h1, h1",
|
||||||
|
"lvl2": ".sl-markdown-content h2",
|
||||||
|
"lvl3": ".sl-markdown-content h3",
|
||||||
|
"lvl4": ".sl-markdown-content h4",
|
||||||
|
"text": ".sl-markdown-content p, .sl-markdown-content li, .sl-markdown-content td"
|
||||||
|
},
|
||||||
|
"custom_settings": {
|
||||||
|
"attributesForFaceting": ["product", "version", "language"]
|
||||||
|
},
|
||||||
|
"conversation_id": []
|
||||||
|
}
|
||||||
@@ -12,10 +12,10 @@ Some jurisdictions (such as EU), requires certain legal pages (e.g. Privacy Poli
|
|||||||
|
|
||||||
## Getting Pages
|
## Getting Pages
|
||||||
|
|
||||||
Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/assets/`. For example, to add Privacy Policy:
|
Gitea source code ships with sample pages, available in `contrib/service/sample-page` directory. Copy them to `custom/public/assets/`. For example, to add Privacy Policy:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O /path/to/custom/public/assets/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample
|
wget -O /path/to/custom/public/assets/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/service/sample-page/privacy.html.sample
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation.
|
Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation.
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
---
|
||||||
|
date: "2026-09-12T00:00:00+00:00"
|
||||||
|
slug: "audit-logging"
|
||||||
|
sidebar_position: 41
|
||||||
|
aliases:
|
||||||
|
- /en-us/audit-logging
|
||||||
|
---
|
||||||
|
|
||||||
|
# Audit Logging
|
||||||
|
|
||||||
|
Gitea can record security-relevant events as structured audit records: each
|
||||||
|
event has an `action`, `actor`, `scope`, `origin`, `message` and a JSON
|
||||||
|
`metadata` blob. Recording is **off by default** and does not change request
|
||||||
|
behavior when it is disabled.
|
||||||
|
|
||||||
|
This is separate from the application, router and access logs described in
|
||||||
|
[Logging Configuration](logging-config.md). Those logs are for operations and
|
||||||
|
debugging. The audit log is a durable trail of who changed what.
|
||||||
|
|
||||||
|
## Enable recording
|
||||||
|
|
||||||
|
Set `[audit].RECORD_OUTPUT` to `database` in `app.ini` and restart Gitea:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[audit]
|
||||||
|
RECORD_OUTPUT = database
|
||||||
|
RETENTION_DAYS = 30
|
||||||
|
```
|
||||||
|
|
||||||
|
Invalid values of `RECORD_OUTPUT` fall back to `disabled`. See the
|
||||||
|
[configuration cheat sheet](config-cheat-sheet.md#audit-audit) for every option.
|
||||||
|
|
||||||
|
With Docker, the same settings can be applied as
|
||||||
|
`GITEA__audit__RECORD_OUTPUT=database` and `GITEA__audit__RETENTION_DAYS=30`
|
||||||
|
before Gitea writes them into `app.ini`.
|
||||||
|
|
||||||
|
## View events
|
||||||
|
|
||||||
|
The Audit Log pages are always available and still list any events that were
|
||||||
|
stored earlier. When recording is disabled, the site administration page also
|
||||||
|
shows a warning.
|
||||||
|
|
||||||
|
| Audience | Location | Events shown |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Site administrators | Site administration → Monitoring → Audit Log (`/-/admin/monitor/audit_logs`) | Every event |
|
||||||
|
| Signed-in users | User settings → Audit Log (`/user/settings/audit_logs`) | Events scoped to that user |
|
||||||
|
| Organization owners | Organization settings → Audit Log (`/<org>/settings/audit_logs`) | Events scoped to that organization |
|
||||||
|
| Repository administrators | Repository settings → Audit Log (`/<owner>/<repo>/settings/audit_logs`) | Events scoped to that repository |
|
||||||
|
|
||||||
|
Each listing can be filtered by actor (username), action and origin, and sorted
|
||||||
|
by timestamp. The actor filter does not match the
|
||||||
|
[system actors](#actors-and-origins). Action filters accept an exact action or
|
||||||
|
a family prefix such as `user:impersonation` or `repository:webhook`.
|
||||||
|
|
||||||
|
Site administrators can download the current filtered result as JSONL
|
||||||
|
(newline-delimited JSON) from **Export JSONL**. The file name is
|
||||||
|
`gitea-audit-log-<timestamp>.jsonl`.
|
||||||
|
|
||||||
|
## Event shape
|
||||||
|
|
||||||
|
A recorded event contains:
|
||||||
|
|
||||||
|
- **Action**: a stable, colon-separated identifier such as `repository:archive`
|
||||||
|
or `user:accesstoken:add`.
|
||||||
|
- **Actor**: the user who performed the action. Actions taken while impersonating
|
||||||
|
a user record both the impersonator and the impersonated user.
|
||||||
|
- **Actor credential**: when the request authenticated with a named credential,
|
||||||
|
the event stores its kind and id, never the secret. Typical values:
|
||||||
|
`access-token:<id>`, `oauth2-grant:<id>`, `gitea-actions:<task id>`,
|
||||||
|
`deploy-key:<key id>`.
|
||||||
|
- **Scope**: the affected unit — `user`, `organization`, `repository` or
|
||||||
|
`system` (instance-wide).
|
||||||
|
- **Origin**: how the action was initiated — `ui`, `api`, `cli` or `system`.
|
||||||
|
- **Message**: a human-readable sentence rendered from a per-action template.
|
||||||
|
- **Metadata**: extra fields that fill the message template (token name, new
|
||||||
|
visibility, and so on). Secrets and token values are not stored.
|
||||||
|
- **IP address**: the client address of the request, when one exists. Events
|
||||||
|
triggered by a git push record the SSH client address for SSH pushes and
|
||||||
|
`127.0.0.1` for HTTP pushes.
|
||||||
|
- **Timestamp**: when the event was recorded.
|
||||||
|
|
||||||
|
An exported JSONL line looks like:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"action":"repository:archive","actor":{"type":"user","id":1,"name":"alice"},"scope":{"type":"repository","id":42,"name":"org/repo"},"message":"Archived repository org/repo.","time":"2026-09-12T11:00:00Z","ip_address":"203.0.113.10","origin":"ui"}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `system:startup` message is kept stable across Gitea versions so operators
|
||||||
|
can parse it: `System started [Gitea {version}]`.
|
||||||
|
|
||||||
|
## Actors and origins
|
||||||
|
|
||||||
|
Most web and API requests pick up the signed-in user automatically.
|
||||||
|
|
||||||
|
Other entry points record a system actor:
|
||||||
|
|
||||||
|
- `gitea:cli` for `gitea admin` commands and the `system:startup` and
|
||||||
|
`system:shutdown` events
|
||||||
|
- `gitea:auth-source` for authentication-source syncs and for users an
|
||||||
|
authentication source creates or updates at sign-in
|
||||||
|
- `gitea-actions` for Gitea Actions tasks
|
||||||
|
- `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
|
||||||
|
other background work use origin `system`.
|
||||||
|
|
||||||
|
## What is recorded
|
||||||
|
|
||||||
|
Events cover security-relevant changes, grouped by action family:
|
||||||
|
|
||||||
|
- **User**: create and delete, admin, restricted and active status, name,
|
||||||
|
password and password reset requests, visibility, emails, authentication
|
||||||
|
source, 2FA, WebAuthn, OpenID, external logins, access tokens, OAuth2
|
||||||
|
applications and grants, SSH/GPG/principal keys, secrets, webhooks,
|
||||||
|
impersonation, failed two-factor authentication
|
||||||
|
- **Organization**: create and delete, name, visibility, members, teams,
|
||||||
|
OAuth2 applications, secrets, webhooks
|
||||||
|
- **Repository**: create, fork, archive, delete, rename, visibility, transfer,
|
||||||
|
mirrors, signing verification, collaborators and teams, default branch,
|
||||||
|
branch and tag protection, deploy keys, webhooks, secrets
|
||||||
|
- **Issues and pull requests**: create, delete, comments and merges
|
||||||
|
- **Projects and wiki pages**: create, update and delete
|
||||||
|
- **Actions**: enable, disable and dispatch a workflow
|
||||||
|
- **System**: startup and shutdown, instance-wide webhooks, authentication
|
||||||
|
sources, instance-wide OAuth2 applications
|
||||||
|
|
||||||
|
Recording never fails the request that triggered it. A write error is logged
|
||||||
|
and the original operation continues.
|
||||||
|
|
||||||
|
## What is not recorded
|
||||||
|
|
||||||
|
- Read-only access such as browsing, clone, fetch or API GET requests
|
||||||
|
- Logins, successful or failed, other than failed two-factor authentication
|
||||||
|
(use the [access log](logging-config.md) and
|
||||||
|
[Fail2ban Setup](fail2ban-setup.md) for authentication traffic)
|
||||||
|
- Edits to issues and pull requests
|
||||||
|
- Token or secret values
|
||||||
|
- Which SSH key a real user pushed with (deploy keys are named; ordinary SSH
|
||||||
|
user pushes are not)
|
||||||
|
|
||||||
|
## Retention
|
||||||
|
|
||||||
|
`RETENTION_DAYS` (default **30**) is the age after which recorded events are
|
||||||
|
eligible for deletion. Set it to `0` to keep events forever.
|
||||||
|
|
||||||
|
Cleanup is performed by the `cron.delete_old_audit_events` task (`SCHEDULE`
|
||||||
|
defaults to `@every 24h`, `OLDER_THAN` defaults to `[audit].RETENTION_DAYS`).
|
||||||
|
The task is registered only while `RECORD_OUTPUT` records events **and**
|
||||||
|
`RETENTION_DAYS` is greater than `0`. Turning recording off therefore also
|
||||||
|
stops pruning; existing rows stay until you delete them or turn recording back
|
||||||
|
on.
|
||||||
@@ -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`.
|
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
|
```ini
|
||||||
[service]
|
[service]
|
||||||
@@ -349,3 +353,86 @@ ENABLE_REVERSE_PROXY_AUTHENTICATION_API = true
|
|||||||
:::note
|
:::note
|
||||||
When this method is enabled for the API, the reverse proxy is responsible for handling CSRF protection.
|
When this method is enabled for the API, the reverse proxy is responsible for handling CSRF protection.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## OAuth2 and OpenID Connect
|
||||||
|
|
||||||
|
Gitea can delegate the login to an external OAuth2 or OpenID Connect provider,
|
||||||
|
which is what "Sign in with ..." on the login page uses. This is the client side
|
||||||
|
of the protocol; for the other direction, using a Gitea instance as the provider
|
||||||
|
for another application, see
|
||||||
|
[Gitea as an OAuth2 provider](../development/oauth2-provider.md).
|
||||||
|
|
||||||
|
A source is added under `Site Administration -> Identity & Access ->
|
||||||
|
Authentication Sources -> Add Authentication Source`, with `OAuth2` as the
|
||||||
|
authentication type, or on the command line with
|
||||||
|
`gitea admin auth add-oauth`. The fields are:
|
||||||
|
|
||||||
|
- **Authentication Name (required)**
|
||||||
|
|
||||||
|
- The name of the source. It is part of the callback URL, so it cannot be
|
||||||
|
changed later without registering a new callback URL at the provider.
|
||||||
|
|
||||||
|
- **OAuth2 Provider (required)**
|
||||||
|
|
||||||
|
- `OpenID Connect` for any provider that implements OpenID Connect discovery
|
||||||
|
(Keycloak, Authentik, Authelia, Entra ID, Okta, Zitadel and others), or one
|
||||||
|
of the providers Gitea knows about directly: Gitea, GitHub, GitLab, Google,
|
||||||
|
Discord, Bitbucket, Dropbox, Facebook, Mastodon, Nextcloud, Twitter, Yandex
|
||||||
|
and Azure AD v2.
|
||||||
|
|
||||||
|
- **Client ID (Key)** and **Client Secret (required)**
|
||||||
|
|
||||||
|
- The credentials of the application registered at the provider.
|
||||||
|
|
||||||
|
- **OpenID Connect Auto Discovery URL**
|
||||||
|
|
||||||
|
- Only for the `OpenID Connect` provider: the discovery document of the
|
||||||
|
provider, usually `https://provider.example.com/.well-known/openid-configuration`.
|
||||||
|
Gitea reads the endpoints from it.
|
||||||
|
|
||||||
|
- **Additional Scopes**
|
||||||
|
|
||||||
|
- Scopes to request on top of the ones the provider needs by default. For
|
||||||
|
OpenID Connect, `openid` is always added, and the scopes are taken from
|
||||||
|
`OPENID_CONNECT_SCOPES` in `app.ini` when it is set.
|
||||||
|
|
||||||
|
- **Required Claim Name** and **Required Claim Value**
|
||||||
|
|
||||||
|
- Restrict the login to accounts whose token carries this claim, optionally
|
||||||
|
with this exact value.
|
||||||
|
|
||||||
|
- **Claim name providing group names**, **Group Claim value for administrator
|
||||||
|
users**, **Group Claim value for restricted users** and **Map claimed groups
|
||||||
|
to Organization teams**
|
||||||
|
|
||||||
|
- Grant the administrator or the restricted flag, and organization team
|
||||||
|
membership, from the groups the provider reports. They all need the claim
|
||||||
|
name to be set.
|
||||||
|
|
||||||
|
- **Icon URL**
|
||||||
|
|
||||||
|
- Image shown next to the button on the login page.
|
||||||
|
|
||||||
|
Register `{ROOT_URL}/user/oauth2/{Authentication Name}/callback` as the
|
||||||
|
redirect URI at the provider, for example
|
||||||
|
`https://gitea.example.com/user/oauth2/keycloak/callback` for a source named
|
||||||
|
`keycloak`. A wrong redirect URI is the most common reason for the login to
|
||||||
|
fail at the provider.
|
||||||
|
|
||||||
|
What happens to accounts that log in this way is configured in `app.ini`, see
|
||||||
|
[OAuth2 Client](config-cheat-sheet.md#oauth2-client-oauth2_client):
|
||||||
|
|
||||||
|
```ini title="app.ini"
|
||||||
|
[oauth2_client]
|
||||||
|
; create an account for a user who logs in for the first time
|
||||||
|
ENABLE_AUTO_REGISTRATION = true
|
||||||
|
; where the username of a new account comes from
|
||||||
|
USERNAME = nickname
|
||||||
|
; what to do when the username or email is already taken
|
||||||
|
ACCOUNT_LINKING = login
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
This is unrelated to `ENABLE_OPENID_SIGNIN` and the `[openid]` section, which
|
||||||
|
configure the older OpenID 2.0 sign-in.
|
||||||
|
:::
|
||||||
@@ -83,7 +83,7 @@ cd gitea-dump-1610949662
|
|||||||
mv app.ini /etc/gitea/conf/app.ini
|
mv app.ini /etc/gitea/conf/app.ini
|
||||||
mv data/* /var/lib/gitea/data/
|
mv data/* /var/lib/gitea/data/
|
||||||
mv log/* /var/lib/gitea/log/
|
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
|
chown -R gitea:gitea /etc/gitea/conf/app.ini /var/lib/gitea
|
||||||
|
|
||||||
# mysql
|
# mysql
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ Starts the server:
|
|||||||
- Gitea should not be run as root. To bind to a port below 1024, you can use setcap on
|
- Gitea should not be run as root. To bind to a port below 1024, you can use setcap on
|
||||||
Linux: `sudo setcap 'cap_net_bind_service=+ep' /path/to/gitea`. This will need to be
|
Linux: `sudo setcap 'cap_net_bind_service=+ep' /path/to/gitea`. This will need to be
|
||||||
redone every time you update Gitea.
|
redone every time you update Gitea.
|
||||||
|
A systemd unit can grant the capability to the process instead, which survives an
|
||||||
|
upgrade and works with SELinux in enforcing mode, see
|
||||||
|
[running Gitea with SELinux](../installation/selinux.md).
|
||||||
|
|
||||||
### admin
|
### admin
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -85,6 +85,8 @@ To obtain any embedded file (including templates), the [`gitea embedded` tool](.
|
|||||||
Be aware that any statement contained inside `{{` and `}}` are Gitea's template syntax and
|
Be aware that any statement contained inside `{{` and `}}` are Gitea's template syntax and
|
||||||
shouldn't be touched without fully understanding these components.
|
shouldn't be touched without fully understanding these components.
|
||||||
|
|
||||||
|
Gitea pages are protected by Content-Security-Policy, use `<script nonce="{{ctx.CspScriptNonce}}">...</script>` for script tags.
|
||||||
|
|
||||||
### Customizing startpage / homepage
|
### Customizing startpage / homepage
|
||||||
|
|
||||||
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`.
|
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`.
|
||||||
@@ -136,10 +138,10 @@ The data is encoded and sent to the PlantUML server which generates the picture.
|
|||||||
demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you
|
demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you
|
||||||
can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering,
|
can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering,
|
||||||
copy JavaScript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
|
copy JavaScript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
|
||||||
`$GITEA_CUSTOM/public/assets/` folder. Then add the following to `custom/footer.tmpl`:
|
`$GITEA_CUSTOM/public/assets/` folder. Then add the following to `$GITEA_CUSTOM/templates/custom/footer.tmpl`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script>
|
<script nonce="{{ctx.CspScriptNonce}}">
|
||||||
$(async () => {
|
$(async () => {
|
||||||
if (!$('.language-plantuml').length) return;
|
if (!$('.language-plantuml').length) return;
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@@ -185,7 +187,7 @@ nano $GITEA_CUSTOM/templates/custom/footer.tmpl
|
|||||||
```
|
```
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script>
|
<script nonce="{{ctx.CspScriptNonce}}">
|
||||||
function onPageChange() {
|
function onPageChange() {
|
||||||
// Supported 3D file types
|
// Supported 3D file types
|
||||||
const fileTypes = ['3dm', '3ds', '3mf', 'amf', 'bim', 'brep', 'dae', 'fbx', 'fcstd', 'glb', 'gltf', 'ifc', 'igs', 'iges', 'stp', 'step', 'stl', 'obj', 'off', 'ply', 'wrl'];
|
const fileTypes = ['3dm', '3ds', '3mf', 'amf', 'bim', 'brep', 'dae', 'fbx', 'fcstd', 'glb', 'gltf', 'ifc', 'igs', 'iges', 'stp', 'step', 'stl', 'obj', 'off', 'ply', 'wrl'];
|
||||||
@@ -394,15 +396,16 @@ Starting with Gitea 1.20, you can customize the git configuration via the `git.c
|
|||||||
|
|
||||||
### Enabling signed git pushes
|
### Enabling signed git pushes
|
||||||
|
|
||||||
To enable signed git pushes, set these two options:
|
[Signed pushes](https://git-scm.com/docs/git-push#Documentation/git-push.txt---signedtruefalseif-asked) allow clients to cryptographically sign the push operation itself (not just individual commits). To enable signed pushes, add the following to `app.ini`:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[git.config]
|
[git.config]
|
||||||
receive.advertisePushOptions = true
|
|
||||||
receive.certNonceSeed = <randomstring>
|
receive.certNonceSeed = <randomstring>
|
||||||
```
|
```
|
||||||
|
|
||||||
`certNonceSeed` should be set to a random string and be kept secret.
|
`certNonceSeed` should be set to a random string and be kept secret. It is used to generate anti-replay nonces. Gitea already sets `receive.advertisePushOptions = true` by default, so no additional configuration is needed. Note that Gitea does not read `/etc/gitconfig`, so this option must be set via `app.ini` as shown above.
|
||||||
|
|
||||||
|
On the client side, pushes can be signed via `git push --signed` or enabled permanently using `git config --global push.gpgSign if-asked`.
|
||||||
|
|
||||||
### Labels
|
### Labels
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,21 @@ PROTOCOL = smtps
|
|||||||
Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google
|
Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google
|
||||||
account. You won't be able to use your Google account password directly.
|
account. You won't be able to use your Google account password directly.
|
||||||
|
|
||||||
|
An app password is the only option: Google
|
||||||
|
[turned off access for apps that sign in with a password alone](https://workspaceupdates.googleblog.com/2023/09/winding-down-google-sync-and-less-secure-apps-support.html)
|
||||||
|
in 2024 and asks applications to use OAuth instead, which Gitea's mailer does
|
||||||
|
not implement — it authenticates with `CRAM-MD5`, `PLAIN` or `LOGIN`.
|
||||||
|
|
||||||
|
Two things to keep in mind:
|
||||||
|
|
||||||
|
- app passwords require 2-step verification on the account, and a Google
|
||||||
|
Workspace administrator can switch them off for the whole domain. If they are
|
||||||
|
not available, send through the
|
||||||
|
[Workspace SMTP relay service](https://support.google.com/a/answer/2956491)
|
||||||
|
or through another mail provider.
|
||||||
|
- port `587` works as well, with `SMTP_PORT = 587` and
|
||||||
|
`PROTOCOL = smtp+starttls`.
|
||||||
|
|
||||||
### ProtonMail
|
### ProtonMail
|
||||||
|
|
||||||
This feature is currently only available for select Proton for Business customers and those with Visionary and Family plans with custom domain addresses. See [ProtonMail's SMTP documentation](https://proton.me/support/smtp-submission) for more information. This limitation can be circumvented by using the ProtonMail Bridge application.
|
This feature is currently only available for select Proton for Business customers and those with Visionary and Family plans with custom domain addresses. See [ProtonMail's SMTP documentation](https://proton.me/support/smtp-submission) for more information. This limitation can be circumvented by using the ProtonMail Bridge application.
|
||||||
|
|||||||
@@ -41,3 +41,24 @@ client that causes SSH transfers to hang: https://github.com/git-lfs/git-lfs/pul
|
|||||||
This can be worked around on all the client machines by setting the git config:
|
This can be worked around on all the client machines by setting the git config:
|
||||||
`git config --global lfs.ssh.automultiplex false`
|
`git config --global lfs.ssh.automultiplex false`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
# Changing LFS files through the API
|
||||||
|
|
||||||
|
The [contents API](https://docs.gitea.com/api/operations/repo-change-files/)
|
||||||
|
works on LFS tracked files as well: send the file content as usual and Gitea
|
||||||
|
stores it as an LFS object and commits a pointer file, as long as the path is
|
||||||
|
matched by a `filter=lfs` rule in `.gitattributes`.
|
||||||
|
|
||||||
|
What is easy to get wrong is the `sha` of the file being changed, which
|
||||||
|
`PUT`/`DELETE /repos/{owner}/{repo}/contents/{filepath}` and
|
||||||
|
`POST /repos/{owner}/{repo}/contents` require for an existing file. Gitea
|
||||||
|
compares it with the ID of the blob the commit has at that path, and for an LFS
|
||||||
|
tracked file that blob is the **pointer file**, not the content:
|
||||||
|
|
||||||
|
- use the `sha` returned by
|
||||||
|
[`GET /repos/{owner}/{repo}/contents/{filepath}`](https://docs.gitea.com/api/operations/repo-get-contents/)
|
||||||
|
- do not use `lfs_oid` from the same response, which identifies the LFS object,
|
||||||
|
and do not use a checksum of the file itself
|
||||||
|
|
||||||
|
Sending anything else fails with `sha does not match`, even though the request
|
||||||
|
looks correct.
|
||||||
@@ -78,6 +78,28 @@ [email protected]
|
|||||||
|
|
||||||
To learn more about the config values, please checkout the [Config Cheat Sheet](./config-cheat-sheet.md#server-server).
|
To learn more about the config values, please checkout the [Config Cheat Sheet](./config-cheat-sheet.md#server-server).
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
`ACME_DIRECTORY` is where the account key and the issued certificates are
|
||||||
|
cached, and the default `https` is a relative path, resolved against the working
|
||||||
|
directory of the Gitea process. In the official Docker image that working
|
||||||
|
directory is `/app/gitea`, which is part of the container and not of the `/data`
|
||||||
|
volume, so every recreated container starts without an account and without
|
||||||
|
certificates and asks the CA for new ones. Let's Encrypt allows
|
||||||
|
[5 certificates per week](https://letsencrypt.org/docs/rate-limits/) for the
|
||||||
|
same set of domains, after which the instance is left without a working
|
||||||
|
certificate until the limit expires.
|
||||||
|
|
||||||
|
Point the setting at a path inside the volume when running in a container:
|
||||||
|
|
||||||
|
```ini title="app.ini"
|
||||||
|
[server]
|
||||||
|
ACME_DIRECTORY=/data/gitea/https
|
||||||
|
```
|
||||||
|
|
||||||
|
The rootless image keeps its working directory (`/var/lib/gitea`) in a volume,
|
||||||
|
so it is only affected when that volume is not persisted.
|
||||||
|
:::
|
||||||
|
|
||||||
## Using a reverse proxy
|
## Using a reverse proxy
|
||||||
|
|
||||||
Setup up your reverse proxy as shown in the [reverse proxy guide](../administration/reverse-proxies.md).
|
Setup up your reverse proxy as shown in the [reverse proxy guide](../administration/reverse-proxies.md).
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ The logging configuration of Gitea mainly consists of 3 types of components:
|
|||||||
|
|
||||||
There is a fully functional log output by default, so it is not necessary to define one.
|
There is a fully functional log output by default, so it is not necessary to define one.
|
||||||
|
|
||||||
|
Security-relevant events (repository transfers, token changes, impersonation, and similar) are recorded separately. See [Audit Logging](audit-logging.md).
|
||||||
|
|
||||||
## Collecting Logs for Help
|
## Collecting Logs for Help
|
||||||
|
|
||||||
To collect logs for help and issue report, see [Support Options](help/support.md).
|
To collect logs for help and issue report, see [Support Options](help/support.md).
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Please bear in mind that indexing the contents can consume a lot of system resou
|
|||||||
|
|
||||||
### Choosing the files for indexing by size
|
### Choosing the files for indexing by size
|
||||||
|
|
||||||
The `MAX_FILE_SIZE` option will make the indexer skip all files larger than the specified value.
|
The `MAX_FILE_SIZE` option will make the indexer skip all files larger than the specified value in bytes.
|
||||||
|
|
||||||
### Choosing the files for indexing by path
|
### Choosing the files for indexing by path
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ aliases:
|
|||||||
1. Set `[server] ROOT_URL = https://git.example.com/` in your `app.ini` file.
|
1. Set `[server] ROOT_URL = https://git.example.com/` in your `app.ini` file.
|
||||||
2. Make the reverse-proxy pass `https://git.example.com/foo` to `http://gitea:3000/foo`.
|
2. Make the reverse-proxy pass `https://git.example.com/foo` to `http://gitea:3000/foo`.
|
||||||
3. Make sure the reverse-proxy does not decode the URI. The request `https://git.example.com/a%2Fb` should be passed as `http://gitea:3000/a%2Fb`.
|
3. Make sure the reverse-proxy does not decode the URI. The request `https://git.example.com/a%2Fb` should be passed as `http://gitea:3000/a%2Fb`.
|
||||||
4. Make sure `Host` and `X-Fowarded-Proto` headers are correctly passed to Gitea to make Gitea see the real URL being visited.
|
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.
|
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.
|
||||||
|
|
||||||
### Use a sub-path
|
### Use a sub-path
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ server {
|
|||||||
location / {
|
location / {
|
||||||
client_max_body_size 512M;
|
client_max_body_size 512M;
|
||||||
proxy_pass http://localhost:3000;
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Connection $http_connection;
|
proxy_set_header Connection $http_connection;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -67,6 +69,7 @@ server {
|
|||||||
rewrite ^ $request_uri;
|
rewrite ^ $request_uri;
|
||||||
rewrite ^/(gitea($|/))?(.*) /$3 break;
|
rewrite ^/(gitea($|/))?(.*) /$3 break;
|
||||||
proxy_pass http://127.0.0.1:3000$uri;
|
proxy_pass http://127.0.0.1:3000$uri;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
# other common HTTP headers, see the "Nginx" config section above
|
# other common HTTP headers, see the "Nginx" config section above
|
||||||
proxy_set_header Connection $http_connection;
|
proxy_set_header Connection $http_connection;
|
||||||
@@ -113,6 +116,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
# other directives, see the "Nginx" config section above
|
||||||
proxy_pass http://localhost:3000;
|
proxy_pass http://localhost:3000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,6 +133,7 @@ server {
|
|||||||
server_name git.example.com;
|
server_name git.example.com;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
# other directives, see the "Nginx" config section above
|
||||||
proxy_pass http://localhost:3000;
|
proxy_pass http://localhost:3000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,14 +161,14 @@ If you are using Nginx Proxy Manager to serve your Gitea instance it differs sli
|
|||||||
|
|
||||||
It is [adding some directives](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf) for a custom location by default, so you have to skip these from the above mentioned Nginx config. Otherwise Nginx will produce `400 bad request` error due to duplicated directives (`proxy_set_header Host $host` is the particularly problematic one).
|
It is [adding some directives](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/docker/rootfs/etc/nginx/conf.d/include/proxy.conf) for a custom location by default, so you have to skip these from the above mentioned Nginx config. Otherwise Nginx will produce `400 bad request` error due to duplicated directives (`proxy_set_header Host $host` is the particularly problematic one).
|
||||||
|
|
||||||
So while creating the `/` Custom location, just add the following lines to it's configuration:
|
So while creating the `/` Custom location, just add the following line to it's configuration:
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
client_max_body_size 512M;
|
client_max_body_size 512M;
|
||||||
proxy_set_header Connection $http_connection;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Enable `Websockets Support` on the proxy host, Nginx Proxy Manager then adds the WebSocket directives itself. Adding `proxy_http_version` on top of that makes Nginx refuse to start.
|
||||||
|
|
||||||
## Apache HTTPD
|
## Apache HTTPD
|
||||||
|
|
||||||
If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
|
If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
|
||||||
@@ -174,13 +179,15 @@ If you want Apache HTTPD to serve your Gitea instance, you can add the following
|
|||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
ProxyRequests off
|
ProxyRequests off
|
||||||
AllowEncodedSlashes NoDecode
|
AllowEncodedSlashes NoDecode
|
||||||
ProxyPass / http://localhost:3000/ nocanon
|
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
|
||||||
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`.
|
The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`.
|
||||||
|
|
||||||
|
`upgrade=websocket` requires Apache HTTPD 2.4.48 or later. On older versions you **MUST** remove it, otherwise Apache HTTPD will not start.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
If you wish to use Let's Encrypt with webroot validation, add the line `ProxyPass /.well-known !` before `ProxyPass` to disable proxying these requests to Gitea.
|
If you wish to use Let's Encrypt with webroot validation, add the line `ProxyPass /.well-known !` before `ProxyPass` to disable proxying these requests to Gitea.
|
||||||
@@ -198,7 +205,7 @@ In case you already have a site, and you want Gitea to share the domain name, yo
|
|||||||
</Proxy>
|
</Proxy>
|
||||||
AllowEncodedSlashes NoDecode
|
AllowEncodedSlashes NoDecode
|
||||||
# Note: no trailing slash after either /git or port
|
# Note: no trailing slash after either /git or port
|
||||||
ProxyPass /git http://localhost:3000 nocanon
|
ProxyPass /git http://localhost:3000 nocanon upgrade=websocket
|
||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
@@ -207,7 +214,7 @@ In case you already have a site, and you want Gitea to share the domain name, yo
|
|||||||
Then you **MUST** set something like `[server] ROOT_URL = http://git.example.com/git/` correctly in your configuration.
|
Then you **MUST** set something like `[server] ROOT_URL = http://git.example.com/git/` correctly in your configuration.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`.
|
The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`. `upgrade=websocket` requires Apache HTTPD 2.4.48 or later, remove it on older versions.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Apache HTTPD and serve static resources directly
|
## Apache HTTPD and serve static resources directly
|
||||||
@@ -248,12 +255,16 @@ Set `[server] STATIC_URL_PREFIX = /_/static` in your configuration.
|
|||||||
|
|
||||||
AllowEncodedSlashes NoDecode
|
AllowEncodedSlashes NoDecode
|
||||||
# Note: no trailing slash after either /git or port
|
# Note: no trailing slash after either /git or port
|
||||||
ProxyPass / http://localhost:3000/ nocanon
|
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
|
||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`. `upgrade=websocket` requires Apache HTTPD 2.4.48 or later, remove it on older versions.
|
||||||
|
:::
|
||||||
|
|
||||||
## Caddy
|
## Caddy
|
||||||
|
|
||||||
If you want Caddy to serve your Gitea instance, you can add the following server block to your Caddyfile:
|
If you want Caddy to serve your Gitea instance, you can add the following server block to your Caddyfile:
|
||||||
@@ -288,11 +299,13 @@ If you wish to run Gitea with IIS. You will need to setup IIS with URL Rewrite a
|
|||||||
|
|
||||||
- Install Application Request Routing (ARR for short) either by using the Microsoft Web Platform Installer 5.1 (WebPI) or downloading the extension from [IIS.net](https://www.iis.net/downloads/microsoft/application-request-routing)
|
- Install Application Request Routing (ARR for short) either by using the Microsoft Web Platform Installer 5.1 (WebPI) or downloading the extension from [IIS.net](https://www.iis.net/downloads/microsoft/application-request-routing)
|
||||||
- Once the module is installed in IIS, you will see a new Icon in the IIS Administration Console called URL Rewrite.
|
- Once the module is installed in IIS, you will see a new Icon in the IIS Administration Console called URL Rewrite.
|
||||||
|
- Install the `WebSocket Protocol` Windows feature, otherwise ARR cannot proxy Gitea's WebSocket endpoint.
|
||||||
- Open the IIS Manager Console and click on the `Gitea Proxy` Website from the tree view on the left. Select and double click the URL Rewrite Icon from the middle pane to load the URL Rewrite interface.
|
- Open the IIS Manager Console and click on the `Gitea Proxy` Website from the tree view on the left. Select and double click the URL Rewrite Icon from the middle pane to load the URL Rewrite interface.
|
||||||
- Choose the `Add Rule` action from the right pane of the management console and select the `Reverse Proxy Rule` from the `Inbound and Outbound Rules` category.
|
- Choose the `Add Rule` action from the right pane of the management console and select the `Reverse Proxy Rule` from the `Inbound and Outbound Rules` category.
|
||||||
- In the Inbound Rules section, set the server name to be the host that Gitea is running on with its port. e.g. if you are running Gitea on the localhost with port 3000, the following should work: `127.0.0.1:3000`
|
- In the Inbound Rules section, set the server name to be the host that Gitea is running on with its port. e.g. if you are running Gitea on the localhost with port 3000, the following should work: `127.0.0.1:3000`
|
||||||
- Enable SSL Offloading
|
- Enable SSL Offloading
|
||||||
- In the Outbound Rules, ensure `Rewrite the domain names of the links in HTTP response` is set and set the `From:` field as above and the `To:` to your external hostname, say: `git.example.com`
|
- In the Outbound Rules, ensure `Rewrite the domain names of the links in HTTP response` is set and set the `From:` field as above and the `To:` to your external hostname, say: `git.example.com`
|
||||||
|
- Turn `Reverse rewrite host in response headers` off, in the `Server Proxy Settings` of Application Request Routing (select the server node in the IIS Manager, open `Application Request Routing Cache`, then `Server Proxy Settings` in the right pane). While it is on, ARR rewrites the host of the `Location` header back to the internal one, so the redirects Gitea sends after a sign-in or a form submission send the browser to `127.0.0.1:3000` instead of `git.example.com`.
|
||||||
- Now edit the `web.config` for your website to match the following: (changing `127.0.0.1:3000` and `git.example.com` as appropriate)
|
- Now edit the `web.config` for your website to match the following: (changing `127.0.0.1:3000` and `git.example.com` as appropriate)
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ then the config file (app.ini) should exists in the "custom/conf" directory of y
|
|||||||
Some package vendors might use "/etc/gitea" to store the config file, while some others don't.
|
Some package vendors might use "/etc/gitea" to store the config file, while some others don't.
|
||||||
|
|
||||||
You could manually find the config file (app.ini) by checking Gitea's startup logs
|
You could manually find the config file (app.ini) by checking Gitea's startup logs
|
||||||
or reading the Gitea Web's Site Administrator -> Confugiraton Summary.
|
or reading the Gitea Web's Site Administrator -> Configuration Summary.
|
||||||
|
|
||||||
If you are using some isolated enviroments like container (docker),
|
If you are using some isolated enviroments like container (docker),
|
||||||
the path you see usually is not what it is in the host's filesystem.
|
the path you see usually is not what it is in the host's filesystem.
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ You can try it out using [the online demo](https://demo.gitea.com).
|
|||||||
|
|
||||||
- **Security**
|
- **Security**
|
||||||
|
|
||||||
Gitea places a strong emphasis on security, offering features such as user permission management, access control lists, and more to ensure the security of code and data.
|
Gitea places a strong emphasis on security, offering features such as user permission management, access control lists, [audit logging](administration/audit-logging.md), and more to ensure the security of code and data.
|
||||||
|
|
||||||
- **Code Review**
|
- **Code Review**
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ _Symbols used in table:_
|
|||||||
| Telemetry | **✘** | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Telemetry | **✘** | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
|
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
|
||||||
| WebAuthn (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
| WebAuthn (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||||
|
| Audit log | ✓ | ✓ | ⁄ | ✓ | ✓ | ? | ? |
|
||||||
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Built-in Package/Container Registry | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ |
|
| Built-in Package/Container Registry | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ |
|
||||||
| Sync commits to an external repo (push mirror) | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ | ✓ |
|
| Sync commits to an external repo (push mirror) | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ | ✓ |
|
||||||
|
|||||||
@@ -40,7 +40,24 @@ chmod +x gitea
|
|||||||
|
|
||||||
Note that the above command will download Gitea @version@ for 64-bit Linux.
|
Note that the above command will download Gitea @version@ for 64-bit Linux.
|
||||||
|
|
||||||
## Verify GPG signature
|
## Verify signature
|
||||||
|
|
||||||
|
### Sigstore
|
||||||
|
|
||||||
|
Starting with v1.27 Gitea signs all binaries using [sigstore](https://sigstore.dev/) to prevent against unwanted modification of binaries.
|
||||||
|
To validate the binary, download the bundle file which ends in `sigstore.json` for the binary you downloaded and use the [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) command line tool.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cosign verify-blob gitea-@version@-linux-amd64 --bundle gitea-@version@-linux-amd64.sigstore.json --certificate-oidc-issuer=https://token.actions.githubusercontent.com --certificate-identity-regexp="https://github.com/go-gitea/gitea/.github/workflows/release-.*"
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command outputs `Verified OK`, binary was not modified.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
The above command will match any release workflow. You may choose to restrict the identity further by requiring a specific branch or workflow to be matched. For example this url will match only nightly builds made on main branch: `https://github.com/go-gitea/gitea/.github/workflows/release-nightly.yml@refs/heads/main`
|
||||||
|
:::
|
||||||
|
|
||||||
|
### GPG
|
||||||
|
|
||||||
Gitea signs all binaries with a [GPG key](https://keys.openpgp.org/search?q=teabot%40gitea.io) to prevent against unwanted modification of binaries.
|
Gitea signs all binaries with a [GPG key](https://keys.openpgp.org/search?q=teabot%40gitea.io) to prevent against unwanted modification of binaries.
|
||||||
To validate the binary, download the signature file which ends in `.asc` for the binary you downloaded and use the GPG command line tool.
|
To validate the binary, download the signature file which ends in `.asc` for the binary you downloaded and use the GPG command line tool.
|
||||||
@@ -53,6 +70,7 @@ gpg --verify gitea-@[email protected] gitea-@version@-linux-amd64
|
|||||||
Look for the text `Good signature from "Teabot <[email protected]>"` to assert a good binary,
|
Look for the text `Good signature from "Teabot <[email protected]>"` to assert a good binary,
|
||||||
despite warnings like `This key is not certified with a trusted signature!`.
|
despite warnings like `This key is not certified with a trusted signature!`.
|
||||||
|
|
||||||
|
|
||||||
## Recommended server configuration
|
## Recommended server configuration
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
@@ -153,6 +171,13 @@ Supported values for `<shell>` are `bash`, `fish`, `pwsh` and `zsh`. Details on
|
|||||||
|
|
||||||
After you complete the above steps, you can run Gitea two ways:
|
After you complete the above steps, you can run Gitea two ways:
|
||||||
|
|
||||||
|
:::note
|
||||||
|
On a distribution with SELinux in enforcing mode (Fedora, RHEL, CentOS Stream,
|
||||||
|
Rocky Linux, AlmaLinux and others), the binary and the data directory need
|
||||||
|
labels the default policy does not give them, and binding to a port below 1024
|
||||||
|
takes an extra step. See [running Gitea with SELinux](selinux.md).
|
||||||
|
:::
|
||||||
|
|
||||||
### 1. Creating a service file to start Gitea automatically (recommended)
|
### 1. Creating a service file to start Gitea automatically (recommended)
|
||||||
|
|
||||||
See how to create [Linux service](installation/run-as-service-in-ubuntu.md)
|
See how to create [Linux service](installation/run-as-service-in-ubuntu.md)
|
||||||
@@ -214,9 +239,7 @@ As of v1.8, there is a problem with the arm7 version of Gitea, and it doesn't ru
|
|||||||
|
|
||||||
It is recommended to switch to the arm6 version, which has been tested and shown to work on Raspberry Pis and similar devices.
|
It is recommended to switch to the arm6 version, which has been tested and shown to work on Raspberry Pis and similar devices.
|
||||||
|
|
||||||
<!---
|
{/* please remove after fixing the arm7 bug */}
|
||||||
please remove after fixing the arm7 bug
|
|
||||||
--->
|
|
||||||
### Git error after updating to a new version of Gitea
|
### Git error after updating to a new version of Gitea
|
||||||
|
|
||||||
If during the update, the binary file name has been changed to a new version of Gitea,
|
If during the update, the binary file name has been changed to a new version of Gitea,
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ aliases:
|
|||||||
- /en-us/install-from-source
|
- /en-us/install-from-source
|
||||||
---
|
---
|
||||||
|
|
||||||
|
:::warning This document is outdated, pleaes refer to [build-source.md](https://github.com/go-gitea/gitea/tree/main/docs/build-source.md):::
|
||||||
|
|
||||||
# Installation from source
|
# Installation from source
|
||||||
|
|
||||||
You should [install go](https://go.dev/doc/install) and set up your go
|
You should [install go](https://go.dev/doc/install) and set up your go
|
||||||
@@ -21,7 +23,7 @@ version is @minNodeVersion@ and the latest LTS version is recommended.
|
|||||||
:::note
|
:::note
|
||||||
Go version @minGoVersion@ or higher is required. However, it is recommended to
|
Go version @minGoVersion@ or higher is required. However, it is recommended to
|
||||||
obtain the same version as our continuous integration, see the advice given in
|
obtain the same version as our continuous integration, see the advice given in
|
||||||
[Hacking on Gitea](development/hacking-on-gitea.md)
|
[Hacking on Gitea](https://github.com/go-gitea/gitea/blob/main/docs/build-setup.md)
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
@@ -71,7 +73,7 @@ To build from source, the following programs must be present on the system:
|
|||||||
|
|
||||||
- `go` @minGoVersion@ or higher, see [here](https://go.dev/dl/)
|
- `go` @minGoVersion@ or higher, see [here](https://go.dev/dl/)
|
||||||
- `node` @minNodeVersion@ or higher with `npm`, see [here](https://nodejs.org/en/download/)
|
- `node` @minNodeVersion@ or higher with `npm`, see [here](https://nodejs.org/en/download/)
|
||||||
- `make`, see [here](development/hacking-on-gitea.md#installing-make)
|
- `make`, see [here](https://github.com/go-gitea/gitea/blob/main/docs/build-setup.md#make)
|
||||||
|
|
||||||
Various [make tasks](https://github.com/go-gitea/gitea/blob/main/Makefile)
|
Various [make tasks](https://github.com/go-gitea/gitea/blob/main/Makefile)
|
||||||
are provided to keep the build process as simple as possible.
|
are provided to keep the build process as simple as possible.
|
||||||
@@ -125,6 +127,12 @@ launched manually from command line, it can be killed by pressing `Ctrl + C`.
|
|||||||
./gitea web
|
./gitea web
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
A binary built this way carries no SELinux label of its own. On a distribution
|
||||||
|
with SELinux in enforcing mode, see
|
||||||
|
[running Gitea with SELinux](selinux.md) before installing it as a service.
|
||||||
|
:::
|
||||||
|
|
||||||
## Changing default paths
|
## Changing default paths
|
||||||
|
|
||||||
Gitea will search for a number of things from the _`CustomPath`_. By default this is
|
Gitea will search for a number of things from the _`CustomPath`_. By default this is
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
---
|
|
||||||
date: "2016-12-01T16:00:00+02:00"
|
|
||||||
slug: "install-on-cloud-provider"
|
|
||||||
sidebar_position: 90
|
|
||||||
aliases:
|
|
||||||
- /en-us/install-on-cloud-provider
|
|
||||||
---
|
|
||||||
|
|
||||||
# Installation on Cloud Provider
|
|
||||||
|
|
||||||
## Cloudron
|
|
||||||
|
|
||||||
Gitea is available as a 1-click install on [Cloudron](https://cloudron.io).
|
|
||||||
Cloudron makes it easy to run apps like Gitea on your server and keep them up-to-date and secure.
|
|
||||||
|
|
||||||
[](https://cloudron.io/button.html?app=io.gitea.cloudronapp)
|
|
||||||
|
|
||||||
The Gitea package is maintained [here](https://git.cloudron.io/cloudron/gitea-app).
|
|
||||||
|
|
||||||
There is a [demo instance](https://my.demo.cloudron.io) (username: cloudron password: cloudron) where
|
|
||||||
you can experiment with running Gitea.
|
|
||||||
|
|
||||||
## Linode
|
|
||||||
|
|
||||||
[Linode](https://www.linode.com/) has Gitea as an app in their marketplace.
|
|
||||||
|
|
||||||
To deploy Gitea to Linode, have a look at the [Linode Marketplace](https://www.linode.com/marketplace/apps/linode/gitea/).
|
|
||||||
|
|
||||||
## alwaysdata
|
|
||||||
|
|
||||||
[alwaysdata](https://www.alwaysdata.com/) has Gitea as an app in their marketplace.
|
|
||||||
|
|
||||||
To deploy Gitea to alwaysdata, have a look at the [alwaysdata Marketplace](https://www.alwaysdata.com/en/marketplace/gitea/).
|
|
||||||
|
|
||||||
## Exoscale
|
|
||||||
|
|
||||||
[Exoscale](https://www.exoscale.com/) provides Gitea managed by [Glasskube](https://glasskube.eu/) in their marketplace.
|
|
||||||
|
|
||||||
Exoscale is a European cloud service provider.
|
|
||||||
|
|
||||||
The package is maintained and update via the open source [Glasskube Kubernetes Operator](https://github.com/glasskube/operator).
|
|
||||||
|
|
||||||
To deploy Gitea to Exoscale, have a look at the [Exoscale Marketplace](https://www.exoscale.com/marketplace/listing/glasskube-gitea/).
|
|
||||||
@@ -12,7 +12,7 @@ You can run Gitea as a Linux service, using either systemd or supervisor. The st
|
|||||||
|
|
||||||
## Using systemd
|
## Using systemd
|
||||||
|
|
||||||
Copy the sample [gitea.service](https://github.com/go-gitea/gitea/blob/main/contrib/systemd/gitea.service) to `/etc/systemd/system/gitea.service`, then edit the file with your favorite editor.
|
Copy the sample [gitea.service](https://github.com/go-gitea/gitea/blob/main/contrib/service/systemd/gitea.service) to `/etc/systemd/system/gitea.service`, then edit the file with your favorite editor.
|
||||||
|
|
||||||
Uncomment any service that needs to be enabled on this host, such as MySQL.
|
Uncomment any service that needs to be enabled on this host, such as MySQL.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ mkdir /home/git/gitea/log/supervisor
|
|||||||
```
|
```
|
||||||
|
|
||||||
Append the configuration from the sample
|
Append the configuration from the sample
|
||||||
[supervisord config](https://github.com/go-gitea/gitea/blob/main/contrib/supervisor/gitea) to `/etc/supervisor/supervisord.conf`.
|
[supervisord config](https://github.com/go-gitea/gitea/blob/main/contrib/service/supervisor/gitea) to `/etc/supervisor/supervisord.conf`.
|
||||||
|
|
||||||
Using your favorite editor, change the user (`git`) and home
|
Using your favorite editor, change the user (`git`) and home
|
||||||
(`/home/git`) settings to match the deployment environment. Change the PORT
|
(`/home/git`) settings to match the deployment environment. Change the PORT
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
---
|
||||||
|
date: "2026-08-13T00:00:00+00:00"
|
||||||
|
slug: "selinux"
|
||||||
|
sidebar_position: 45
|
||||||
|
---
|
||||||
|
|
||||||
|
# Running Gitea with SELinux
|
||||||
|
|
||||||
|
Distributions such as Fedora, RHEL, CentOS Stream, Rocky Linux and AlmaLinux
|
||||||
|
ship SELinux in enforcing mode. Packages from a distribution repository come
|
||||||
|
with a policy that fits them, but an installation
|
||||||
|
[from binary](from-binary.md) or [from source](from-source.md) puts the binary
|
||||||
|
and the data in paths the policy knows nothing about, so the labels have to be
|
||||||
|
set by hand. The same applies to any other distribution where SELinux is
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
Do not turn SELinux off to work around the problems below. `setenforce 0` is
|
||||||
|
useful to confirm that a failure really comes from SELinux, but switch it back
|
||||||
|
on with `setenforce 1` afterwards.
|
||||||
|
|
||||||
|
## Binding to a port below 1024
|
||||||
|
|
||||||
|
Gitea should not run as root, and an unprivileged process may not bind to a
|
||||||
|
port below 1024. Granting the capability to the binary with
|
||||||
|
`setcap 'cap_net_bind_service=+ep' /usr/local/bin/gitea` is often suggested,
|
||||||
|
but it is the least robust option:
|
||||||
|
|
||||||
|
- file capabilities are stored in an extended attribute of the binary, so they
|
||||||
|
are lost every time the binary is replaced, which happens on every upgrade.
|
||||||
|
- the SELinux policy has to allow the capability for the label of the binary,
|
||||||
|
and a binary in a path such as `/opt` usually does not carry a label that
|
||||||
|
allows it.
|
||||||
|
|
||||||
|
Let systemd grant the capability to the process instead. It works with SELinux
|
||||||
|
in enforcing mode and survives upgrades, the sample unit file has the two lines
|
||||||
|
commented out:
|
||||||
|
|
||||||
|
```ini title="/etc/systemd/system/gitea.service"
|
||||||
|
[Service]
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload and restart the service afterwards:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl restart gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
If the capability still does not reach the process, add `PrivateUsers=false` to
|
||||||
|
the unit: the sandboxing runs the service in a user namespace where the
|
||||||
|
capability does not apply to the host.
|
||||||
|
|
||||||
|
Two alternatives avoid the privileged port altogether, and are what most
|
||||||
|
installations end up doing:
|
||||||
|
|
||||||
|
- put a [reverse proxy](../administration/reverse-proxies.md) in front of Gitea
|
||||||
|
and let it own ports `80` and `443`.
|
||||||
|
- redirect the port in the firewall, for example with
|
||||||
|
`firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=3000`.
|
||||||
|
|
||||||
|
## Labelling the binary and the data directory
|
||||||
|
|
||||||
|
If Gitea starts but cannot read its own files, or fails in ways that are not
|
||||||
|
explained by the file permissions, the labels are usually wrong. The tools come
|
||||||
|
from the `policycoreutils-python-utils` package.
|
||||||
|
|
||||||
|
Label the binary as an executable and the data directory as application state:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo semanage fcontext -a -t bin_t '/usr/local/bin/gitea'
|
||||||
|
sudo restorecon -v /usr/local/bin/gitea
|
||||||
|
|
||||||
|
sudo semanage fcontext -a -t var_lib_t '/var/lib/gitea(/.*)?'
|
||||||
|
sudo restorecon -Rv /var/lib/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
`semanage fcontext` records the rule, `restorecon` applies it to the files that
|
||||||
|
are already there. Use the two together rather than `chcon`, whose labels are
|
||||||
|
reverted by the next relabel of the file system.
|
||||||
|
|
||||||
|
Adjust the paths if the installation does not follow
|
||||||
|
[installation from binary](from-binary.md); the configuration in `/etc/gitea`
|
||||||
|
is read with the label distributions give to `/etc`, so it normally needs
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
## Finding out what was denied
|
||||||
|
|
||||||
|
SELinux denials are written to the audit log, not to the Gitea log, so a
|
||||||
|
failure often looks like a permission problem without any further explanation:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ausearch -m AVC -c gitea --start recent
|
||||||
|
```
|
||||||
|
|
||||||
|
If a denial shows up that the rules above do not cover, turn it into a local
|
||||||
|
policy module. Read what it allows before installing it, `audit2allow` writes
|
||||||
|
down whatever was denied, including the things that were denied for a good
|
||||||
|
reason:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ausearch -c gitea --raw | audit2allow -M gitea-local
|
||||||
|
cat gitea-local.te
|
||||||
|
sudo semodule -i gitea-local.pp
|
||||||
|
```
|
||||||
|
|
||||||
|
If the denials point at a path Gitea should not be using at all, fix the path
|
||||||
|
instead of allowing the access.
|
||||||
@@ -8,15 +8,19 @@ aliases:
|
|||||||
|
|
||||||
# Installation with Docker (rootless)
|
# Installation with Docker (rootless)
|
||||||
|
|
||||||
Gitea provides automatically updated Docker images within its Docker Hub organization. It is
|
## Relation to rootful image
|
||||||
possible to always use the latest stable tag or to use another service that handles updating
|
|
||||||
Docker images.
|
|
||||||
|
|
||||||
The rootless image uses Gitea internal SSH to provide Git protocol and doesn't support OpenSSH.
|
* Rootless image doesn't require "root" privilege on the host, while it may have stricter UID/GID requirement.
|
||||||
|
* Rootless image must use its bulitin SSH server, while the rootful one must its managed standalone OpenSSH server.
|
||||||
|
* The volume mapping and directory layout is different between them.
|
||||||
|
|
||||||
This reference setup guides users through the setup based on `docker-compose`, but the installation
|
Except the differences above, the rootless image shares the same mechanism with rootful image,
|
||||||
of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself, follow
|
including: port mapping, custimzation, upgrading, environment variables, etc.
|
||||||
the official [install instructions](https://docs.docker.com/compose/install/).
|
Read more in "[Installation with Docker (rootful)](./with-docker.md)"
|
||||||
|
|
||||||
|
ATTENTION: the rootful/rootless images are not compatible with the other.
|
||||||
|
If you have chosen one, you should always use the same one,
|
||||||
|
don't switch to the other one by changing the compose file's `image` value.
|
||||||
|
|
||||||
## Basics
|
## Basics
|
||||||
|
|
||||||
@@ -34,8 +38,6 @@ touch docker-compose.yml
|
|||||||
Then paste the following content into a file named `docker-compose.yml`:
|
Then paste the following content into a file named `docker-compose.yml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "2"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
server:
|
||||||
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
||||||
@@ -56,115 +58,15 @@ Note that the volume should be owned by the user/group with the UID/GID specifie
|
|||||||
sudo chown 1000:1000 config/ data/
|
sudo chown 1000:1000 config/ data/
|
||||||
```
|
```
|
||||||
|
|
||||||
> If you don't give the volume correct permissions, the container may not start.
|
> If you don't give the volume correct permissions, the container may present the following errors in the logs:
|
||||||
|
|
||||||
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly-rootless`)
|
```sh
|
||||||
|
server-1 | 2026-03-11T12:57:50.794102045Z mkdir: can't create directory '/var/lib/gitea/git': Permission denied
|
||||||
## Custom port
|
server-1 | 2026-03-11T12:57:50.796198843Z /var/lib/gitea/git is not writable
|
||||||
|
server-1 | 2026-03-11T12:57:50.796235667Z docker setup failed
|
||||||
To bind the integrated ssh and the webserver on a different port, adjust
|
|
||||||
the port section. It's common to just change the host port and keep the ports within
|
|
||||||
the container like they are.
|
|
||||||
|
|
||||||
```diff
|
|
||||||
version: "2"
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- ./data:/var/lib/gitea
|
|
||||||
- ./config:/etc/gitea
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
ports:
|
|
||||||
- - "3000:3000"
|
|
||||||
- - "2222:2222"
|
|
||||||
+ - "80:3000"
|
|
||||||
+ - "22:2222"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## MySQL database
|
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:@dockerVersion@-rootless`, but if you'd like to use the latest development version then `:main-nightly-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly-rootless`)
|
||||||
|
|
||||||
To start Gitea in combination with a MySQL database, apply these changes to the
|
|
||||||
`docker-compose.yml` file created above.
|
|
||||||
|
|
||||||
```diff
|
|
||||||
version: "2"
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
|
||||||
+ environment:
|
|
||||||
+ - GITEA__database__DB_TYPE=mysql
|
|
||||||
+ - GITEA__database__HOST=db:3306
|
|
||||||
+ - GITEA__database__NAME=gitea
|
|
||||||
+ - GITEA__database__USER=gitea
|
|
||||||
+ - GITEA__database__PASSWD=gitea
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- ./data:/var/lib/gitea
|
|
||||||
- ./config:/etc/gitea
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
- "2222:2222"
|
|
||||||
+ depends_on:
|
|
||||||
+ - db
|
|
||||||
+
|
|
||||||
+ db:
|
|
||||||
+ image: docker.io/library/mysql:8
|
|
||||||
+ restart: always
|
|
||||||
+ environment:
|
|
||||||
+ - MYSQL_ROOT_PASSWORD=gitea
|
|
||||||
+ - MYSQL_USER=gitea
|
|
||||||
+ - MYSQL_PASSWORD=gitea
|
|
||||||
+ - MYSQL_DATABASE=gitea
|
|
||||||
+ volumes:
|
|
||||||
+ - ./mysql:/var/lib/mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
## PostgreSQL database
|
|
||||||
|
|
||||||
To start Gitea in combination with a PostgreSQL database, apply these changes to
|
|
||||||
the `docker-compose.yml` file created above.
|
|
||||||
|
|
||||||
```diff
|
|
||||||
version: "2"
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
|
||||||
environment:
|
|
||||||
+ - GITEA__database__DB_TYPE=postgres
|
|
||||||
+ - GITEA__database__HOST=db:5432
|
|
||||||
+ - GITEA__database__NAME=gitea
|
|
||||||
+ - GITEA__database__USER=gitea
|
|
||||||
+ - GITEA__database__PASSWD=gitea
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- ./data:/var/lib/gitea
|
|
||||||
- ./config:/etc/gitea
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
- "2222:2222"
|
|
||||||
+ depends_on:
|
|
||||||
+ - db
|
|
||||||
+
|
|
||||||
+ db:
|
|
||||||
+ image: docker.io/library/postgres:14
|
|
||||||
+ restart: always
|
|
||||||
+ environment:
|
|
||||||
+ - POSTGRES_USER=gitea
|
|
||||||
+ - POSTGRES_PASSWORD=gitea
|
|
||||||
+ - POSTGRES_DB=gitea
|
|
||||||
+ volumes:
|
|
||||||
+ - ./postgres:/var/lib/postgresql/data
|
|
||||||
```
|
|
||||||
|
|
||||||
## Named volumes
|
## Named volumes
|
||||||
|
|
||||||
@@ -174,8 +76,6 @@ create the required volume. You don't need to worry about permissions with
|
|||||||
named volumes; Docker will deal with that automatically.
|
named volumes; Docker will deal with that automatically.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
version: "2"
|
|
||||||
|
|
||||||
+volumes:
|
+volumes:
|
||||||
+ gitea-data:
|
+ gitea-data:
|
||||||
+ driver: local
|
+ driver: local
|
||||||
@@ -207,8 +107,6 @@ As an example to clone the host user `git` definition use the command `id -u git
|
|||||||
Please make sure that the mounted folders are writable by the user.
|
Please make sure that the mounted folders are writable by the user.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
version: "2"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
server:
|
||||||
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
image: docker.gitea.com/gitea:@dockerVersion@-rootless
|
||||||
@@ -223,95 +121,3 @@ services:
|
|||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "2222:2222"
|
- "2222:2222"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Startup
|
|
||||||
|
|
||||||
:::note
|
|
||||||
From July 2023 Compose V1 stopped receiving updates. It's also no longer available in new releases of Docker Desktop.
|
|
||||||
|
|
||||||
Compose V2 is included with all currently supported versions of Docker Desktop. Please use V2 to do below operations.
|
|
||||||
:::
|
|
||||||
|
|
||||||
To start this setup based on `docker-compose`, execute `docker-compose up -d`,
|
|
||||||
to launch Gitea in the background. Using `docker-compose ps` will show if Gitea
|
|
||||||
started properly. Logs can be viewed with `docker-compose logs`.
|
|
||||||
|
|
||||||
To shut down the setup, execute `docker-compose down`. This will stop
|
|
||||||
and kill the containers. The volumes will still exist.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
If using a non-3000 port on http, change app.ini to match
|
|
||||||
`LOCAL_ROOT_URL = http://localhost:3000/`.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
After starting the Docker setup via `docker-compose`, Gitea should be available using a
|
|
||||||
favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the
|
|
||||||
installation wizard. If the database was started with the `docker-compose` setup as
|
|
||||||
documented above, please note that `db` must be used as the database hostname.
|
|
||||||
|
|
||||||
## Customization
|
|
||||||
|
|
||||||
Customization files described [here](../administration/customizing-gitea.md) should
|
|
||||||
be placed in `/var/lib/gitea/custom` directory. If using host volumes, it's quite easy to access these
|
|
||||||
files; for named volumes, this is done through another container or by direct access at
|
|
||||||
`/var/lib/docker/volumes/gitea_gitea/_/var_lib_gitea`. The configuration file will be saved at
|
|
||||||
`/etc/gitea/app.ini` after the installation.
|
|
||||||
|
|
||||||
## Upgrading
|
|
||||||
|
|
||||||
:::warning
|
|
||||||
:exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation:
|
|
||||||
:::
|
|
||||||
|
|
||||||
To upgrade your installation to the latest release:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Edit `docker-compose.yml` to update the version, if you have one specified
|
|
||||||
# Pull new images
|
|
||||||
docker-compose pull
|
|
||||||
# Start a new container, automatically removes old one
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## Upgrading from standard image
|
|
||||||
|
|
||||||
- Backup your setup
|
|
||||||
- Change volume mountpoint from /data to /var/lib/gitea
|
|
||||||
- If you used a custom app.ini move it to a new volume mounted to /etc/gitea
|
|
||||||
- Rename folder (inside volume) gitea to custom
|
|
||||||
- Edit app.ini if needed
|
|
||||||
- Set START_SSH_SERVER = true
|
|
||||||
- Use image docker.gitea.com/gitea:@dockerVersion@-rootless
|
|
||||||
|
|
||||||
## Managing Deployments With Environment Variables
|
|
||||||
|
|
||||||
In addition to the environment variables above, any settings in `app.ini` can be set
|
|
||||||
or overridden with an environment variable of the form: `GITEA__SECTION_NAME__KEY_NAME`.
|
|
||||||
These settings are applied each time the docker container starts, and won't be passed into Gitea's sub-processes.
|
|
||||||
Full information [here](https://github.com/go-gitea/gitea/tree/main/contrib/environment-to-ini).
|
|
||||||
|
|
||||||
These environment variables can be passed to the docker container in `docker-compose.yml`.
|
|
||||||
The following example will enable a smtp mail server if the required env variables
|
|
||||||
`GITEA__mailer__FROM`, `GITEA__mailer__HOST`, `GITEA__mailer__PASSWD` are set on the host
|
|
||||||
or in a `.env` file in the same directory as `docker-compose.yml`.
|
|
||||||
|
|
||||||
The settings can be also set or overridden with the content of a file by defining an environment variable of the form:
|
|
||||||
`GITEA__section_name__KEY_NAME__FILE` that points to a file.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
...
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
environment:
|
|
||||||
- GITEA__mailer__ENABLED=true
|
|
||||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
|
||||||
- GITEA__mailer__PROTOCOL=smtp
|
|
||||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
|
||||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
|
||||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
|
||||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
|
||||||
```
|
|
||||||
|
|
||||||
To set required TOKEN and SECRET values, consider using Gitea's built-in [generate utility functions](../administration/command-line.md#generate).
|
|
||||||
@@ -12,9 +12,16 @@ Gitea provides automatically updated Docker images within its Docker Hub organiz
|
|||||||
possible to always use the latest stable tag or to use another service that handles updating
|
possible to always use the latest stable tag or to use another service that handles updating
|
||||||
Docker images.
|
Docker images.
|
||||||
|
|
||||||
This reference setup guides users through the setup based on `docker-compose`, but the installation
|
This reference setup guides users through the setup based on `docker compose`.
|
||||||
of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself, follow
|
Docker compose has been included in the Docker Engine since the shift to Compose v2.
|
||||||
the official [install instructions](https://docs.docker.com/compose/install/).
|
If, for some reason, compose is not available on your system, follow the official [install instructions](https://docs.docker.com/compose/install/).
|
||||||
|
|
||||||
|
This document targets for the default rootful image. For the rootless image,
|
||||||
|
see "[Installation with Docker (rootless)](./with-docker-rootless.md)"
|
||||||
|
|
||||||
|
ATTENTION: the rootful/rootless images are not compatible with the other.
|
||||||
|
If you have chosen one, you should always use the same one,
|
||||||
|
don't switch to the other one by changing the compose file's `image` value.
|
||||||
|
|
||||||
## Basics
|
## Basics
|
||||||
|
|
||||||
@@ -23,11 +30,9 @@ image as a service. Since there is no database available, one can be initialized
|
|||||||
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
|
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
|
||||||
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
|
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
|
||||||
If you don't give the volume correct permissions, the container may not start.
|
If you don't give the volume correct permissions, the container may not start.
|
||||||
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly`)
|
For a stable release you can use `:latest`, `:1` or specify a certain release like `:@dockerVersion@`, but if you'd like to use the latest development version of Gitea then you could use the `:main-nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.27-nightly`)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "3"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
external: false
|
external: false
|
||||||
@@ -58,8 +63,6 @@ the port section. It's common to just change the host port and keep the ports wi
|
|||||||
the container like they are.
|
the container like they are.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
version: "3"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
external: false
|
external: false
|
||||||
@@ -93,8 +96,6 @@ To start Gitea in combination with a MySQL database, apply these changes to the
|
|||||||
`docker-compose.yml` file created above.
|
`docker-compose.yml` file created above.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
version: "3"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
external: false
|
external: false
|
||||||
@@ -143,9 +144,14 @@ services:
|
|||||||
To start Gitea in combination with a PostgreSQL database, apply these changes to
|
To start Gitea in combination with a PostgreSQL database, apply these changes to
|
||||||
the `docker-compose.yml` file created above.
|
the `docker-compose.yml` file created above.
|
||||||
|
|
||||||
```diff
|
:::note
|
||||||
version: "3"
|
The example pins a major version on purpose: PostgreSQL does not upgrade its data
|
||||||
|
directory on its own, moving to a newer major version later requires `pg_upgrade`
|
||||||
|
or a dump and restore. Start a new instance on the newest version Gitea supports,
|
||||||
|
see [database preparation](database-preparation.md) for the supported versions.
|
||||||
|
:::
|
||||||
|
|
||||||
|
```diff
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
external: false
|
external: false
|
||||||
@@ -176,7 +182,7 @@ services:
|
|||||||
+ - db
|
+ - db
|
||||||
+
|
+
|
||||||
+ db:
|
+ db:
|
||||||
+ image: docker.io/library/postgres:14
|
+ image: docker.io/library/postgres:18
|
||||||
+ restart: always
|
+ restart: always
|
||||||
+ environment:
|
+ environment:
|
||||||
+ - POSTGRES_USER=gitea
|
+ - POSTGRES_USER=gitea
|
||||||
@@ -185,7 +191,7 @@ services:
|
|||||||
+ networks:
|
+ networks:
|
||||||
+ - gitea
|
+ - gitea
|
||||||
+ volumes:
|
+ volumes:
|
||||||
+ - ./postgres:/var/lib/postgresql/data
|
+ - ./postgres:/var/lib/postgresql
|
||||||
```
|
```
|
||||||
|
|
||||||
## Named volumes
|
## Named volumes
|
||||||
@@ -196,8 +202,6 @@ create the required volume. You don't need to worry about permissions with
|
|||||||
named volumes; Docker will deal with that automatically.
|
named volumes; Docker will deal with that automatically.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
version: "3"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
external: false
|
external: false
|
||||||
@@ -227,17 +231,11 @@ MySQL or PostgreSQL containers will need to be created separately.
|
|||||||
|
|
||||||
## Startup
|
## Startup
|
||||||
|
|
||||||
:::note
|
To start this setup based on `docker compose`, execute `docker compose up -d`,
|
||||||
From July 2023 Compose V1 stopped receiving updates. It's also no longer available in new releases of Docker Desktop.
|
to launch Gitea in the background. Using `docker compose ps` will show if Gitea
|
||||||
|
started properly. Logs can be viewed with `docker compose logs`.
|
||||||
|
|
||||||
Compose V2 is included with all currently supported versions of Docker Desktop. Please use V2 to do below operations.
|
To shut down the setup, execute `docker compose down`. This will stop
|
||||||
:::
|
|
||||||
|
|
||||||
To start this setup based on `docker-compose`, execute `docker-compose up -d`,
|
|
||||||
to launch Gitea in the background. Using `docker-compose ps` will show if Gitea
|
|
||||||
started properly. Logs can be viewed with `docker-compose logs`.
|
|
||||||
|
|
||||||
To shut down the setup, execute `docker-compose down`. This will stop
|
|
||||||
and kill the containers. The volumes will still exist.
|
and kill the containers. The volumes will still exist.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
@@ -247,9 +245,9 @@ If using a non-3000 port on http, change app.ini to match
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
After starting the Docker setup via `docker-compose`, Gitea should be available using a
|
After starting the Docker setup via `docker compose`, Gitea should be available using a
|
||||||
favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the
|
favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the
|
||||||
installation wizard. If the database was started with the `docker-compose` setup as
|
installation wizard. If the database was started with the `docker compose` setup as
|
||||||
documented above, please note that `db` must be used as the database hostname.
|
documented above, please note that `db` must be used as the database hostname.
|
||||||
|
|
||||||
## Configure the user inside Gitea using environment variables
|
## Configure the user inside Gitea using environment variables
|
||||||
@@ -279,17 +277,18 @@ To upgrade your installation to the latest release:
|
|||||||
```bash
|
```bash
|
||||||
# Edit `docker-compose.yml` to update the version, if you have one specified
|
# Edit `docker-compose.yml` to update the version, if you have one specified
|
||||||
# Pull new images
|
# Pull new images
|
||||||
docker-compose pull
|
docker compose pull
|
||||||
# Start a new container, automatically removes old one
|
# Start a new container, automatically removes old one
|
||||||
docker-compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## Managing Deployments With Environment Variables
|
## Managing Deployments With Environment Variables
|
||||||
|
|
||||||
In addition to the environment variables above, any settings in `app.ini` can be set
|
In addition to the environment variables above, any settings in `app.ini` can be set
|
||||||
or overridden with an environment variable of the form: `GITEA__SECTION_NAME__KEY_NAME`.
|
or overridden with an environment variable of the form: `GITEA__section_name__KEY_NAME=value`.
|
||||||
These settings are applied each time the docker container starts, and won't be passed into Gitea's sub-processes.
|
These settings are applied each time the docker container starts by `environment-to-ini` command
|
||||||
Full information [here](https://github.com/go-gitea/gitea/tree/master/contrib/environment-to-ini).
|
(a warpper of `gitea config edit-ini`), and won't be passed into Gitea's sub-processes.
|
||||||
|
See `./gitea config edit-ini --help` for more details.
|
||||||
|
|
||||||
These environment variables can be passed to the docker container in `docker-compose.yml`.
|
These environment variables can be passed to the docker container in `docker-compose.yml`.
|
||||||
The following example will enable an smtp mail server if the required env variables
|
The following example will enable an smtp mail server if the required env variables
|
||||||
@@ -332,5 +331,6 @@ services:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### SSH with multiple IP addresses
|
### SSH with multiple IP addresses
|
||||||
|
|
||||||
This assumes that the host machine has more than one reachable IP address: `192.168.1.1` (host) `192.168.1.2` (gitea)
|
This assumes that the host machine has more than one reachable IP address: `192.168.1.1` (host) `192.168.1.2` (gitea)
|
||||||
On the host machine, configure SSHD in `/etc/ssh/sshd_config` to listen on one IP address `ListenAddress 192.168.1.1`. In the compose file the SSH port forwarding then needs to be changed to `"192.168.1.2:22:22"`. The port forwarding needs to be adjusted similarily for all other forwarded ports to avoid problems with DNS.
|
On the host machine, configure SSHD in `/etc/ssh/sshd_config` to listen on one IP address `ListenAddress 192.168.1.1`. In the compose file the SSH port forwarding then needs to be changed to `"192.168.1.2:22:22"`. The port forwarding needs to be adjusted similarily for all other forwarded ports to avoid problems with DNS.
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
---
|
||||||
|
date: "2026-09-03T20:00:00+02:00"
|
||||||
|
slug: "install-with-podman-quadlet"
|
||||||
|
sidebar_position: 65
|
||||||
|
aliases:
|
||||||
|
- /en-us/install-with-podman-quadlet
|
||||||
|
---
|
||||||
|
|
||||||
|
# Installation with Podman Quadlet
|
||||||
|
|
||||||
|
Similarly to [Docker](with-docker.md), [Podman](https://podman.io/) can be used to deploy Gitea.
|
||||||
|
|
||||||
|
This reference setup guides users through the setup based on Podman Quadlet.
|
||||||
|
Podman Quadlet is the native integration of Podman through systemd.
|
||||||
|
|
||||||
|
To learn more about Podman Quadlet, see [systemd units using Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
|
||||||
|
|
||||||
|
This setup installs the quadlets in `~/.config/containers/systemd/`, the directory for rootless quadlets, and uses the rootless images.
|
||||||
|
If you install them in a rootful directory such as `/etc/containers/systemd/`, use the rootful images instead.
|
||||||
|
|
||||||
|
## Basics
|
||||||
|
|
||||||
|
Since Podman v6.0 a single `gitea.quadlets` file can hold multiple quadlets separated by the `---` delimiter.
|
||||||
|
|
||||||
|
Paste the following content into a file named `gitea.quadlets`
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# FileName=gitea-data
|
||||||
|
[Volume]
|
||||||
|
VolumeName=gitea-data
|
||||||
|
---
|
||||||
|
# FileName=gitea-config
|
||||||
|
[Volume]
|
||||||
|
VolumeName=gitea-config
|
||||||
|
---
|
||||||
|
# FileName=gitea
|
||||||
|
[Container]
|
||||||
|
PublishPort=2222:2222
|
||||||
|
PublishPort=3000:3000
|
||||||
|
Image=docker.gitea.com/gitea:@dockerVersion@-rootless
|
||||||
|
ContainerName=gitea
|
||||||
|
Mount=type=volume,src=gitea-data.volume,destination=/var/lib/gitea
|
||||||
|
Mount=type=volume,src=gitea-config.volume,destination=/etc/gitea
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
# Start with the user session
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
You can run the installation command
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ podman quadlet install ./gitea.quadlets --application=gitea
|
||||||
|
/home/user/.config/containers/systemd/gitea/gitea-data.volume
|
||||||
|
/home/user/.config/containers/systemd/gitea/gitea-config.volume
|
||||||
|
/home/user/.config/containers/systemd/gitea/gitea.container
|
||||||
|
```
|
||||||
|
|
||||||
|
The `--application=gitea` flag allows us to tell podman to group the quadlets together, this can help for managing and organizing the quadlets files.
|
||||||
|
|
||||||
|
You can validate the quadlets are properly installed by looking at the list command
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ podman quadlet list
|
||||||
|
NAME UNIT NAME PATH ON DISK STATUS APPLICATION POD
|
||||||
|
gitea-config.volume gitea-config-volume.service /home/user/.config/containers/systemd/gitea/gitea-config.volume active/exited gitea
|
||||||
|
gitea-data.volume gitea-data-volume.service /home/user/.config/containers/systemd/gitea/gitea-data.volume active/exited gitea
|
||||||
|
gitea.container gitea.service /home/user/.config/containers/systemd/gitea/gitea.container failed/failed gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
You can start the application by running `systemctl --user start gitea` command.
|
||||||
|
|
||||||
|
`WantedBy=default.target` starts the service when the user session starts.
|
||||||
|
Rootless user services do not run without a session, so to start Gitea at boot, enable lingering for the user with `loginctl enable-linger $USER`.
|
||||||
|
|
||||||
|
## Databases
|
||||||
|
|
||||||
|
### PostgreSQL database
|
||||||
|
|
||||||
|
To start Gitea in combination with a PostgreSQL database, apply these changes to the
|
||||||
|
`gitea.quadlets` file created above.
|
||||||
|
|
||||||
|
To start Gitea with a database, we need to create a network, so the database and Gitea container can communicate.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
# FileName=gitea-data
|
||||||
|
[Volume]
|
||||||
|
VolumeName=gitea-data
|
||||||
|
---
|
||||||
|
# FileName=gitea-config
|
||||||
|
[Volume]
|
||||||
|
VolumeName=gitea-config
|
||||||
|
---
|
||||||
|
+ # FileName=gitea-postgres-data
|
||||||
|
+ [Volume]
|
||||||
|
+ VolumeName=gitea-postgres-data
|
||||||
|
+ ---
|
||||||
|
+ # FileName=gitea
|
||||||
|
+ [Network]
|
||||||
|
+ NetworkName=gitea
|
||||||
|
+ ---
|
||||||
|
+ # FileName=gitea-postgres
|
||||||
|
+ [Container]
|
||||||
|
+ Image=docker.io/library/postgres:18
|
||||||
|
+ ContainerName=gitea-postgres
|
||||||
|
+ Network=gitea.network
|
||||||
|
+ Mount=type=volume,src=gitea-postgres-data.volume,destination=/var/lib/postgresql
|
||||||
|
+ Environment=POSTGRES_USER=gitea
|
||||||
|
+ Environment=POSTGRES_PASSWORD=gitea
|
||||||
|
+ Environment=POSTGRES_DB=gitea
|
||||||
|
+
|
||||||
|
+ [Service]
|
||||||
|
+ Restart=always
|
||||||
|
+
|
||||||
|
+ [Install]
|
||||||
|
+ # Start with the user session
|
||||||
|
+ WantedBy=default.target
|
||||||
|
+ ---
|
||||||
|
# FileName=gitea
|
||||||
|
+ [Unit]
|
||||||
|
+ Requires=gitea-postgres.service
|
||||||
|
+ After=gitea-postgres.service
|
||||||
|
+
|
||||||
|
[Container]
|
||||||
|
PublishPort=2222:2222
|
||||||
|
PublishPort=3000:3000
|
||||||
|
Image=docker.gitea.com/gitea:@dockerVersion@-rootless
|
||||||
|
ContainerName=gitea
|
||||||
|
Mount=type=volume,src=gitea-data.volume,destination=/var/lib/gitea
|
||||||
|
Mount=type=volume,src=gitea-config.volume,destination=/etc/gitea
|
||||||
|
+ Network=gitea.network
|
||||||
|
+ Environment=GITEA__database__DB_TYPE=postgres
|
||||||
|
+ Environment=GITEA__database__HOST=gitea-postgres:5432
|
||||||
|
+ Environment=GITEA__database__NAME=gitea
|
||||||
|
+ Environment=GITEA__database__USER=gitea
|
||||||
|
+ Environment=GITEA__database__PASSWD=gitea
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
# Start with the user session
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
As systemd manages the container we can use `journalctl` to access the logs
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ journalctl --user --follow --unit=gitea.service
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:263:runWeb() [I] Starting Gitea on PID: 2
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:115:showWebStartupMessage() [I] Gitea version: 1.27.3 built with go1.26.7-X:jsonv2 : bindata, timetzdata,
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:116:showWebStartupMessage() [I] * RunMode: prod
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:117:showWebStartupMessage() [I] * AppPath: /usr/local/bin/gitea
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:118:showWebStartupMessage() [I] * WorkPath: /var/lib/gitea
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:119:showWebStartupMessage() [I] * CustomPath: /var/lib/gitea/custom
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:120:showWebStartupMessage() [I] * ConfigFile: /etc/gitea/app.ini
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:121:showWebStartupMessage() [I] Prepare to run install page
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:329:listen() [I] Listen: http://0.0.0.0:3000
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 cmd/web.go:333:listen() [I] AppURL(ROOT_URL): http://localhost:3000/
|
||||||
|
gitea[5967]: 2026/09/03 14:50:42 modules/graceful/server.go:52:NewServer() [I] Starting new Web server: tcp:0.0.0.0:3000 on PID: 2
|
||||||
|
```
|
||||||
@@ -10,13 +10,13 @@ aliases:
|
|||||||
|
|
||||||
# Protected branches
|
# 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
|
## Creating or editing a rule
|
||||||
|
|
||||||
1. Open the repository and select **Settings → Branches** (repository admin permission required).
|
1. Open the repository and select **Settings → Branches** (repository admin permission required).
|
||||||
2. Select **Add new rule** or **Edit** next to an existing rule.
|
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**.
|
4. Select **Save rule**.
|
||||||
|
|
||||||
The rule immediately applies to all matching branches, even if the branches are created in the future.
|
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.
|
- **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).
|
- **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.
|
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.
|
- **Disable force push** completely forbids rewriting history on the branch.
|
||||||
- **Enable force push** allows anyone who can push to also force push.
|
- **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
|
## Pull request merges and approvals
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
date: "2026-08-30T00:00:00+02:00"
|
||||||
|
slug: "artifacts"
|
||||||
|
sidebar_position: 70
|
||||||
|
---
|
||||||
|
|
||||||
|
# Artifacts
|
||||||
|
|
||||||
|
Workflow runs can store files such as test results, coverage reports, and build output as artifacts. Artifacts are uploaded by workflows, for example with [`actions/upload-artifact`](https://github.com/actions/upload-artifact), and appear on the run page after the upload completes.
|
||||||
|
|
||||||
|
## Previewing artifacts
|
||||||
|
|
||||||
|
Select an artifact on the run page to open its file browser and preview in the same tab. The preview identifies the originating run and attempt, and provides links back to that run and to download the complete artifact. Selecting files in the browser updates the preview in the same tab.
|
||||||
|
|
||||||
|
Artifact previews:
|
||||||
|
|
||||||
|
- require sign-in and access to the Actions run to open the preview page
|
||||||
|
- render text-based files, images (including SVG), and PDFs
|
||||||
|
- run HTML and JavaScript content in a sandboxed frame
|
||||||
|
|
||||||
|
Preview content is loaded through signed URLs that expire after one hour and do not require a session cookie. Reopen the preview page to obtain a fresh URL after it expires.
|
||||||
|
|
||||||
|
The file browser lists up to 2,000 files per artifact. Larger artifacts show a notice when the list is truncated.
|
||||||
|
|
||||||
|
Unsupported or oversized files can still be downloaded with the complete artifact.
|
||||||
|
|
||||||
|
## Instance configuration
|
||||||
|
|
||||||
|
Site administrators can limit the total artifact size that can be browsed or previewed with `ARTIFACT_PREVIEW_MAX_SIZE` in the `[actions]` section of `app.ini`. The default is 10 MiB. Set it to `0` to disable previews or `-1` to allow artifacts of any size.
|
||||||
|
|
||||||
|
The size of an individual previewed file is also limited by [`MAX_DISPLAY_FILE_SIZE`](../../administration/config-cheat-sheet.md#ui-ui) in the `[ui]` section.
|
||||||
@@ -6,123 +6,94 @@ sidebar_position: 120
|
|||||||
|
|
||||||
# Compared to GitHub Actions
|
# Compared to GitHub Actions
|
||||||
|
|
||||||
Even though Gitea Actions is designed to be compatible with GitHub Actions, there are some differences between them.
|
Gitea Actions is designed to be compatible with GitHub Actions, with the differences below.
|
||||||
|
|
||||||
## Additional features
|
## Additional features
|
||||||
|
|
||||||
### Absolute action URLs
|
### Absolute action URLs
|
||||||
|
|
||||||
Gitea Actions supports defining actions via absolute URL, which means that you can use actions from any git repository.
|
`uses:` accepts an absolute URL to any git host, e.g. `uses: https://gitea.com/actions/checkout@v4`.
|
||||||
Like `uses: https://github.com/actions/checkout@v4` or `uses: http://your_gitea.com/owner/repo@branch`.
|
|
||||||
|
### Action prefixes
|
||||||
|
|
||||||
|
`uses:` accepts these prefixes:
|
||||||
|
|
||||||
|
- `self:` references your own Gitea instance, e.g. `uses: self:owner/repo@v1` or `uses: self:owner/repo/.gitea/workflows/build.yml@v1`
|
||||||
|
- `builtin:` runs an action built into Gitea Runner, which needs no download and no Node in the job image, e.g. `uses: builtin:checkout`
|
||||||
|
|
||||||
|
`builtin:checkout` accepts the `repository`, `ref`, `token`, `path` and `fetch-depth` inputs of `actions/checkout` with the same defaults, and fails on any other input.
|
||||||
|
|
||||||
|
### Workflow-relative actions
|
||||||
|
|
||||||
|
`$/` references the repository and commit of the workflow, or of the enclosing composite action, e.g. `uses: $/.gitea/actions/build`.
|
||||||
|
Unlike `./`, it needs no checkout first.
|
||||||
|
|
||||||
### Actions written in Go
|
### Actions written in Go
|
||||||
|
|
||||||
Gitea Actions supports writing actions in Go.
|
|
||||||
See [Creating Go Actions](https://blog.gitea.com/creating-go-actions/).
|
See [Creating Go Actions](https://blog.gitea.com/creating-go-actions/).
|
||||||
|
|
||||||
### Support the non-standard syntax @yearly, @monthly, @weekly, @daily, @hourly on schedule
|
### Support the non-standard syntax @yearly, @monthly, @weekly, @daily, @hourly on schedule
|
||||||
|
|
||||||
Github Actions doesn't support that. https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
|
`schedule` also accepts `@yearly`, `@monthly`, `@weekly`, `@daily` and `@hourly`, which [GitHub does not](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule).
|
||||||
|
|
||||||
## Unsupported workflows syntax
|
## Unsupported workflows syntax
|
||||||
|
|
||||||
### `concurrency`
|
|
||||||
|
|
||||||
It's used to run a single job at a time.
|
|
||||||
See [Using concurrency](https://docs.github.com/en/actions/using-jobs/using-concurrency).
|
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### `permissions` and `jobs.<job_id>.permissions`
|
|
||||||
|
|
||||||
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions).
|
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### `jobs.<job_id>.timeout-minutes`
|
|
||||||
|
|
||||||
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes).
|
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### `jobs.<job_id>.continue-on-error`
|
|
||||||
|
|
||||||
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error).
|
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### `jobs.<job_id>.environment`
|
### `jobs.<job_id>.environment`
|
||||||
|
|
||||||
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idenvironment).
|
[`jobs.<job_id>.environment`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idenvironment) is ignored.
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### Complex `runs-on`
|
### Complex `runs-on`
|
||||||
|
|
||||||
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on).
|
[`runs-on`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on) supports:
|
||||||
|
|
||||||
Gitea Actions only supports `runs-on: xyz` or `runs-on: [xyz]` now.
|
- Static strings: `runs-on: self-hosted`
|
||||||
|
- Arrays of labels: `runs-on: [linux, self-hosted]`
|
||||||
|
- String expressions: `runs-on: ${{ github.event_name == 'push' && 'ubuntu-latest' || 'self-hosted' }}`
|
||||||
|
- Arrays containing expressions: `runs-on: [linux, "${{ github.event_name == 'push' && 'ubuntu-latest' || 'self-hosted' }}"]`
|
||||||
|
|
||||||
## Missing features
|
## Missing features
|
||||||
|
|
||||||
### Package repository authorization
|
### Package repository authorization
|
||||||
|
|
||||||
The `GITEA_TOKEN` for a job running within a repository should be able to publish to the associated package repository (i.e. to upload OCI images). See the "packages" scope for the "default access" in [Automatic token authentication](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).
|
`GITEA_TOKEN` cannot publish to the package registry of its repository, e.g. to push OCI images.
|
||||||
|
Use a personal access token instead, see [this issue](https://github.com/go-gitea/gitea/issues/23642#issuecomment-2119876692).
|
||||||
This is not implemented in Gitea Actions now. A workaround for Gitea Actions is to use a Personal Access Token (PAT). See this [github issue and comment](https://github.com/go-gitea/gitea/issues/23642#issuecomment-2119876692) for tracking this feature.
|
|
||||||
|
|
||||||
### Problem Matchers
|
### Problem Matchers
|
||||||
|
|
||||||
Problem Matchers are a way to scan the output of actions for a specified regex pattern and surface that information prominently in the UI.
|
[Problem matchers](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md) are ignored.
|
||||||
See [Problem matchers](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md).
|
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### Create an error annotation
|
### Create an error annotation
|
||||||
|
|
||||||
See [Creating an annotation for an error](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-creating-an-annotation-for-an-error)
|
[Error annotations](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-creating-an-annotation-for-an-error) are ignored.
|
||||||
|
|
||||||
It's ignored by Gitea Actions now.
|
|
||||||
|
|
||||||
### Expressions
|
### Expressions
|
||||||
|
|
||||||
For [expressions](https://docs.github.com/en/actions/learn-github-actions/expressions), only [`always()`](https://docs.github.com/en/actions/learn-github-actions/expressions#always) is supported.
|
[Expressions](https://docs.github.com/en/actions/learn-github-actions/expressions) support the standard GitHub functions and contexts.
|
||||||
|
|
||||||
## Missing UI features
|
## Missing UI features
|
||||||
|
|
||||||
### Pre and Post steps
|
### Pre and Post steps
|
||||||
|
|
||||||
Pre and Post steps don't have their own section in the job log user interface.
|
Pre and post steps have no section of their own in the job log.
|
||||||
|
|
||||||
### Services steps
|
### Services steps
|
||||||
|
|
||||||
Services steps don't have their own section in the job log user interface.
|
Service steps have no section of their own in the job log.
|
||||||
|
|
||||||
## Different behavior
|
## Different behavior
|
||||||
|
|
||||||
### Concurrency
|
### Job token permissions (`permissions`)
|
||||||
|
|
||||||
As of v1.21.0, gitea behaves as if `concurrency.cancel-in-progress` is set to `true`.
|
`permissions` and `jobs.<job_id>.permissions` control the `GITEA_TOKEN` permissions, clamped by the repository and owner settings and further restricted for fork pull requests and cross-repository access.
|
||||||
|
GitHub-only scopes like `statuses`, `checks`, `deployments`, `security-events` and `pages` are not supported, while Gitea adds `code`, `releases`, `wiki` and `projects`. `id-token` works like on GitHub, see [OpenID Connect](openid-connect.md).
|
||||||
This means that newly-triggered workflows will pre-empt runs already in progress for previous triggers.
|
See [Actions job token permissions](token-permissions.md).
|
||||||
|
|
||||||
See [PR #25716](https://github.com/go-gitea/gitea/pull/25716) for additional details.
|
|
||||||
|
|
||||||
### Downloading actions
|
### Downloading actions
|
||||||
|
|
||||||
Previously (Pre 1.21.0), `[actions].DEFAULT_ACTIONS_URL` defaulted to `https://gitea.com`.
|
Actions without a host, like `uses: actions/checkout@v4`, are downloaded from `https://github.com`, or from your own instance when `[actions].DEFAULT_ACTIONS_URL` is `self`.
|
||||||
We have since restricted this option to only allow two values (`github` and `self`).
|
See the [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions).
|
||||||
When set to `github`, the new default, Gitea will download non-fully-qualified actions from `https://github.com`.
|
For other sources, see [Absolute action URLs](#absolute-action-urls), [Action prefixes](#action-prefixes) and [Workflow-relative actions](#workflow-relative-actions).
|
||||||
For example, if you use `uses: actions/checkout@v4`, it will download the checkout repository from `https://github.com/actions/checkout.git`.
|
|
||||||
|
|
||||||
If you want to download an action from another git hoster, you can use an absolute URL, e.g. `uses: https://gitea.com/actions/checkout@v4`.
|
|
||||||
|
|
||||||
If your Gitea instance is in an intranet or a restricted area, you can set the URL to `self` to only download actions from your own instance by default.
|
|
||||||
Of course, you can still use absolute URLs in workflows.
|
|
||||||
|
|
||||||
More details about the `[actions].DEFAULT_ACTIONS_URL` configuration can be found in the [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions)。
|
|
||||||
|
|
||||||
### Context availability
|
### Context availability
|
||||||
|
|
||||||
Context availability is not checked, so you can use the env context on more places.
|
[Context availability](https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability) is not checked, so contexts like `env` work in more places.
|
||||||
See [Context availability](https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability).
|
|
||||||
@@ -8,33 +8,9 @@ sidebar_position: 140
|
|||||||
|
|
||||||
Gitea Actions has multiple components. This document describes them individually.
|
Gitea Actions has multiple components. This document describes them individually.
|
||||||
|
|
||||||
## Act
|
## Gitea Runner
|
||||||
|
|
||||||
The [nektos/act](https://github.com/nektos/act) project is an excellent tool that allows you to run your GitHub Actions locally.
|
Gitea Runner is based on a hard fork of [nektos/act](https://github.com/nektos/act).
|
||||||
We were inspired by this and wondered if it would be possible to run actions for Gitea.
|
|
||||||
|
|
||||||
However, while [nektos/act](https://github.com/nektos/act) is designed as a command line tool, what we actually needed was a Go library with modifications specifically for Gitea.
|
|
||||||
So we forked it as [gitea/act](https://gitea.com/gitea/act).
|
|
||||||
|
|
||||||
This is a soft fork that will periodically follow the upstream.
|
|
||||||
Although some custom commits have been added, we will try our best to avoid changing too much of the original code.
|
|
||||||
|
|
||||||
The forked act is just a shim or adapter for Gitea's specific usage.
|
|
||||||
There are some additional commits that have been made, such as:
|
|
||||||
|
|
||||||
- Outputting execution logs to logger hook so they can be reported to Gitea
|
|
||||||
- Disabling the GraphQL URL, since Gitea doesn't support it
|
|
||||||
- Starting a new container for every job instead of reusing to ensure isolation.
|
|
||||||
|
|
||||||
These modifications have no reason to be merged into the upstream.
|
|
||||||
They don't make sense if the user just wants to run trusted actions locally.
|
|
||||||
|
|
||||||
However, there may be overlaps in the future, such as a required bug fix or new feature needed by both projects.
|
|
||||||
In these cases, we will contribute the changes back to the upstream repository.
|
|
||||||
|
|
||||||
## Act runner
|
|
||||||
|
|
||||||
Gitea's runner is called act runner because it's based on act.
|
|
||||||
|
|
||||||
Like other CI runners, we designed it as an external part of Gitea, which means it should run on a different server than Gitea.
|
Like other CI runners, we designed it as an external part of Gitea, which means it should run on a different server than Gitea.
|
||||||
|
|
||||||
@@ -43,11 +19,11 @@ Additionally, the runner will introduce itself to Gitea and declare what kind of
|
|||||||
|
|
||||||
Earlier, we mentioned that `runs-on: ubuntu-latest` in a workflow file means that the job will be run on a runner with the `ubuntu-latest` label.
|
Earlier, we mentioned that `runs-on: ubuntu-latest` in a workflow file means that the job will be run on a runner with the `ubuntu-latest` label.
|
||||||
But how does the runner know to run `ubuntu-latest`? The answer lies in mapping the label to an environment.
|
But how does the runner know to run `ubuntu-latest`? The answer lies in mapping the label to an environment.
|
||||||
That's why when you add custom labels during registration, you will need to input some complex content like `my_custom_label:docker://centos:7`.
|
That's why each label of a runner names an environment, like `my_custom_label:docker://centos:7`.
|
||||||
This means that the runner can take the job which needs to run on `my_custom_label`, and it will run it via a docker container with the image `centos:7`.
|
This means that the runner can take the job which needs to run on `my_custom_label`, and it will run it via a docker container with the image `centos:7`.
|
||||||
|
|
||||||
Docker isn't the only option, though.
|
Docker isn't the only option, though.
|
||||||
The act also supports running jobs directly on the host.
|
The runner also supports running jobs directly on the host.
|
||||||
This is achieved through labels like `linux_arm:host`.
|
This is achieved through labels like `linux_arm:host`.
|
||||||
This label indicates that the runner can take a job that needs to run on `linux_arm` and run it directly on the host.
|
This label indicates that the runner can take a job that needs to run on `linux_arm` and run it directly on the host.
|
||||||
|
|
||||||
@@ -58,16 +34,15 @@ So,
|
|||||||
- `my_custom_label:docker://node:18`: Run jobs labeled with `my_custom_label` using the `node:18` Docker image.
|
- `my_custom_label:docker://node:18`: Run jobs labeled with `my_custom_label` using the `node:18` Docker image.
|
||||||
- `my_custom_label:host`: Run jobs labeled with `my_custom_label` directly on the host.
|
- `my_custom_label:host`: Run jobs labeled with `my_custom_label` directly on the host.
|
||||||
- `my_custom_label`: Same as `my_custom_label:host`.
|
- `my_custom_label`: Same as `my_custom_label:host`.
|
||||||
- `my_custom_label:vm:ubuntu-latest`: (Example only, not implemented) Run jobs labeled with `my_custom_label` using a virtual machine with the `ubuntu-latest` ISO.
|
|
||||||
|
|
||||||
## Communication protocol
|
## Communication protocol
|
||||||
|
|
||||||
As act runner is an independent part of Gitea, we needed a protocol for runners to communicate with the Gitea instance.
|
As the runner is an independent part of Gitea, we needed a protocol for runners to communicate with the Gitea instance.
|
||||||
However, we did not think it was a good idea to have Gitea listen on a new port.
|
However, we did not think it was a good idea to have Gitea listen on a new port.
|
||||||
Instead, we wanted to reuse the HTTP port, which means we needed a protocol that is compatible with HTTP.
|
Instead, we wanted to reuse the HTTP port, which means we needed a protocol that is compatible with HTTP.
|
||||||
We chose to use gRPC over HTTP.
|
We chose to use gRPC over HTTP.
|
||||||
|
|
||||||
We use [actions-proto-def](https://gitea.com/gitea/actions-proto-def) and [actions-proto-go](https://gitea.com/gitea/actions-proto-go) to wire them up.
|
The protocol is defined in [actions-proto-def](https://gitea.com/gitea/actions-proto-def), its Go code lives in [actionslib](https://gitea.com/gitea/actionslib).
|
||||||
More information about gRPC can be found on [its website](https://grpc.io/).
|
More information about gRPC can be found on [its website](https://grpc.io/).
|
||||||
|
|
||||||
## Network architecture
|
## Network architecture
|
||||||
@@ -79,9 +54,9 @@ This will help you troubleshoot some problems and explain why it's a bad idea to
|
|||||||
|
|
||||||
There are four network connections marked in the picture, and the direction of the arrows indicates the direction of establishing the connections.
|
There are four network connections marked in the picture, and the direction of the arrows indicates the direction of establishing the connections.
|
||||||
|
|
||||||
### Connection 1, act runner to Gitea instance
|
### Connection 1, runner to Gitea instance
|
||||||
|
|
||||||
The act runner must be able to connect to Gitea to receive tasks and send back the execution results.
|
The runner must be able to connect to Gitea to receive tasks and send back the execution results.
|
||||||
|
|
||||||
### Connection 2, job containers to Gitea instance
|
### Connection 2, job containers to Gitea instance
|
||||||
|
|
||||||
@@ -92,10 +67,11 @@ Fetching code is not always necessary to run some jobs, but it is required in mo
|
|||||||
If you use a loopback address to register a runner, the runner can connect to Gitea when it is on the same machine.
|
If you use a loopback address to register a runner, the runner can connect to Gitea when it is on the same machine.
|
||||||
However, if a job container tries to fetch code from localhost, it will fail because Gitea is not in the same container.
|
However, if a job container tries to fetch code from localhost, it will fail because Gitea is not in the same container.
|
||||||
|
|
||||||
### Connection 3, act runner to internet
|
### Connection 3, runner to internet
|
||||||
|
|
||||||
When you use some actions like `actions/checkout@v4`, the act runner downloads the scripts, not the job containers.
|
When you use some actions like `actions/checkout@v4`, the runner downloads the scripts, not the job containers.
|
||||||
By default, it downloads from [github.com](http://github.com/), so it requires access to the internet. If you configure the `DEFAULT_ACTIONS_URL` to `self`, then it will download from your Gitea instance by default. Then it will not connect to internet when downloading the action itself.
|
By default, it downloads them from [github.com](https://github.com/), which requires internet access.
|
||||||
|
With `DEFAULT_ACTIONS_URL` set to `self`, or with `uses: self:owner/repo@ref`, it downloads them from your Gitea instance instead.
|
||||||
It also downloads some docker images from Docker Hub by default, which also requires internet access.
|
It also downloads some docker images from Docker Hub by default, which also requires internet access.
|
||||||
|
|
||||||
However, internet access is not strictly necessary.
|
However, internet access is not strictly necessary.
|
||||||
|
|||||||
+29
-77
@@ -27,50 +27,24 @@ Still, this is completely optional since both options have the same effect at th
|
|||||||
|
|
||||||
## Where will the runner download scripts when using actions such as `actions/checkout@v4`?
|
## Where will the runner download scripts when using actions such as `actions/checkout@v4`?
|
||||||
|
|
||||||
There are tens of thousands of [actions scripts](https://github.com/marketplace?type=actions) in GitHub, and when you write `uses: actions/checkout@v4`, it downloads the scripts from [github.com/actions/checkout](http://github.com/actions/checkout) by default.
|
From `https://github.com` by default, or from your own instance when `[actions].DEFAULT_ACTIONS_URL` is `self`, see the [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions).
|
||||||
But what if you want to use actions from other places such as gitea.com instead of GitHub?
|
|
||||||
|
|
||||||
The good news is that you can specify the URL prefix to use actions from anywhere.
|
To use an action from elsewhere, name its host:
|
||||||
This is an extra syntax in Gitea Actions.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
- `uses: https://gitea.com/xxx/xxx@xxx`
|
- `uses: https://gitea.com/owner/repo@ref`
|
||||||
- `uses: https://github.com/xxx/xxx@xxx`
|
- `uses: http://your_gitea_instance.com/owner/repo@ref`
|
||||||
- `uses: http://your_gitea_instance.com/xxx@xxx`
|
- `uses: self:owner/repo@ref` for your own Gitea instance
|
||||||
|
|
||||||
Be careful, the `https://` or `http://` prefix is necessary!
|
|
||||||
|
|
||||||
This is one of the differences from GitHub Actions which supports actions scripts only from GitHub.
|
|
||||||
But it should allow users much more flexibility in how they run Actions.
|
|
||||||
|
|
||||||
Alternatively, if you want your runners to download actions from your own Gitea instance by default, you can configure it by setting `[actions].DEFAULT_ACTIONS_URL`.
|
|
||||||
See [Configuration Cheat Sheet](../../administration/config-cheat-sheet.md#actions-actions).
|
|
||||||
|
|
||||||
## How to limit the permission of the runners?
|
## How to limit the permission of the runners?
|
||||||
|
|
||||||
Runners have no more permissions than simply connecting to your Gitea instance.
|
Runners only connect to your Gitea instance.
|
||||||
When any runner receives a job to run, it will temporarily gain limited permission to the repository associated with the job.
|
For each job, a runner gets a `GITEA_TOKEN` limited to the job's repository, see [Actions job token permissions](token-permissions.md).
|
||||||
If you want to give more permissions to the runner, allowing it to access more private repositories or external systems, you can pass [secrets](usage/actions/secrets.md) to it.
|
To give a job access to more private repositories or external systems, pass it [secrets](usage/actions/secrets.md).
|
||||||
|
|
||||||
Refined permission control to Actions is a complicated job.
|
## Which operating systems are supported by Gitea Runner?
|
||||||
In the future, we will add more options to Gitea to make it more configurable, such as allowing more write access to repositories or read access to all repositories in the same organization.
|
|
||||||
|
|
||||||
## Which operating systems are supported by act runner?
|
Official binaries are released for Linux, macOS and Windows.
|
||||||
|
Other systems supported by Go and Docker work in theory.
|
||||||
We released official binaries for Linux, macOS, and Windows.
|
|
||||||
While other operating systems are theoretically supported if it is supported by golang and docker(docker mode enabled).
|
|
||||||
|
|
||||||
One thing to note is that if you choose to run jobs directly on the host instead of in job containers, the environmental differences between operating systems may cause unexpected failures.
|
|
||||||
|
|
||||||
For example, bash is not available on Windows in most cases, while act tries to use bash to run scripts by default.
|
|
||||||
Therefore, you need to specify `powershell` as the default shell in your workflow file, see [defaults.run](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrun).
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: powershell
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to avoid being hacked?
|
## How to avoid being hacked?
|
||||||
|
|
||||||
@@ -99,50 +73,21 @@ It is exciting to be able to reuse them.
|
|||||||
|
|
||||||
## What if it runs on multiple labels, such as `runs-on: [label_a, label_b]`?
|
## What if it runs on multiple labels, such as `runs-on: [label_a, label_b]`?
|
||||||
|
|
||||||
This is valid syntax.
|
The job runs on a runner that has all of the labels, as on [GitHub](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on).
|
||||||
It means that it should run on runners that have both the `label_a` **and** `label_b` labels, see [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on).
|
The runner uses the environment of the first label it has.
|
||||||
Unfortunately, act runner does not work this way until v0.2.11.
|
|
||||||
As mentioned, we map labels to environments:
|
|
||||||
|
|
||||||
- `ubuntu` → `ubuntu:22.04`
|
|
||||||
- `centos` → `centos:8`
|
|
||||||
|
|
||||||
But we need to map label groups to environments instead, like so:
|
|
||||||
|
|
||||||
- `[ubuntu]` → `ubuntu:22.04`
|
|
||||||
- `[with-gpu]` → `linux:with-gpu`
|
|
||||||
- `[ubuntu, with-gpu]` → `ubuntu:22.04_with-gpu`
|
|
||||||
|
|
||||||
We also need to re-design how tasks are assigned to runners.
|
|
||||||
A runner with `ubuntu`, `centos`, or `with-gpu` does not necessarily indicate that it can accept jobs with `[centos, with-gpu]`.
|
|
||||||
Therefore, the runner should inform the Gitea instance that it can only accept jobs with `[ubuntu]`, `[centos]`, `[with-gpu]`, and `[ubuntu, with-gpu]`.
|
|
||||||
This is not a technical problem, it was just overlooked in the early design.
|
|
||||||
See [runtime.go#L65](https://gitea.com/gitea/act_runner/src/commit/90b8cc6a7a48f45cc28b5ef9660ebf4061fcb336/runtime/runtime.go#L65).
|
|
||||||
|
|
||||||
Currently, the act runner attempts to match everyone in the labels and uses the first match it finds.
|
|
||||||
|
|
||||||
## What is the difference between agent labels and custom labels for a runner?
|
## What is the difference between agent labels and custom labels for a runner?
|
||||||
|
|
||||||

|
Gitea no longer has custom labels.
|
||||||
|
A runner declares its labels every time it starts, from its `runner.labels` configuration or the labels given at registration, so change them there and restart the runner.
|
||||||
Agent labels are reported to the Gitea instance by the runner during registration.
|
|
||||||
Custom labels, on the other hand, are added manually by a Gitea administrator or owners of the organization or repository (depending on the level of the runner).
|
|
||||||
|
|
||||||
However, the design here needs improvement, as it currently has some rough edges.
|
|
||||||
You can add a custom label such as `centos` to a registered runner, which means the runner will receive jobs with `runs-on: centos`.
|
|
||||||
However, the runner may not know which environment to use for this label, resulting in it using a default image or leading to a logical dead end.
|
|
||||||
This default may not match user expectations.
|
|
||||||
See [runtime.go#L71](https://gitea.com/gitea/act_runner/src/commit/90b8cc6a7a48f45cc28b5ef9660ebf4061fcb336/runtime/runtime.go#L71).
|
|
||||||
|
|
||||||
In the meantime, we suggest that you re-register your runner if you want to change its labels.
|
|
||||||
|
|
||||||
## Will there be more implementations for Gitea Actions runner?
|
## Will there be more implementations for Gitea Actions runner?
|
||||||
|
|
||||||
Although we would like to provide more options, our limited manpower means that act runner will be the only officially supported runner at the moment.
|
Although we would like to provide more options, our limited manpower means that Gitea Runner will be the only officially supported runner at the moment.
|
||||||
|
|
||||||
However, both Gitea and act runner are completely open source under MIT License, so anyone can modify the code to satisfy their requirements.
|
However, both Gitea and Gitea Runner are completely open source under MIT License, so anyone can modify the code to satisfy their requirements.
|
||||||
|
|
||||||
In case you fork act runner to create your own version: Please contribute the changes back if you can and if you think your changes will help others as well.
|
In case you fork Gitea Runner to create your own version: Please contribute the changes back if you can and if you think your changes will help others as well.
|
||||||
|
|
||||||
## What workflow trigger events does Gitea support?
|
## What workflow trigger events does Gitea support?
|
||||||
|
|
||||||
@@ -150,21 +95,25 @@ All events listed in this table are supported events and are compatible with Git
|
|||||||
For events supported only by GitHub, see GitHub's [documentation](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows).
|
For events supported only by GitHub, see GitHub's [documentation](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows).
|
||||||
|
|
||||||
| trigger event | activity types |
|
| trigger event | activity types |
|
||||||
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| create | not applicable |
|
| create | not applicable |
|
||||||
| delete | not applicable |
|
| delete | not applicable |
|
||||||
| fork | not applicable |
|
| fork | not applicable |
|
||||||
| gollum | not applicable |
|
| gollum | not applicable |
|
||||||
| push | not applicable |
|
| push | not applicable |
|
||||||
|
| schedule | not applicable |
|
||||||
|
| workflow_dispatch | not applicable |
|
||||||
|
| workflow_call | not applicable |
|
||||||
| issues | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `milestoned`, `demilestoned`, `labeled`, `unlabeled` |
|
| issues | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `milestoned`, `demilestoned`, `labeled`, `unlabeled` |
|
||||||
| issue_comment | `created`, `edited`, `deleted` |
|
| issue_comment | `created`, `edited`, `deleted` |
|
||||||
| pull_request | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `synchronize`, `labeled`, `unlabeled` |
|
| pull_request<br/>pull_request_target | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `synchronize`, `labeled`, `unlabeled`, `milestoned`, `demilestoned`, `review_requested`, `review_request_removed` |
|
||||||
| pull_request_review | `submitted`, `edited` |
|
| pull_request_review | `submitted`, `edited` |
|
||||||
| pull_request_review_comment | `created`, `edited` |
|
| pull_request_review_comment | `created`, `edited` |
|
||||||
| release | `published`, `edited` |
|
| release | `published`, `edited` |
|
||||||
| registry_package | `published` |
|
| registry_package | `published` |
|
||||||
| workflow_dispatch | not applicable |
|
| workflow_run | `requested`, `in_progress`, `completed` |
|
||||||
| workflow_run | `requested`, `completed` |
|
|
||||||
|
> Without an explicit `types:` filter, `pull_request` and `pull_request_target` only run on `opened`, `reopened` and `synchronize`, matching GitHub. All other events run on every activity type they support.
|
||||||
|
|
||||||
> For `pull_request` events, in [GitHub Actions](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request), the `ref` is `refs/pull/:prNumber/merge`, which is a reference to the merge commit preview. However, Gitea has no such reference.
|
> For `pull_request` events, in [GitHub Actions](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request), the `ref` is `refs/pull/:prNumber/merge`, which is a reference to the merge commit preview. However, Gitea has no such reference.
|
||||||
> Therefore, the `ref` in Gitea Actions is `refs/pull/:prNumber/head`, which points to the head of pull request rather than the preview of the merge commit.
|
> Therefore, the `ref` in Gitea Actions is `refs/pull/:prNumber/head`, which points to the head of pull request rather than the preview of the merge commit.
|
||||||
@@ -173,3 +122,6 @@ For events supported only by GitHub, see GitHub's [documentation](https://docs.g
|
|||||||
|
|
||||||
Go to the repository's **Settings** > **Actions** > **General** page and add collaborative owners.
|
Go to the repository's **Settings** > **Actions** > **General** page and add collaborative owners.
|
||||||
The private repositories of collaborative owners are allowed to access the actions and workflows in the current repository.
|
The private repositories of collaborative owners are allowed to access the actions and workflows in the current repository.
|
||||||
|
|
||||||
|
To share within the same user or organization, add the private repositories under its **Settings** > **Actions** > **General** > **Cross-Repository Access** instead.
|
||||||
|
See [Cross-repository access](token-permissions.md#cross-repository-access).
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
date: "2026-08-23T00:00:00+00:00"
|
||||||
|
slug: "openid-connect"
|
||||||
|
sidebar_position: 40
|
||||||
|
---
|
||||||
|
|
||||||
|
# OpenID Connect
|
||||||
|
|
||||||
|
Jobs can request short-lived OpenID Connect (OIDC) tokens to sign in to cloud providers and other services without storing long-lived secrets. The tokens use the GitHub Actions format, so actions like `aws-actions/configure-aws-credentials`, `google-github-actions/auth` and `azure/login` work unchanged.
|
||||||
|
|
||||||
|
## Trusting Gitea
|
||||||
|
|
||||||
|
Add Gitea as an OIDC identity provider in the service:
|
||||||
|
|
||||||
|
- Issuer: `<ROOT_URL>/api/actions/oidc`
|
||||||
|
- Audience: `<ROOT_URL>/<owner>`, unless the workflow requests another one
|
||||||
|
|
||||||
|
Then limit which workflows can sign in with a condition on the [`sub` claim](#claims).
|
||||||
|
|
||||||
|
Gitea signs the tokens with a key it creates at `<APP_DATA_PATH>/jwt/actions_oidc.pem`. Instances behind a load balancer must share this file.
|
||||||
|
|
||||||
|
## Requesting a token
|
||||||
|
|
||||||
|
Grant the `id-token` permission to the workflow or job:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
```
|
||||||
|
|
||||||
|
Default permissions never include it, and jobs from fork pull requests never get it. Owners and repositories can disable it with their [maximum token permissions](token-permissions.md#maximum-token-permissions-clamping).
|
||||||
|
|
||||||
|
Actions like the ones above request the token themselves. In a script, use `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --fail --silent --show-error \
|
||||||
|
--header "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
|
||||||
|
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=my-service"
|
||||||
|
```
|
||||||
|
|
||||||
|
The token is in the `value` field of the response and expires after five minutes.
|
||||||
|
|
||||||
|
## Claims
|
||||||
|
|
||||||
|
The `sub` claim names the owner and repository with their IDs, so a renamed or recreated repository cannot match an existing trust policy:
|
||||||
|
|
||||||
|
```text
|
||||||
|
repo:<owner>@<owner-id>/<repo>@<repo-id>:ref:<ref>
|
||||||
|
repo:<owner>@<owner-id>/<repo>@<repo-id>:pull_request
|
||||||
|
```
|
||||||
|
|
||||||
|
The `pull_request` event uses the second form, all other events use the first, including `pull_request_target`.
|
||||||
|
|
||||||
|
The other claims match GitHub's, like `repository`, `ref`, `sha`, `workflow_ref` and `job_workflow_ref`. The discovery document at `<ROOT_URL>/api/actions/oidc/.well-known/openid-configuration` lists them all.
|
||||||
|
|
||||||
|
Differences from GitHub Actions:
|
||||||
|
|
||||||
|
- There is no `environment` claim.
|
||||||
|
- Pull request runs use `refs/pull/<index>/head` and its commit, not the merge ref and merge commit.
|
||||||
|
- `run_number` counts runs per repository, not per workflow.
|
||||||
@@ -21,8 +21,8 @@ To avoid confusion, we have clarified the spelling here:
|
|||||||
## Runners
|
## Runners
|
||||||
|
|
||||||
Just like other CI/CD solutions, Gitea doesn't run the jobs itself, but delegates the jobs to runners.
|
Just like other CI/CD solutions, Gitea doesn't run the jobs itself, but delegates the jobs to runners.
|
||||||
The runner of Gitea Actions is called [act runner](https://gitea.com/gitea/act_runner), it is a standalone program and also written in Go.
|
The runner of Gitea Actions is called [Gitea Runner](https://gitea.com/gitea/runner), it is a standalone program and also written in Go.
|
||||||
An important part of the application comes from a [fork](https://gitea.com/gitea/act) of [nektos/act](http://github.com/nektos/act).
|
An important part of the application comes from a hard fork of [nektos/act](http://github.com/nektos/act).
|
||||||
|
|
||||||
Because the runner is deployed independently, there could be potential security issues.
|
Because the runner is deployed independently, there could be potential security issues.
|
||||||
To avoid them, please follow two simple rules:
|
To avoid them, please follow two simple rules:
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ If you want to learn more or encounter any problems while configuring it, please
|
|||||||
|
|
||||||
### Set up runner
|
### Set up runner
|
||||||
|
|
||||||
Gitea Actions requires [act runner](https://gitea.com/gitea/act_runner) to run the jobs.
|
Gitea Actions requires [Gitea Runner](https://gitea.com/gitea/runner) to run the jobs.
|
||||||
In order to avoid consuming too many resources and affecting the Gitea instance, it is recommended to start runners on separate machines from the Gitea instance.
|
In order to avoid consuming too many resources and affecting the Gitea instance, it is recommended to start runners on separate machines from the Gitea instance.
|
||||||
|
|
||||||
You can use the [pre-built binaries](http://dl.gitea.com/act_runner) or the [docker images](https://hub.docker.com/r/gitea/act_runner/tags) to set up the runner.
|
You can use the [pre-built binaries](http://dl.gitea.com/gitea-runner) or the [docker images](https://hub.docker.com/r/gitea/runner/tags) to set up the runner.
|
||||||
|
|
||||||
Before proceeding any further, we suggest running it as a command line with pre-built binaries to ensure that it works with your environment, especially if you are running a runner on your localhost.
|
Before proceeding any further, we suggest running it as a command line with pre-built binaries to ensure that it works with your environment, especially if you are running a runner on your localhost.
|
||||||
And it could be easier to debug if something goes wrong.
|
And it could be easier to debug if something goes wrong.
|
||||||
@@ -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:
|
Before running a runner, you should first register it to your Gitea instance using the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./act_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`.
|
There are two arguments required, `instance` and `token`.
|
||||||
@@ -69,14 +69,14 @@ If this file is missing or corrupted, you can simply remove it and register agai
|
|||||||
Finally, it's time to start the runner:
|
Finally, it's time to start the runner:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./act_runner daemon
|
gitea-runner daemon
|
||||||
```
|
```
|
||||||
|
|
||||||
And you can see the new runner in the management page:
|
And you can see the new runner in the management page:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You can find more information by visiting [Act runner](act-runner.mdxc).
|
You can find more information by visiting [Gitea Runner](runner.mdx).
|
||||||
|
|
||||||
### Use Actions
|
### Use Actions
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
date: "2023-04-27T15:00:00+08:00"
|
||||||
|
slug: "runner"
|
||||||
|
sidebar_position: 20
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gitea Runner
|
||||||
|
|
||||||
|
This page will introduce the [Gitea Runner](https://gitea.com/gitea/runner), which is the runner for Gitea Actions.
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
For detailed installation, configuration, and usage instructions, see the [Gitea Runner documentation](/runner/).
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Obtain a registration token
|
||||||
|
|
||||||
|
You can register a runner at different levels. It can be:
|
||||||
|
|
||||||
|
- Instance level: The runner will run jobs for all repositories in the instance.
|
||||||
|
- Organization level: The runner will run jobs for all repositories in the organization.
|
||||||
|
- Repository level: The runner will run jobs for the repository it belongs to.
|
||||||
|
|
||||||
|
Note that the repository may still use instance-level or organization-level runners even if it has its own repository-level runners. A future release may provide an option to allow more control over this.
|
||||||
|
|
||||||
|
Before registering the runner and running it, you need a registration token. The level of the runner determines where to obtain the registration token.
|
||||||
|
|
||||||
|
- Instance level: The admin settings page, like `<your_gitea.com>/-/admin/actions/runners`.
|
||||||
|
- Organization level: The organization settings page, like `<your_gitea.com>/<org>/settings/actions/runners`.
|
||||||
|
- Repository level: The repository settings page, like `<your_gitea.com>/<owner>/<repo>/settings/actions/runners`.
|
||||||
|
|
||||||
|
If you cannot see the settings page, please make sure that you have the right permissions and that Actions have been enabled.
|
||||||
|
|
||||||
|
The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`.
|
||||||
|
|
||||||
|
A registration token can also be obtained from the Gitea [command-line interface](../../administration/command-line.md#actions-generate-runner-token):
|
||||||
|
|
||||||
|
```
|
||||||
|
gitea --config /etc/gitea/app.ini actions generate-runner-token
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use `GITEA_RUNNER_REGISTRATION_TOKEN`/`GITEA_RUNNER_REGISTRATION_TOKEN_FILE` environment variables to set a global runner registration token when Gitea starts, for example:
|
||||||
|
|
||||||
|
```
|
||||||
|
openssl rand -hex 24 > /some-dir/runner-token
|
||||||
|
export GITEA_RUNNER_REGISTRATION_TOKEN_FILE=/some-dir/runner-token
|
||||||
|
./gitea --config ...
|
||||||
|
```
|
||||||
|
|
||||||
|
The token from the environment is valid until you reset the token (re-create a new one) via the web UI or API.
|
||||||
|
|
||||||
|
Tokens are valid for registering multiple runners, until they are revoked and replaced by a new token using the token reset link in the web interface.
|
||||||
|
|
||||||
|
Once you have a registration token, follow the [Gitea Runner documentation](/runner/) to install, configure, and run your runner.
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
date: "2026-06-26T00:00:00+00:00"
|
||||||
|
slug: "scoped-workflows"
|
||||||
|
sidebar_position: 60
|
||||||
|
---
|
||||||
|
|
||||||
|
# Scoped Workflows
|
||||||
|
|
||||||
|
Scoped workflows let you maintain Actions workflows in one central **source** repository and have them run automatically on many other repositories, without copying the workflow files into each one.
|
||||||
|
|
||||||
|
A workflow file committed under a source repository's scoped-workflow directory runs on every repository that the source applies to (a "consuming" repository). Each run executes **in the consuming repository's own context**: its runners, secrets, `GITEA_TOKEN`, and branch, while the workflow **content is read from the source repository**. This is useful for mandating shared CI across an organization or instance: linting, security scans, compliance or policy checks, and similar.
|
||||||
|
|
||||||
|
## Levels
|
||||||
|
|
||||||
|
A source repository can be registered at two levels:
|
||||||
|
|
||||||
|
- **Owner level**: registered by an organization or user. The source's workflows run on every repository owned by that organization or user.
|
||||||
|
- **Instance level**: registered by a site administrator. The source's workflows run on **every** repository on the instance.
|
||||||
|
|
||||||
|
The same repository may be registered at both levels; it is still evaluated once per matching event.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Instance-level sources apply to **every** repository on the instance, and a required one cannot be opted out. Detection runs on every repository's events. Register them deliberately.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Scoped workflows live in a directory that is separate from regular workflows. It is controlled by `SCOPED_WORKFLOW_DIRS` in the `[actions]` section of `app.ini`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[actions]
|
||||||
|
SCOPED_WORKFLOW_DIRS = .gitea/scoped_workflows
|
||||||
|
```
|
||||||
|
|
||||||
|
- The default is `.gitea/scoped_workflows`.
|
||||||
|
- It may list multiple directories (comma-separated).
|
||||||
|
- It **must not overlap** with `WORKFLOW_DIRS` (the regular workflow directories, by default `.gitea/workflows` and `.github/workflows`).
|
||||||
|
- Leaving it empty means no directory holds scoped workflows, so none are found or run. The settings page still appears and sources can still be registered, but no scoped workflow runs.
|
||||||
|
|
||||||
|
Keeping scoped workflows in their own directory means a source repository's *own* Actions are unaffected: only files under `SCOPED_WORKFLOW_DIRS` are treated as scoped workflows.
|
||||||
|
|
||||||
|
## Providing scoped workflows from a repository
|
||||||
|
|
||||||
|
1. In the would-be source repository, commit your workflow files under the scoped-workflow directory on its **default branch**, for example `.gitea/scoped_workflows/lint.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Lint
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: echo "lint the consuming repository here"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Register the repository as a source:
|
||||||
|
|
||||||
|
- **Organization**: *Organization Settings -> Actions -> Scoped Workflows*
|
||||||
|
- **User**: *User Settings -> Actions -> Scoped Workflows*
|
||||||
|
- **Instance (admin)**: *Site Administration -> Actions -> Scoped Workflows*
|
||||||
|
|
||||||
|
Search for and add the repository. From then on, its scoped workflows apply to the consuming repositories at that level.
|
||||||
|
|
||||||
|
The source repository is within its own scope, so it runs these workflows on itself like any other consumer.
|
||||||
|
|
||||||
|
## How scoped workflows run
|
||||||
|
|
||||||
|
- The run belongs to the **consuming** repository and uses its runners, secrets, `GITEA_TOKEN`, and ref. It behaves like a normal run there, including rerun, logs, and commit statuses.
|
||||||
|
- The workflow **content is read from the source** repository, pinned to the source's default-branch commit at the time of the event.
|
||||||
|
- Detection uses the consuming repository's event, so the workflow's `on:` triggers (such as `push` and `pull_request`) must match that event.
|
||||||
|
|
||||||
|
## Opting out
|
||||||
|
|
||||||
|
A consuming repository can disable a scoped workflow it does not want, from its **Actions** page (the workflow appears under its source). A workflow that has been marked **required** (see below) can never be disabled or opted out by a consuming repository.
|
||||||
|
|
||||||
|
## Required workflows and the merge gate
|
||||||
|
|
||||||
|
On the Scoped Workflows settings page you can mark individual workflows as **required** and give each one or more **status-check patterns** (one glob per line). A required scoped workflow:
|
||||||
|
|
||||||
|
- Cannot be disabled by consuming repositories.
|
||||||
|
- Gates pull-request merges: a consuming pull request can only be merged once a commit status matching **every** pattern has **passed** (must-present-and-pass). A required check that never posts a status **blocks** the merge rather than being silently skipped, so disabling Actions on the consumer cannot bypass it.
|
||||||
|
|
||||||
|
The status-check context a scoped run posts has the form:
|
||||||
|
|
||||||
|
```
|
||||||
|
<source repo full name>: <workflow display name> / <job> (<event>)
|
||||||
|
```
|
||||||
|
|
||||||
|
The settings page previews these "Expected status checks" for each workflow and marks the ones your patterns match, so you can confirm a pattern is correct. A common pattern wildcards the job and event, for example `my-org/ci-repo: Lint / *`.
|
||||||
|
|
||||||
|
Enforcement scope:
|
||||||
|
|
||||||
|
- A required check is enforced on any target branch that has a **branch protection rule**, even one whose own status checks are disabled.
|
||||||
|
- A target branch with **no** protection rule is not gated.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Only a workflow that runs on an event that posts a commit status (`push`, `pull_request`, `pull_request_target`, `release`) can be required. A workflow that runs only on events like `workflow_dispatch`, `schedule` or `workflow_call` posts no status, so marking it required would block every consuming pull request forever. The settings page warns you in this case.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Reusable workflows (`uses:`)
|
||||||
|
|
||||||
|
Scoped workflows can call reusable workflows:
|
||||||
|
|
||||||
|
- A **local** reference (`uses: ./...` or `uses: $/...`) resolves against the **source** repository: the repository the calling workflow's content came from, not the consuming repository.
|
||||||
|
- A **cross-repository** reference (`uses: owner/repo/...@ref` or `uses: self:owner/repo/...@ref`) is resolved with the **consuming repository's** read permission. If it points to a private repository, make sure every consuming repository can read it; otherwise the workflow will fail there.
|
||||||
|
|
||||||
|
A reusable workflow can live under `SCOPED_WORKFLOW_DIRS` (or `WORKFLOW_DIRS`) of the source repository.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
A source repository's workflow content is executed in every repository it applies to, and its step scripts and their output are written to that repository's Actions logs, readable by anyone who can view the consuming repository's Actions.
|
||||||
|
|
||||||
|
- Registering a **private** repository as a source therefore discloses its workflow logic through those logs. Only register repositories whose workflow content may be shared with every consuming repository.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- `on: schedule` and `on: workflow_run` are currently not supported as scoped workflow triggers.
|
||||||
|
- Scoped workflow content is read from the source's default branch; other branches of the source are not used.
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
---
|
||||||
|
date: "2026-03-19T00:00:00+01:00"
|
||||||
|
slug: "token-permissions"
|
||||||
|
sidebar_position: 30
|
||||||
|
---
|
||||||
|
|
||||||
|
# Actions job token permissions (`GITEA_TOKEN`)
|
||||||
|
|
||||||
|
Every Actions job receives a built-in token (`GITEA_TOKEN`) which can be used to access Gitea (Git over HTTP(S), API requests, etc.).
|
||||||
|
This page documents how Gitea decides what the token is allowed to do.
|
||||||
|
|
||||||
|
In workflows, it is available as `${{ secrets.GITEA_TOKEN }}`. These settings and `permissions:` only affect `GITEA_TOKEN` (not other secrets like personal access tokens). For API calls, see [API authentication](../../development/api-usage.md#authentication).
|
||||||
|
|
||||||
|
## Where permissions come from
|
||||||
|
|
||||||
|
Gitea determines the job token permissions in this order:
|
||||||
|
|
||||||
|
1. Job-level `permissions:` (`jobs.<job_id>.permissions`)
|
||||||
|
2. Workflow-level `permissions:` (top-level)
|
||||||
|
3. Default permissions from settings (owner or repository)
|
||||||
|
|
||||||
|
The result is then **clamped** by the configured maximum token permissions (see below).
|
||||||
|
|
||||||
|
## Supported workflow syntax
|
||||||
|
|
||||||
|
Gitea supports the GitHub Actions-compatible `permissions:` keyword.
|
||||||
|
|
||||||
|
### Scalar values
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
permissions: read-all # or: write-all
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scoped mapping
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: none
|
||||||
|
```
|
||||||
|
|
||||||
|
Valid access mode values for each scope are `read`, `write`, and `none`.
|
||||||
|
|
||||||
|
### Supported scopes
|
||||||
|
|
||||||
|
- `contents` (applies to `code` and `releases`)
|
||||||
|
- `code`
|
||||||
|
- `releases`
|
||||||
|
- `issues`
|
||||||
|
- `pull-requests`
|
||||||
|
- `actions`
|
||||||
|
- `wiki`
|
||||||
|
- `projects`
|
||||||
|
- `packages` (if supported by the target feature)
|
||||||
|
- `id-token` (`write` allows requesting [OpenID Connect tokens](openid-connect.md), `read` grants nothing)
|
||||||
|
|
||||||
|
If you specify both `contents` and a more granular scope (like `code` or `releases`), the granular scope wins for that unit.
|
||||||
|
|
||||||
|
### Compatibility notes
|
||||||
|
|
||||||
|
Gitea supports a subset of GitHub Actions permission scopes.
|
||||||
|
GitHub-only scopes such as `statuses`, `checks`, `deployments`, `security-events`, and `pages` are not currently supported by Gitea Actions.
|
||||||
|
|
||||||
|
Gitea also exposes repository-unit scopes that do not exist as separate scopes in GitHub Actions:
|
||||||
|
|
||||||
|
- `code`
|
||||||
|
- `releases`
|
||||||
|
- `wiki`
|
||||||
|
- `projects`
|
||||||
|
|
||||||
|
## Default permission mode
|
||||||
|
|
||||||
|
If neither the workflow nor the job defines `permissions:`, Gitea uses the configured default mode:
|
||||||
|
|
||||||
|
- **Permissive**: read and write permissions for most units in the job's repository (backwards-compatible default).
|
||||||
|
- **Restricted**: read-only permissions for `code`, `releases`, and `packages` in the job's repository, and no access to other units by default.
|
||||||
|
|
||||||
|
Neither mode includes `id-token`.
|
||||||
|
|
||||||
|
## Maximum token permissions (clamping)
|
||||||
|
|
||||||
|
You can configure a maximum permission per repository unit and for `id-token`.
|
||||||
|
The job's effective permissions are computed as:
|
||||||
|
|
||||||
|
`effective = min(requested, maximum)`
|
||||||
|
|
||||||
|
This means workflows can reduce permissions for a job, but cannot exceed your configured maximum.
|
||||||
|
If you don't configure a maximum, the maximum defaults to `write` for all scopes.
|
||||||
|
Maximums saved before Gitea supported `id-token` deny it until you set it to `write`.
|
||||||
|
|
||||||
|
## Where to configure
|
||||||
|
|
||||||
|
You can configure defaults and maximums at:
|
||||||
|
|
||||||
|
- **User / Organization**: `Settings` → `Actions` → `General`
|
||||||
|
- **Repository**: `Settings` → `Actions` → `General`
|
||||||
|
- For repositories in an organization, the repository can follow the owner-level configuration, or opt out with **Override owner-level configuration**.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Cross-repository access
|
||||||
|
|
||||||
|
By default, `GITEA_TOKEN` only has access to:
|
||||||
|
|
||||||
|
- The job's repository (according to the computed permissions)
|
||||||
|
- Public repositories (read-only)
|
||||||
|
|
||||||
|
Access to other private repositories is denied by default.
|
||||||
|
A user or organization can allow read-only access to selected private repositories via **Settings → Actions → General → Cross-Repository Access**.
|
||||||
|
|
||||||
|
Private repositories can also allow selected collaborative owners via **Settings → Actions → General**.
|
||||||
|
This allows the private repositories of those owners to read the current private repository for Actions use, such as private actions and reusable workflows.
|
||||||
|
|
||||||
|
Fork pull request workflows never gain cross-repository access to private repositories, even if those repositories are listed.
|
||||||
@@ -6,11 +6,171 @@ sidebar_position: 25
|
|||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
|
|
||||||
|
## Environment variables
|
||||||
|
|
||||||
|
These environment variables are set automatically in every workflow run and can be accessed directly (e.g. `$CI` in shell scripts).
|
||||||
|
|
||||||
|
| Name | Description | Example |
|
||||||
|
|---|---|---|
|
||||||
|
| `CI` | Always set to `true`. | `true` |
|
||||||
|
| `GITEA_ACTIONS` | Always set to `true`. Useful to distinguish Gitea Actions from other CI systems. | `true` |
|
||||||
|
| `GITEA_ACTIONS_RUNNER_VERSION` | The version of the runner executing the workflow. | `1.0.8` |
|
||||||
|
| `GITEA_DOCKER_WORKSPACE` | The workspace path as the Docker daemon sees it, for bind mounts into containers a job starts, e.g. `${GITEA_DOCKER_WORKSPACE:-.}/data:/app/data` in a compose file. Only set for jobs running in a container. | `/var/lib/docker/volumes/GITEA-ACTIONS-TASK-42_***/_data` |
|
||||||
|
| `GITEA_ENV`<br/>`GITHUB_ENV` | Path to the file that sets environment variables for subsequent steps. | `/home/runner/work/_temp/_runner_file_commands/set_env_***` |
|
||||||
|
| `GITEA_OUTPUT`<br/>`GITHUB_OUTPUT` | Path to the file that sets step output parameters. | `/home/runner/work/_temp/_runner_file_commands/set_output_***` |
|
||||||
|
| `GITEA_PATH`<br/>`GITHUB_PATH` | Path to the file that adds system `PATH` entries for subsequent steps. | `/home/runner/work/_temp/_runner_file_commands/add_path_***` |
|
||||||
|
| `GITEA_STATE`<br/>`GITHUB_STATE` | Path to the file that sets step state variables. | `/home/runner/work/_temp/_runner_file_commands/save_state_***` |
|
||||||
|
| `GITEA_STEP_SUMMARY`<br/>`GITHUB_STEP_SUMMARY` | Path to the file for writing job summaries. | `/home/runner/work/_temp/_runner_file_commands/step_summary_***` |
|
||||||
|
| `GITHUB_ACTIONS` | Always set to `true`. | `true` |
|
||||||
|
| `GITHUB_ACTION` | The name of the action currently running, or the step `id`. | `__run` |
|
||||||
|
| `GITHUB_ACTION_PATH` | The path where the action is located. | `/home/runner/work/_actions/actions/checkout/v4` |
|
||||||
|
| `GITHUB_ACTION_REF` | The ref of the action being executed. | `v4` |
|
||||||
|
| `GITHUB_ACTION_REPOSITORY` | The owner and repository of the action. | `actions/checkout` |
|
||||||
|
| `GITHUB_ACTOR` | The username of the user that triggered the workflow. | `silverwind` |
|
||||||
|
| `GITHUB_API_URL` | The URL of the REST API. | `https://gitea.com/api/v1` |
|
||||||
|
| `GITHUB_BASE_REF` | The target branch of a pull request. | `main` |
|
||||||
|
| `GITHUB_EVENT_NAME` | The name of the event that triggered the workflow. | `push` |
|
||||||
|
| `GITHUB_EVENT_PATH` | Path to the file containing the event webhook payload. | `/home/runner/work/_temp/_github_workflow/event.json` |
|
||||||
|
| `GITHUB_GRAPHQL_URL` | Empty in Gitea (GraphQL is not supported). | _(empty)_ |
|
||||||
|
| `GITHUB_HEAD_REF` | The source branch of a pull request. | `feature-branch` |
|
||||||
|
| `GITHUB_JOB` | The `job_id` of the current job. | `build` |
|
||||||
|
| `GITHUB_REF` | The fully-formed ref that triggered the workflow. | `refs/heads/main` |
|
||||||
|
| `GITHUB_REF_NAME` | The short ref name. | `main` |
|
||||||
|
| `GITHUB_REF_TYPE` | The type of ref: `branch` or `tag`. | `branch` |
|
||||||
|
| `GITHUB_REPOSITORY` | The owner and repository name. | `gitea/docs` |
|
||||||
|
| `GITHUB_REPOSITORY_OWNER` | The repository owner's username. | `gitea` |
|
||||||
|
| `GITHUB_RETENTION_DAYS` | The number of days that artifacts are kept, empty when kept forever. | `90` |
|
||||||
|
| `GITHUB_RUN_ATTEMPT` | The attempt number of the workflow run. | `1` |
|
||||||
|
| `GITHUB_RUN_ID` | A unique number for each workflow run. | `1234` |
|
||||||
|
| `GITHUB_RUN_NUMBER` | A unique number for each run of a particular workflow. | `42` |
|
||||||
|
| `GITHUB_SERVER_URL` | The URL of the Gitea instance. | `https://gitea.com` |
|
||||||
|
| `GITHUB_SHA` | The commit SHA that triggered the workflow. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
|
||||||
|
| `GITHUB_WORKFLOW` | The name of the workflow. | `CI` |
|
||||||
|
| `GITHUB_WORKSPACE` | The default working directory on the runner. | `/workspace/gitea/docs` |
|
||||||
|
|
||||||
|
### Runner environment variables
|
||||||
|
|
||||||
|
| Name | Description | Example |
|
||||||
|
|---|---|---|
|
||||||
|
| `RUNNER_ARCH` | The architecture of the runner. | `X64` |
|
||||||
|
| `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` |
|
||||||
|
|
||||||
|
### Internal environment variables
|
||||||
|
|
||||||
|
These are used internally by the runner and actions. They are typically not needed in workflows directly.
|
||||||
|
|
||||||
|
| Name | Description | Example |
|
||||||
|
|---|---|---|
|
||||||
|
| `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_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/` |
|
||||||
|
|
||||||
|
## Context variables
|
||||||
|
|
||||||
|
These variables are available in workflow expressions via `${{ gitea.<name> }}`. For compatibility, `${{ github.<name> }}` works as an alias.
|
||||||
|
|
||||||
|
| 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_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.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.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.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 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.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.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.gitea_default_actions_url` | The default URL for downloading actions. Gitea-specific. | `https://github.com` |
|
||||||
|
|
||||||
|
### Event payload
|
||||||
|
|
||||||
|
`gitea.event` is the webhook payload of the event that triggered the run, so which fields exist depends on `gitea.event_name`.
|
||||||
|
The same payload is written as JSON to the file at `gitea.event_path`.
|
||||||
|
|
||||||
|
Payloads use Gitea's webhook format, which is close to GitHub's but not identical. Differences are noted below.
|
||||||
|
Reading a field that the payload does not have returns an empty value instead of failing, so `${{ gitea.event.pull_request.number }}` is empty on a `push` run.
|
||||||
|
|
||||||
|
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.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` |
|
||||||
|
|
||||||
|
The remaining fields are specific to one or a few events:
|
||||||
|
|
||||||
|
| Name | Events | Description | Example |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `gitea.event.schedule` | `schedule` | The cron expression that triggered the run. | `*/5 * * * *` |
|
||||||
|
| `gitea.event.inputs.<name>` | `workflow_dispatch`, `workflow_call` | A raw input value. Prefer `${{ inputs.<name> }}`, which also applies the input's `default`. | `true` |
|
||||||
|
| `gitea.event.workflow` | `workflow_dispatch` | The file name of the dispatched workflow. | `ci.yaml` |
|
||||||
|
| `gitea.event.ref` | `push`, `create`, `delete`, `workflow_dispatch` | The ref of the event. Unlike GitHub, `create` and `delete` use the full ref instead of the short name. | `refs/heads/main` |
|
||||||
|
| `gitea.event.ref_type` | `create`, `delete` | The type of ref: `branch` or `tag`. | `tag` |
|
||||||
|
| `gitea.event.before`<br/>`gitea.event.after` | `push` | The commit SHA before and after the push. | `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2` |
|
||||||
|
| `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.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.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` |
|
||||||
|
| `gitea.event.pull_request.head.ref`<br/>`gitea.event.pull_request.head.sha`<br/>`gitea.event.pull_request.head.repo.full_name` | `pull_request`, `pull_request_target`, `pull_request_review`, `pull_request_review_comment` | The source branch of the pull request. | `feature-branch` |
|
||||||
|
| `gitea.event.pull_request.base.ref`<br/>`gitea.event.pull_request.base.sha` | `pull_request`, `pull_request_target`, `pull_request_review`, `pull_request_review_comment` | The target branch of the pull request. | `main` |
|
||||||
|
| `gitea.event.review.type` | `pull_request_review`, `pull_request_review_comment` | The kind of review: `pull_request_review_approved`, `pull_request_review_rejected` or `pull_request_review_comment`. GitHub uses `review.state` with the values `approved`, `changes_requested` and `commented`. | `pull_request_review_approved` |
|
||||||
|
| `gitea.event.review.content` | `pull_request_review`, `pull_request_review_comment` | The body of the review. GitHub names this field `review.body`. | `Ship it` |
|
||||||
|
| `gitea.event.changes.title.from`<br/>`gitea.event.changes.body.from` | `issues`, `issue_comment`, `pull_request` | The previous value. Only set when `action` is `edited`. | `Old title` |
|
||||||
|
| `gitea.event.release.tag_name`<br/>`gitea.event.release.name`<br/>`gitea.event.release.body`<br/>`gitea.event.release.draft`<br/>`gitea.event.release.prerelease` | `release` | The release the event happened on. | `v1.2.3` |
|
||||||
|
| `gitea.event.package.name`<br/>`gitea.event.package.type`<br/>`gitea.event.package.version` | `registry_package` | The package the event happened on. | `gitea` |
|
||||||
|
| `gitea.event.workflow_run.id`<br/>`gitea.event.workflow_run.event`<br/>`gitea.event.workflow_run.status`<br/>`gitea.event.workflow_run.conclusion`<br/>`gitea.event.workflow_run.head_branch`<br/>`gitea.event.workflow_run.head_sha` | `workflow_run` | The workflow run that the event reports on. | `success` |
|
||||||
|
|
||||||
|
`schedule` runs have no webhook of their own. Their payload is the payload of the push that registered the schedule, with `schedule`, `repository`, `sender` and, for organization-owned repositories, `organization` filled in.
|
||||||
|
Only those fields are meaningful, and `sender.login` is always `gitea-actions`.
|
||||||
|
|
||||||
|
## User-defined variables
|
||||||
|
|
||||||
You can create configuration variables on the user, organization and repository level.
|
You can create configuration variables on the user, organization and repository level.
|
||||||
The level of the variable depends on where you created it. When creating a variable, the
|
The level of the variable depends on where you created it. When creating a variable, the
|
||||||
key will be converted to uppercase. You need use uppercase on the yaml file.
|
key will be converted to uppercase. You need use uppercase on the yaml file.
|
||||||
|
|
||||||
## Naming conventions
|
### Naming conventions
|
||||||
|
|
||||||
The following rules apply to variable names:
|
The following rules apply to variable names:
|
||||||
|
|
||||||
@@ -21,12 +181,12 @@ The following rules apply to variable names:
|
|||||||
- Variable names must be unique at the level they are created at.
|
- Variable names must be unique at the level they are created at.
|
||||||
- Variable names must not start with `CI`.
|
- Variable names must not start with `CI`.
|
||||||
|
|
||||||
## Using variable
|
### Using variables
|
||||||
|
|
||||||
After creating configuration variables, they will be automatically filled in the `vars` context.
|
After creating configuration variables, they will be automatically filled in the `vars` context.
|
||||||
They can be accessed through expressions like `${{ vars.VARIABLE_NAME }}` in the workflow.
|
They can be accessed through expressions like `${{ vars.VARIABLE_NAME }}` in the workflow.
|
||||||
|
|
||||||
## Precedence
|
### Precedence
|
||||||
|
|
||||||
If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence:
|
If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence:
|
||||||
A repository variable will always be chosen over an organization/user variable.
|
A repository variable will always be chosen over an organization/user variable.
|
||||||
@@ -19,30 +19,33 @@ Git version 2.29 or higher is required on the server side for this to work.
|
|||||||
## Creating PRs with AGit
|
## Creating PRs with AGit
|
||||||
|
|
||||||
AGit allows to create PRs while pushing code to the remote repo.
|
AGit allows to create PRs while pushing code to the remote repo.
|
||||||
This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git).
|
This can be done by pushing to a special refspec (a location identifier known to git) instead of to a branch.
|
||||||
The following example illustrates this:
|
The following example illustrates this:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git push origin HEAD:refs/for/main
|
git push origin HEAD:refs/for/main -o topic="topic_of_my_PR"
|
||||||
```
|
```
|
||||||
|
|
||||||
The command has the following structure:
|
The command has the following structure:
|
||||||
|
|
||||||
- `HEAD`: The target branch
|
```shell
|
||||||
- `origin`: The target repository (not a fork!)
|
git push <remote> <local-rev>:refs/for/<branch>[/<topic>] [-o <option>[=<value>] ...]
|
||||||
- `HEAD`: The local branch containing the changes you are proposing
|
```
|
||||||
- `refs/<for|draft|for-review>/<branch>`: The target PR type and configuration
|
|
||||||
- `for`: Create a normal PR with `<branch>` as the target branch
|
- `<remote>`: The remote pointing at the target repository (not a fork!), `origin` in the example above
|
||||||
- `draft`/`for-review`: Currently ignored silently
|
- `<local-rev>`: The local branch or commit containing the changes you are proposing, `HEAD` in the example above
|
||||||
- `<branch>/`: The branch you want your changes to be merged into
|
- `refs/for/<branch>`: The target PR type and configuration
|
||||||
- `-o <topic|title|description>`: Options for the PR
|
- `for`: Create a normal PR with `<branch>` as the target branch. This is the only prefix supported at the moment, `refs/draft/...` and `refs/for-review/...` are reserved for future use and do not create a PR.
|
||||||
- `topic`: The topic of this change. It will become the name of the branch holding the changes waiting for review. This is REQUIRED to trigger a pull request.
|
- `<branch>`: The branch you want your changes to be merged into
|
||||||
|
- `<topic>`: Optional, an alternative to `-o topic=<topic>`. The push is rejected with `topic-branch is not set` if the topic is given in neither place.
|
||||||
|
- `-o <option>[=<value>]`: Options for the PR
|
||||||
|
- `topic`: The topic of this change. It will become the name of the branch holding the changes waiting for review (prefixed with your user name). This is REQUIRED to trigger a pull request, unless it is already part of the refspec.
|
||||||
- `title`: The PR title (optional but recommended), only used for topics not already having an associated PR.
|
- `title`: The PR title (optional but recommended), only used for topics not already having an associated PR.
|
||||||
- `description`: The PR description (optional but recommended), only used for topics not already having an associated PR.
|
- `description`: The PR description (optional but recommended), only used for topics not already having an associated PR.
|
||||||
- `force-push=true`: Specifies whether to force-update the target branch.
|
- `force-push=true`: Specifies whether to force-update the target branch.
|
||||||
- Note: omitting the value and using just `-o force-push` will also work.
|
- Note: omitting the value and using just `-o force-push` will also work.
|
||||||
|
|
||||||
Here's another advanced example for creating a new PR targeting `main` with `topic`, `title`, and `description`:
|
Here's another example for creating a new PR targeting `main` with `topic`, `title`, and `description`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git push origin HEAD:refs/for/main -o topic="topic_of_my_PR" -o title="Title of the PR" -o description="# The PR Description\nThis can be **any** markdown content.\n- [x] Ok"
|
git push origin HEAD:refs/for/main -o topic="topic_of_my_PR" -o title="Title of the PR" -o description="# The PR Description\nThis can be **any** markdown content.\n- [x] Ok"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ creating issues and pull requests. This will cut down on the initial back and fo
|
|||||||
of getting some clarifying details.
|
of getting some clarifying details.
|
||||||
It is currently not possible to provide generic issue/pull-request templates globally.
|
It is currently not possible to provide generic issue/pull-request templates globally.
|
||||||
|
|
||||||
Additionally, the New Issue page URL can be suffixed with `?title=Issue+Title&body=Issue+Text` and the form will be populated with those strings. Those strings will be used instead of the template if there is one.
|
Additionally, the New Issue page URL can be suffixed with `?title=Issue+Title&body=Issue+Text` and the form will be populated with those strings. Those strings will be used instead of the template if there is one. See [Pre-filling Issues and Pull Requests](prefill-issues-pull-requests.md) for all parameters.
|
||||||
|
|
||||||
## File names
|
## File names
|
||||||
|
|
||||||
@@ -100,6 +100,8 @@ about: "This template is for testing!"
|
|||||||
title: "[TEST] "
|
title: "[TEST] "
|
||||||
ref: "main"
|
ref: "main"
|
||||||
assignees: ["user1"]
|
assignees: ["user1"]
|
||||||
|
projects:
|
||||||
|
- Example Project
|
||||||
labels:
|
labels:
|
||||||
|
|
||||||
- bug
|
- bug
|
||||||
@@ -114,6 +116,7 @@ In the above example, when a user is presented with the list of issues they can
|
|||||||
`This template is for testing!`. When submitting an issue with the above example, the issue title would be pre-populated with
|
`This template is for testing!`. When submitting an issue with the above example, the issue title would be pre-populated with
|
||||||
`[TEST] ` while the issue body would be pre-populated with `This is the template!`.
|
`[TEST] ` while the issue body would be pre-populated with `This is the template!`.
|
||||||
The issue would be assigned to `user1`.
|
The issue would be assigned to `user1`.
|
||||||
|
The issue would be assigned to the project `Example Project`.
|
||||||
The issue would also be assigned two labels,
|
The issue would also be assigned two labels,
|
||||||
`bug` and `help needed`, and the issue will have a reference to `main`.
|
`bug` and `help needed`, and the issue will have a reference to `main`.
|
||||||
|
|
||||||
|
|||||||
Loaded 50 of 2340 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user