Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions .github/workflows/cicd-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,21 +174,21 @@ jobs:
HAS_MBRIDGE=$(echo "$LABELS" | jq 'any(. == "Run MBridge tests")')

if [ "$IS_MERGE_GROUP" == "true" ]; then
SCOPE=mr-github; N_REPEAT=1; LIGHTWEIGHT=false
SCOPE=L1; N_REPEAT=1; LIGHTWEIGHT=false
elif [ "$HAS_RUN_TESTS" == "true" ]; then
SCOPE=mr-github; N_REPEAT=1; LIGHTWEIGHT=true
SCOPE=L1; N_REPEAT=1; LIGHTWEIGHT=true
elif [ "$HAS_RUN_FUNCTIONAL" == "true" ]; then
SCOPE=mr-github; N_REPEAT=5; LIGHTWEIGHT=false
SCOPE=L1; N_REPEAT=5; LIGHTWEIGHT=false
elif [ "$IS_CI_WORKLOAD" == "true" ] || [ "$EVENT_NAME" == "workflow_dispatch" ]; then
# Scheduled / dispatch / release have no PR labels; default to the
# full functional scope so cadence (set below) is the discriminator.
# `workflow_dispatch` is forced into this branch because upstream
# pre-flight reports is_ci_workload=false when dispatched from a
# `pull-request/*` branch, which would otherwise drop us into the
# slim scope.
SCOPE=mr-github; N_REPEAT=5; LIGHTWEIGHT=false
# full functional tier (L1) so cadence (set below) is the
# discriminator. `workflow_dispatch` is forced into this branch
# because upstream pre-flight reports is_ci_workload=false when
# dispatched from a `pull-request/*` branch, which would otherwise
# drop us into the slim tier.
SCOPE=L1; N_REPEAT=5; LIGHTWEIGHT=false
else
SCOPE=mr-github-slim; N_REPEAT=5; LIGHTWEIGHT=false
SCOPE=L0; N_REPEAT=5; LIGHTWEIGHT=false
fi

if [ "$HAS_MBRIDGE" == "true" || $IS_MERGE_GROUP == "true" ]; then
Expand Down Expand Up @@ -233,7 +233,7 @@ jobs:
_RT=$( [ "$IS_MERGE_GROUP" != "true" ] && [ "$HAS_RUN_TESTS" == "true" ] && echo "**→**" || echo "" )
_RF=$( [ "$IS_MERGE_GROUP" != "true" ] && [ "$HAS_RUN_TESTS" != "true" ] && [ "$HAS_RUN_FUNCTIONAL" == "true" ] && echo "**→**" || echo "" )
_CI=$( [ "$IS_MERGE_GROUP" != "true" ] && [ "$HAS_RUN_TESTS" != "true" ] && [ "$HAS_RUN_FUNCTIONAL" != "true" ] && [ "$IS_CI_WORKLOAD" == "true" ] && echo "**→**" || echo "" )
_DF=$( [ "$SCOPE" == "mr-github-slim" ] && echo "**→**" || echo "" )
_DF=$( [ "$SCOPE" == "L0" ] && echo "**→**" || echo "" )
_LTS=$( [ "$HAS_LTS" == "true" ] && echo "**→**" || echo "" )
_DEV=$( [ "$HAS_LTS" != "true" ] && echo "**→**" || echo "" )
_CMG=$( [ "$CADENCE" == "mergegroup" ] && echo "**→**" || echo "" )
Expand All @@ -260,11 +260,11 @@ jobs:

