diff --git a/README.md b/README.md index 2c398f4..61ec968 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,18 @@ Common steps for initializing a job for GitHub actions. This composite action co > https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver > and installs it to `/usr/local/bin/semver`. +**Deterministic Zip** + +| Input | Description | Required | Default | +|-------------------------|----------------------------------|----------|---------| +| setup-deterministic-zip | Whether to setup deterministic-zip | No | false | + +> [!NOTE] +> `setup-deterministic-zip` installs [timo-reymann/deterministic-zip](https://github.com/timo-reymann/deterministic-zip) +> `1.2.0` to `/usr/local/bin/deterministic-zip`. The release asset is verified against a +> hard-coded per-platform SHA-256 (fail-closed) rather than the release's own `.sha256` +> sidecar, so an upstream asset swap is rejected. Supports Linux/macOS on amd64/arm64. + ### Outputs **Checkout Outputs** @@ -264,6 +276,7 @@ Common steps for initializing a job for GitHub actions. This composite action co python-version: '3.12' python-cache: 'pip' setup-semver: 'true' + setup-deterministic-zip: 'true' ``` **Blocking Egress Traffic** diff --git a/action.yml b/action.yml index e8ca374..253a0ad 100644 --- a/action.yml +++ b/action.yml @@ -178,6 +178,10 @@ inputs: description: 'Whether to setup semver tool' required: false default: 'false' + setup-deterministic-zip: + description: 'Whether to setup deterministic-zip' + required: false + default: 'false' # expose outputs from the sub-actions outputs: @@ -595,6 +599,64 @@ runs: echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" echo "::endgroup::" + - name: Setup Deterministic Zip + id: setup-deterministic-zip + if: ${{ inputs.setup-deterministic-zip == 'true' }} + shell: bash + env: + # Pinned to timo-reymann/deterministic-zip 1.2.0 with a per-platform SHA-256. + # The release ships its own .sha256 sidecars, but those are NOT trusted here: + # a release-asset swap on the upstream repo would replace the sidecar alongside the + # binary. Hard-coding the expected digests makes any such tamper fail closed. + # To bump: change DZIP_VERSION and refresh every DZIP_SHA256_* below, e.g. + # curl -sSL ...//deterministic-zip_linux-amd64 | shasum -a 256 + DZIP_VERSION: '1.2.0' + DZIP_SHA256_LINUX_AMD64: '56e9c2e28c9f535f100df1a94df122b62f4f2f66300abde2cf68d6a236ee5eaa' + DZIP_SHA256_LINUX_ARM64: 'fdb7a11ede185a6002c3d9f79489078ac12386297af2e4200e720fe12cc7f22e' + DZIP_SHA256_DARWIN_AMD64: 'ba34c4b871ac7a2bf38e51ad7310865badd7dd21d017efb6ed8eeb1c260bed38' + DZIP_SHA256_DARWIN_ARM64: '86677a58ceffc31419d5815f7e6fb7b096b78e20a9c73dbf28f999c4ad8bfc67' + run: | + case "${RUNNER_OS}" in + Linux) DZIP_OS="linux" ;; + macOS) DZIP_OS="darwin" ;; + *) echo "Unsupported runner OS for deterministic-zip setup: ${RUNNER_OS}"; exit 1 ;; + esac + + case "${RUNNER_ARCH}" in + X64) DZIP_ARCH="amd64" ;; + ARM64) DZIP_ARCH="arm64" ;; + *) echo "Unsupported runner arch for deterministic-zip setup: ${RUNNER_ARCH}"; exit 1 ;; + esac + + case "${DZIP_OS}-${DZIP_ARCH}" in + linux-amd64) EXPECTED_SHA="${DZIP_SHA256_LINUX_AMD64}" ;; + linux-arm64) EXPECTED_SHA="${DZIP_SHA256_LINUX_ARM64}" ;; + darwin-amd64) EXPECTED_SHA="${DZIP_SHA256_DARWIN_AMD64}" ;; + darwin-arm64) EXPECTED_SHA="${DZIP_SHA256_DARWIN_ARM64}" ;; + *) echo "No pinned deterministic-zip checksum for ${DZIP_OS}-${DZIP_ARCH}"; exit 1 ;; + esac + + DZIP_ASSET="deterministic-zip_${DZIP_OS}-${DZIP_ARCH}" + DZIP_URL="https://github.com/timo-reymann/deterministic-zip/releases/download/${DZIP_VERSION}/${DZIP_ASSET}" + + echo "::group::Download deterministic-zip ${DZIP_VERSION}" + curl -sSfL "${DZIP_URL}" -o /tmp/deterministic-zip \ + || { echo "Failed to download deterministic-zip binary"; exit 1; } + echo "::endgroup::" + + echo "::group::Verify deterministic-zip Checksum" + echo "${EXPECTED_SHA} /tmp/deterministic-zip" | shasum -a 256 -c - \ + || { echo "deterministic-zip checksum verification failed"; exit 1; } + echo "::endgroup::" + + echo "::group::Change deterministic-zip Binary Permissions" + sudo install -m 755 /tmp/deterministic-zip /usr/local/bin/deterministic-zip + echo "::endgroup::" + + echo "::group::Show deterministic-zip Version Info" + deterministic-zip --version + echo "::endgroup::" + branding: icon: 'arrow-up-right' color: 'green'