From c37503590fa2eb57afa7f6ba98dfc53a1bd7fb37 Mon Sep 17 00:00:00 2001 From: Dmitrii Creed Date: Sun, 17 May 2026 00:22:14 +0400 Subject: [PATCH 1/3] feat: setup-sc-tooling + install-attest-tools composites (Step A+B of pin-reduction) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidates the two most-paired composite actions into higher-level ones so consumers reference one composite instead of two-to-three. ## setup-sc-tooling Wraps install-sc + install-welder with skip flags so consumers that need only one (e.g. simple-forge.yml uses welder alone) still go through the same entry point. jobs: build: steps: - uses: simple-container-com/actions/setup-sc-tooling@ # was: install-sc + install-welder on two separate `uses:` lines Both install scripts are invoked directly via `${{ github.action_path }}/../install-sc/install.sh` instead of `uses:`-ing the sibling composite — GitHub Actions doesn't support `${{ github.action_ref }}` in `uses:` ref positions, so the indirection would require hardcoding a self-referencing SHA. Calling the .sh scripts directly keeps the composite self-contained at whatever ref the consumer pinned. ## install-attest-tools Promotes simple-container-com/api's local .github/actions/install-attest-tools to the shared ruleset for cross-consumer reuse. Installs cosign (v2.4.1) + syft (v1.16.0) at SHA-pinned versions and asserts `gh` is on PATH (used by `gh attestation verify`). Every consumer publishing signed artifacts needs this same toolchain at the same versions; sharing it here means a single bump propagates to all consumers via Dependabot. ## Tests New `.github/workflows/self-test-composites.yml` exercises: - setup-sc-tooling default (both tools install, outputs populated, binaries executable); - setup-sc-tooling with `install-welder: false` (sc present, welder absent — guards the skip-flag plumbing); - setup-sc-tooling with `install-sc: false` (mirror case); - install-attest-tools (cosign + syft + gh all run `--version`). actionlint clean. ## Consumer-side impact (followup PR) After this lands, simple-container-com/api will swap: - install-sc (×8) + install-welder (×6) → setup-sc-tooling (×4) - local install-attest-tools (×3) → install-attest-tools (×3, shared ref) Net pin reduction: 27 → 17 entries (Step A+B of the consolidation plan). Step C (full sc-release reusable workflow) tracked in HARDENING.md for a dedicated session — that one needs preview-build validation cycles that don't fit a single review pass. Signed-off-by: Dmitrii Creed --- .github/workflows/self-test-composites.yml | 103 +++++++++++++++++++++ install-attest-tools/action.yml | 45 +++++++++ setup-sc-tooling/action.yml | 69 ++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 .github/workflows/self-test-composites.yml create mode 100644 install-attest-tools/action.yml create mode 100644 setup-sc-tooling/action.yml diff --git a/.github/workflows/self-test-composites.yml b/.github/workflows/self-test-composites.yml new file mode 100644 index 0000000..11136f7 --- /dev/null +++ b/.github/workflows/self-test-composites.yml @@ -0,0 +1,103 @@ +name: Self-test composites + +on: + pull_request: + branches: [main] + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +jobs: + setup-sc-tooling: + name: setup-sc-tooling — both tools + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Setup SC tooling + id: setup + uses: ./setup-sc-tooling + + - name: Verify sc + welder on PATH + shell: bash + run: | + set -euo pipefail + for tool in sc welder; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "::error::$tool not on PATH after setup-sc-tooling" + exit 1 + fi + "$tool" --version || "$tool" version || true + done + [ -n "${{ steps.setup.outputs.sc-version }}" ] || { echo '::error::sc-version output empty'; exit 1; } + [ -n "${{ steps.setup.outputs.welder-version }}" ] || { echo '::error::welder-version output empty'; exit 1; } + [ -x "${{ steps.setup.outputs.sc-binary }}" ] || { echo '::error::sc-binary output is not executable'; exit 1; } + [ -x "${{ steps.setup.outputs.welder-binary }}" ] || { echo '::error::welder-binary output is not executable'; exit 1; } + + setup-sc-tooling-skip-welder: + name: setup-sc-tooling — install-sc only (skip welder) + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: { persist-credentials: false } + + - name: Setup sc only + uses: ./setup-sc-tooling + with: + install-welder: 'false' + + - name: Verify sc present, welder absent + shell: bash + run: | + set -euo pipefail + command -v sc >/dev/null 2>&1 || { echo '::error::sc not installed'; exit 1; } + if command -v welder >/dev/null 2>&1; then + echo '::error::welder should not be installed when install-welder=false' + exit 1 + fi + + setup-sc-tooling-skip-sc: + name: setup-sc-tooling — welder only (skip sc) + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: { persist-credentials: false } + + - name: Setup welder only + uses: ./setup-sc-tooling + with: + install-sc: 'false' + + - name: Verify welder present, sc absent + shell: bash + run: | + set -euo pipefail + command -v welder >/dev/null 2>&1 || { echo '::error::welder not installed'; exit 1; } + if command -v sc >/dev/null 2>&1; then + echo '::error::sc should not be installed when install-sc=false' + exit 1 + fi + + install-attest-tools: + name: install-attest-tools — cosign + syft + gh + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: { persist-credentials: false } + + - name: Install attestation tools + uses: ./install-attest-tools + + - name: Verify cosign + syft + gh + shell: bash + run: | + set -euo pipefail + cosign version + syft version + gh --version | head -n 1 diff --git a/install-attest-tools/action.yml b/install-attest-tools/action.yml new file mode 100644 index 0000000..cd094be --- /dev/null +++ b/install-attest-tools/action.yml @@ -0,0 +1,45 @@ +name: 'Install attestation tools' +description: | + Install cosign + syft with single-source SHA pins for use across SC + release pipelines (image signing, CycloneDX SBOM generation, SLSA + attestation verification). Provenance verification uses the `gh` CLI + (preinstalled on GitHub-hosted runners) against the GitHub-native + attestation API, so no separate `slsa-verifier` install is required — + this composite asserts `gh` is present and fails fast if it's missing. + + Originally lived at `simple-container-com/api/.github/actions/install-attest-tools`; + promoted to the shared `simple-container-com/actions` ruleset for + cross-consumer reuse (every consumer that publishes signed artifacts + needs the same toolchain at the same pinned versions). + +inputs: + cosign-version: + description: 'Cosign CLI release tag to install (e.g. `v2.4.1`).' + required: false + default: 'v2.4.1' + syft-version: + description: 'Syft CLI release tag to install (e.g. `v1.16.0`).' + required: false + default: 'v1.16.0' + +runs: + using: 'composite' + steps: + - name: Install cosign + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + with: + cosign-release: ${{ inputs.cosign-version }} + + - name: Install syft + uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 + with: + syft-version: ${{ inputs.syft-version }} + + - name: Verify gh CLI is available (for `gh attestation verify`) + shell: bash + run: | + if ! command -v gh >/dev/null 2>&1; then + echo "::error::gh CLI not found on PATH — required for 'gh attestation verify' provenance checks. Install gh or switch to a runner image that ships it." >&2 + exit 1 + fi + gh --version | head -n 1 diff --git a/setup-sc-tooling/action.yml b/setup-sc-tooling/action.yml new file mode 100644 index 0000000..6bc7e2b --- /dev/null +++ b/setup-sc-tooling/action.yml @@ -0,0 +1,69 @@ +name: 'Setup SC Tooling' +description: | + Install Simple Container CLI (`sc`) and/or Welder in one step. Both + install scripts are invoked directly (not via the `install-sc` / + `install-welder` composites) to avoid GitHub Actions' restriction + against composite-to-composite `uses:` references that interpolate + the parent ref — this keeps the composite self-contained at whatever + SHA the consumer pinned. + +inputs: + install-sc: + description: 'Install the sc CLI (`true` / `false`).' + required: false + default: 'true' + install-welder: + description: 'Install Welder (`true` / `false`).' + required: false + default: 'true' + sc-version: + description: 'sc CLI version (e.g. `2026.4.12` or a `-preview.` tag). Empty → latest.' + required: false + default: '' + sc-sha256: + description: 'OPTIONAL hex SHA256 of the sc tarball. When set, the download is verified before extraction.' + required: false + default: '' + welder-version: + description: 'Welder version (e.g. `2026.4.12`). Empty → latest.' + required: false + default: '' + welder-sha256: + description: 'OPTIONAL hex SHA256 of the Welder tarball.' + required: false + default: '' + +outputs: + sc-version: + description: 'The sc version that was installed (resolved from input or `latest`).' + value: ${{ steps.install_sc.outputs.version }} + sc-binary: + description: 'Absolute path to the installed `sc` binary.' + value: ${{ steps.install_sc.outputs.binary }} + welder-version: + description: 'The Welder version that was installed.' + value: ${{ steps.install_welder.outputs.version }} + welder-binary: + description: 'Absolute path to the installed `welder` binary.' + value: ${{ steps.install_welder.outputs.binary }} + +runs: + using: 'composite' + steps: + - name: Install sc + id: install_sc + if: inputs.install-sc == 'true' + shell: bash + env: + SC_VERSION: ${{ inputs.sc-version }} + SC_SHA256: ${{ inputs.sc-sha256 }} + run: ${{ github.action_path }}/../install-sc/install.sh + + - name: Install Welder + id: install_welder + if: inputs.install-welder == 'true' + shell: bash + env: + WELDER_VERSION: ${{ inputs.welder-version }} + WELDER_SHA256: ${{ inputs.welder-sha256 }} + run: ${{ github.action_path }}/../install-welder/install.sh From 452f27c252741abc3da4951e0ce8beed064b313f Mon Sep 17 00:00:00 2001 From: Dmitrii Creed Date: Sun, 17 May 2026 00:30:31 +0400 Subject: [PATCH 2/3] fix(self-test): use block-form `persist-credentials` to satisfy own rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semgrep-self-test scan fired `gha-checkout-missing-persist-credentials-false` three times on this same workflow file — the rule's regex expects the flag on its own line (block form `with:\n persist-credentials: false`) and doesn't recognize the inline-flow `with: { persist-credentials: false }` form I used for the three skip-flag jobs. Eating our own dogfood: convert all four checkout steps to block form. `bash semgrep-scan/run-tests.sh` now 0 findings full-repo. Signed-off-by: Dmitrii Creed --- .github/workflows/self-test-composites.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/self-test-composites.yml b/.github/workflows/self-test-composites.yml index 11136f7..4fba5b7 100644 --- a/.github/workflows/self-test-composites.yml +++ b/.github/workflows/self-test-composites.yml @@ -45,7 +45,8 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: { persist-credentials: false } + with: + persist-credentials: false - name: Setup sc only uses: ./setup-sc-tooling @@ -67,7 +68,8 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: { persist-credentials: false } + with: + persist-credentials: false - name: Setup welder only uses: ./setup-sc-tooling @@ -89,7 +91,8 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: { persist-credentials: false } + with: + persist-credentials: false - name: Install attestation tools uses: ./install-attest-tools From 19c531d8b72c072d5452f0883b8a660b7f641dda Mon Sep 17 00:00:00 2001 From: Dmitrii Creed Date: Sun, 17 May 2026 00:50:23 +0400 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20drop=20self-test=20workflow=20?= =?UTF-8?q?=E2=80=94=20consumer=20CI=20is=20the=20integration=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The other composites in this repo (install-sc, install-welder, notify-telegram, sbom-generate, sbom-scan, trufflehog-scan, …) all ship without a dedicated per-composite self-test workflow. setup-sc- tooling and install-attest-tools are thin wrappers that delegate to existing install.sh scripts; the real integration surface is consumer CI (api, everworker, payspace) which exercises them on every release. If we ever hit a regression a self-test would have caught, we'll add one back surgically. For now, dropping the workflow keeps this PR aligned with the rest of the repo's testing convention and saves the ~30s CI tax per push. Signed-off-by: Dmitrii Creed --- .github/workflows/self-test-composites.yml | 106 --------------------- 1 file changed, 106 deletions(-) delete mode 100644 .github/workflows/self-test-composites.yml diff --git a/.github/workflows/self-test-composites.yml b/.github/workflows/self-test-composites.yml deleted file mode 100644 index 4fba5b7..0000000 --- a/.github/workflows/self-test-composites.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: Self-test composites - -on: - pull_request: - branches: [main] - push: - branches: [main] - workflow_dispatch: - -permissions: - contents: read - -jobs: - setup-sc-tooling: - name: setup-sc-tooling — both tools - runs-on: ubuntu-24.04 - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Setup SC tooling - id: setup - uses: ./setup-sc-tooling - - - name: Verify sc + welder on PATH - shell: bash - run: | - set -euo pipefail - for tool in sc welder; do - if ! command -v "$tool" >/dev/null 2>&1; then - echo "::error::$tool not on PATH after setup-sc-tooling" - exit 1 - fi - "$tool" --version || "$tool" version || true - done - [ -n "${{ steps.setup.outputs.sc-version }}" ] || { echo '::error::sc-version output empty'; exit 1; } - [ -n "${{ steps.setup.outputs.welder-version }}" ] || { echo '::error::welder-version output empty'; exit 1; } - [ -x "${{ steps.setup.outputs.sc-binary }}" ] || { echo '::error::sc-binary output is not executable'; exit 1; } - [ -x "${{ steps.setup.outputs.welder-binary }}" ] || { echo '::error::welder-binary output is not executable'; exit 1; } - - setup-sc-tooling-skip-welder: - name: setup-sc-tooling — install-sc only (skip welder) - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Setup sc only - uses: ./setup-sc-tooling - with: - install-welder: 'false' - - - name: Verify sc present, welder absent - shell: bash - run: | - set -euo pipefail - command -v sc >/dev/null 2>&1 || { echo '::error::sc not installed'; exit 1; } - if command -v welder >/dev/null 2>&1; then - echo '::error::welder should not be installed when install-welder=false' - exit 1 - fi - - setup-sc-tooling-skip-sc: - name: setup-sc-tooling — welder only (skip sc) - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Setup welder only - uses: ./setup-sc-tooling - with: - install-sc: 'false' - - - name: Verify welder present, sc absent - shell: bash - run: | - set -euo pipefail - command -v welder >/dev/null 2>&1 || { echo '::error::welder not installed'; exit 1; } - if command -v sc >/dev/null 2>&1; then - echo '::error::sc should not be installed when install-sc=false' - exit 1 - fi - - install-attest-tools: - name: install-attest-tools — cosign + syft + gh - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Install attestation tools - uses: ./install-attest-tools - - - name: Verify cosign + syft + gh - shell: bash - run: | - set -euo pipefail - cosign version - syft version - gh --version | head -n 1