mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
fix(ci): merge the matrix row's disable tokens with the caller's list
Both deploy steps set `disable: ${{ matrix.disable || inputs.disable }}`.
A row carries tokens of its own whenever its network mode needs them (a
clearnet row disables Tor), so the caller's list never reached the
deploy. In CI run 40979252521 the workspace swarm zombie for
svc-db-mariadb/postgres deployed 19 apps instead of 7 on its clearnet
row (fedora: 4h06 for one step, job cancelled at 345 min), while the
debian multi row with no tokens got 7, like main (32m44).
The steps now pass format('{0} {1}', matrix.disable, inputs.disable);
every reader splits on spaces and commas and drops duplicates and blank
keys. Both input descriptions follow. test_deploy_disable_merge.py reads
the live expressions; against the old fallback it fails two subtests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
46962b5110
commit
57e574ac2d
2 files changed
+80
-4
No files matched your search
@@ -75,7 +75,7 @@ on:
|
||||
type: string
|
||||
default: ""
|
||||
disable:
|
||||
description: "Comma-separated provider keys removed from the test inventory; used when the matrix row carries none of its own."
|
||||
description: "Comma-separated provider keys removed from the test inventory, on top of the matrix row's own tokens."
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
@@ -144,7 +144,7 @@ on:
|
||||
type: string
|
||||
default: ""
|
||||
disable:
|
||||
description: "🚫 Provider keys removed from the test inventory (comma-separated)"
|
||||
description: "🚫 Provider keys removed from the test inventory on top of the matrix row's own tokens (comma-separated)"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
@@ -374,7 +374,7 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
variant: ${{ matrix.variant }}
|
||||
disable: ${{ matrix.disable || inputs.disable }}
|
||||
disable: ${{ format('{0} {1}', matrix.disable, inputs.disable) }}
|
||||
network: ${{ matrix.network }}
|
||||
INFINITO_SWARM_VPN: ${{ matrix.vpn }}
|
||||
INFINITO_SWARM_MESHES: ${{ inputs.meshes }}
|
||||
@@ -387,7 +387,7 @@ jobs:
|
||||
env:
|
||||
apps: ${{ matrix.apps }}
|
||||
variant: ${{ matrix.variant }}
|
||||
disable: ${{ matrix.disable || inputs.disable }}
|
||||
disable: ${{ format('{0} {1}', matrix.disable, inputs.disable) }}
|
||||
network: ${{ matrix.network }}
|
||||
ANSIBLE_LOG_PATH: /tmp/ansible-${{ matrix.apps }}.log
|
||||
run: ./scripts/tests/deploy/ci/all.sh 2>&1 | tee "/tmp/ansible-${{ matrix.apps }}.log"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from cli.administration.inventory.provision.services_disabler import (
|
||||
parse_services_disabled,
|
||||
)
|
||||
from tests.utils import PROJECT_ROOT
|
||||
from utils.cache.files import read_text
|
||||
|
||||
DEPLOY_WORKFLOW = PROJECT_ROOT / ".github" / "workflows" / "call-test-deploy.yml"
|
||||
|
||||
_DISABLE_ENV = re.compile(r"^\s+disable:\s*\$\{\{\s*(.*?)\s*\}\}\s*$")
|
||||
_FORMAT = re.compile(
|
||||
r"format\('(?P<template>[^']*)',\s*matrix\.disable,\s*inputs\.disable\)"
|
||||
)
|
||||
_FALLBACK = re.compile(r"matrix\.disable\s*\|\|\s*inputs\.disable")
|
||||
|
||||
OLD_EXPRESSION = "matrix.disable || inputs.disable"
|
||||
|
||||
|
||||
def disable_expressions() -> list[str]:
|
||||
return [
|
||||
match.group(1)
|
||||
for line in read_text(str(DEPLOY_WORKFLOW)).splitlines()
|
||||
if not line.lstrip().startswith("#")
|
||||
for match in [_DISABLE_ENV.match(line)]
|
||||
if match
|
||||
]
|
||||
|
||||
|
||||
def evaluate(expression: str, row: str, passed: str) -> list[str]:
|
||||
"""The provider keys a step receives, as the deploy parses them.
|
||||
|
||||
Args:
|
||||
expression: the step-env expression, without the ``${{ }}`` wrapper.
|
||||
row: the matrix row's ``disable`` value.
|
||||
passed: the caller's ``disable`` input.
|
||||
"""
|
||||
template = _FORMAT.fullmatch(expression)
|
||||
if template:
|
||||
return parse_services_disabled(template.group("template").format(row, passed))
|
||||
if _FALLBACK.fullmatch(expression):
|
||||
return parse_services_disabled(row or passed)
|
||||
raise AssertionError(f"unsupported disable expression: {expression}")
|
||||
|
||||
|
||||
class TestDeployDisableMerge(unittest.TestCase):
|
||||
def test_both_deploy_steps_set_disable(self) -> None:
|
||||
self.assertEqual(len(disable_expressions()), 2)
|
||||
|
||||
def test_row_tokens_keep_the_passed_list(self) -> None:
|
||||
for expression in disable_expressions():
|
||||
with self.subTest(expression=expression):
|
||||
self.assertEqual(
|
||||
evaluate(expression, "tor", "docs,matomo"),
|
||||
["tor", "docs", "matomo"],
|
||||
)
|
||||
|
||||
def test_passed_list_reaches_a_row_without_tokens(self) -> None:
|
||||
for expression in disable_expressions():
|
||||
with self.subTest(expression=expression):
|
||||
self.assertEqual(evaluate(expression, "", "docs"), ["docs"])
|
||||
|
||||
def test_row_tokens_reach_a_caller_without_a_list(self) -> None:
|
||||
for expression in disable_expressions():
|
||||
with self.subTest(expression=expression):
|
||||
self.assertEqual(evaluate(expression, "tor", ""), ["tor"])
|
||||
|
||||
def test_the_old_fallback_drops_the_passed_list(self) -> None:
|
||||
self.assertEqual(evaluate(OLD_EXPRESSION, "tor", "docs,matomo"), ["tor"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user