- Shell 100%
Both install steps run under set -o pipefail and printed the version with head -1. head exits after one line, and when the tool still has output to write it dies of SIGPIPE, so the step exits 141. That failed the osv job on infra main at f2fd8bd (run 2052) right after it printed the version, and blocked a deploy. sed -n 1p reads to the end, so the tool always finishes. Agent: Aki |
||
|---|---|---|
| .forgejo/workflows | ||
| actionlint | ||
| gitleaks | ||
| lint-eol | ||
| lint-python | ||
| lint-shell | ||
| lint-trailers | ||
| lint-yaml | ||
| osv-scanner | ||
| renovate | ||
| scan | ||
| scripts | ||
| .gitattributes | ||
| LICENSE | ||
| README.md | ||
| renovate.json | ||
actions
Shared Forgejo Actions for any repo on this instance, public or private.
| Action | What it does | Inputs |
|---|---|---|
gitleaks |
Installs a pinned, checksum-verified gitleaks and scans the working tree (not history). | path (.), version, sha256 |
lint-shell |
shellcheck over every tracked *.sh. |
severity (error) |
lint-yaml |
Checks every tracked *.yml/*.yaml parses. |
none |
lint-python |
Installs a pinned, checksum-verified ruff and runs ruff check with the calling repo's ruff.toml/pyproject.toml (lint only, no format check). |
path (.), version, sha256 |
lint-eol |
Every tracked text file is stored as LF and has eol=lf set, so a Windows checkout or git archive can't write CRLF. |
allow-crlf (globs) |
actionlint |
Installs a pinned, checksum-verified actionlint and lints every tracked workflow in .forgejo/workflows / .github/workflows. Forgejo's full-URL uses: and forgejo context are allowed. |
runner-labels (docker ubuntu-latest), version, sha256 |
lint-trailers |
Each commit by one of authors carries exactly one Agent: trailer that git itself reads (git interpret-trailers --parse). Fails on PR commits only; on a push it reports. |
authors (required), range, report (auto), path (.) |
osv-scanner |
Installs a pinned, checksum-verified osv-scanner and checks every lockfile/manifest against OSV. Fails on a known vulnerability; no package files is a pass. | path (.), fail-on-vuln (true), version, sha256 |
scan |
Runs the agent-kit scan pack (ak scan) over every tracked file, plus private layer files from the workspace or another repo. agent-kit is fetched at a pinned SHA with a read token and installed in a venv. Hits name the rule and line, never the text. Mode check only loads the layers and fails on a bad one. Fails closed without a token. |
kit-repo, kit-ref (or kit-path), token, layers, layers-repo, layers-ref (main), layers-path (scan-layers), mode (scan), path, exclude, kinds |
lint-shell, lint-yaml, lint-python, lint-eol, actionlint and osv-scanner need a checkout first. lint-shell and lint-yaml
install their tool with apt when the job image lacks it, so they expect a Debian/Ubuntu
image; lint-python, actionlint and osv-scanner (like gitleaks) download a pinned linux x64 binary and need only curl;
lint-eol needs only git; lint-trailers needs git and a full checkout (fetch-depth: 0).
scan needs a checkout, git, python3 (it installs python3-venv with apt when the image lacks it) and network to the package index.
Usage
Refer to actions by full URL and pin them to a full commit SHA:
jobs:
lint:
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: https://git.nas.lab.aareon.pro/ci/actions/gitleaks@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/lint-shell@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/lint-yaml@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/lint-python@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/lint-eol@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/actionlint@<commit-sha>
- uses: https://git.nas.lab.aareon.pro/ci/actions/osv-scanner@<commit-sha>
lint-trailers needs the whole history and the author emails to check:
trailers:
runs-on: docker
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: https://git.nas.lab.aareon.pro/ci/actions/lint-trailers@<commit-sha>
with:
authors: agent@example.org
A short name like ci/actions/gitleaks would be looked up on data.forgejo.org,
not here. A SHA can't be moved; a tag or branch can.
scan needs a read token for agent-kit, and for the layer repo if there is one, passed
from a secret. Pin kit-ref to a full SHA like the action itself; the layers follow
layers-ref (main) so a merged rule applies to the next run. Skip test fixtures that
hold sample secrets with exclude:
scan:
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: https://git.nas.lab.aareon.pro/ci/actions/scan@<commit-sha>
with:
kit-repo: owner/agent-kit
kit-ref: <agent-kit commit-sha>
token: ${{ secrets.SCAN_TOKEN }}
layers-repo: owner/rules
exclude: |
tests/fixtures/
The repo that holds the layers checks them on every change with mode: check and
layers: <folder>, so a bad line fails its own PR before it reaches anyone else.
Renovate preset
renovate/default.json is the shared Renovate
config for repos on this instance. A repo opts in with a renovate.json of:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>ci/actions//renovate/default"]
}
It extends config:recommended with a dependency dashboard issue, a weekly schedule (security
fixes from osv.dev at any time), at most 5 open PRs, a 3-day wait on new npm/PyPI releases, one
grouped PR that moves every ci/actions SHA pin to the newest commit on main, and short
uses: names in Forgejo workflows looked up on data.forgejo.org (whose tags differ from
github.com). Database images (postgres, redis, mariadb, ...) only get a major-version PR once
it is approved on the dashboard. Nothing is automerged.
Rules (this repo is public)
- Nothing internal. No hostnames, IPs, host paths, usernames or secrets. Anything
site-specific comes in through an input from the calling repo.
scripts/check-public-safe.shenforces the common cases in CI, alongside gitleaks. - Secrets only through inputs. An action never reads a secret from the environment on its own; the caller passes each one explicitly, so it's clear what can see what.
- Inputs go through
env:, never straight intorun:as${{ inputs.x }}, so a value can't inject shell. - Pin third-party downloads by version and checksum, as
gitleaksdoes. - Changes land by PR.
mainneeds the owner's approval, and only the owner can createv*tags. Callers still pin by SHA.
Actions that need lab-specific knowledge don't belong here; keep them in a private repo.