Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/workflows/go-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,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
goprivate:
description: 'GOPRIVATE glob applied when XRAPH_REPO_TOKEN is set. Narrow it to what is genuinely private - the glob also sets GONOPROXY, so a broad one drags every public module under it off the proxy and onto a full git clone per job, for nothing. Comma-separated for more than one.'
type: string
default: 'github.com/xraph/*'
secrets:
CODECOV_TOKEN:
required: false
XRAPH_REPO_TOKEN:
description: 'Read access to the private repositories in this org. Without it, private modules are never fetched and a repo that needs one fails at download.'
required: false

jobs:
setup:
Expand Down Expand Up @@ -129,6 +136,27 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

# kgkit and any other private xraph module is not on the public proxy, and
# an unauthenticated fetch comes back "repository not found", which reads
# as a missing repo rather than a missing credential. Carry the token on
# the org's clone URL and take the private paths off the proxy.
#
# The rewrite is scoped to the org rather than to all of github.com, so it
# cannot clobber a credential a consumer has already set for somewhere
# else. No-op without the secret, so public-only consumers are unaffected.
- name: Configure Go module auth
shell: bash
env:
XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }}
GOPRIVATE_GLOB: ${{ inputs.goprivate }}
run: |
set -euo pipefail
if [ -n "${XRAPH_REPO_TOKEN:-}" ]; then
git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/xraph/".insteadOf "https://github.com/xraph/"
echo "GOPRIVATE=${GOPRIVATE_GLOB}" >> "$GITHUB_ENV"
echo "- private modules: \`${GOPRIVATE_GLOB}\`, fetched over the token" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Set up Go
uses: actions/setup-go@v7
with:
Expand Down Expand Up @@ -267,6 +295,27 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

# kgkit and any other private xraph module is not on the public proxy, and
# an unauthenticated fetch comes back "repository not found", which reads
# as a missing repo rather than a missing credential. Carry the token on
# the org's clone URL and take the private paths off the proxy.
#
# The rewrite is scoped to the org rather than to all of github.com, so it
# cannot clobber a credential a consumer has already set for somewhere
# else. No-op without the secret, so public-only consumers are unaffected.
- name: Configure Go module auth
shell: bash
env:
XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }}
GOPRIVATE_GLOB: ${{ inputs.goprivate }}
run: |
set -euo pipefail
if [ -n "${XRAPH_REPO_TOKEN:-}" ]; then
git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/xraph/".insteadOf "https://github.com/xraph/"
echo "GOPRIVATE=${GOPRIVATE_GLOB}" >> "$GITHUB_ENV"
echo "- private modules: \`${GOPRIVATE_GLOB}\`, fetched over the token" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Set up Go
uses: actions/setup-go@v7
with:
Expand Down Expand Up @@ -299,6 +348,27 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

# kgkit and any other private xraph module is not on the public proxy, and
# an unauthenticated fetch comes back "repository not found", which reads
# as a missing repo rather than a missing credential. Carry the token on
# the org's clone URL and take the private paths off the proxy.
#
# The rewrite is scoped to the org rather than to all of github.com, so it
# cannot clobber a credential a consumer has already set for somewhere
# else. No-op without the secret, so public-only consumers are unaffected.
- name: Configure Go module auth
shell: bash
env:
XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }}
GOPRIVATE_GLOB: ${{ inputs.goprivate }}
run: |
set -euo pipefail
if [ -n "${XRAPH_REPO_TOKEN:-}" ]; then
git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/xraph/".insteadOf "https://github.com/xraph/"
echo "GOPRIVATE=${GOPRIVATE_GLOB}" >> "$GITHUB_ENV"
echo "- private modules: \`${GOPRIVATE_GLOB}\`, fetched over the token" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Set up Go
uses: actions/setup-go@v7
with:
Expand Down Expand Up @@ -366,6 +436,27 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

# kgkit and any other private xraph module is not on the public proxy, and
# an unauthenticated fetch comes back "repository not found", which reads
# as a missing repo rather than a missing credential. Carry the token on
# the org's clone URL and take the private paths off the proxy.
#
# The rewrite is scoped to the org rather than to all of github.com, so it
# cannot clobber a credential a consumer has already set for somewhere
# else. No-op without the secret, so public-only consumers are unaffected.
- name: Configure Go module auth
shell: bash
env:
XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }}
GOPRIVATE_GLOB: ${{ inputs.goprivate }}
run: |
set -euo pipefail
if [ -n "${XRAPH_REPO_TOKEN:-}" ]; then
git config --global url."https://x-access-token:${XRAPH_REPO_TOKEN}@github.com/xraph/".insteadOf "https://github.com/xraph/"
echo "GOPRIVATE=${GOPRIVATE_GLOB}" >> "$GITHUB_ENV"
echo "- private modules: \`${GOPRIVATE_GLOB}\`, fetched over the token" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Set up Go
uses: actions/setup-go@v7
with:
Expand Down
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,43 @@ npm-global-packages: 'typescript@5.8.2 esbuild@0.28.1'

Both default to empty, so nothing is installed unless asked.

## Private modules

`kgkit` is private. Anything that depends on it dies at `go mod download` with
"repository not found", which reads like a typo in the import path and isn't
one: Go asked proxy.golang.org, got a 404 back, and never got as far as trying
git, because nothing had told it that path was private to begin with.

Hand the workflow a token with read access and it sorts out the rest:

```yaml
jobs:
ci:
uses: xraph/workflows/.github/workflows/go-ci.yml@v1
with:
goprivate: github.com/xraph/kgkit
secrets:
XRAPH_REPO_TOKEN: ${{ secrets.XRAPH_REPO_TOKEN }}
```

Every job that downloads dependencies rewrites `https://github.com/xraph/`
to carry that token, then sets `GOPRIVATE` so those paths skip the proxy and go
straight to git. Leave the secret out and the step does nothing. A public-only
repo never has to think about it. The rewrite is scoped to the org and not to
all of github.com, so it won't stamp on a credential you already set up for
somewhere else.

Keep `goprivate` narrow. It sets `GONOPROXY` too, so a glob wider than your real
private modules drags perfectly public ones off the proxy and clones each of
them from scratch, in every job, on every run. foundry names a single module for
that reason: it pulls in twenty-two xraph modules and exactly one of them is
private. The default is `github.com/xraph/*`, which is the safe answer when you
do not know and the slow one when you do.

Read access on the private repos is all the token needs. A fine-grained PAT
works. So does a GitHub App installation token. The default `GITHUB_TOKEN` does
not, and cannot: it only ever reaches the repo the workflow is running in.

## Escaping the Makefile probe

`go-ci.yml` prefers a Makefile target when one matching the step exists. That
Expand Down