The third port of the same two things. Gitea walks WORKFLOW_DIRS and stops at the first directory that exists, so .gitea/workflows/ replaces .github/workflows/ outright on a Gitea instance — which is the point, since deploy.yml there is built on repository_dispatch and an environment: and Gitea has neither. Four differences shape the files: - No environment:, so no scoped secret and no required reviewers. The file does not write the key at all rather than claim a protection that Gitea parses and ignores; what gates a deploy is write access to the repository. - No repository_dispatch. External callers post to the workflow dispatch API, which fills in the same form — and can return a run id, so unlike repository_dispatch the caller may follow the deploy it asked for. - runs-on takes a literal label only, so GitHub's vars.DEPLOY_RUNNER expression becomes one documented line to edit. - A job is itself a container with no Docker socket, so the secret scan runs the pinned gitleaks binary instead of the upstream image. Input validation carries over unchanged and matters more here: type: choice constrains the dispatch form, not the API. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
113 lines
4.7 KiB
YAML
113 lines
4.7 KiB
YAML
---
|
|
# The static gate on Gitea. The same three checks as .github/workflows/lint.yml,
|
|
# with the adjustments a Gitea runner forces. Setup: docs/ci-gitea.md.
|
|
#
|
|
# Creating .gitea/workflows/ at all is a decision rather than a convenience.
|
|
# Gitea walks WORKFLOW_DIRS in order — `.gitea/workflows` then `.github/workflows`
|
|
# by default — and stops at the first directory that exists. So this directory
|
|
# replaces the GitHub workflows wholesale on a Gitea instance, which is what you
|
|
# want: deploy.yml there is built on `repository_dispatch` and an `environment:`,
|
|
# and Gitea has neither.
|
|
#
|
|
# Delete whichever platform you are not using rather than letting it rot.
|
|
name: lint
|
|
|
|
on:
|
|
push:
|
|
branches: ["**"]
|
|
pull_request:
|
|
|
|
# Concurrency syntax landed in Gitea 1.26. Older instances ignore this block
|
|
# rather than failing on it — you simply get both runs.
|
|
concurrency:
|
|
group: lint-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
ansible:
|
|
name: yamllint + ansible-lint + syntax
|
|
# A literal label, never `${{ vars.SOMETHING }}`: Gitea supports `runs-on: xyz`
|
|
# and `runs-on: [xyz]` and nothing more. There are also no hosted runners, so
|
|
# this label is only ever your own — see "Runners" in docs/ci-gitea.md.
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
# Resolved against DEFAULT_ACTIONS_URL, which is github.com unless your
|
|
# administrator set it to `self`. On an instance that cannot reach github.com
|
|
# this step is the first thing that fails, and it fails for every workflow —
|
|
# mirror actions/checkout into the instance, or set the setting back.
|
|
- uses: actions/checkout@v4
|
|
|
|
# Keep this even though the runner image ships a Python. Ubuntu 24.04 images
|
|
# are PEP 668 "externally managed", where a plain `pip install` refuses to
|
|
# touch the system interpreter; setup-python brings its own and sidesteps it.
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
# scripts/check.sh is the single source of the version pins; it prints them
|
|
# so that this workflow installs exactly what a contributor runs locally.
|
|
# Nothing here can drift from `make check`.
|
|
- name: Install the pinned toolchain
|
|
run: |
|
|
set -eu
|
|
scripts/check.sh --print-specs | tee /dev/stderr | xargs -d '\n' pip install --quiet
|
|
|
|
- name: Run the static gate
|
|
run: RUNNER=installed scripts/check.sh
|
|
|
|
shell:
|
|
name: shellcheck
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
# Jobs run as root inside the runner's container, where `sudo` is often not
|
|
# installed at all. Asking for it only when the uid is not 0 keeps this step
|
|
# working on a container runner and on a `:host` runner alike.
|
|
- name: Install shellcheck
|
|
run: |
|
|
set -eu
|
|
if ! command -v shellcheck >/dev/null 2>&1; then
|
|
sudo=""
|
|
[ "$(id -u)" -eq 0 ] || sudo=sudo
|
|
$sudo apt-get update -qq
|
|
$sudo apt-get install -y --no-install-recommends shellcheck
|
|
fi
|
|
- name: Check the shell scripts
|
|
run: shellcheck scripts/*.sh server/*/*/app/*.sh
|
|
|
|
secrets:
|
|
name: secret scan
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
# detect scans history, not just the working tree. A secret that was
|
|
# committed and then removed is still a leaked secret.
|
|
fetch-depth: 0
|
|
|
|
# The GitHub workflow runs the upstream gitleaks *image*. That is not
|
|
# portable here: an act_runner job is itself a container, and it has no
|
|
# Docker socket unless the administrator mounted one into it, so
|
|
# `docker run` fails with "Cannot connect to the Docker daemon". The
|
|
# released binary needs nothing but curl and has the same behaviour.
|
|
#
|
|
# Pinned deliberately: a scanner that changes under you turns a green
|
|
# history red on a morning you changed nothing.
|
|
- name: Fetch the pinned gitleaks binary
|
|
env:
|
|
GITLEAKS_VERSION: 8.30.1
|
|
run: |
|
|
set -eu
|
|
base=https://github.com/gitleaks/gitleaks/releases/download
|
|
curl -sSfL -o /tmp/gitleaks.tar.gz \
|
|
"$base/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
|
|
# Left in /tmp and run from there. Installing into /usr/local/bin would
|
|
# need root, which a `:host` runner does not have and should not want.
|
|
tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks
|
|
chmod +x /tmp/gitleaks
|
|
|
|
- name: Scan the working tree and history for committed secrets
|
|
run: |
|
|
/tmp/gitleaks detect --source=. --config=.gitleaks.toml \
|
|
--redact --verbose --no-banner
|