diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 35f8670..b47db77 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -10,13 +10,22 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # svu needs full history + tags + fetch-depth: 0 - uses: actions/setup-go@v5 with: - go-version: '1.26' + go-version: "1.26" cache: false + - name: Install PAM headers (needed by go test) + run: sudo apt-get update && sudo apt-get install -y libpam0g-dev + + - name: Run tests + run: | + set -ex + go vet ./... + go test ./... + - name: Install svu timeout-minutes: 3 run: | @@ -94,22 +103,10 @@ jobs: MINISIGN_PASSWORD: ${{ secrets.MINISIGN_PASSWORD }} run: | set -ex - # Install the minisign CLI (pure Go, ~2s). - go install aead.dev/minisign/cmd/minisign@latest - - # Generate sha256sums.txt from the built binaries. cd dist sha256sum nadir-* > sha256sums.txt cat sha256sums.txt - - # Write the secret key to a temp file, sign, shred it. - KEYFILE=$(mktemp) - trap 'shred -u "$KEYFILE" 2>/dev/null || rm -f "$KEYFILE"' EXIT - printf '%s\n' "$MINISIGN_SECRET_KEY" > "$KEYFILE" - - # minisign -Sm signs the file, reading the key from -s and password - # from stdin. The .minisig is written next to the input file. - printf '%s' "$MINISIGN_PASSWORD" | minisign -Sm sha256sums.txt -s "$KEYFILE" -t "nadir release" + go run ../tools/sign-checksums sha256sums.txt ls -la sha256sums.txt sha256sums.txt.minisig - name: Tag and release diff --git a/go.mod b/go.mod index 69a38a9..be713c8 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,10 @@ require ( ) require ( + aead.dev/minisign v0.3.0 github.com/dustin/go-humanize v1.0.1 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/jedisct1/go-minisign v0.0.0-20260527172527-a09352b57a22 // indirect + github.com/jedisct1/go-minisign v0.0.0-20260527172527-a09352b57a22 github.com/mattn/go-isatty v0.0.21 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect diff --git a/go.sum b/go.sum index 4a971a5..5c5076b 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +aead.dev/minisign v0.3.0 h1:8Xafzy5PEVZqYDNP60yJHARlW1eOQtsKNp/Ph2c0vRA= +aead.dev/minisign v0.3.0/go.mod h1:NLvG3Uoq3skkRMDuc3YHpWUTMTrSExqm+Ij73W13F6Y= github.com/coder/websocket v1.8.15 h1:6B2JPeOGlpff2Uz6vOEH1Vzpi0iUz20A+lPVhPHtNUA= github.com/coder/websocket v1.8.15/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= @@ -38,12 +40,10 @@ golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/sign-checksums b/sign-checksums new file mode 100755 index 0000000..96d8696 Binary files /dev/null and b/sign-checksums differ diff --git a/tools/sign-checksums/main.go b/tools/sign-checksums/main.go new file mode 100644 index 0000000..33c6389 --- /dev/null +++ b/tools/sign-checksums/main.go @@ -0,0 +1,54 @@ +// Command sign-checksums is a CI helper that signs a file using minisign. +// +// The minisign CLI reads passwords from /dev/tty, which doesn't exist in CI +// runners. This program uses the library directly: password and encrypted +// secret key come from environment variables, no terminal required. +// +// Usage (in CI): +// +// MINISIGN_SECRET_KEY=... MINISIGN_PASSWORD=... go run ./tools/sign-checksums dist/sha256sums.txt +// +// Produces dist/sha256sums.txt.minisig alongside the input. +package main + +import ( + "fmt" + "os" + + "aead.dev/minisign" +) + +func main() { + if len(os.Args) != 2 { + fmt.Fprintf(os.Stderr, "usage: sign-checksums \n") + os.Exit(2) + } + filePath := os.Args[1] + + password := os.Getenv("MINISIGN_PASSWORD") + keyBytes := []byte(os.Getenv("MINISIGN_SECRET_KEY")) + if len(keyBytes) == 0 { + fmt.Fprintln(os.Stderr, "MINISIGN_SECRET_KEY is not set") + os.Exit(1) + } + + key, err := minisign.DecryptKey(password, keyBytes) + if err != nil { + fmt.Fprintf(os.Stderr, "decrypt key: %v\n", err) + os.Exit(1) + } + + message, err := os.ReadFile(filePath) + if err != nil { + fmt.Fprintf(os.Stderr, "read %s: %v\n", filePath, err) + os.Exit(1) + } + + sig := minisign.Sign(key, message) + sigPath := filePath + ".minisig" + if err := os.WriteFile(sigPath, sig, 0644); err != nil { + fmt.Fprintf(os.Stderr, "write %s: %v\n", sigPath, err) + os.Exit(1) + } + fmt.Printf("signed %s -> %s\n", filePath, sigPath) +}