chore(ci): require Go 1.20 or newer
- commit
- 42c4a8e684f93803e321d999727d5ea1dd78e688
- author
- brice · · 2026-06-09 17:35 UTC
- parent
- bc8a21d
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +22 -7
M .github/workflows/test.yml +2 -3
| @@ -10,7 +10,7 @@ jobs: | |||
| 10 | 10 | strategy: | |
| 11 | 11 | matrix: | |
| 12 | 12 | os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest] | |
| 13 | - | go: ['1.18.x', '1.19.x', '1.20.x', '1.21.x', '1.22.x', '1.23.x', '1.24.x', '1.25.x', '1.26.x'] | |
| 13 | + | go: ['1.20.x', '1.21.x', '1.22.x', '1.23.x', '1.24.x', '1.25.x', '1.26.x'] | |
| 14 | 14 | name: Test with Go ${{ matrix.go }} on ${{ matrix.os }} | |
| 15 | 15 | runs-on: ${{ matrix.os }} | |
| 16 | 16 | defaults: | |
| @@ -156,13 +156,12 @@ jobs: | |||
| 156 | 156 | go env -u CXX | |
| 157 | 157 | ||
| 158 | 158 | - name: go test race (no Cgo) | |
| 159 | - | if: ${{ runner.os == 'macOS' && !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | |
| 159 | + | if: runner.os == 'macOS' | |
| 160 | 160 | run: | | |
| 161 | 161 | # -race usually requires Cgo, but macOS is an exception. See https://go.dev/doc/articles/race_detector#Requirements | |
| 162 | 162 | env CGO_ENABLED=0 go test -race -shuffle=on -v -count=10 ./... | |
| 163 | 163 | ||
| 164 | 164 | - name: go test race (Cgo) | |
| 165 | - | if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | |
| 166 | 165 | run: | | |
| 167 | 166 | env CGO_ENABLED=1 go test -race -shuffle=on -v -count=10 ./... | |
| 168 | 167 | ||
| @@ -10,7 +10,7 @@ jobs: | |||||
| 10 | strategy: | 10 | strategy: | ||
| 11 | matrix: | 11 | matrix: | ||
| 12 | os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest] | 12 | os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest] | ||
| 13 | - | go: ['1.18.x', '1.19.x', '1.20.x', '1.21.x', '1.22.x', '1.23.x', '1.24.x', '1.25.x', '1.26.x'] | 13 | + | go: ['1.20.x', '1.21.x', '1.22.x', '1.23.x', '1.24.x', '1.25.x', '1.26.x'] |
| 14 | name: Test with Go ${{ matrix.go }} on ${{ matrix.os }} | 14 | name: Test with Go ${{ matrix.go }} on ${{ matrix.os }} | ||
| 15 | runs-on: ${{ matrix.os }} | 15 | runs-on: ${{ matrix.os }} | ||
| 16 | defaults: | 16 | defaults: | ||
| @@ -156,13 +156,12 @@ jobs: | |||||
| 156 | go env -u CXX | 156 | go env -u CXX | ||
| 157 | 157 | ||||
| 158 | - name: go test race (no Cgo) | 158 | - name: go test race (no Cgo) | ||
| 159 | - | if: ${{ runner.os == 'macOS' && !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | 159 | + | if: runner.os == 'macOS' |
| 160 | run: | | 160 | run: | | ||
| 161 | # -race usually requires Cgo, but macOS is an exception. See https://go.dev/doc/articles/race_detector#Requirements | 161 | # -race usually requires Cgo, but macOS is an exception. See https://go.dev/doc/articles/race_detector#Requirements | ||
| 162 | env CGO_ENABLED=0 go test -race -shuffle=on -v -count=10 ./... | 162 | env CGO_ENABLED=0 go test -race -shuffle=on -v -count=10 ./... | ||
| 163 | 163 | ||||
| 164 | - name: go test race (Cgo) | 164 | - name: go test race (Cgo) | ||
| 165 | - | if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | |||
| 166 | run: | | 165 | run: | | ||
| 167 | env CGO_ENABLED=1 go test -race -shuffle=on -v -count=10 ./... | 166 | env CGO_ENABLED=1 go test -race -shuffle=on -v -count=10 ./... | ||
| 168 | 167 | ||||
M README.md +15 -3
| @@ -101,9 +101,21 @@ exhaustion on Unix-like platforms, set `PUREGO_CALLBACK_LEDGER=1` to append JSON | |||
| 101 | 101 | callback lifecycle events to `/tmp/purego-callback-ledger-<pid>.jsonl`, or set | |
| 102 | 102 | `PUREGO_CALLBACK_LEDGER_FILE=/path/to/file.jsonl` to choose the output file. Stack | |
| 103 | 103 | capture is also disabled by default; set `PUREGO_CALLBACK_LEDGER_STACK=1` when call | |
| 104 | - | site attribution is needed. For ad-hoc stderr/file traces near callback exhaustion, | |
| 105 | - | set `PUREGO_CALLBACK_TRACE=1`; `PUREGO_CALLBACK_TRACE_FILE` overrides the default | |
| 106 | - | `/tmp/purego-callback-trace-<pid>.log` path. | |
| 104 | + | site attribution is needed. Stack capture adds per-callback overhead and should be | |
| 105 | + | reserved for active debugging sessions. For ad-hoc stderr/file traces near callback | |
| 106 | + | exhaustion, set `PUREGO_CALLBACK_TRACE=1`; `PUREGO_CALLBACK_TRACE_FILE` overrides | |
| 107 | + | the default `/tmp/purego-callback-trace-<pid>.log` path. | |
| 108 | + | ||
| 109 | + | Diagnostic files are created with `0o600` permissions. They are append-only and | |
| 110 | + | unbounded, so long-running processes can exhaust disk space if diagnostics stay | |
| 111 | + | enabled. A ledger line is a JSON object such as: | |
| 112 | + | ||
| 113 | + | ```json | |
| 114 | + | {"time":"2026-06-09T14:03:00Z","pid":1234,"seq":42,"event":"alloc","index":7,"addr":"0x1234","stack":"..."} | |
| 115 | + | ``` | |
| 116 | + | ||
| 117 | + | Use `time` as the timestamp, `index` as the callback ID, and the `pid`, `seq`, | |
| 118 | + | `event`, `addr`, and optional `stack` fields when parsing the ledger output. | |
| 107 | 119 | ||
| 108 | 120 | ## Questions | |
| 109 | 121 | ||
| @@ -101,9 +101,21 @@ exhaustion on Unix-like platforms, set `PUREGO_CALLBACK_LEDGER=1` to append JSON | |||||
| 101 | callback lifecycle events to `/tmp/purego-callback-ledger-<pid>.jsonl`, or set | 101 | callback lifecycle events to `/tmp/purego-callback-ledger-<pid>.jsonl`, or set | ||
| 102 | `PUREGO_CALLBACK_LEDGER_FILE=/path/to/file.jsonl` to choose the output file. Stack | 102 | `PUREGO_CALLBACK_LEDGER_FILE=/path/to/file.jsonl` to choose the output file. Stack | ||
| 103 | capture is also disabled by default; set `PUREGO_CALLBACK_LEDGER_STACK=1` when call | 103 | capture is also disabled by default; set `PUREGO_CALLBACK_LEDGER_STACK=1` when call | ||
| 104 | - | site attribution is needed. For ad-hoc stderr/file traces near callback exhaustion, | 104 | + | site attribution is needed. Stack capture adds per-callback overhead and should be |
| 105 | - | set `PUREGO_CALLBACK_TRACE=1`; `PUREGO_CALLBACK_TRACE_FILE` overrides the default | 105 | + | reserved for active debugging sessions. For ad-hoc stderr/file traces near callback |
| 106 | - | `/tmp/purego-callback-trace-<pid>.log` path. | 106 | + | exhaustion, set `PUREGO_CALLBACK_TRACE=1`; `PUREGO_CALLBACK_TRACE_FILE` overrides |
| 107 | + | the default `/tmp/purego-callback-trace-<pid>.log` path. | |||
| 108 | + | ||||
| 109 | + | Diagnostic files are created with `0o600` permissions. They are append-only and | |||
| 110 | + | unbounded, so long-running processes can exhaust disk space if diagnostics stay | |||
| 111 | + | enabled. A ledger line is a JSON object such as: | |||
| 112 | + | ||||
| 113 | + | ```json | |||
| 114 | + | {"time":"2026-06-09T14:03:00Z","pid":1234,"seq":42,"event":"alloc","index":7,"addr":"0x1234","stack":"..."} | |||
| 115 | + | ``` | |||
| 116 | + | ||||
| 117 | + | Use `time` as the timestamp, `index` as the callback ID, and the `pid`, `seq`, | |||
| 118 | + | `event`, `addr`, and optional `stack` fields when parsing the ledger output. | |||
| 107 | 119 | ||||
| 108 | ## Questions | 120 | ## Questions | ||
| 109 | 121 | ||||
M go.mod +1 -1
| @@ -1,3 +1,3 @@ | |||
| 1 | 1 | module github.com/bnema/purego | |
| 2 | 2 | ||
| 3 | - | go 1.18 | |
| 3 | + | go 1.20 | |
| @@ -1,3 +1,3 @@ | |||||
| 1 | module github.com/bnema/purego | 1 | module github.com/bnema/purego | ||
| 2 | 2 | ||||
| 3 | - | go 1.18 | 3 | + | go 1.20 |
M syscall_unix.go +4 -0
| @@ -342,6 +342,10 @@ func traceCallbackAllocation(event string, val reflect.Value, remaining int) { | |||
| 342 | 342 | if traceFile == "" { | |
| 343 | 343 | traceFile = fmt.Sprintf("/tmp/purego-callback-trace-%d.log", os.Getpid()) | |
| 344 | 344 | } | |
| 345 | + | // traceCallbackAllocation intentionally accepts the opt-in | |
| 346 | + | // PUREGO_CALLBACK_TRACE_FILE path. Users must set PUREGO_CALLBACK_TRACE=1 to | |
| 347 | + | // enable tracing, and callers who override the path control their debugging | |
| 348 | + | // environment. This documents the deliberate gosec G304 tradeoff for audits. | |
| 345 | 349 | if f, err := os.OpenFile(traceFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600); err == nil { | |
| 346 | 350 | _, _ = f.WriteString(message) | |
| 347 | 351 | _ = f.Close() | |
| @@ -342,6 +342,10 @@ func traceCallbackAllocation(event string, val reflect.Value, remaining int) { | |||||
| 342 | if traceFile == "" { | 342 | if traceFile == "" { | ||
| 343 | traceFile = fmt.Sprintf("/tmp/purego-callback-trace-%d.log", os.Getpid()) | 343 | traceFile = fmt.Sprintf("/tmp/purego-callback-trace-%d.log", os.Getpid()) | ||
| 344 | } | 344 | } | ||
| 345 | + | // traceCallbackAllocation intentionally accepts the opt-in | |||
| 346 | + | // PUREGO_CALLBACK_TRACE_FILE path. Users must set PUREGO_CALLBACK_TRACE=1 to | |||
| 347 | + | // enable tracing, and callers who override the path control their debugging | |||
| 348 | + | // environment. This documents the deliberate gosec G304 tradeoff for audits. | |||
| 345 | if f, err := os.OpenFile(traceFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600); err == nil { | 349 | if f, err := os.OpenFile(traceFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600); err == nil { | ||
| 346 | _, _ = f.WriteString(message) | 350 | _, _ = f.WriteString(message) | ||
| 347 | _ = f.Close() | 351 | _ = f.Close() | ||