# ci-workflows Shared reusable Forgejo Actions workflows for every repo on git.capybara.network. | Workflow | Tool | Fails on | |---|---|---| | `secrets.yml` | gitleaks, full git history | any secret not listed in `.gitleaksignore` | | `sast.yml` | semgrep, `p/default` | any finding not suppressed with `nosemgrep` or `.semgrepignore` | | `deps.yml` | osv-scanner | a known vulnerability in a lockfile or manifest, unless ignored in `osv-scanner.toml` | | `lint.yml` | shellcheck, ruff, hadolint, yamllint, actionlint, `tofu fmt` + tflint | lint errors; each linter runs only if matching files exist | The tools are baked into the runner image (`flux-talos`, `clusters/talos/apps/forgejo-runner/image/Dockerfile`); these workflows install nothing at run time. ## Using them Add `.forgejo/workflows/checks.yml` to a repo: ```yaml name: checks on: push: branches: [main] pull_request: jobs: secrets: runs-on: ubuntu-latest uses: capyadmin/ci-workflows/.forgejo/workflows/secrets.yml@v1 sast: runs-on: ubuntu-latest uses: capyadmin/ci-workflows/.forgejo/workflows/sast.yml@v1 deps: runs-on: ubuntu-latest uses: capyadmin/ci-workflows/.forgejo/workflows/deps.yml@v1 lint: runs-on: ubuntu-latest uses: capyadmin/ci-workflows/.forgejo/workflows/lint.yml@v1 ``` Two Forgejo 11 constraints shape this, both verified on this instance on 18 Oct 2026: - **This repo must stay public.** The runner fetches a cross-repo reusable workflow anonymously; with the repo private the calling job fails. Never put anything secret here. - **The calling job needs `runs-on`.** Forgejo 11 expands the reusable workflow in the runner, not the server, so the caller has to be scheduled onto one. GitHub forbids this combination; `lint.yml` tells actionlint to ignore it. Inputs (all optional) are documented at the top of each workflow, e.g.: ```yaml lint: runs-on: ubuntu-latest uses: capyadmin/ci-workflows/.forgejo/workflows/lint.yml@v1 with: ruff-format: true shellcheck-severity: error ``` ## Versioning `v1` is a moving tag on the latest compatible commit. A change that could newly fail existing callers (a stricter default, a new linter switched on by default) goes out as `v2`.