Skip to content

Commit eed0791

Browse files
[CRE] mixed-env nightly full-matrix sweep + chain-specific variants
Extends mixed-env coverage beyond the per-PR OCR3/DON2DON subset. - Nightly full sweep (cre-mixed-env-nightly.yaml): runs the entire CRE matrix under mixed-env (mixed_env_all: true), comparing today's develop nightly image against a previous one — catching non-determinism introduced into develop between nightlies, across the whole suite. No image build (reuses nightlies). - cre-system-tests.yaml: adds a mixed_env_all input + matrix logic that appends mixed-env to the default (EVM) topology list and the chain-specific mixed-env variants to the Solana/Aptos/Stellar tests; generalizes the render step and the chainlink-image gating to any `mixed-env*` topology. - Chain-specific mixed-env templates: mixed-env-solana-don, mixed-env-aptos-don, mixed-env-stellar-don (2-2 PR/develop split; verified via `topology show`). - render-mixed-env.sh generalized to render any mixed-env-*-don.toml.tmpl. - gitignore covers rendered configs/mixed-env-*.toml; docs updated. Sharding / Module_Cache / Multi_Gateway need their own mixed variants (follow-up). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 63aada7 commit eed0791

8 files changed

Lines changed: 503 additions & 15 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: CRE Mixed-Env Nightly Sweep
2+
3+
# Runs the full CRE system-test matrix under the mixed-env topology (2 nodes on
4+
# today's develop nightly image, 2 on yesterday's) to catch non-determinism /
5+
# cross-version incompatibilities introduced into develop between nightlies —
6+
# across the whole suite (EVM + Solana/Aptos/Stellar), not just the per-PR subset.
7+
#
8+
# It calls cre-system-tests.yaml directly with mixed_env_all: true, so no image
9+
# build is needed: both images are the cached nightly develop builds.
10+
11+
on:
12+
schedule:
13+
# After the nightly image build (docker-build.yml runs at 03:00 UTC).
14+
- cron: "0 5 * * *"
15+
workflow_dispatch:
16+
inputs:
17+
baseline_date:
18+
description: "Baseline nightly date (YYYYMMDD). Defaults to yesterday."
19+
required: false
20+
type: string
21+
default: ""
22+
23+
permissions:
24+
contents: read
25+
id-token: write
26+
27+
jobs:
28+
set-dates:
29+
runs-on: ubuntu-latest
30+
outputs:
31+
today: ${{ steps.d.outputs.today }}
32+
baseline: ${{ steps.d.outputs.baseline }}
33+
steps:
34+
- id: d
35+
shell: bash
36+
run: |
37+
today="$(date -u +'%Y%m%d')"
38+
baseline="${{ inputs.baseline_date }}"
39+
if [[ -z "${baseline}" ]]; then
40+
baseline="$(date -u -d 'yesterday' +'%Y%m%d')"
41+
fi
42+
echo "today=${today}" | tee -a "$GITHUB_OUTPUT"
43+
echo "baseline=${baseline}" | tee -a "$GITHUB_OUTPUT"
44+
45+
mixed-env-sweep:
46+
needs: set-dates
47+
permissions:
48+
contents: read
49+
id-token: write
50+
uses: ./.github/workflows/cre-system-tests.yaml
51+
secrets: inherit
52+
with:
53+
ecr: "sdlc"
54+
chainlink_image_repository_path: "chainlink"
55+
# "PR" side = today's develop nightly.
56+
chainlink_image_tag: "nightly-${{ needs.set-dates.outputs.today }}"
57+
# Baseline side = a previous develop nightly, so the 2-2 split compares two
58+
# develop builds and surfaces non-determinism introduced since then.
59+
mixed_env_baseline_image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:nightly-${{ needs.set-dates.outputs.baseline }}"
60+
mixed_env_all: true

.github/workflows/cre-system-tests.yaml

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ on:
3838
description:
3939
"Full baseline (develop) chainlink image ref for the mixed-env
4040
topology. If empty, defaults to the develop nightly image."
41+
mixed_env_all:
42+
required: false
43+
type: boolean
44+
default: false
45+
description:
46+
"Nightly full sweep: also run every test under a mixed-env topology
47+
(EVM base + chain-specific variants)."
4148
workflow_call:
4249
inputs:
4350
chainlink_image_repository_path:
@@ -71,6 +78,13 @@ on:
7178
description:
7279
"Full baseline (develop) chainlink image ref for the mixed-env
7380
topology. If empty, defaults to the develop nightly image."
81+
mixed_env_all:
82+
required: false
83+
type: boolean
84+
default: false
85+
description:
86+
"Nightly full sweep: also run every test under a mixed-env topology
87+
(EVM base + chain-specific variants)."
7488

