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
82 changes: 82 additions & 0 deletions .github/workflows/govulncheck-modules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: govulncheck (Go modules)

# Every Go module the repo ships is scanned by govulncheck through the same
# fail-closed gate (scripts/govulncheck-gate.mjs + security/govulncheck-exceptions.json)
# at the same pinned version. templates/go is scanned in go-template.yml; this
# workflow covers the other shipped modules. tests/govulncheck-all-modules.test.ts
# fails when a go.mod exists that is neither gated in CI nor listed as excluded
# (with a reason) in security/govulncheck-modules.json.
#
# The dated-exception nightly (govulncheck-nightly.yml) scans the same modules
# over both lane refs, so an exception expires ON its date. That file is kept
# byte-identical with main's copy.

on:
pull_request:
paths:
- 'packages/kn-next-operator/**'
- 'packages/scale-zero-pg/gateway/**'
- '.github/workflows/govulncheck-modules.yml'
- 'scripts/govulncheck-gate.mjs'
- 'security/govulncheck-exceptions.json'
- 'security/govulncheck-modules.json'
- 'tests/govulncheck-all-modules.test.ts'
- 'tests/govulncheck-gate.test.ts'
- 'tests/govulncheck-gate-scope.test.ts'
- 'tests/govulncheck-gate-known-modules.test.ts'
push:
branches: [main, 'integration/**']
paths:
- 'packages/kn-next-operator/**'
- 'packages/scale-zero-pg/gateway/**'
- '.github/workflows/govulncheck-modules.yml'
- 'scripts/govulncheck-gate.mjs'
- 'security/govulncheck-exceptions.json'
- 'security/govulncheck-modules.json'
- 'tests/govulncheck-all-modules.test.ts'
- 'tests/govulncheck-gate.test.ts'
- 'tests/govulncheck-gate-scope.test.ts'
- 'tests/govulncheck-gate-known-modules.test.ts'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: govulncheck-modules-${{ github.ref }}
cancel-in-progress: true

jobs:
govulncheck:
name: govulncheck gate (${{ matrix.module }})
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
strategy:
fail-fast: false
matrix:
module:
- packages/kn-next-operator
- packages/scale-zero-pg/gateway
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Go (${{ matrix.module }}/go.mod)
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: ${{ matrix.module }}/go.mod
cache-dependency-path: ${{ matrix.module }}/go.sum

- name: Setup Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '24'

- name: govulncheck (pinned) through the fail-closed gate
working-directory: ${{ matrix.module }}
# JSON mode exits 0 on findings; the gate does the failing, and only
# through a dated entry in security/govulncheck-exceptions.json.
run: |
set -euo pipefail
go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 -format json ./... | node "$GITHUB_WORKSPACE/scripts/govulncheck-gate.mjs" "${{ matrix.module }}"
56 changes: 33 additions & 23 deletions .github/workflows/govulncheck-nightly.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
name: govulncheck nightly

# A dated govulncheck exception (security/govulncheck-exceptions.json) must stop
# passing ON its expiry date, not whenever the next PR happens to touch the Go
# template. go-template.yml only runs on path-filtered events, so this nightly
# runs the same fail-closed gate over BOTH lane refs, the way
# passing ON its expiry date, not whenever the next PR happens to touch Go code.
# The PR-time workflows are path-filtered, so this nightly runs the same
# fail-closed gate over BOTH lane refs and EVERY Go module, the way
# mutation-prover-nightly.yml does: a `schedule:` trigger only fires from the
# default branch's copy of this file (main), so the integration/v2 content it must
# prove is reached by checking the ref out explicitly. A ref that carries no Go
# template (main, today) skips its steps by FILE PRESENCE, so the lane turns on by
# itself when the template lands there.
# prove is reached by checking the ref out explicitly. Each leg runs THAT ref's
# own gate script and exceptions file.
#
# Fail-closed: every leg requires its module, the gate and the exceptions file and
# FAILS when one is missing. The one exemption is templates/go on main, which has
# no Go template yet; that single leg skips by FILE PRESENCE and turns on by itself
# when the template lands there. The operator and gateway modules exist on both
# refs, so they can never skip.
#
# This file is kept byte-identical on main and integration/v2.

on:
schedule:
Expand All @@ -20,7 +27,7 @@ permissions:

jobs:
govulncheck:
name: govulncheck gate (${{ matrix.ref }})
name: govulncheck gate (${{ matrix.ref }}, ${{ matrix.module }})
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
Expand All @@ -29,40 +36,43 @@ jobs:
fail-fast: false
matrix:
ref: [main, integration/v2]
module: [templates/go, packages/kn-next-operator, packages/scale-zero-pg/gateway]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ matrix.ref }}

