diff --git a/.github/workflows/codegen.yaml b/.github/workflows/codegen.yaml index 0f2264c6..7d639947 100644 --- a/.github/workflows/codegen.yaml +++ b/.github/workflows/codegen.yaml @@ -11,17 +11,21 @@ on: jobs: check: runs-on: ubuntu-24.04 + # go and the codegen tools come from the flake and tools.lock. + defaults: + run: + shell: nix develop --command bash -e {0} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - id: go-version - uses: opendefensecloud/dev-kit/.github/actions/get-go-version@f16fb83a8669ba840346929d9c45b9efe95c4da0 # v1.0.15 - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - go-version: ${{ steps.go-version.outputs.version }} + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} - name: Run codegen run: | make codegen - name: Check for changes - uses: opendefensecloud/dev-kit/.github/actions/diff-check@f16fb83a8669ba840346929d9c45b9efe95c4da0 # v1.0.15 + uses: opendefensecloud/dev-kit/.github/actions/diff-check@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 diff --git a/.github/workflows/golang.yaml b/.github/workflows/golang.yaml index 110af33e..7c9e7aa2 100644 --- a/.github/workflows/golang.yaml +++ b/.github/workflows/golang.yaml @@ -9,6 +9,7 @@ on: - "**/*.go" - ".github/workflows/golang.yaml" - ".golangci.yml" + - "flake.lock" - "flake.nix" - "go.mod" - "go.sum" @@ -20,6 +21,7 @@ on: - "**/*.go" - ".github/workflows/golang.yaml" - ".golangci.yml" + - "flake.lock" - "flake.nix" - "go.mod" - "go.sum" @@ -32,36 +34,71 @@ env: jobs: lint: runs-on: ubuntu-24.04 - outputs: - go-version: ${{ steps.go-version.outputs.version }} + # Tools (go, golangci-lint, shellcheck, addlicense) come from the flake + # and tools.lock. `make lint` runs both lint-no-golangci and golangci-lint. + defaults: + run: + shell: nix develop --command bash -e {0} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - id: go-version - uses: opendefensecloud/dev-kit/.github/actions/get-go-version@f16fb83a8669ba840346929d9c45b9efe95c4da0 # v1.0.15 - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - go-version: ${{ steps.go-version.outputs.version }} - - name: lint-license-and-shell - run: | - make lint-no-golangci - - name: golangci-lint - uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9 + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} + # actions/setup-go used to warm GOMODCACHE / GOCACHE for us, and + # golangci-lint-action kept golangci-lint's own analysis cache. Nix + # provides the toolchain but neither cache, so restore all three + # explicitly. The key is trust-scoped (pr/trusted) so a pull request + # cannot poison the cache used by builds of trusted refs, and it covers + # tools.lock / .golangci.yml because a golangci-lint version or config + # change invalidates its analysis results. + - name: Cache Go module, build and lint caches + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/.cache/golangci-lint + key: go-cache-lint-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum', 'tools.lock', '.golangci.yml') }}-${{ github.sha }} + restore-keys: | + go-cache-lint-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum', 'tools.lock', '.golangci.yml') }}- + go-cache-lint-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}- + - name: lint + run: make lint test: needs: lint runs-on: ubuntu-24.04 + defaults: + run: + shell: nix develop --command bash -e {0} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 + with: + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} + # See the lint job for rationale. Separate cache scope per job so lint + # (compile-side artefacts only) does not clobber test, which also builds + # envtest / ginkgo binaries. + - name: Cache Go module + build caches + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - go-version: ${{ needs.lint.outputs.go-version }} + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-cache-test-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum') }}-${{ github.sha }} + restore-keys: | + go-cache-test-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum') }}- + go-cache-test-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}- - name: test - run: | - make test + run: make test - name: Convert coverage to lcov uses: jandelgado/gcov2lcov-action@e4612787670fc5b5f49026b8c29c5569921de1db # v1.2.0 with: diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 39fad8cb..96137624 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -17,6 +17,10 @@ on: jobs: lint: runs-on: ubuntu-24.04 + # helm comes from the flake (dev-kit's defaultPkgs). + defaults: + run: + shell: nix develop --command bash -e {0} steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -24,10 +28,11 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Set up Helm - uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - version: 'v4.2.4' + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} - name: Lint Helm charts run: | diff --git a/.github/workflows/helm-publish.yaml b/.github/workflows/helm-publish.yaml index e7df2b33..1a554d97 100644 --- a/.github/workflows/helm-publish.yaml +++ b/.github/workflows/helm-publish.yaml @@ -34,6 +34,13 @@ jobs: (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ok-to-helm')) || (github.event_name == 'release' && github.event.action == 'published') + # helm comes from the flake. cosign comes from cosign-installer on the + # runner PATH; nix develop inherits PATH so it remains reachable from + # inside the dev shell. + defaults: + run: + shell: nix develop --command bash -e {0} + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -41,10 +48,11 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Set up Helm - uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - version: 'v4.2.4' + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} - name: Install cosign uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f07d5393..ccb8a434 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -16,6 +16,16 @@ jobs: contents: write id-token: write # for keyless cosign sign-blob attestations: write # for build-provenance attestation + # go comes from the flake. cosign comes from cosign-installer on the + # runner PATH; nix develop inherits PATH so it remains reachable from + # inside the dev shell. No actions/cache here: this is a privileged + # signing job, so it deliberately does not share a Go cache with + # unprivileged workflows (cache poisoning). This replaces the previous + # setup-go `cache: false`. + defaults: + run: + shell: nix develop --command bash -e {0} + steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -23,21 +33,11 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Extract go version from flake.nix - id: get-go-version - run: | - GO_VERSION="$(sed -nE 's/^[[:space:]]*goVersion[[:space:]]*=[[:space:]]*"([0-9]+\.[0-9]+\.[0-9]+)";[[:space:]]*$/\1/p' flake.nix)" - if [ "$(printf '%s\n' "$GO_VERSION" | sed '/^$/d' | wc -l)" -ne 1 ]; then - echo "::error::Expected exactly one goVersion assignment in flake.nix" - exit 1 - fi - echo "version=$GO_VERSION" >> $GITHUB_OUTPUT - - - name: Setup Go - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - go-version: ${{ steps.get-go-version.outputs.version }} - cache: false # privileged signing job: avoid shared cache (cache-poisoning) + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} - name: Run tests run: make test @@ -74,7 +74,11 @@ jobs: # --bundle arc-.intoto.jsonl env: BUNDLE: ${{ steps.attest.outputs.bundle-path }} - run: cp "${BUNDLE}" "bin/arc-${GITHUB_REF_NAME}.intoto.jsonl" + run: | + # Tags may legally contain '/', which would turn the asset name into a + # path under a directory that does not exist and fail the release job. + asset_tag="${GITHUB_REF_NAME//\//-}" + cp "${BUNDLE}" "bin/arc-${asset_tag}.intoto.jsonl" - name: Install cosign uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 diff --git a/.github/workflows/test-e2e.yaml b/.github/workflows/test-e2e.yaml index 984de361..b87f626f 100644 --- a/.github/workflows/test-e2e.yaml +++ b/.github/workflows/test-e2e.yaml @@ -20,36 +20,40 @@ permissions: jobs: test-e2e: runs-on: ubuntu-24.04 + # go, kind, kubectl and helm all come from the flake. The e2e suite + # creates the cluster itself via `make test-e2e`, pinned to + # KIND_NODE_IMAGE (derived from ENVTEST_K8S_VERSION) — the Makefile + # stays the single source of truth for the K8s version. + defaults: + run: + shell: nix develop --command bash -e {0} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - id: go-version - uses: opendefensecloud/dev-kit/.github/actions/get-go-version@f16fb83a8669ba840346929d9c45b9efe95c4da0 # v1.0.15 - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + - name: Set up nix with the shared Cachix cache + uses: opendefensecloud/dev-kit/.github/actions/setup-nix@7427f5e62c1c45ec058e3e2b483a75d9dbe48805 # v2.2.0 with: - go-version: ${{ steps.go-version.outputs.version }} - - name: Install Tools + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + cachix-signing-key: ${{ secrets.CACHIX_SIGNING_KEY }} + # actions/setup-go used to warm GOMODCACHE / GOCACHE for us; restore + # them explicitly now. Trust-scoped (pr/trusted) so a pull request + # cannot poison the cache used by builds of trusted refs. + - name: Cache Go module + build caches + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-cache-e2e-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum') }}-${{ github.sha }} + restore-keys: | + go-cache-e2e-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}-${{ hashFiles('go.sum') }}- + go-cache-e2e-${{ github.event_name == 'pull_request' && 'pr' || 'trusted' }}- + - name: Report tool versions run: | - # Install kind. The e2e suite creates the cluster itself via - # `make test-e2e`, pinned to KIND_NODE_IMAGE (derived from - # ENVTEST_K8S_VERSION) — the Makefile is the single source of truth - # for the K8s version, so we only need the binary here. - KIND_VERSION="v0.31.0" - curl -Lo ./kind "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64" - chmod +x ./kind - sudo mv ./kind /usr/local/bin/kind kind version - - # Install kubectl - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" - chmod +x ./kubectl - sudo mv ./kubectl /usr/local/bin/kubectl kubectl version --client - - # Install helm - curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash - helm version + helm version --short - name: Run E2E Test Suite env: E2E_IMAGE_SOURCE: ${{ inputs.is-local && 'local' || 'ghcr' }} diff --git a/Makefile b/Makefile index b520d586..01472bb5 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # Include ODC common make targets -DEV_KIT_VERSION := v2.1.0 +DEV_KIT_VERSION := v2.2.0 -include common.mk common.mk: @[ -f .common.mk-download ] || \ diff --git a/flake.lock b/flake.lock index 3c120d6f..d90aa774 100644 --- a/flake.lock +++ b/flake.lock @@ -15,15 +15,16 @@ ] }, "locked": { - "lastModified": 1787918634, - "narHash": "sha256-d/GY4lc2ssP2ax6GGLaakYkXZcW8XM1IlFO98qd7sXQ=", + "lastModified": 1788351182, + "narHash": "sha256-3fOyooxR5RHBdnacI/dw/jxGvr+WJdauzE5iW+hvmAI=", "owner": "opendefensecloud", "repo": "dev-kit", - "rev": "3ce2ec4d731819f2ddcd5b6d9fba88979bb4c04f", + "rev": "7427f5e62c1c45ec058e3e2b483a75d9dbe48805", "type": "github" }, "original": { "owner": "opendefensecloud", + "ref": "v2.2.0", "repo": "dev-kit", "type": "github" } diff --git a/flake.nix b/flake.nix index b5d181a6..2ecc5c53 100644 --- a/flake.nix +++ b/flake.nix @@ -12,7 +12,7 @@ }; dev-kit = { - url = "github:opendefensecloud/dev-kit"; + url = "github:opendefensecloud/dev-kit/v2.2.0"; inputs.nixpkgs.follows = "nixpkgs"; inputs.go-overlay.follows = "go-overlay"; inputs.flake-utils.follows = "flake-utils"; @@ -29,7 +29,6 @@ inherit system; goVersion = "1.26.6"; packages = [ - pkgs.cosign pkgs.trivy ]; preCommitHooks = {