Files
computer-playbook/scripts/tests/deploy/act/workflow.sh
T
kevinveenbirkenbachandClaude Opus 5.5 ca6faac318 fix(ci): share the vulnerability databases with act runs and local deploys
Under act the deploy job pinned an engine but skipped the cache restores, so
every local swarm-* run stopped on a missing Grype database. The swarm
matrix also ran inside the act job container, where the shared host
directory did not exist, and the workspace job would have kept a copy of
about 5 GB in every worktree.

- scripts/tests/deploy/act/workflow.sh requires
  INFINITO_VULNERABILITY_DB_HOST_PATH, creates it on the host and binds it
  into the job container at the same path, because that container drives
  the host daemon, which resolves every stack and swarm node bind on the
  host.
- call-test-deploy.yml pins engine and database path in one step that runs
  only outside act; under act the deploy draws an engine and refreshes the
  shared directory. call-test-workspace.yml takes the shared path under act.
- The refresh lock moves into the shared directory, so host deploys and act
  runs serialize on one file, and a root refresh hands its files to the
  directory owner. hand_over skips paths a mocked download never created,
  which failed four TestRefresh cases when the gate ran as root.
- A missing INFINITO_VULNERABILITY_DB_HOST_PATH stops compose up with a
  "run 'make dotenv'" hint instead of a KeyError.
- Rationale paragraphs in the database and compose docstrings are dropped.

Part of #1324

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 02:44:59 +01:00

108 lines
4.4 KiB
Bash
Executable File

#!/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:=}"
: "${INFINITO_VULNERABILITY_DB_HOST_PATH:?INFINITO_VULNERABILITY_DB_HOST_PATH is not set; run 'make dotenv' to generate the .env single source of truth}"
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:-<all>} matrix=${ACT_MATRIX:-<none>} inputs=${ACT_INPUTS:-<none>} ==="
# 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
mkdir -p "${INFINITO_VULNERABILITY_DB_HOST_PATH}"
cmd+=(--container-options "${ACT_CONTAINER_OPTIONS} --volume ${INFINITO_VULNERABILITY_DB_HOST_PATH}:${INFINITO_VULNERABILITY_DB_HOST_PATH}")
cmd+=(--env "INFINITO_VULNERABILITY_DB_HOST_PATH=${INFINITO_VULNERABILITY_DB_HOST_PATH}")
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[@]}"