diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abd3ce5..ff09c58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -140,24 +140,44 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + artifact-required: "true" + - target: x86_64-unknown-linux-musl + artifact-required: "true" + - target: aarch64-unknown-linux-gnu + artifact-required: "true" + - target: aarch64-unknown-linux-musl + artifact-required: "false" steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 - - name: Fetch, cosign-verify, and run the pinned CLI release + - name: Fetch, cosign-verify, and smoke test the pinned CLI release env: CLI_REF: 87f4bf08b63712d3600030a7c458f0b790cfc0d5 # postil-cli v0.1.1 CLI_RELEASE: v0.1.1 + TARGET: ${{ matrix.target }} + ARTIFACT_REQUIRED: ${{ matrix.artifact-required }} run: | set -euo pipefail DEST="$RUNNER_TEMP/postil-bin" mkdir -p "$DEST" - target="x86_64-unknown-linux-gnu" base="https://github.com/postil-dev/postil-cli/releases/download/$CLI_RELEASE" - curl -fsSL -o "$DEST/postil.tar.gz" "$base/postil-$target.tar.gz" - curl -fsSL -o "$DEST/postil.tar.gz.sha256" "$base/postil-$target.tar.gz.sha256" - curl -fsSL -o "$DEST/postil.tar.gz.sig" "$base/postil-$target.tar.gz.sig" - curl -fsSL -o "$DEST/postil.tar.gz.pem" "$base/postil-$target.tar.gz.pem" + if ! curl -fsSL -o "$DEST/postil.tar.gz" "$base/postil-$TARGET.tar.gz" \ + || ! curl -fsSL -o "$DEST/postil.tar.gz.sha256" "$base/postil-$TARGET.tar.gz.sha256" \ + || ! curl -fsSL -o "$DEST/postil.tar.gz.sig" "$base/postil-$TARGET.tar.gz.sig" \ + || ! curl -fsSL -o "$DEST/postil.tar.gz.pem" "$base/postil-$TARGET.tar.gz.pem"; then + if [ "$ARTIFACT_REQUIRED" = "false" ]; then + echo "::notice::no $TARGET artifact on $CLI_RELEASE; the action falls back to a source build for this target" + exit 0 + fi + echo "::error::missing required $TARGET artifact on $CLI_RELEASE" + exit 1 + fi expected=$(awk '{print $1}' "$DEST/postil.tar.gz.sha256") actual=$(sha256sum "$DEST/postil.tar.gz" | awk '{print $1}') @@ -172,7 +192,11 @@ jobs: tar -xzf "$DEST/postil.tar.gz" -C "$DEST" chmod +x "$DEST/postil" - "$DEST/postil" --version + if [ "$TARGET" = "x86_64-unknown-linux-gnu" ] || [ "$TARGET" = "x86_64-unknown-linux-musl" ]; then + "$DEST/postil" --version + else + file "$DEST/postil" + fi # Boundary: this is as far as the smoke test goes. The action's # "Review" step, deliberately not exercised here, takes it from diff --git a/README.md b/README.md index 4cc7525..aa2a9a3 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,12 @@ jobs: Set `timeout-minutes` on the job: a hung model endpoint or a stuck source build should not tie up your runner queue indefinitely. +When `cli-release` is set, Linux runners fetch a verified prebuilt CLI when one +matches the runner. The action supports glibc and Alpine/musl runners with +`bash`, `curl`, `jq`, `tar`, and checksum tools available on `x86_64` and +`aarch64`/`arm64`; unsupported platforms fall back to building the CLI from the +pinned `cli-ref`. + > **Note:** there is no `@v1` tag yet — this action has not had a tagged > release. Until one is published, pin the action to a reviewed commit SHA > (`postil-dev/postil-action@<40-hex sha>`) instead of `@v1`. Pinning to a SHA diff --git a/action.yml b/action.yml index b42d70c..0f57bba 100644 --- a/action.yml +++ b/action.yml @@ -107,12 +107,45 @@ runs: if: inputs.cli-release != '' uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 + - name: Select postil target + id: target + shell: bash + run: | + set -euo pipefail + + target="" + if [ "$RUNNER_OS" = "Linux" ]; then + libc="gnu" + if command -v ldd >/dev/null 2>&1; then + ldd_output="$(ldd --version 2>&1 || ldd /bin/sh 2>&1 || true)" + if printf '%s\n' "$ldd_output" | grep -qi musl; then + libc="musl" + fi + elif { compgen -G "/lib/ld-musl-*.so.1" >/dev/null \ + || compgen -G "/usr/lib/ld-musl-*.so.1" >/dev/null; }; then + libc="musl" + fi + + case "$(uname -m)" in + x86_64) target="x86_64-unknown-linux-$libc" ;; + aarch64|arm64) target="aarch64-unknown-linux-$libc" ;; + esac + fi + + if [ -n "$target" ]; then + echo "Selected postil target $target" + else + echo "::notice::no prebuilt target for $RUNNER_OS/$(uname -m); falling back to source build" + fi + echo "target=$target" >> "$GITHUB_OUTPUT" + - name: Install postil shell: bash env: CLI_REF: ${{ inputs.cli-ref }} CLI_RELEASE: ${{ inputs.cli-release }} GH_TOKEN: ${{ inputs.github-token }} + POSTIL_TARGET: ${{ steps.target.outputs.target }} run: | set -euo pipefail DEST="$RUNNER_TEMP/postil-bin" @@ -133,13 +166,7 @@ runs: if [ "$tag_sha" = "$CLI_REF" ]; then # Prebuilt artifacts are Linux-only here; other runners fall back # to the source build rather than fetching a binary that cannot run. - target="" - if [ "$RUNNER_OS" = "Linux" ]; then - case "$(uname -m)" in - x86_64) target="x86_64-unknown-linux-gnu" ;; - aarch64|arm64) target="aarch64-unknown-linux-gnu" ;; - esac - fi + target="$POSTIL_TARGET" if [ -n "$target" ]; then base="https://github.com/postil-dev/postil-cli/releases/download/$CLI_RELEASE" if curl -fsSL --retry 3 --retry-connrefused --retry-delay 2 -o "$DEST/postil.tar.gz" "$base/postil-$target.tar.gz" \ @@ -168,8 +195,6 @@ runs: else echo "::warning::no prebuilt artifact (or signature) for $target on $CLI_RELEASE; falling back to source build" fi - else - echo "::notice::no prebuilt target for $RUNNER_OS/$(uname -m); falling back to source build" fi else echo "::warning::release $CLI_RELEASE points at ${tag_sha:-unknown}, not cli-ref $CLI_REF; falling back to source build"