Files
supabase/.github/workflows/docs-lint-v2.yml
Charis da724eb8c6 ci: add zizmor lint and harden GitHub Actions workflows (#47895)
## Summary
- Add a zizmor config and CI job that lints `.github/workflows` on every
PR touching it, downloading and attestation-verifying the pinned v1.26.1
release binary (cached across runs)
- Fix the mutable-tag and excess-permission findings zizmor surfaces in
`braintrust-evals.yml`, `publish_image.yml`, and
`self-host-tests-smoke.yml`: pin `actions/checkout`/`actions/setup-node`
to commit SHAs, and scope `pull-requests`/`packages`/`id-token`
permissions down to the specific jobs that need them

## Test plan
- [x] Confirm the `zizmor` job runs and passes on this PR

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added automated security scanning for workflow changes on pull
requests.
  * Added configuration to allow specific workflow trigger exceptions.

* **Security**
* Tightened GitHub Actions permissions at the workflow level and
re-granted only where required per job.
* Pinned common build action versions to specific commits for more
consistent execution.

* **Maintenance**
* Updated workflow caching and action step annotations without changing
linting or fixing behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 16:57:44 -04:00

109 lines
4.3 KiB
YAML

name: docs_lint
# Runs the docs linter on PRs that edit docs content.
# There are two branches of this workflow for internal and external PRs, due
# to the security design of GitHub Actions.
#
# Internal PRs:
# Have write permissions, so comments are written directly by reviewdog.
#
# External PRs:
# Have read-only permissions, so lint results are uploaded as an artifact, to
# be written to the PR in a subsequent workflow_run action that has write
# permissions. See ./docs/lint-v2-comment.yml.
#
# See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
on:
pull_request:
env:
CARGO_NET_GIT_FETCH_WITH_CLI: true
permissions:
pull-requests: write
jobs:
supa-mdx-lint:
name: supa-mdx-lint
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
sparse-checkout: |
supa-mdx-lint.config.toml
supa-mdx-lint
apps/docs/content
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
docs:
- 'apps/docs/content/**'
- 'supa-mdx-lint/**'
- 'supa-mdx-lint.config.toml'
- name: cache cargo
id: cache-cargo
if: steps.filter.outputs.docs == 'true'
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: 6b08233ff8bca855f6a38246b2a8049332219188
- name: install linter
if: steps.filter.outputs.docs == 'true' && steps.cache-cargo.outputs.cache-hit != 'true'
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 6b08233ff8bca855f6a38246b2a8049332219188
- name: install reviewdog
if: steps.filter.outputs.docs == 'true'
uses: reviewdog/action-setup@3f401fe1d58fe77e10d665ab713057375e39b887 # v1.3.0
with:
reviewdog_version: v0.20.2
- name: run linter (internal)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name == github.repository
env:
BASE_REF: ${{ github.base_ref }}
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -o pipefail
git diff --name-only "origin/$BASE_REF" HEAD \
| { grep -E "^apps/docs/content/" || test $? = 1; } \
| xargs -r supa-mdx-lint --format rdf \
| reviewdog -f=rdjsonl -reporter=github-pr-review -tee
- id: external_lint
name: run linter (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository
env:
BASE_REF: ${{ github.base_ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -o pipefail
run_lints() {
git diff --name-only "origin/$BASE_REF" HEAD \
| { grep -E "^apps/docs/content/" || test $? = 1; } \
| xargs -rx -n 1000000000 supa-mdx-lint --format markdown
}
set +e
LINT_RESULTS=$(run_lints)
LINT_EXIT_CODE=$?
set -e
echo "LINT_EXIT_CODE=$LINT_EXIT_CODE" >> $GITHUB_OUTPUT
if [[ $LINT_EXIT_CODE -ne 0 ]]; then
mkdir -p ./__github_actions__pr
echo "${{ github.event.number }}" > ./__github_actions__pr/pr_number.txt
echo "$LINT_RESULTS" > ./__github_actions__pr/lint_results.txt
fi
- name: save results as artifact (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository && steps.external_lint.outputs.LINT_EXIT_CODE != 0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: lint_results
path: __github_actions__pr/
- name: fail if linter fails (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository && steps.external_lint.outputs.LINT_EXIT_CODE != 0
run: exit 1