Artifact e3f04f930d8212ee62076e6dc275540c583b5e474cd5103ee8699a8566e9a994:
- File
.github/workflows/release.yml
— part of check-in
[9d35407ecb]
at
2026-07-27 19:57:22
on branch trunk
— fix: pin submodules to v0.7.0 instead of an orphaned pseudo-version (#190) (#195)
All three submodules required the root module at v0.6.4-0.20260724230440-48111c1c984d. That pseudo-version names a commit pushed on the #118 PR branch, which was squash-merged — rewriting the work as a new commit and orphaning 48111c1. `git branch -r --contains` finds it on no branch; it survives only in proxy.golang.org's cache.
CI never noticed because it resolves through the proxy. Direct-from-git resolution fails outright:
$ GOMODCACHE=$(mktemp -d) GOWORK=off go mod download github.com/danmestas/go-libfossil go: github.com/danmestas/[email protected]: invalid version: unknown revision 48111c1c984d
v0.7.0 is tagged and reachable, so the bootstrap constraint that forced a pseudo-version is gone. Repoint all three at the tag and tidy. The root go.mod hash is unchanged between the orphaned commit and v0.7.0, so this is a pure provenance fix with no dependency movement.
Add a release guard alongside the existing `replace` guard: any in-repo module required at a pseudo-version now fails the release before the tag ships. The pattern anchors on the 14-digit timestamp and 12-hex hash, and accepts either separator before the timestamp so the vX.Y.Z-0.<ts>-<hash> form is caught as well as v0.0.0-<ts>-<hash>. Third-party pseudo-versions such as ncruces/go-sqlite3-wasm are deliberately untouched. (user: [email protected], size: 3294) [annotate] [blame] [check-ins using]
name: Release on: push: tags: - 'v*' permissions: contents: write jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # The go-libfossil rename left temporary `replace` directives bridging the # in-repo modules to local paths. A tag carrying them breaks # `go install github.com/danmestas/go-libfossil/cmd/libfossil@<tag>` and any # `@version` fetch of the driver submodules, because Go refuses a main module # that contains replace directives. Unblock a release by cutting new tags for # the submodules with the corrected module paths, bumping the root module's # requires to those versions, then deleting the replace blocks (and the stale # old-path lines they leave behind in the go.sum files). - name: Guard against replace directives run: | offenders=$(git ls-files '*go.mod' | xargs -r grep -l '^replace' || true) if [ -n "$offenders" ]; then echo "::error::refusing to release: go.mod replace directives present in:" echo "$offenders" exit 1 fi # A pseudo-version names a bare commit rather than a tag. When the commit # comes from a PR branch that is later squash-merged, the original is # rewritten and orphaned, so the require line resolves only for as long as # proxy.golang.org keeps its cached copy; anything on direct git (e.g. # GOPRIVATE=github.com/danmestas/*) fails outright. That shipped in v0.7.0 # unnoticed because CI reads through the proxy. In-repo modules must # therefore reference each other by released tag only. Unblock a release by # pointing the offending requires at the current tag and running # `go mod tidy` in each affected module. - name: Guard against in-repo pseudo-version requires run: | offenders=$(git ls-files '*go.mod' | xargs -r grep -nE \ 'github\.com/danmestas/go-libfossil(/[^[:space:]]+)?[[:space:]]+v[0-9][^[:space:]]*[-.][0-9]{14}-[0-9a-f]{12}' || true) if [ -n "$offenders" ]; then echo "::error::refusing to release: in-repo pseudo-version requires present:" echo "$offenders" exit 1 fi - name: Create GitHub release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh release create "${{ github.ref_name }}" \ --generate-notes \ --verify-tag - name: Dispatch downstream bump env: GH_TOKEN: ${{ secrets.DISPATCH_PAT }} DOWNSTREAM: EdgeSync MODULE_PATH: github.com/danmestas/go-libfossil run: | gh api -X POST "repos/danmestas/${DOWNSTREAM}/dispatches" \ -f event_type=upstream-bump \ -f client_payload[repo]=${{ github.event.repository.name }} \ -f client_payload[module_path]=${MODULE_PATH} \ -f client_payload[version]=${{ github.ref_name }} \ -f client_payload[release_url]=${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }} \ -f client_payload[tag_sha]=${{ github.sha }} \ -f client_payload[actor]=${{ github.actor }}