7589
jobs:
7690
define-test-matrix:
@@ -143,6 +157,22 @@ jobs:
143157
]
144158
}'
145159
160+
# Nightly full sweep: when mixed_env_all is set, also run every EVM-based test
161+
# under mixed-env, and the chain-specific tests under their chain mixed-env variant.
162+
# (Sharding / Module_Cache / Multi_Gateway need their own mixed variants — follow-up.)
163+
if [[ "${{ inputs.mixed_env_all }}" == "true" ]]; then
164+
TOPOLOGIES_JSON=$(jq -c '. + [{"topology":"mixed-env","configs":"configs/mixed-env-don.toml"}]' <<<"$TOPOLOGIES_JSON")
165+
MIXED_PER_TEST='{
166+
"Test_CRE_V2_Aptos_Suite":[{"topology":"mixed-env-aptos","configs":"configs/mixed-env-aptos-don.toml"}],
167+
"Test_CRE_V2_Stellar_Suite":[{"topology":"mixed-env-stellar","configs":"configs/mixed-env-stellar-don.toml"}],
168+
"Test_CRE_V2_Solana_Write":[{"topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"}],
169+
"Test_CRE_V2_Solana_LogTrigger":[{"topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"}],
170+
"Test_CRE_V2_Solana_Read_Accounts":[{"topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"}]
171+
}'
172+
PER_TEST_TOPOLOGIES_JSON=$(jq -c -n --argjson a "$PER_TEST_TOPOLOGIES_JSON" --argjson b "$MIXED_PER_TEST" \
173+
'reduce ($b|to_entries[]) as $e ($a; .[$e.key] = ((.[$e.key] // []) + $e.value))')
174+
fi
175+
146176
test_names=$(grep -rh -oP '^func \K(Test|Example)[^(]+' system-tests/tests/smoke/cre/*_test.go | grep -v Test_Upgrade | grep -v '^TestMain$')
147177
148178
tests=$(echo "$test_names" | jq -c -R -s \
@@ -276,7 +306,7 @@ jobs:
276306
working-directory: system-tests/lib
277307

278308
- name: Render mixed-env topology
279-
if: ${{ matrix.tests.topology == 'mixed-env' }}
309+
if: ${{ startsWith(matrix.tests.topology, 'mixed-env') }}
280310
working-directory: core/scripts/cre/environment
281311
shell: bash
282312
env:
@@ -296,7 +326,8 @@ jobs:
296326
export CRE_PR_IMAGE CRE_BASELINE_IMAGE
297327
echo "PR image: ${CRE_PR_IMAGE}"
298328
echo "Baseline image: ${CRE_BASELINE_IMAGE}"
299-
bash configs/render-mixed-env.sh
329+
echo "Config: ${{ matrix.tests.configs }}"
330+
bash configs/render-mixed-env.sh "${{ matrix.tests.configs }}"
300331
301332
- name: Start observability stack (Beholder suite)
302333
if: contains(matrix.tests.test_name, 'Beholder_Suite')
@@ -386,7 +417,7 @@ jobs:
386417
# CTF_CHAINLINK_IMAGE empty (a non-empty value forces every node onto one image).
387418
# NB: the non-empty value must sit on the `&&` side — `cond && '' || X` always
388419
# yields X in GitHub Actions because '' is falsy.
389-
chainlink-image: "${{ matrix.tests.topology != 'mixed-env' && env.CHAINLINK_IMAGE_FULL || '' }}"
420+
chainlink-image: "${{ !startsWith(matrix.tests.topology, 'mixed-env') && env.CHAINLINK_IMAGE_FULL || '' }}"
390421
chip-router-image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{
391422
secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
392423
ctf-configs: ${{ matrix.tests.configs }}
@@ -451,7 +482,7 @@ jobs:
451482
# Dedicated hard gate. The smoke step above is continue-on-error
452483
# (auto-quarantine), which would swallow the in-test TestMain scan, so we
453484
# re-scan the live node containers here and fail the job on any marker.
454-
if: ${{ always() && matrix.tests.topology == 'mixed-env' }}
485+
if: ${{ always() && startsWith(matrix.tests.topology, 'mixed-env') }}
455486
shell: bash
456487
run: |
457488
set -uo pipefail

core/scripts/cre/environment/.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ cre_v*
1515
configs/*-cache.toml
1616
cache/
1717

18-
# rendered mixed-env topology (generated from configs/mixed-env-don.toml.tmpl)
19-
configs/mixed-env-don.toml
18+
# rendered mixed-env topologies (generated from configs/mixed-env-*.toml.tmpl); .tmpl are tracked
19+
configs/mixed-env-*.toml
2020

2121
logs/
2222

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Mixed-env Aptos topology (template) — derived from workflow-gateway-don-aptos.toml.
2+
#
3+
# Same as workflow-gateway-don-aptos, except the workflow DON runs 2 nodes on the PR
4+
# image and 2 on the develop image, to surface non-determinism between the two code
5+
# versions (see docs/mixed-env.md). Render with configs/render-mixed-env.sh:
6+
#
7+
# CRE_PR_IMAGE=<pr> CRE_BASELINE_IMAGE=<develop> \
8+
# ./configs/render-mixed-env.sh configs/mixed-env-aptos-don.toml
9+
#
10+
# Keep in sync with workflow-gateway-don-aptos.toml if that base topology changes.
11+
# Do NOT set CTF_CHAINLINK_IMAGE with this topology (it would force one image on all nodes).
12+
13+
[chip_router]
14+
image = "local-cre-chip-router:v1.0.1"
15+
16+
[[blockchains]]
17+
type = "anvil"
18+
chain_id = "1337"
19+
container_name = "anvil-1337"
20+
docker_cmd_params = ["-b", "0.5", "--mixed-mining"]
21+
22+
[[blockchains]]
23+
type = "aptos"
24+
chain_id = "4"
25+
26+
[jd]
27+
csa_encryption_key = "d1093c0060d50a3c89c189b2e485da5a3ce57f3dcb38ab7e2c0d5f0bb2314a44"
28+
image = "job-distributor:0.28.0"
29+
30+
[infra]
31+
type = "docker"
32+
33+
[[nodesets]]
34+
nodes = 4
35+
name = "workflow"
36+
don_family = "test-don-family"
37+
don_types = ["workflow"]
38+
override_mode = "each"
39+
http_port_range_start = 10100
40+
41+
supported_evm_chains = [1337]
42+
env_vars = { CL_CRE_SETTINGS_DEFAULT = '{"PerWorkflow":{"CapabilityCallTimeout":"5m0s","ChainAllowed":{"Default":"false","Values":{"1337":"true","4457093679053095497":"true"}},"ExecutionTimestampsEnabled":"true","FeatureAptosWriteReportBlockTimestampActivePeriod":"[2020-01-01 00:00:00 +0000 UTC,2030-01-01 00:00:00 +0000 UTC]"}}' }
43+
capabilities = ["cron", "consensus", "aptos-4", "don-time"]
44+
registry_based_launch_allowlist = ["cron-trigger@1.0.0"]
45+
46+
[nodesets.db]
47+
image = "postgres:12.0"
48+
port = 13000
49+
50+
[[nodesets.node_specs]] # node 0 - PR
51+
roles = ["plugin"]
52+
[nodesets.node_specs.node]
53+
image = "${CRE_PR_IMAGE}"
54+
pull_image = true
55+
user_config_overrides = ""
56+
[[nodesets.node_specs]] # node 1 - PR
57+
roles = ["plugin"]
58+
[nodesets.node_specs.node]
59+
image = "${CRE_PR_IMAGE}"
60+
pull_image = true
61+
user_config_overrides = ""
62+
[[nodesets.node_specs]] # node 2 - develop
63+
roles = ["plugin"]
64+
[nodesets.node_specs.node]
65+
image = "${CRE_BASELINE_IMAGE}"
66+
pull_image = true
67+
user_config_overrides = ""
68+
[[nodesets.node_specs]] # node 3 - develop
69+
roles = ["plugin"]
70+
[nodesets.node_specs.node]
71+
image = "${CRE_BASELINE_IMAGE}"
72+
pull_image = true
73+
user_config_overrides = ""
74+
75+
[[nodesets]]
76+
nodes = 1
77+
name = "bootstrap-gateway"
78+
don_family = "test-don-family"
79+
don_types = ["bootstrap", "gateway"]
80+
override_mode = "each"
81+
http_port_range_start = 10300
82+
83+
supported_evm_chains = [1337]
84+
85+
[nodesets.db]
86+
image = "postgres:12.0"
87+
port = 13200
88+
89+
[[nodesets.node_specs]]
90+
roles = ["bootstrap", "gateway"]
91+
[nodesets.node_specs.node]
92+
image = "${CRE_BASELINE_IMAGE}"
93+
pull_image = true
94+
custom_ports = ["5002:5002", "15002:15002"]
95+
user_config_overrides = ""

0 commit comments

Comments
 (0)