appstore: carry install.json/install.sh on install + wire trust ancho… #71
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: ['v*'] | |
| permissions: | |
| contents: write | |
| id-token: write # PILOT-120: OIDC for SLSA attestation | |
| attestations: write # PILOT-120: actions/attest-build-provenance | |
| jobs: | |
| test: | |
| name: Test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| # macos-latest dropped from the release test matrix: the hosted | |
| # runner's TMPDIR (/var/folders/.../T/) has been rejecting | |
| # t.TempDir() with EACCES on every release since the runner | |
| # image update in mid-May. Every test that touches a temp dir | |
| # fails immediately, blocking release tags. Darwin still gets | |
| # full coverage in the build matrix (darwin/amd64, darwin/arm64) | |
| # so we still ship signed mac binaries; macOS test coverage | |
| # continues in PR ci.yml and the nightly suite where the | |
| # runner behavior is the same but the gate is non-blocking. | |
| os: [ubuntu-latest] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Vet | |
| run: go vet ./... | |
| - name: Build all binaries | |
| run: make build | |
| - name: Unit tests | |
| # Release gate runs the same -short unit suite as ci.yml so the | |
| # release pipeline validates the same coverage that PRs validate. | |
| # The previous gate ran the heavy integration suite in ./tests/ | |
| # against loopback HTTP servers; that suite has been broken on | |
| # the GH Actions runner network stack for ~2 weeks (every | |
| # v1.10.1+ release run failed here), blocking every release tag | |
| # since 2026-05-16. Integration tests still run nightly via | |
| # nightly.yml and locally via `go test ./tests/`. | |
| run: go test -short -count=1 -timeout 600s ./pkg/... ./cmd/... ./internal/... | |
| build: | |
| name: Build (${{ matrix.goos }}/${{ matrix.goarch }}) | |
| needs: test | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| matrix: | |
| include: | |
| - goos: linux | |
| goarch: amd64 | |
| runner: ubuntu-latest | |
| - goos: linux | |
| goarch: arm64 | |
| runner: ubuntu-latest | |
| - goos: darwin | |
| goarch: amd64 | |
| runner: macos-latest | |
| - goos: darwin | |
| goarch: arm64 | |
| runner: macos-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Build release binaries | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| CGO_ENABLED: '0' | |
| run: | | |
| VERSION=${GITHUB_REF_NAME} | |
| LDFLAGS="-s -w -X main.version=${VERSION}" | |
| BINS="daemon pilotctl updater" | |
| mkdir -p dist | |
| for bin in $BINS; do | |
| echo "Building $bin for ${{ matrix.goos }}/${{ matrix.goarch }}..." | |
| go build -ldflags "$LDFLAGS" -o dist/$bin ./cmd/$bin | |
| done | |
| # Ad-hoc codesign + drop quarantine on darwin builds so downloaded | |
| # binaries don't trigger "killed: 9" or Gatekeeper "cannot be opened | |
| # because Apple cannot check it for malicious software". Ad-hoc | |
| # signing is enough to make the binary launch — full notarization | |
| # would need APPLE_ID + APP_SPECIFIC_PASSWORD secrets and a paid | |
| # developer cert; out of scope for this release. | |
| - name: macOS ad-hoc codesign + strip quarantine | |
| if: matrix.goos == 'darwin' | |
| run: | | |
| for bin in dist/*; do | |
| echo "codesigning $bin..." | |
| codesign --force --deep --sign - "$bin" | |
| xattr -cr "$bin" || true | |
| done | |
| for bin in dist/*; do | |
| codesign -dv "$bin" 2>&1 | grep -E "Signature|Authority|TeamIdentifier" | head -1 | |
| done | |
| - name: Smoke test binaries | |
| if: matrix.goos == 'linux' && matrix.goarch == 'amd64' || matrix.goos == 'darwin' | |
| run: | | |
| echo "=== Binary smoke tests ===" | |
| for bin in dist/*; do | |
| name=$(basename $bin) | |
| # Verify it's a valid executable | |
| file $bin | |
| # Version flag check (all binaries should accept -h without crashing) | |
| timeout 5 $bin -h 2>&1 || true | |
| echo " ✓ $name" | |
| done | |
| echo "" | |
| echo "=== Daemon help test ===" | |
| dist/daemon -h 2>&1 | head -5 | |
| echo " ✓ daemon shows help" | |
| echo "" | |
| echo "=== pilotctl version test ===" | |
| dist/pilotctl version 2>&1 || dist/pilotctl -h 2>&1 | head -3 | |
| echo " ✓ pilotctl responds" | |
| - name: Package archive | |
| run: | | |
| ARCHIVE="pilot-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz" | |
| tar -czf $ARCHIVE -C dist . | |
| echo "ARCHIVE=$ARCHIVE" >> $GITHUB_ENV | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pilot-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: ${{ env.ARCHIVE }} | |
| release: | |
| name: Create release | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Collect archives | |
| run: | | |
| mkdir -p release | |
| find artifacts -name '*.tar.gz' -exec cp {} release/ \; | |
| ls -la release/ | |
| - name: Generate checksums | |
| run: | | |
| cd release | |
| sha256sum *.tar.gz > checksums.txt | |
| cat checksums.txt | |
| # PILOT-120: SLSA build provenance attestation via Sigstore. | |
| # Attests every release tarball + checksums.txt. Consumers (updater, | |
| # install.sh) can verify with `gh attestation verify` or `cosign` | |
| # to prove the artifact was built by THIS workflow on this repo, | |
| # not substituted somewhere downstream. | |
| - name: Attest build provenance (SLSA) | |
| uses: actions/attest-build-provenance@v4 | |
| with: | |
| subject-path: | | |
| release/*.tar.gz | |
| release/checksums.txt | |
| - name: Create GitHub release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| release/*.tar.gz | |
| release/checksums.txt | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: ${{ contains(github.ref_name, '-rc') || contains(github.ref_name, '-beta') }} |