Files
ironclaw/.github/workflows/platform-and-compat.yml
dependabot[bot] c1db630b1f chore(deps): bump the actions group across 1 directory with 5 updates
Bumps the actions group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) | `1.0.183` | `1.0.208` |
| [actions/setup-node](https://github.com/actions/setup-node) | `4.0.2` | `7.0.0` |
| [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) | `e18b497796c12c097a38f9edb9d0641fb99eee32` | `f0d9c3887740aee45f6153b24b3a6b815192ec16` |
| [docker/login-action](https://github.com/docker/login-action) | `4.5.2` | `4.6.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.2.0` | `4.3.0` |



Updates `anthropics/claude-code-action` from 1.0.183 to 1.0.208
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](be7b93b190...e8c2d7c16c)

Updates `actions/setup-node` from 4.0.2 to 7.0.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4.0.2...v7)

Updates `Swatinem/rust-cache` from e18b497796c12c097a38f9edb9d0641fb99eee32 to f0d9c3887740aee45f6153b24b3a6b815192ec16
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](e18b497796...f0d9c38877)

Updates `docker/login-action` from 4.5.2 to 4.6.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](371161bbe7...dbcb813823)

Updates `docker/setup-buildx-action` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](bb05f3f551...37fe631027)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.198
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: docker/login-action
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: Swatinem/rust-cache
  dependency-version: f0d9c3887740aee45f6153b24b3a6b815192ec16
  dependency-type: direct:production
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-30 20:16:14 +00:00

585 lines
25 KiB
YAML