| | Trigger | \`scope\` | \`n_repeat\` | \`lightweight\` |
|---|---|---|---|---|
| $_MG | Merge group | \`mr-github\` | \`1\` | \`false\` |
| $_RT | Label: _Run tests_ | \`mr-github\` | \`1\` | \`true\` |
| $_RF | Label: _Run functional tests_ | \`mr-github\` | \`5\` | \`false\` |
| $_CI | Schedule / dispatch (CI workload) | \`mr-github\` | \`5\` | \`false\` |
| $_DF | _(default)_ | \`mr-github-slim\` | \`5\` | \`false\` |
| $_MG | Merge group | \`L1\` | \`1\` | \`false\` |
| $_RT | Label: _Run tests_ | \`L1\` | \`1\` | \`true\` |
| $_RF | Label: _Run functional tests_ | \`L1\` | \`5\` | \`false\` |
| $_CI | Schedule / dispatch (CI workload) | \`L1\` | \`5\` | \`false\` |
| $_DF | _(default)_ | \`L0\` | \`5\` | \`false\` |

**Cadence** _(filter bypassed when \`Run tests\` or \`Run functional tests\` label is set)_

Expand Down
10 changes: 10 additions & 0 deletions .gitlab/stages/04.functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ functional:configure:
RELEASE_ARGS=()
fi
- |
# NOTE: $FUNCTIONAL_TEST_SCOPE is supplied by external scheduled-pipeline
# configurations and uses the GitLab-side legacy values: `mr`, `mr-slim`,
# `nightly`, `weekly`, `unit-tests`, `release`.
# - `mr` / `mr-slim` / `unit-tests` / `release` pass through verbatim
# and match recipe rows tagged with the same string. They are
# intentionally NOT aliased (see LEGACY_SCOPE_ALIASES in
# tests/test_utils/python_scripts/recipe_parser.py) so the GitLab
# and GitHub matrices stay decoupled.
# - `nightly` / `weekly` are aliased to L2 / L3 by the parser and also
# inject a default cadence when the recipe has no explicit one.
ARGS=(
"--scope $FUNCTIONAL_TEST_SCOPE"
"--n-repeat $FUNCTIONAL_TEST_REPEAT"
Expand Down
61 changes: 56 additions & 5 deletions tests/test_utils/python_scripts/recipe_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,44 @@
logger = logging.getLogger(__name__)

DEFAULT_CADENCE = ["pr", "nightly", "mergegroup"]
ALLOWED_CADENCE_VALUES = set(DEFAULT_CADENCE)
ALLOWED_CADENCE_VALUES = set(DEFAULT_CADENCE) | {"weekly"}

# Maps legacy `scope` values (encoded "when" + "which suite" together) onto the
# new vocabulary: an L-tier (cost class) plus, where the legacy name implied a
# trigger, a default cadence. The tier acts purely as a suite/cost label;
# cadence remains the trigger axis.
#
# Only GitHub-side scopes (`mr-github-slim`, `mr-github`) are aliased onto the
# L-tier names. GitLab-only scopes (`mr`, `mr-slim`, `unit-tests`) are
# intentionally left as pass-through so GitLab `--scope mr*` / `--scope
# unit-tests` continue to match recipes verbatim and don't bleed into the
# GitHub L0 / L1 matrix.
LEGACY_SCOPE_ALIASES = {
# GitHub-only scopes are aliased onto the L-tier vocabulary so the GH CI
# workflow can filter on `L0` / `L1`. GitLab-only scopes (`mr`, `mr-slim`)
# are intentionally NOT aliased: they pass through to recipe rows verbatim
# and remain matchable by GitLab's `--scope mr-slim` / `--scope mr` calls,
# without bleeding into the GitHub `L0` / `L1` matrix.
"mr-github-slim": ("L0", None),
"mr-github": ("L1", None),
"nightly": ("L2", ["nightly"]),
"weekly": ("L3", ["weekly"]),
}
Comment thread
balasaajay marked this conversation as resolved.


def _apply_scope_alias(scope_value: str, explicit_cadence: Optional[List[str]]) -> tuple:
"""Resolve a legacy scope value to (new_scope, cadence).

If the scope value is in the alias map, returns the new tier name. The
alias's cadence is used only when `explicit_cadence` is None — explicit
per-product or outer cadence always wins.
"""
if scope_value not in LEGACY_SCOPE_ALIASES:
return scope_value, explicit_cadence
new_scope, alias_cadence = LEGACY_SCOPE_ALIASES[scope_value]
if explicit_cadence is not None or alias_cadence is None:
return new_scope, explicit_cadence
return new_scope, list(alias_cadence)


def _validate_cadence(cadence: List[str], test_case: str) -> None:
Expand Down Expand Up @@ -81,17 +118,31 @@ def flatten_products(workload_manifest: dotdict) -> dotdict:
cartesian_values = [param_dict[k] for k in cartesian_keys]

# Resolve effective cadence: inner overrides outer, default loose.
effective_cadence = inner_cadence if inner_cadence is not None else outer_cadence
if effective_cadence is None:
effective_cadence = list(DEFAULT_CADENCE)
# `explicit_cadence` is None when neither inner nor outer set it,
# which is the only case where a legacy scope alias may inject a
# default cadence (e.g. scope: [nightly] -> cadence: [nightly]).
explicit_cadence = inner_cadence if inner_cadence is not None else outer_cadence
default_cadence = (
list(explicit_cadence) if explicit_cadence is not None else list(DEFAULT_CADENCE)
)

param_combinations = itertools.product(*cartesian_values)

for value_combination in param_combinations:
# Map parameter names to their values
flattened = dict(zip(cartesian_keys, value_combination))
flattened["test_case"] = test_case
flattened["cadence"] = effective_cadence
# Apply legacy scope alias per row so that scope: [mr, nightly]
# produces two rows with the right (tier, cadence) each.
row_cadence = default_cadence
if "scope" in flattened:
new_scope, aliased_cadence = _apply_scope_alias(
flattened["scope"], explicit_cadence
)
flattened["scope"] = new_scope
if aliased_cadence is not None:
row_cadence = list(aliased_cadence)
flattened["cadence"] = row_cadence
flattened_products.append(flattened)

workload_manifest.products = flattened_products
Expand Down
Loading