diff --git a/README.md b/README.md index 8891e7e..c4464fa 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,17 @@ merge with rebase or merge commits instead, set `commits-mode: block`. to fetch the commits. The action makes no API calls and never writes anything. With `commits-mode: off` it reads only the event payload. -While the `commitlint` repository is private, `go install` needs credentials -to fetch the module. The action rewrites only `github.com/DivergentCodes/` -URLs to carry `github-token`, so the token is never offered to another host or -org, and sets `GOPRIVATE` so the public proxy and checksum database are -bypassed. Pass a token that can read that repo: +The action installs the linter with a public `go install` first. If the +`commitlint` repository is public, that path is used and the module proxy's +**checksum-database verification applies** — nothing else is needed. + +If that fetch fails, the repository is private and credentials are required. +The action then rewrites only `github.com/DivergentCodes/` URLs to carry +`github-token`, so the token is never offered to another host or org, and sets +`GOPRIVATE` for the retry. `GOPRIVATE` bypasses the proxy and checksum +database — unavoidable for a private module, which is why it is scoped to the +fallback rather than applied unconditionally. Pass a token that can read the +repo: ```yaml - uses: DivergentCodes/commitlint-action@ diff --git a/action.yml b/action.yml index cefa2aa..d5140b1 100644 --- a/action.yml +++ b/action.yml @@ -45,34 +45,42 @@ runs: go-version: stable cache: false - # `go install` fetches over HTTPS with no credentials, so while the - # commitlint repo is private git prompts for a username and dies with - # "terminal prompts disabled". Rewrite only DivergentCodes URLs to carry - # the token, so it is never offered to another host or org, and set - # GOPRIVATE so the public proxy and checksum database — which cannot see a - # private module — are bypassed rather than consulted and failed. - # - # This is a no-op once commitlint is public: the rewrite still matches, but - # a public fetch would have succeeded anyway. + # Public first, credentials only as a fallback. The private path has to set + # GOPRIVATE, which bypasses the module proxy *and the checksum database* — + # unavoidable for a private module, but a real loss of supply-chain + # verification. Attempting the public fetch first means a public commitlint + # keeps that verification instead of silently forfeiting it. - name: Install commitlint shell: bash env: VERSION: ${{ inputs.version }} GH_TOKEN: ${{ inputs.github-token }} - GOPRIVATE: github.com/DivergentCodes/* run: | set -euo pipefail + + if go install "github.com/DivergentCodes/commitlint@${VERSION}"; then + exit 0 + fi + + if [ -z "${GH_TOKEN:-}" ]; then + echo "::error::could not fetch github.com/DivergentCodes/commitlint@${VERSION}; if that repository is private, pass a token that can read it via the github-token input" + exit 1 + fi + + echo "public fetch failed; retrying with credentials" cleanup() { git config --global --unset-all \ url."https://x-access-token:${GH_TOKEN}@github.com/DivergentCodes/".insteadOf || true } trap cleanup EXIT - # The token stays in the environment rather than argv, and Actions - # masks it in logs; the trap keeps it out of later steps' git config. + # Rewrite only DivergentCodes URLs, so the token is never offered to + # another host or org. It stays in the environment rather than argv, + # Actions masks it in logs, and the trap keeps it out of later steps. git config --global \ url."https://x-access-token:${GH_TOKEN}@github.com/DivergentCodes/".insteadOf \ "https://github.com/DivergentCodes/" - go install "github.com/DivergentCodes/commitlint@${VERSION}" + GOPRIVATE='github.com/DivergentCodes/*' \ + go install "github.com/DivergentCodes/commitlint@${VERSION}" - name: Lint PR title if: ${{ inputs.pr-title-mode != 'off' && github.event_name == 'pull_request' }}