From 56b40ab72b4d47bf56cc10e871c2c65e59d71f88 Mon Sep 17 00:00:00 2001 From: Rex Raphael Date: Fri, 4 Sep 2026 15:19:45 -0500 Subject: [PATCH] feat(go-ci): support private Go module dependencies A repo whose go.mod requires a private repo in this org has had no way to make go-ci.yml resolve it. A caller can't inject a step into a reusable workflow's jobs, so nothing on the consumer's side could fix this. This just bit a newly published module that depends on a private sibling repo. Add an optional XRAPH_REPO_TOKEN secret and a "Configure Go module auth" step in test, lint, verify and security, run before each job's Set up Go. The step is a no-op when the secret is unset, so every existing caller keeps working exactly as before. GOPRIVATE defaults to github.com/xraph/* and is now an input too, so a caller can override it if it ever needs to. --- .github/workflows/go-ci.yml | 67 +++++++++++++++++++++++++++++++++++++ README.md | 26 ++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 32f325a..e893eb8 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -1,3 +1,19 @@ +# Private Go module dependencies +# +# A repo whose go.mod requires a private repo in this org needs the module +# proxy path authenticated before any `go` command touches the network. Pass +# the org secret through: +# +# secrets: +# XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} +# +# A caller using `secrets: inherit` gets this automatically, no change +# needed. A caller passing secrets explicitly (as the README recommends) +# must add the line above itself, alongside CODECOV_TOKEN. +# +# The secret is optional. Leave it unset and every job runs exactly as it +# does today - the auth step becomes a no-op. + name: Go CI on: @@ -67,9 +83,16 @@ on: description: 'Check that nested go.mod files require their siblings at versions the module proxy can serve. A nested module replace is ignored once the module is somebody else dependency, so a require naming an unpublished version breaks go get for every consumer while every local build keeps working. No-op in a repo with a single go.mod.' type: boolean default: true + private-module-pattern: + description: 'GOPRIVATE pattern applied when XRAPH_REPO_TOKEN is set. Only takes effect if the secret is present.' + type: string + default: 'github.com/xraph/*' secrets: CODECOV_TOKEN: required: false + XRAPH_REPO_TOKEN: + description: 'Org token for resolving private github.com/xraph/* Go modules. Optional - unset means public-only, matching current behavior.' + required: false jobs: setup: @@ -129,6 +152,17 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Configure Go module auth + env: + XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} + PRIVATE_MODULE_PATTERN: ${{ inputs.private-module-pattern }} + run: | + set -euo pipefail + if [ -n "${XRAPH_REPO_TOKEN}" ]; then + git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + echo "GOPRIVATE=${PRIVATE_MODULE_PATTERN}" >> "$GITHUB_ENV" + fi + - name: Set up Go uses: actions/setup-go@v7 with: @@ -267,6 +301,17 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Configure Go module auth + env: + XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} + PRIVATE_MODULE_PATTERN: ${{ inputs.private-module-pattern }} + run: | + set -euo pipefail + if [ -n "${XRAPH_REPO_TOKEN}" ]; then + git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + echo "GOPRIVATE=${PRIVATE_MODULE_PATTERN}" >> "$GITHUB_ENV" + fi + - name: Set up Go uses: actions/setup-go@v7 with: @@ -299,6 +344,17 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Configure Go module auth + env: + XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} + PRIVATE_MODULE_PATTERN: ${{ inputs.private-module-pattern }} + run: | + set -euo pipefail + if [ -n "${XRAPH_REPO_TOKEN}" ]; then + git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + echo "GOPRIVATE=${PRIVATE_MODULE_PATTERN}" >> "$GITHUB_ENV" + fi + - name: Set up Go uses: actions/setup-go@v7 with: @@ -366,6 +422,17 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Configure Go module auth + env: + XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} + PRIVATE_MODULE_PATTERN: ${{ inputs.private-module-pattern }} + run: | + set -euo pipefail + if [ -n "${XRAPH_REPO_TOKEN}" ]; then + git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + echo "GOPRIVATE=${PRIVATE_MODULE_PATTERN}" >> "$GITHUB_ENV" + fi + - name: Set up Go uses: actions/setup-go@v7 with: diff --git a/README.md b/README.md index b81899d..302dafa 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,32 @@ npm-global-packages: 'typescript@5.8.2 esbuild@0.28.1' Both default to empty, so nothing is installed unless asked. +## Private Go module dependencies + +A repo whose go.mod requires a private repo in this org needs the module +proxy authenticated before any `go` command touches the network, and a +reusable workflow's caller cannot inject a step into its jobs to do that +itself. `go-ci.yml` covers it directly: pass the org secret through, and a +"Configure Go module auth" step runs in `test`, `lint`, `verify` and +`security`, before that job's `Set up Go` step, so it takes effect for +`go mod download`, `golangci-lint`, `go vet`, `gosec` and `govulncheck` alike. + +```yaml +secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }} +``` + +The secret is optional and defaults to unset, so every existing caller is +unaffected. If your workflow uses `secrets: inherit`, you already get this +for free and there is nothing to change. If you pass secrets explicitly, as +recommended above, add the `XRAPH_REPO_TOKEN` line yourself alongside +`CODECOV_TOKEN`. + +The step sets `GOPRIVATE` to `github.com/xraph/*` by default. Override it +with the `private-module-pattern` input if your module paths need a +different pattern, though that should be rare inside this org. + ## Escaping the Makefile probe `go-ci.yml` prefers a Makefile target when one matching the step exists. That