name: Platform & Compat
on:
workflow_call:
inputs:
ref:
description: Commit SHA or ref to test
required: false
type: string
include_docker:
description: Include Docker image build in this reusable test run
required: false
type: boolean
default: true
deep:
description: >-
Marker that this run is a reusable deep-CI invocation. Callers never
need to set it: the default makes `inputs.deep` true exactly when
this workflow runs via workflow_call, and the empty inputs context
makes it falsy on direct triggers. Job conditions must use this
instead of `github.event_name == 'workflow_call'` — in a reusable
workflow, github.event_name reflects the CALLER's event (e.g.
`schedule` under Nightly Deep CI), so that comparison never matches
and the gated jobs silently skip.
required: false
type: boolean
default: true
pull_request:
branches:
- main
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
permissions:
contents: read
concurrency:
group: platform-and-compat-${{ github.event_name }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
# Tests must never touch the real OS keychain (macOS Keychain auth dialog /
# Linux Secret Service). Guarded by
# crates/substrates/ironclaw_secrets/src/keychain.rs::os_keychain_suppressed:
# cfg!(test) covers unit tests; this covers integration/e2e that link the
# non-cfg(test) library.
IRONCLAW_DISABLE_OS_KEYCHAIN: "1"
# Pin wall-clock rendering inputs so a test cannot pass or fail on the
# runner's locale. Reborn renders model-visible time slices, and date/number
# formatting differs by locale, so an unpinned runner turns a formatting
# regression into an unreproducible flake. UTC also keeps recorded fixtures
# comparable with what a developer sees locally.
TZ: "UTC"
LANG: "C.UTF-8"
jobs:
changes:
name: Detect code changes
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
docs_only: ${{ steps.non_diff.outputs.docs_only || steps.diff.outputs.docs_only }}
has_core_code: ${{ steps.non_diff.outputs.has_core_code || steps.diff.outputs.has_core_code }}
has_direct_wasm_abi_risk: ${{ steps.non_diff.outputs.has_direct_wasm_abi_risk || steps.diff.outputs.has_direct_wasm_abi_risk }}
has_wasm_abi_risk: ${{ steps.non_diff.outputs.has_wasm_abi_risk || steps.diff.outputs.has_wasm_abi_risk }}
has_legacy_tests: ${{ steps.non_diff.outputs.has_legacy_tests || steps.diff.outputs.has_legacy_tests }}
has_docker_risk: ${{ steps.non_diff.outputs.has_docker_risk || steps.diff.outputs.has_docker_risk }}
steps:
- id: non_diff
if: github.event_name != 'pull_request' && github.event_name != 'merge_group'
run: |
echo "docs_only=false" >> "$GITHUB_OUTPUT"
echo "has_core_code=true" >> "$GITHUB_OUTPUT"
echo "has_legacy_tests=true" >> "$GITHUB_OUTPUT"
echo "has_direct_wasm_abi_risk=true" >> "$GITHUB_OUTPUT"
echo "has_wasm_abi_risk=true" >> "$GITHUB_OUTPUT"
echo "has_docker_risk=true" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
with:
fetch-depth: 0
persist-credentials: false
- id: diff
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
env:
BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
HEAD_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
run: |
CHANGED_FILES="$(git diff --name-only "$BASE_SHA"..."$HEAD_SHA")"
echo "Changed files:"
if [ -n "$CHANGED_FILES" ]; then
printf '%s\n' "$CHANGED_FILES"
else
echo "<none>"
fi
has_match() {
printf '%s\n' "$CHANGED_FILES" | grep -Eq "$1"
}
printf '%s\n' "$CHANGED_FILES" | scripts/ci/classify-test-scope.sh >> "$GITHUB_OUTPUT"
has_direct_wasm_abi_risk=false
# Crate scopes are matched by NAME at any depth: `crates/([^/]+/)*<name>/`
# keeps matching once crates move into family directories
# (crates/<family>/ironclaw_*, PROPOSAL §5). A flat `crates/<name>/`
# prefix stops matching there, `has_direct_wasm_abi_risk` goes false,
# and every WASM ABI check silently skips — the WS10 failure mode
# (#6963). `crates/ironclaw_wasm_product_adapters/` was also dropped:
# that crate no longer exists, so the alternative had been matching
# nothing. The bare `wit/` alternative went the same way when the WIT
# directory moved inside its owning crate (CHECKLIST WS4): the ABI
# files are `crates/lanes/ironclaw_wasm/wit/*.wit` now, already in scope via
# the `ironclaw_wasm` crate alternative, which unlike a repo-root
# prefix survives the WS7 family move too.
# scripts/ci/ws12_workflow_contracts.py pins this regex
# against the real crate inventory and against a real first-party
# extension manifest path, so a renamed, moved or deleted crate fails
# loudly here instead of quietly falling out of scope.
if has_match '^(crates/([^/]+/)*ironclaw_common/|crates/([^/]+/)*ironclaw_wasm/|crates/([^/]+/)*packages/[^/]+/(manifest\.toml|wasm-src/)|registry/|scripts/build-wasm-extensions\.sh$|scripts/check-version-bumps\.sh$|\.github/workflows/(platform-and-compat|nightly-deep-ci)\.yml$)'; then
has_direct_wasm_abi_risk=true
fi
echo "has_direct_wasm_abi_risk=$has_direct_wasm_abi_risk" >> "$GITHUB_OUTPUT"
if [ "$has_direct_wasm_abi_risk" = true ] || has_match '^(Cargo\.toml|Cargo\.lock)$'; then
echo "has_wasm_abi_risk=true" >> "$GITHUB_OUTPUT"
else
echo "has_wasm_abi_risk=false" >> "$GITHUB_OUTPUT"
fi
if has_match '^(Dockerfile|\.dockerignore$|docker/reborn/(entrypoint|start-sshd)\.sh$|\.github/workflows/platform-and-compat\.yml$)'; then
echo "has_docker_risk=true" >> "$GITHUB_OUTPUT"
else
echo "has_docker_risk=false" >> "$GITHUB_OUTPUT"
fi
hooks-parity-tests:
name: Hooks Predicate-Backend Parity Tests
needs: changes
if: needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.has_legacy_tests == 'true' && needs.changes.outputs.has_core_code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: ironclaw_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgres://postgres:postgres@localhost/ironclaw_test
# Turn a missing/unreachable Postgres into a HARD failure so the full
# cross-backend matrix (in-memory + libSQL + Postgres) cannot skip-pass.
IRONCLAW_REQUIRE_POSTGRES: "1"
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Install Rust
uses: ./.github/actions/setup-rust
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 # v2
with:
key: hooks-parity
# Keep saves to protected-branch and merge_group runs so the ~10 GB
# repo cache LRU is seeded by shared states, not arbitrary PR branches.
save-if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'merge_group' }}
# Full parity matrix across all three backends. Backend implementations
# always compile; --features integration adds the multi-host adversarial
# suite, and IRONCLAW_REQUIRE_POSTGRES=1 (set above) makes the Postgres
# leg mandatory. The libSQL leg always runs (embedded temp-file).
- name: Run hooks parity matrix + multi-host adversarial suite (all backends)
run: |
timeout --signal=INT --kill-after=30s 15m \
cargo test -p ironclaw_hooks \
--features integration,test-support \
--test parity_matrix \
--test multi_host_adversarial \
--test predicate_state_postgres_contract \
--test predicate_state_postgres_adversarial \
--test predicate_state_libsql_contract \
-- --nocapture
windows-build:
name: Windows Build (${{ matrix.name }})
needs: changes
if: needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.has_legacy_tests == 'true' && (github.event_name == 'push' || inputs.deep == true)
runs-on: windows-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
# This job only runs on push / workflow_call (never on PR or
# merge_group), so it always builds the full feature matrix — no
# event-conditional SLIM/FULL indirection. Feature permutations are
# workspace-wide now that the v1 root package (and its
# html-to-markdown/bedrock/import features) is gone: `--all-features`
# enables every workspace member's features (including the heavy
# `bedrock` AWS lane), `default` builds the default set.
include:
- name: all-features
flags: "--all-features"
- name: default
flags: ""
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Install Rust
uses: ./.github/actions/setup-rust
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 # v2
with:
key: windows-${{ matrix.name }}
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Check compilation
run: cargo check --all --benches --tests --examples ${{ matrix.flags }}
wasm-wit-compat:
name: WASM WIT Compatibility
needs: changes
# WIT and registry paths are outside the shared legacy-test classifier;
# the event-specific WASM risk outputs are authoritative for this job.
if: >
needs.changes.outputs.docs_only != 'true' &&
(github.event_name == 'push' ||
inputs.deep == true ||
(github.event_name == 'merge_group' && needs.changes.outputs.has_wasm_abi_risk == 'true') ||
(github.event_name == 'pull_request' && needs.changes.outputs.has_direct_wasm_abi_risk == 'true'))
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Free disk space
run: |
df -h /
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
df -h /
- name: Install Rust
uses: ./.github/actions/setup-rust
with:
targets: wasm32-wasip2
- name: Enable pnpm for setup-node cache
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: |
crates/product/ironclaw_webui/frontend/pnpm-lock.yaml
crates/*/*/ironclaw_webui/frontend/pnpm-lock.yaml
- name: Enable pnpm
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
run: |
set -euo pipefail
webui_dir="$(bash scripts/ci/crate-dir.sh ironclaw_webui)"
cd "${webui_dir}/frontend"
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 # v2
with:
key: wasm-extensions
# Keep saves to protected-branch and merge_group runs so the ~10 GB
# repo cache LRU is seeded by shared states, not arbitrary PR branches.
save-if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'merge_group' }}
- name: Install cargo-component
uses: ./.github/actions/install-cargo-component
- name: Build all WASM extensions against current WIT
run: ./scripts/build-wasm-extensions.sh
- name: Instantiation test (host linker compatibility)
run: |
timeout --signal=INT --kill-after=30s 20m \
cargo test -p ironclaw_wasm --test wit_tool_runtime_contract -- --nocapture
bench-compile:
name: Benchmark Compilation
needs: changes
if: >
needs.changes.outputs.docs_only != 'true' &&
needs.changes.outputs.has_legacy_tests == 'true' &&
(github.event_name == 'push' || inputs.deep == true) &&
needs.changes.outputs.has_core_code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Install Rust
uses: ./.github/actions/setup-rust
- name: Enable pnpm for setup-node cache
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: |
crates/product/ironclaw_webui/frontend/pnpm-lock.yaml
crates/*/*/ironclaw_webui/frontend/pnpm-lock.yaml
- name: Enable pnpm
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
run: |
set -euo pipefail
webui_dir="$(bash scripts/ci/crate-dir.sh ironclaw_webui)"
cd "${webui_dir}/frontend"
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 # v2
with:
key: bench
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Compile benchmarks
run: cargo bench --all-features --no-run
docker-build:
name: Docker Build
needs: changes
# Dockerfile changes must not be a main-only failure: the merge queue
# builds the image when the merge group actually touches Docker inputs.
# The merge_group arm deliberately does not require has_legacy_tests —
# the scope classifier matches Docker inputs directly, so a merge group
# changing only .dockerignore or a Reborn startup script reports
# has_legacy_tests=false while has_docker_risk=true.
if: >
needs.changes.outputs.docs_only != 'true' &&
((needs.changes.outputs.has_legacy_tests == 'true' &&
(github.event_name == 'push' ||
(inputs.deep == true && inputs.include_docker))) ||
(github.event_name == 'merge_group' && needs.changes.outputs.has_docker_risk == 'true'))
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Build Docker image
run: docker build --target runtime -t ironclaw-reborn-test:ci .
- name: Verify in-worker SSH
shell: bash
run: |
set -euo pipefail
test "$(docker image inspect --format '{{.Config.User}}' ironclaw-reborn-test:ci)" = "root"
docker image inspect --format '{{json .Config.ExposedPorts}}' ironclaw-reborn-test:ci \
| grep -q '"2222/tcp"'
ssh_work="$(mktemp -d)"
container_name="ironclaw-reborn-ssh-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
paste_container_name="${container_name}-paste"
cleanup() {
docker rm --force "$container_name" >/dev/null 2>&1 || true
docker rm --force "$paste_container_name" >/dev/null 2>&1 || true
rm -rf "$ssh_work"
}
trap cleanup EXIT
ssh-keygen -q -t ed25519 -N '' -f "$ssh_work/id_ed25519"
docker run --detach \
--name "$container_name" \
--publish 127.0.0.1::2222 \
--env IRONCLAW_REBORN_WEBUI_TOKEN=ssh-ci-webui-token-0123456789abcdef0123456789abcdef \
--env "IRONCLAW_REBORN_SSH_PUBLIC_KEY=$(cat "$ssh_work/id_ed25519.pub")" \
ironclaw-reborn-test:ci
ssh_port="$(docker port "$container_name" 2222/tcp | awk -F: 'NR == 1 { print $NF }')"
ssh_ready=false
for _ in $(seq 1 30); do
if ssh \
-i "$ssh_work/id_ed25519" \
-p "$ssh_port" \
-o BatchMode=yes \
-o ConnectTimeout=1 \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
agent@127.0.0.1 \
'test "$USER" = agent && test "$HOME" = /workspace && test "$PWD" = /workspace'
then
ssh_ready=true
break
fi
if [ "$(docker inspect --format '{{.State.Running}}' "$container_name")" != "true" ]; then
break
fi
sleep 1
done
if [ "$ssh_ready" != "true" ]; then
docker logs "$container_name"
echo "Reborn runtime did not accept an SSH session as agent" >&2
exit 1
fi
paste_key="$(cat "$ssh_work/id_ed25519.pub")"$'\n'
# The key almost always arrives via `cat id_ed25519.pub`, so the value
# carries a trailing newline. start-sshd must tolerate that: it runs
# under the entrypoint's `set -e`, so rejecting a usable key does not
# merely disable SSH, it aborts the whole container boot. Reuses the
# image already built above -- no second build.
docker run --detach \
--name "$paste_container_name" \
--publish 127.0.0.1::2222 \
--env IRONCLAW_REBORN_WEBUI_TOKEN=ssh-ci-webui-token-0123456789abcdef0123456789abcdef \
--env "IRONCLAW_REBORN_SSH_PUBLIC_KEY=${paste_key}" \
ironclaw-reborn-test:ci
paste_port="$(docker port "$paste_container_name" 2222/tcp | awk -F: 'NR == 1 { print $NF }')"
paste_ready=false
for _ in $(seq 1 30); do
if ssh \
-i "$ssh_work/id_ed25519" \
-p "$paste_port" \
-o BatchMode=yes \
-o ConnectTimeout=1 \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
agent@127.0.0.1 'test "$USER" = agent'
then
paste_ready=true
break
fi
if [ "$(docker inspect --format '{{.State.Running}}' "$paste_container_name")" != "true" ]; then
break
fi
sleep 1
done
if [ "$paste_ready" != "true" ]; then
docker logs "$paste_container_name"
echo "A public key with a trailing newline must still be accepted; rejecting it aborts container boot" >&2
exit 1
fi
version-check:
name: Version Bump Check
runs-on: ubuntu-latest
timeout-minutes: 10
needs: changes
if: >
(github.event_name == 'pull_request' || github.event_name == 'merge_group') &&
needs.changes.outputs.docs_only != 'true' &&
needs.changes.outputs.has_legacy_tests == 'true'
permissions:
contents: read
pull-requests: read
issues: read
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
fetch-depth: 0
- name: Resolve version-check skip labels
id: skip_labels
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
HEAD_SHA: ${{ inputs.ref || github.sha }}
PR_LABELS: ${{ github.event_name == 'pull_request' && join(github.event.pull_request.labels.*.name, ',') || '' }}
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "labels=${PR_LABELS}" >> "$GITHUB_OUTPUT"
echo "allow_skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
COMPARE_JSON="$(gh api "repos/${REPO}/compare/${BASE_SHA}...${HEAD_SHA}")"
PR_NUMBERS="$(
printf '%s' "$COMPARE_JSON" | jq -r '.commits[].sha' \
| while read -r sha; do
[ -n "$sha" ] || continue
gh api "repos/${REPO}/commits/${sha}/pulls" \
-H "Accept: application/vnd.github+json" \
--jq '.[].number' 2>/dev/null || true
done \
| awk 'NF && !seen[$0]++'
)"
PR_COUNT="$(printf '%s\n' "$PR_NUMBERS" | awk 'NF' | wc -l | tr -d ' ')"
if [ "${PR_COUNT}" != "1" ]; then
echo "labels=" >> "$GITHUB_OUTPUT"
echo "allow_skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
LABELS="$(
printf '%s\n' "$PR_NUMBERS" \
| while read -r pr; do
[ -n "$pr" ] || continue
gh api "repos/${REPO}/issues/${pr}" --jq '.labels[].name' 2>/dev/null || true
done \
| awk 'NF && !seen[$0]++'
)"
if [ -n "$LABELS" ]; then
echo "labels=$(printf '%s\n' "$LABELS" | paste -sd, -)" >> "$GITHUB_OUTPUT"
else
echo "labels=" >> "$GITHUB_OUTPUT"
fi
echo "allow_skip=true" >> "$GITHUB_OUTPUT"
- name: Check version bumps for changed extensions
env:
PR_LABELS: ${{ steps.skip_labels.outputs.labels }}
GITHUB_BASE_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || github.event_name == 'merge_group' && github.event.merge_group.base_ref || '' }}
ALLOW_SKIP_VERSION_CHECK: ${{ steps.skip_labels.outputs.allow_skip }}
run: ./scripts/check-version-bumps.sh
platform-compat:
name: Platform & Compat
runs-on: ubuntu-latest
timeout-minutes: 15
if: always()
needs:
- changes
- hooks-parity-tests
- windows-build
- wasm-wit-compat
- bench-compile
- docker-build
- version-check
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
persist-credentials: false
- name: Check Platform & Compat jobs
run: |
# shellcheck disable=SC1091
if ! source .github/scripts/ci-job-result-ok.sh; then
echo "Unable to source .github/scripts/ci-job-result-ok.sh"
exit 1
fi
if [[ "${{ needs.changes.result }}" != "success" ]]; then
echo "changes (scope detection) failed: ${{ needs.changes.result }}"
exit 1
fi
# Every job in this workflow is conditionally gated (by event or by
# detected scope), so "skipped" is a legitimate pass; anything that
# actually ran must have succeeded. This roll-up gives the workflow
# one stable check name that branch rulesets can require.
for job_result in \
"hooks-parity-tests=${{ needs.hooks-parity-tests.result }}" \
"windows-build=${{ needs.windows-build.result }}" \
"wasm-wit-compat=${{ needs.wasm-wit-compat.result }}" \
"bench-compile=${{ needs.bench-compile.result }}" \
"docker-build=${{ needs.docker-build.result }}" \
"version-check=${{ needs.version-check.result }}"; do
name="${job_result%%=*}"
result="${job_result##*=}"
if ! job_result_ok "$name" "$result" true "allow"; then
echo "$name failed: $result"
exit 1
fi
done