Files
computer-playbook/docs/agents/action/iteration/workflow.md
kevinveenbirkenbachandClaude Opus 5.5 088c8be14f fix(ci): pull workspace images through the GHCR mirror like the deploy jobs
The workspace jobs pulled every image anonymously from Docker Hub and
two of them failed on its rate limit in run 39059128678 (#990): the
fedora swarm drill on busybox:1.38 on all three nodes, the centos
compose drill while building tor-smtp_custom. The regular deploy jobs
pull through the GHCR mirror, but the mirror was tied to being a real
GitHub runner: Profile.image_mirror_enabled() returned
runs_on_github(), and the swarm routine generated mirrors.yml only when
cli.meta.runtime reported github, which is act inside make
swarm-zombie.

The mirror is now its own capability, INFINITO_GHCR_MIRROR (next to
INFINITO_GHCR_MIRROR_PREFIX), written as a run fact like
INFINITO_CACHE_STACK: true on a real GitHub runner,
false everywhere else, and a non-empty exported value wins for the run.
Profile.image_mirror_enabled() reads the declaration and keeps
runs_on_github() as the fallback, and 02_provision_inventory.sh gates
on the same value instead of the runtime name. make swarm-zombie
forwards it into act through ACT_ENV, since act ignores the host env.

call-test-workspace.yml declares INFINITO_GHCR_MIRROR=true and passes
INFINITO_GHCR_MIRROR_PREFIX into the workspace container. Nothing else
of the workspace changes: is_ci, runs_on_github, the cache stack and
the docker root stay local-like. The step that loads the rescue paths
now removes the .env it generated on the runner, because on debian
rows load.sh sourced it inside the container and the run inherited
INFINITO_RUNNING_ON_GITHUB=true.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 22:40:13 +02:00

3.7 KiB

Workflow Loop

Use this page for iterating on GitHub Actions workflows locally through Act. For role-level and spec-level iteration, see Compose Loop and Playwright Spec Loop. For the swarm deploy loop, see Swarm Loop.

When to use

  • Use this loop while developing, optimizing, or debugging a GitHub Actions workflow locally through Act.
  • For role-level or spec-level iteration use the Compose Loop or Playwright Spec Loop; for the swarm deploy use the Swarm Loop.

The loop

  • When you are developing, optimizing, or debugging GitHub Actions workflows, you SHOULD explicitly propose make act-workflow as the default iterative local debug loop.
  • You MUST NOT assume that Act should be used automatically for workflow work. If the user agrees with the proposal, you SHOULD use make act-workflow for the iteration loop.
  • After the user agrees to use Act, you SHOULD rerun make act-workflow after each focused workflow change and inspect the new output before making further edits.
  • If the workflow uses a distro matrix, you MUST iterate on one distro at a time instead of rerunning the whole matrix during the default debug loop.
  • Debian SHOULD be the preferred distro for that focused workflow iteration unless the failure is clearly distro-specific or the user asked for a different distro.
  • When you constrain an Act matrix run through ACT_MATRIX, you MUST use Act's key:value syntax instead of key=value. Otherwise Act may ignore the filter and rerun the whole matrix.
  • For .github/workflows/call-test-workspace.yml, the preferred focused Debian example is make act-workflow ACT_WORKFLOW=.github/workflows/call-test-workspace.yml ACT_JOB=test-workspace ACT_MATRIX="dev_runtime_image:$(python3 -c 'from utils.distros import dev_runtime_image; print(dev_runtime_image("debian"))')".
  • You SHOULD avoid jumping straight to repeated remote CI reruns when make act-workflow can validate the workflow locally and the user agreed to use it.

Recovery & gotchas

act fails at "Set up job" on recent Docker

make act-* aborts with failed to copy content to container: mkdirat var/run... because the stock runner image's /var/run symlink trips Docker 28/29's stricter docker cp.

Fix: run make act-runner-image once, then prefix any act target with ACT_PLATFORM_IMAGE=local/act-runner-fixed:latest (e.g. ACT_PLATFORM_IMAGE=local/act-runner-fixed:latest make swarm-zombie app=<app>).

A green local workspace run does not clear CI

Two properties of the workspace suite differ between make act-workflow and a GitHub runner, so a class of defects is structurally invisible locally.

Nested Docker state does not survive a teardown locally, but does in CI. INFINITO_DOCKER_VOLUME is the named volume docker (default.env) and a host path (/mnt/docker) on GitHub. compose down -v removes a named volume and cannot remove a bind mount, so every workspace track starts on a clean inner daemon locally while CI carries the previous track's containers into the next one. Defects that need a container, network, or bind source to outlive a teardown cannot reproduce under act.

The runtime identity differs. act sets ACT=true, so detect_gha_act() in runtime.py resolves INFINITO_RUNNING_ON_GITHUB=false where a real runner resolves true. Anything keyed off that fact behaves differently, and act cannot prove a fix to it either way. The image mirror is the exception: CI declares INFINITO_GHCR_MIRROR=true for the workspace suite, while a local run keeps the generated false and pulls upstream.

Run the local loop to iterate quickly; treat CI as the only authority for both classes.