diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0c1c242 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +# CI that runs on the GitHub mirror. +# +# The real pipeline lives in .forgejo/workflows and does the building, the +# registry push and the deploy, because only the Forgejo runner can reach the +# cluster. This workflow deliberately does none of that. It exists so the +# repository a reviewer opens on GitHub shows its own green checks, and so a +# secret can never reach the mirror unnoticed. +# +# No secrets are consumed here and none are needed. + +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + secrets: + name: secret scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + # Run as a plain container rather than a marketplace action, so the same + # command works unchanged on the Forgejo runner. + - name: gitleaks + run: | + docker run --rm -v "$PWD:/repo" \ + ghcr.io/gitleaks/gitleaks:v8.30.1 \ + detect --source /repo --redact -v + + go: + name: vet, test, lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + # The API is written by a separate agent. Until it lands there is no + # go.mod, and this job should pass rather than fail on an empty tree. + - id: probe + run: | + if [ -f apps/api/go.mod ]; then + echo "ready=true" >> "$GITHUB_OUTPUT" + else + echo "ready=false" >> "$GITHUB_OUTPUT" + echo "apps/api/go.mod not present yet, skipping Go checks" >> "$GITHUB_STEP_SUMMARY" + fi + + - uses: actions/setup-go@v7 + if: steps.probe.outputs.ready == 'true' + with: + go-version-file: apps/api/go.mod + cache-dependency-path: apps/api/go.sum + + - name: vet and test + if: steps.probe.outputs.ready == 'true' + working-directory: apps/api + run: | + go vet ./... + go test -race ./... + + - uses: golangci/golangci-lint-action@v9 + if: steps.probe.outputs.ready == 'true' + with: + working-directory: apps/api