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
1 change: 1 addition & 0 deletions .changelog/unreleased/55-go-ci-selftest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **Go lane self-test.** New `self-test-go.yml` exercises `go-ci.yml` end-to-end in CI — calling it via a local reusable ref against fixture modules under `test/fixtures/go/` to prove discovery, `go build`/`go vet`/`go test`, and `exclude-modules` (including a self-validating intentionally-broken excluded module). Closes the workflow-level test gap the Go lane shipped with. (#55)
45 changes: 45 additions & 0 deletions .github/workflows/self-test-go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Self-test (go lane)

# Workflow-level proof that go-ci.yml actually executes in Actions — module
# discovery, `go build` / `go vet` / `go test`, and `exclude-modules` — by
# calling it through a LOCAL (./) reusable ref so the in-PR version is the one
# under test. self-test.yml covers only the classifier scripts (vitest); this
# is the missing execution proof for the reusable Go lane. See issue #55.

on:
pull_request:
paths:
- ".github/workflows/go-ci.yml"
- ".github/workflows/self-test-go.yml"
- "test/fixtures/go/**"
push:
branches: [main]
paths:
- ".github/workflows/go-ci.yml"
- ".github/workflows/self-test-go.yml"
- "test/fixtures/go/**"

concurrency:
group: self-test-go-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
go-lane:
# Calls the in-PR go-ci.yml. It discovers the fixtures under
# test/fixtures/go/ via `git ls-files`, then builds/vets/tests `alpha` and
# `beta` and MUST skip the intentionally-broken `excluded` module. A green
# run proves the lane's shell works AND that exclude-modules skips as
# documented (a broken module that wasn't skipped would fail the build).
uses: ./.github/workflows/go-ci.yml
with:
go-versions: '["stable"]'
# Fixtures are dependency-less, so they have no go.sum. actions/setup-go
# with cache:true + cache-dependency-path '**/go.sum' errors when that
# glob matches nothing — and caching isn't what this self-test proves
# (the lane's discovery/build/vet/test/exclude shell is). Disable it.
cache: false
exclude-modules: |
test/fixtures/go/excluded/
19 changes: 19 additions & 0 deletions test/fixtures/go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Go lane self-test fixtures

These modules exist only to exercise `.github/workflows/go-ci.yml` from
`.github/workflows/self-test-go.yml`. They are **not** shipped or imported by
anything; they are discovered by `go-ci.yml` via `git ls-files '**/go.mod'`.

| Module | Purpose |
| --- | --- |
| `alpha/` | Valid, vet-clean module **with a passing test** — proves `go build`, `go vet`, and `go test` all run. |
| `beta/` | A second valid module — proves multi-module discovery (more than one tracked `go.mod` in one run). |
| `excluded/` | **Intentionally does not compile.** The self-test passes `exclude-modules: test/fixtures/go/excluded/`. If exclusion regresses, this module builds and the job fails — a self-validating proof that `exclude-modules` works. |

**Go version:** each `go.mod` declares `go 1.21` — a modern baseline that
`actions/setup-go` with `go-version: stable` always satisfies (stable is the
latest release). The modules have no dependencies, so `go mod download` is a
no-op and no `go.sum` is needed.

If you change `go-ci.yml`, the self-test re-runs automatically (its `paths`
filter watches `go-ci.yml`, this directory, and the self-test workflow itself).
9 changes: 9 additions & 0 deletions test/fixtures/go/alpha/alpha.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Package alpha is a self-test fixture: a valid, vet-clean Go module that
// go-ci.yml should discover, build, vet, and test. Paired with alpha_test.go
// so the self-test proves `go test` actually runs (not just build/vet).
package alpha

// Add returns the sum of two integers.
func Add(a, b int) int {
return a + b
}
12 changes: 12 additions & 0 deletions test/fixtures/go/alpha/alpha_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package alpha

import "testing"

// TestAdd gives the self-test a real test to execute, proving go-ci.yml's
// `go test` step runs and reports pass/fail (a module with no tests would
// exit 0 regardless).
func TestAdd(t *testing.T) {
if got := Add(2, 3); got != 5 {
t.Fatalf("Add(2, 3) = %d, want 5", got)
}
}
3 changes: 3 additions & 0 deletions test/fixtures/go/alpha/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module example.com/selftest/alpha

go 1.21
9 changes: 9 additions & 0 deletions test/fixtures/go/beta/beta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Package beta is a second valid fixture module. Its only job is to prove
// go-ci.yml discovers and verifies MORE THAN ONE tracked go.mod in a single
// run (multi-module discovery via `git ls-files`).
package beta

// Greeting returns a fixed greeting.
func Greeting() string {
return "beta"
}
3 changes: 3 additions & 0 deletions test/fixtures/go/beta/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module example.com/selftest/beta

go 1.21
12 changes: 12 additions & 0 deletions test/fixtures/go/excluded/broken.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Package excluded is INTENTIONALLY non-compiling. It exists solely to prove
// that go-ci.yml's `exclude-modules` input actually skips a module: the
// self-test passes `exclude-modules: test/fixtures/go/excluded/`, so this file
// must never be compiled. If exclusion ever regresses, the undefined reference
// below fails `go build`/`go vet` and the self-test job goes red — loudly —
// instead of silently passing. See test/fixtures/go/README.md.
package excluded

// Broken references an undefined identifier on purpose.
func Broken() int {
return undefinedOnPurpose
}
3 changes: 3 additions & 0 deletions test/fixtures/go/excluded/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module example.com/selftest/excluded

go 1.21
Loading