name: Build CLI description: | Builds CLI. Optionally, Sigstore tools are used to sign CLI when inputs are provided. A draft release is published when run on v* tag. inputs: targetOS: description: "Build CLI for this OS. [linux, darwin, windows]" required: true default: "linux" targetArch: description: "Build CLI for this architecture. [amd64, arm64]" required: true default: "amd64" enterpriseCLI: description: "Build CLI with enterprise flag." required: false default: "false" cosignPublicKey: description: "Cosign public key" required: false default: "" cosignPrivateKey: description: "Cosign private key" required: false default: "" cosignPassword: description: "Password for Cosign private key" required: false default: "" outputPath: description: "Output path of the binary" required: false push: description: "Push container images" required: false default: false runs: using: "composite" steps: # https://github.blog/2022-04-12-git-security-vulnerability-announced/ - name: Mark repository safe shell: bash run: | git config --global --add safe.directory /__w/constellation/constellation - name: Build CLI shell: bash env: TARGET_GOOS: ${{ inputs.targetOS }} TARGET_GOARCH: ${{ inputs.targetArch }} OUTPUT_PATH: ${{ inputs.outputPath || format('./build/constellation-{0}-{1}', inputs.targetOS, inputs.targetArch) }}${{ inputs.targetOS == 'windows' && '.exe' || '' }} run: | echo "::group::Build CLI" mkdir -p "$(dirname "${OUTPUT_PATH}")" if [ ${{ inputs.enterpriseCLI }} == 'true' ] then cli_variant=enterprise else cli_variant=oss fi label="//cli:cli_${cli_variant}_${TARGET_GOOS}_${TARGET_GOARCH}" bazel build "${label}" repository_root=$(git rev-parse --show-toplevel) out_rel=$(bazel cquery --output=files "${label}") out_loc="$(realpath "${repository_root}/${out_rel}")" cp "${out_loc}" "${OUTPUT_PATH}" chmod +w "${OUTPUT_PATH}" export PATH="$PATH:$(realpath $(dirname "${OUTPUT_PATH}"))" echo "$(realpath $(dirname "${OUTPUT_PATH}"))" >> $GITHUB_PATH echo "::endgroup::" - name: Upload container images if: inputs.push == 'true' shell: bash run: bazel run //bazel/release:push # TODO(3u13r): Replace with https://github.com/sigstore/sigstore-installer/tree/initial # once it has the functionality - name: Install Cosign if: inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 - name: Install Rekor if: inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' shell: bash working-directory: build run: | HOSTOS="$(go env GOOS)" HOSTARCH="$(go env GOARCH)" curl -fsSLO https://github.com/sigstore/rekor/releases/download/v0.12.0/rekor-cli-${HOSTOS}-${HOSTARCH} sudo install rekor-cli-${HOSTOS}-${HOSTARCH} /usr/local/bin/rekor-cli rm rekor-cli-${HOSTOS}-${HOSTARCH} - name: Sign CLI if: inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' shell: bash working-directory: build env: COSIGN_PUBLIC_KEY: ${{ inputs.cosignPublicKey }} COSIGN_PRIVATE_KEY: ${{ inputs.cosignPrivateKey }} COSIGN_PASSWORD: ${{ inputs.cosignPassword }} OUTPUT_PATH: ${{ github.workspace }}/${{ inputs.outputPath || format('./build/constellation-{0}-{1}', inputs.targetOS, inputs.targetArch) }}${{ inputs.targetOS == 'windows' && '.exe' || '' }} run: | echo "$COSIGN_PUBLIC_KEY" > cosign.pub # Enabling experimental mode also publishes signature to Rekor COSIGN_EXPERIMENTAL=1 cosign sign-blob --key env://COSIGN_PRIVATE_KEY "${OUTPUT_PATH}" > "${OUTPUT_PATH}.sig" # Verify - As documentation & check # Local Signature (input: artifact, key, signature) cosign verify-blob --key cosign.pub --signature "${OUTPUT_PATH}.sig" "${OUTPUT_PATH}" # Transparency Log Signature (input: artifact, key) uuid=$(rekor-cli search --artifact "${OUTPUT_PATH}" | tail -n 1) sig=$(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.content) cosign verify-blob --key cosign.pub --signature <(echo $sig) "${OUTPUT_PATH}"