From 544693268cfa6a06cd5a4e70691f6c832f5e701c Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Sat, 14 Nov 2026 04:33:50 -0500 Subject: [PATCH] Fetch every owned org's Go modules from git in releases go-release.yml set GOPRIVATE and GONOSUMDB to the caller's org only, so sangehq/authama's release pulled github.com/simtabi/go-notifykit/src through proxy.golang.org (R-INC-13). Both now list every Simtabi-owned org, re-derived with gh api user/orgs, less the client-owned adelsaiq. A test pins the list and keeps client and deleted orgs off it. Adds the repository's CHANGELOG. --- .github/workflows/go-release.yml | 9 ++++++--- CHANGELOG.md | 25 +++++++++++++++++++++++++ go-release/README.md | 13 +++++++++++++ go-release/tests/test_go_release.py | 23 +++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.github/workflows/go-release.yml b/.github/workflows/go-release.yml index c32ef0b..f0468f0 100644 --- a/.github/workflows/go-release.yml +++ b/.github/workflows/go-release.yml @@ -101,9 +101,12 @@ jobs: env: TAG: ${{ inputs.tag }} # Our own modules come from git, never through the public proxy, so a release build never - # feeds proxy.golang.org or sum.golang.org a tag. - GOPRIVATE: github.com/${{ github.repository_owner }}/* - GONOSUMDB: github.com/${{ github.repository_owner }}/* + # feeds proxy.golang.org or sum.golang.org a tag. Every Simtabi-owned org, not only the + # caller's: sangehq/authama imports github.com/simtabi/go-notifykit/src. Client accounts + # (adelsaiq, dannielagumo) stay off it. Public modules need no credentials over git; the + # checkout's github.token reaches only the caller's own repository. + GOPRIVATE: github.com/simtabi/*,github.com/laranail/*,github.com/ichava/*,github.com/sangehq/*,github.com/simsange/*,github.com/mukoracms/*,github.com/brandgulp/*,github.com/tayariai/*,github.com/tusente/*,github.com/simbi-prjs-clt/*,github.com/simbi-prjs-int/* + GONOSUMDB: github.com/simtabi/*,github.com/laranail/*,github.com/ichava/*,github.com/sangehq/*,github.com/simsange/*,github.com/mukoracms/*,github.com/brandgulp/*,github.com/tayariai/*,github.com/tusente/*,github.com/simbi-prjs-clt/*,github.com/simbi-prjs-int/* steps: - name: Check the tag env: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3f9cf51 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog + +Releases of simtabi/.github's shared workflows. Tags are final: a change ships as the next version, +and callers pin `go-release.yml@ # vX.Y.Z`. + +## [Unreleased] + +### Fixed + +- `go-release.yml` sets `GOPRIVATE` and `GONOSUMDB` to every Simtabi-owned org, not only the + caller's, so a release fetches our own modules from git and never through proxy.golang.org. + `sangehq/authama`'s release pulled `github.com/simtabi/go-notifykit/src` through the public proxy + (finding R-INC-13). `go-release/tests/` pins the list. + +## [1.0.0] - 2026-11-13 + +First tagged release of the shared workflows. + +- `.github/workflows/go-release.yml`: the reusable Go release pipeline every Go project's + `release.yml` calls. It publishes on the repository's GitHub release only, on a pushed `vX.Y.Z` tag + or on request. +- `templates/go/release.yml`: the caller to copy. + +[Unreleased]: https://github.com/simtabi/.github/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/simtabi/.github/releases/tag/v1.0.0 diff --git a/go-release/README.md b/go-release/README.md index 5f044d0..a944160 100644 --- a/go-release/README.md +++ b/go-release/README.md @@ -43,6 +43,19 @@ A pin to a bare commit, or a comment that names a pull request, is never updated |---|---|---| | `SIGNPATH_API_TOKEN` | no | exported to the GoReleaser step for a config that signs through SignPath. Pass it explicitly, `secrets: SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}`, never `secrets: inherit` | +## Our own modules come from git + +The release job sets `GOPRIVATE` and `GONOSUMDB` to every Simtabi-owned org (`simtabi`, `laranail`, +`ichava`, `sangehq`, `simsange`, `mukoracms`, `brandgulp`, `tayariai`, `tusente`, `simbi-prjs-clt`, +`simbi-prjs-int`), so a release fetches those modules from git and never feeds proxy.golang.org or +sum.golang.org a tag, the same as CI. It covers every org, not only the caller's: `sangehq/authama` +imports `github.com/simtabi/go-notifykit/src`. Client accounts (`adelsaiq`, `dannielagumo`) stay off +the list. The list was re-derived on 2026-11-14 with `gh api user/orgs --jq '.[].login'`; when an org +joins or leaves, change the workflow and `OWNED_ORGS` in `go-release/tests/` together. + +Public modules need no credentials over git. The job's `github.token` reaches only the caller's own +repository, so a private module in another repository cannot be fetched by a release build. + ## Attestations Build provenance is attested for `checksums.txt` and any extra assets on a **public** repository diff --git a/go-release/tests/test_go_release.py b/go-release/tests/test_go_release.py index 58cc19d..7b024a6 100644 --- a/go-release/tests/test_go_release.py +++ b/go-release/tests/test_go_release.py @@ -24,6 +24,17 @@ } +# Every Simtabi-owned org, so a release fetches our own modules from git and never feeds +# proxy.golang.org or sum.golang.org a tag (~/.claude/rules/releases.md). Re-derived 2026-11-14 with +# `gh api user/orgs --jq '.[].login'`: 12 orgs, less the client-owned adelsaiq. Client accounts +# (adelsaiq, dannielagumo) and deleted orgs (joemanch, tayaricms, the-omaris) stay off it. +OWNED_ORGS = ( + "simtabi", "laranail", "ichava", "sangehq", "simsange", "mukoracms", "brandgulp", + "tayariai", "tusente", "simbi-prjs-clt", "simbi-prjs-int", +) +NEVER = ("adelsaiq", "dannielagumo", "joemanch", "tayaricms", "the-omaris") + + def triggers(text): """The top-level keys under `on:`, in order.""" block = re.search(r"^on:\n((?:[ \t]+.*\n|\n)+)", text, re.M) @@ -89,6 +100,18 @@ def test_attestations_skip_a_private_repository(self): self.assertRegex(st, r"\n if: .*github\.event\.repository\.private == false", st) + def test_every_owned_org_is_fetched_from_git(self): + env = re.search(r"\n env:\n((?: .*\n)+)", self.job()) + self.assertIsNotNone(env, "the release job sets no env") + for var in ("GOPRIVATE", "GONOSUMDB"): + m = re.search(r"^ " + var + r": (\S+)$", env.group(1), re.M) + self.assertIsNotNone(m, f"the release job does not set {var}") + got = m.group(1).split(",") + self.assertEqual(len(got), len(OWNED_ORGS), f"{var}: {got}") + self.assertEqual(set(got), {f"github.com/{o}/*" for o in OWNED_ORGS}, var) + for other in NEVER: + self.assertNotIn(f"github.com/{other}/*", got, f"{var} names {other}") + def test_node_defaults_to_the_latest_release(self): m = re.search(r"\n node-version:\n(?: .*\n)*? default: (\S+)", self.text) self.assertIsNotNone(m, "no node-version input")