#!/usr/bin/env bash set -euo pipefail : "${ACT_WORKFLOW:?ACT_WORKFLOW is not set (e.g. .github/workflows/call-test-workspace.yml)}" : "${ACT_EVENT:=workflow_dispatch}" : "${ACT_JOB:=}" : "${ACT_MATRIX:=}" : "${INFINITO_CONTAINER:?INFINITO_CONTAINER is not set; source scripts/meta/env/load.sh or invoke via make}" : "${ACT_CONTAINER_OPTIONS:=--privileged --label infinito.worktree=${INFINITO_CONTAINER}}" : "${ACT_NETWORK:=host}" : "${ACT_PULL:=false}" : "${ACT_RM:=true}" : "${ACT_PLATFORM_IMAGE:?ACT_PLATFORM_IMAGE is not set; source scripts/meta/env/load.sh or invoke via make}" : "${ACT_BIND:=false}" : "${ACT_INPUTS:=}" : "${ACT_ENV:=}" if [[ "${ACT_PLATFORM_IMAGE}" == local/act-runner-fixed:latest ]] && ! docker image inspect "${ACT_PLATFORM_IMAGE}" >/dev/null 2>&1; then bash "$(dirname "${BASH_SOURCE[0]}")/build_runner_image.sh" fi _act_cache_path="${ACT_ACTION_CACHE_PATH:-/tmp/actcache/act}" # nocheck: act-tool cache path, not a stack variable _stale_mounts=$(mount | grep -E " on ${_act_cache_path}/[^ ]+ type devtmpfs " || true) if [[ -n "${_stale_mounts}" ]]; then echo "ERROR: stale devtmpfs bind-mounts inside ${_act_cache_path} block act from refreshing the actions cache." >&2 echo "Affected mountpoints:" >&2 echo "${_stale_mounts}" | awk '{print " " $3}' >&2 echo "Fix (run on the host, outside the agent sandbox):" >&2 echo " mount | awk -v p='${_act_cache_path}/' '\$5==\"devtmpfs\" && index(\$3,p)==1 {print \$3}' | sudo xargs -r umount" >&2 echo " sudo rm -rf ${_act_cache_path}" >&2 exit 3 fi echo "=== act: workflow=${ACT_WORKFLOW} event=${ACT_EVENT} job=${ACT_JOB:-} matrix=${ACT_MATRIX:-} inputs=${ACT_INPUTS:-} ===" # Exception: act's bundled Actions schema (pkg/schema/workflow_schema.json, still # true on main at v0.2.89) lacks the `queue` concurrency property that GitHub # shipped on 2026-05-07, and rejects the whole workflow over it instead of # ignoring it, so act is fed a copy without those lines. # TODO: drop this sanitize step once act's schema knows `queue` -- # report https://github.com/nektos/act/issues/6095, # fix in review https://github.com/nektos/act/pull/6152. _act_queue_re='^[[:space:]]*queue:[[:space:]]*(single|max)[[:space:]]*$' _act_sanitized="$(mktemp -d)" trap 'rm -rf "${_act_sanitized}"' EXIT _act_workflow="${_act_sanitized}/$(basename "${ACT_WORKFLOW}")" if [[ -d "${ACT_WORKFLOW}" ]]; then cp -r "${ACT_WORKFLOW}" "${_act_workflow}" find "${_act_workflow}" -type f -name '*.y*ml' \ -exec sed -i -E "/${_act_queue_re}/d" {} + else grep -vE "${_act_queue_re}" "${ACT_WORKFLOW}" >"${_act_workflow}" fi cmd=(act "${ACT_EVENT}" -W "${_act_workflow}") _act_workflows_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)/.github/workflows" while read -r _act_label; do cmd+=(-P "${_act_label}=${ACT_PLATFORM_IMAGE}") done < <(grep -rhE 'runs-on:' "${_act_workflows_dir}" | grep -oE 'ubuntu-[0-9]+\.[0-9]+' | sort -u) if [[ -n "${ACT_JOB}" ]]; then cmd+=(-j "${ACT_JOB}") fi if [[ -n "${ACT_MATRIX}" ]]; then IFS=';' read -ra _act_matrix_filters <<<"${ACT_MATRIX}" for pair in "${_act_matrix_filters[@]}"; do cmd+=(--matrix "${pair}") done fi if [[ -n "${ACT_INPUTS}" ]]; then for pair in ${ACT_INPUTS}; do cmd+=(--input "${pair}") done fi if [[ -n "${ACT_ENV}" ]]; then IFS=';' read -ra _act_env_pairs <<<"${ACT_ENV}" for pair in "${_act_env_pairs[@]}"; do pair="${pair#"${pair%%[![:space:]]*}"}" pair="${pair%"${pair##*[![:space:]]}"}" if [[ -n "${pair}" ]]; then cmd+=(--env "${pair}") fi done fi if [[ -n "${ACT_CONTAINER_OPTIONS}" ]]; then cmd+=(--container-options "${ACT_CONTAINER_OPTIONS}") fi if [[ -n "${ACT_NETWORK}" ]]; then cmd+=(--network "${ACT_NETWORK}") fi cmd+=(--concurrent-jobs "1") cmd+=(--pull="${ACT_PULL}") cmd+=(--action-offline-mode) cmd+=(--action-cache-path "${ACT_ACTION_CACHE_PATH:-/tmp/actcache/act}") # nocheck: act-tool cache path, not a stack variable if [[ "${ACT_RM}" == "true" ]]; then cmd+=(--rm) fi cmd+=(--cache-server-addr 127.0.0.1) cmd+=(--artifact-server-addr 127.0.0.1) if [[ "${ACT_BIND}" == "true" ]]; then cmd+=(--bind) fi "${cmd[@]}"