fix(deploy): stop the deploy from writing bytecode into the tree it archives

The snapshot task tars the live checkout from the repository root. A pristine published image carries no __pycache__, so loading each role's own filter_plugins or lookup_plugins writes one during the play, which moves a directory ctime under roles/. GNU tar answers a changed directory with exit 1 and set -o pipefail turns that into a failed task, which is how run 39113865427 lost docs#0, docs#1 and API#1.

The flagged set is not arbitrary: it is exactly the roles that own a plugin directory AND ran in that play. Three jobs, three different role sets, the same rule each time: 7 of 52 roles in docs#1, 3 of 25 in API#1, 5 in docs#0. web-app-keycloak owns a filter_plugins and was never flagged, because it never ran. The same task passes on the CI workspace with rc 0, where earlier Python steps had already populated those caches.

Set before the first child is spawned, so make setup, the inventory validator, ansible-playbook and every forked worker inherit it. scripts/tests/code/run.sh:31 already uses the same variable for the test suite. cli and utils sit in the snapshot paths too and role lookups import from utils during the play, so the same change closes that race as well.

Two callers still bypass this function and invoke ansible-playbook directly, scripts/tests/deploy/local/sync/role.sh and scripts/tests/design/sync.sh; they remain exposed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-10-18 14:25:46 +02:00
1 parent 415542c754
commit 498d9d1c12
1 file changed
+2
@@ -37,6 +37,8 @@ def run_ansible_playbook(
start_time = dt.datetime.now(tz=dt.UTC)
print(f"\n▶️ Script started at: {start_time.isoformat()}\n", flush=True)
os.environ["PYTHONDONTWRITEBYTECODE"] = "1"
if not skip_build:
print("\n🛠️ Running project build (make setup)...\n", flush=True)
run_make(repo_root, "setup")