# The skip-by-file-presence below is for main, which carries no Go template.
# On integration/v2 the template, the gate and the exceptions MUST exist: a
# missing one means the checkout is wrong, and a skip there would be a green
# run that proved nothing.
- name: Require the Go template and gate on integration/v2
if: ${{ matrix.ref == 'integration/v2' }}
# Everything but the main/templates/go leg MUST find its module, the gate and
# the exceptions file: a missing one means the checkout is wrong, and a skip
# there would be a green run that proved nothing.
- name: Require the module, the gate and the exceptions
if: ${{ !(matrix.ref == 'main' && matrix.module == 'templates/go') }}
env:
MODULE: ${{ matrix.module }}
REF: ${{ matrix.ref }}
run: |
set -euo pipefail
fail() { echo "::error::$1 is missing on integration/v2; refusing to pass without scanning"; exit 1; }
test -f templates/go/go.mod || fail templates/go/go.mod
fail() { echo "::error::$1 is missing on $REF; refusing to pass without scanning"; exit 1; }
test -f "$MODULE/go.mod" || fail "$MODULE/go.mod"
test -f scripts/govulncheck-gate.mjs || fail scripts/govulncheck-gate.mjs
test -f security/govulncheck-exceptions.json || fail security/govulncheck-exceptions.json

- name: Set up Go (templates/go/go.mod)
if: ${{ hashFiles('templates/go/go.mod') != '' }}
- name: Set up Go (${{ matrix.module }}/go.mod)
if: ${{ hashFiles(format('{0}/go.mod', matrix.module)) != '' }}
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: templates/go/go.mod
cache-dependency-path: templates/go/go.sum
go-version-file: ${{ matrix.module }}/go.mod
cache-dependency-path: ${{ matrix.module }}/go.sum

- name: Setup Node.js
if: ${{ hashFiles('templates/go/go.mod') != '' }}
if: ${{ hashFiles(format('{0}/go.mod', matrix.module)) != '' }}
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '24'

- name: govulncheck (pinned) through the fail-closed gate
if: ${{ hashFiles('templates/go/go.mod') != '' }}
working-directory: templates/go
if: ${{ hashFiles(format('{0}/go.mod', matrix.module)) != '' }}
working-directory: ${{ matrix.module }}
run: |
set -euo pipefail
go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 -format json ./... | node "$GITHUB_WORKSPACE/scripts/govulncheck-gate.mjs"
go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 -format json ./... | node "$GITHUB_WORKSPACE/scripts/govulncheck-gate.mjs" "${{ matrix.module }}"
6 changes: 4 additions & 2 deletions packages/scale-zero-pg/gateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Multi-stage build: static Go binary -> distroless.
FROM golang:1.26 AS build
# golang:1.26.9 (digest-pinned; tests/golang-from-lockstep.test.ts keeps it equal to go.mod)
FROM golang:1.26.9@sha256:37cfcca63222ec499bec5e8ad7aad52dbf7529db36d5812b8eae2f0621aa92d6 AS build
WORKDIR /src

# Cache modules first.
Expand All @@ -14,7 +15,8 @@ RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /gateway ./c
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /writer-autoscaler ./cmd/writer-autoscaler \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /zone-operator ./cmd/zone-operator

FROM gcr.io/distroless/static:nonroot
# gcr.io/distroless/static:nonroot
FROM gcr.io/distroless/static:nonroot@sha256:e2e927ec666bae08560abb3c55d0659eceabb657f56b6782ab500a9fc7f555e3
COPY --from=build /gateway /gateway
COPY --from=build /alertsink /alertsink
# pageserver auto-failover controller; the 58-pswatcher Deployment overrides
Expand Down
14 changes: 7 additions & 7 deletions packages/scale-zero-pg/gateway/go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/alpheya/scale-zero-pg/gateway

go 1.26
go 1.26.9

require (
github.com/lib/pq v1.10.9
github.com/robfig/cron/v3 v3.0.1
golang.org/x/sync v0.19.0
golang.org/x/sync v0.23.0
k8s.io/api v0.34.1
k8s.io/apimachinery v0.34.1
k8s.io/client-go v0.34.1
Expand All @@ -27,7 +27,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/spdystream v0.5.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
Expand All @@ -37,11 +37,11 @@ require (
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/net v0.60.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/term v0.46.0 // indirect
golang.org/x/text v0.42.0 // indirect
golang.org/x/time v0.9.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
Expand Down
28 changes: 14 additions & 14 deletions packages/scale-zero-pg/gateway/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y=
github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -104,34 +104,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU=
golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
Loading
Loading