Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
105 changes: 105 additions & 0 deletions .github/workflows/cre-mixed-env-nightly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: CRE Mixed-Env Nightly Sweep

# Runs the full CRE system-test matrix under the mixed-env topology (2 nodes on
# today's develop nightly image, 2 on yesterday's) to catch non-determinism /
# cross-version incompatibilities introduced into develop between nightlies —
# across the whole suite (EVM + Solana/Aptos/Stellar), not just the per-PR subset.
#
# It calls cre-system-tests.yaml directly with mixed_env_all: true, so no image
# build is needed: both images are the cached nightly develop builds.

on:
schedule:
# After the nightly image build (docker-build.yml runs at 03:00 UTC).
- cron: "0 5 * * *"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about triggering it with workflow_call from this workflow? that's what we do for all other nightly tests and it is triggered by Docker Build, which build the nightly image

workflow_dispatch:
inputs:
baseline_date:
description: "Baseline nightly date (YYYYMMDD). Defaults to yesterday."
required: false
type: string
default: ""

permissions:
contents: read
id-token: write

jobs:
set-dates:
runs-on: ubuntu-latest
outputs:
today: ${{ steps.d.outputs.today }}
baseline: ${{ steps.d.outputs.baseline }}
steps:
- id: d
shell: bash
run: |
today="$(date -u +'%Y%m%d')"
baseline="${{ inputs.baseline_date }}"
if [[ -z "${baseline}" ]]; then
baseline="$(date -u -d 'yesterday' +'%Y%m%d')"
fi
echo "today=${today}" | tee -a "$GITHUB_OUTPUT"
echo "baseline=${baseline}" | tee -a "$GITHUB_OUTPUT"

mixed-env-sweep:
needs: set-dates
permissions:
contents: read
id-token: write
uses: ./.github/workflows/cre-mixed-env-tests.yaml
secrets: inherit
with:
ecr: "sdlc"
chainlink_image_repository_path: "chainlink"
# "PR" side = today's develop nightly.
chainlink_image_tag: "nightly-${{ needs.set-dates.outputs.today }}"
# Baseline side = a previous develop nightly, so the 2-2 split compares two
# develop builds and surfaces non-determinism introduced since then.
mixed_env_baseline_image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:nightly-${{ needs.set-dates.outputs.baseline }}"

Check failure on line 59 in .github/workflows/cre-mixed-env-nightly.yaml

View workflow job for this annotation

GitHub Actions / Validate Github Action Workflows

[actionlint] reported by reviewdog 🐶 context "secrets" is not allowed here. available contexts are "github", "inputs", "matrix", "needs", "strategy", "vars". see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability for more details [expression] Raw Output: e:.github/workflows/cre-mixed-env-nightly.yaml:59:38: context "secrets" is not allowed here. available contexts are "github", "inputs", "matrix", "needs", "strategy", "vars". see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability for more details [expression]
full_matrix: true

# There is no PR to block on a scheduled run, so alert the CRE team on Slack when
# the sweep fails (a failure usually means non-determinism was introduced into
# develop between the two nightlies, or a job/infra error).
notify-on-failure:
name: Notify Slack on failure
if: failure()
needs: [set-dates, mixed-env-sweep]
runs-on: ubuntu-latest
environment:
name: integration
deployment: false
steps:
- name: Send Slack notification (#cre-platform-operations)
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0

Check warning on line 75 in .github/workflows/cre-mixed-env-nightly.yaml

View workflow job for this annotation

GitHub Actions / Validate Workflow Changes

1. Action is using node20. Versions older than node24 are being deprecated. Use a newer version of the action if possible. (node-version / warning)
with:
errors: "true"
method: chat.postMessage
token: ${{ secrets.QA_SLACK_API_KEY }}
# If delivery fails, invite the bot to the channel, or replace the name
# with the channel ID (Cxxxxxxxx) which chat.postMessage resolves more reliably.
payload: |
{
"channel": "#cre-platform-operations",
"text": "CRE Mixed-Env Nightly Sweep failed — possible non-determinism introduced into develop.",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*:rotating_light: CRE Mixed-Env Nightly Sweep failed :rotating_light:*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Today's develop nightly `nightly-${{ needs.set-dates.outputs.today }}` vs baseline `nightly-${{ needs.set-dates.outputs.baseline }}`. A failure usually means *non-determinism was introduced into develop* between these nightlies (or a job/infra error). Run: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.run_id }}>. Please investigate."
}
},
{
"type": "divider"
}
]
}
58 changes: 44 additions & 14 deletions .github/workflows/cre-mixed-env-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ on:
fallback: a release/* base with no published base image is skipped (no correct
baseline vs develop); every other base (develop, or a stacked feature branch) falls
back to the develop nightly."
full_matrix:
required: false
type: boolean
default: false
description:
"Full sweep: also include chain-specific and other special-topology
tests (nightly). Per-PR runs leave this false."
workflow_call:
inputs:
chainlink_image_repository_path:
Expand Down Expand Up @@ -101,6 +108,13 @@ on:
fallback: a release/* base with no published base image is skipped (no correct
baseline vs develop); every other base (develop, or a stacked feature branch) falls
back to the develop nightly."
full_matrix:
required: false
type: boolean
default: false
description:
"Full sweep: also include chain-specific and other special-topology
tests (nightly). Per-PR runs leave this false."

jobs:
define-test-matrix:
Expand All @@ -114,27 +128,42 @@ jobs:
id: define-matrix
shell: bash
run: |
# Tests worth running under mixed-env: the OCR3/DON2DON-heavy ones.
TESTS='[
"Test_CRE_V2_Suite_Bucket_A",
"Test_CRE_V2_Suite_Bucket_B",
"Test_CRE_V2_EVM_Read_HeavyCalls",
"Test_CRE_V2_EVM_Read_StateQueries",
"Test_CRE_V2_EVM_Read_TxArtifacts"
# Per-PR set: the OCR3/DON2DON-heavy EVM tests, on the base mixed-env topology.
ENTRIES='[
{"test_name":"Test_CRE_V2_Suite_Bucket_A","topology":"mixed-env","configs":"configs/mixed-env-don.toml"},
{"test_name":"Test_CRE_V2_Suite_Bucket_B","topology":"mixed-env","configs":"configs/mixed-env-don.toml"},
{"test_name":"Test_CRE_V2_EVM_Read_HeavyCalls","topology":"mixed-env","configs":"configs/mixed-env-don.toml"},
{"test_name":"Test_CRE_V2_EVM_Read_StateQueries","topology":"mixed-env","configs":"configs/mixed-env-don.toml"},
{"test_name":"Test_CRE_V2_EVM_Read_TxArtifacts","topology":"mixed-env","configs":"configs/mixed-env-don.toml"}
]'

# Nightly full sweep: add the special-topology tests under their mixed-env variant.
if [[ "${{ inputs.full_matrix }}" == "true" ]]; then
FULL='[
{"test_name":"Test_CRE_V2_Aptos_Suite","topology":"mixed-env-aptos","configs":"configs/mixed-env-aptos-don.toml"},
{"test_name":"Test_CRE_V2_Stellar_Suite","topology":"mixed-env-stellar","configs":"configs/mixed-env-stellar-don.toml"},
{"test_name":"Test_CRE_V2_Solana_Write","topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"},
{"test_name":"Test_CRE_V2_Solana_LogTrigger","topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"},
{"test_name":"Test_CRE_V2_Solana_Read_Accounts","topology":"mixed-env-solana","configs":"configs/mixed-env-solana-don.toml"},
{"test_name":"Test_CRE_V2_Sharding","topology":"mixed-env-sharded","configs":"configs/mixed-env-sharded-don.toml"},
{"test_name":"Test_CRE_V2_Module_Cache","topology":"mixed-env-cache-test","configs":"configs/mixed-env-cache-test-don.toml"},
{"test_name":"Test_CRE_V2_HTTP_Action_Multi_Gateway","topology":"mixed-env-multi-gateway","configs":"configs/mixed-env-multi-gateway-don.toml"}
]'
ENTRIES=$(jq -c -n --argjson a "$ENTRIES" --argjson b "$FULL" '$a + $b')
fi

matrix=$(jq -c -n \
--argjson tests "$TESTS" \
--argjson entries "$ENTRIES" \
--argjson run_id "${{ github.run_id }}" \
--arg run_attempt "${{ github.run_attempt }}" '
$tests | to_entries | map({
test_name: .value,
$entries | to_entries | map(.value + {
test_id: .key,
runs_on: "runs-on=\($run_id)-\(.key)-\($run_attempt)/cpu=16/ram=64/family=m7i+m8i/spot=co/image=ubuntu24-full-x64/extras=s3-cache+tmpfs"
})')
echo "matrix=$matrix" | tee -a "${GITHUB_OUTPUT}"

run-mixed-env-tests:
name: ${{ matrix.tests.test_name }} (mixed-env)
name: ${{ matrix.tests.test_name }} (${{ matrix.tests.topology }})
permissions:
contents: read
id-token: write
Expand Down Expand Up @@ -290,6 +319,7 @@ jobs:
export CRE_PR_IMAGE CRE_BASELINE_IMAGE
echo "PR image: ${CRE_PR_IMAGE}"
echo "Baseline image: ${CRE_BASELINE_IMAGE}"
echo "Config: ${{ matrix.tests.configs }}"
# Fail fast with a clear error if either image is missing from the registry
# (e.g. a transient build/registry failure, or the develop nightly hasn't been
# published yet) instead of failing deep inside env start.
Expand All @@ -306,7 +336,7 @@ jobs:
echo "Re-run once the image is available, or override the develop side via the mixed_env_baseline_image input."
exit 1
fi
bash configs/render-mixed-env.sh
bash configs/render-mixed-env.sh "${{ matrix.tests.configs }}"

- name: Start local CRE
id: start-local-cre
Expand All @@ -321,7 +351,7 @@ jobs:
chainlink-image: ""
chip-router-image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{
secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
ctf-configs: configs/mixed-env-don.toml
ctf-configs: ${{ matrix.tests.configs }}
retry-count: "3"
retry-delay-seconds: "15"
cleanup-on-error: "false"
Expand All @@ -348,7 +378,7 @@ jobs:
TEST_NAME: ${{ matrix.tests.test_name }}
TEST_TIMEOUT: 7m
RUN_QUARANTINED_TESTS: "true"
TOPOLOGY_NAME: mixed-env
TOPOLOGY_NAME: ${{ matrix.tests.topology }}
GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }}
PARALLEL_COUNT: "10"
CRE_TEST_PARALLEL_ENABLED: "true"
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/cre/environment/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ cre_v*
configs/*-cache.toml
cache/

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

logs/

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Mixed-env Aptos topology (template) — derived from workflow-gateway-don-aptos.toml.
#
# Same as workflow-gateway-don-aptos, except the workflow DON runs 2 nodes on the PR
# image and 2 on the develop image, to surface non-determinism between the two code
# versions (see docs/mixed-env.md). Render with configs/render-mixed-env.sh:
#
# CRE_PR_IMAGE=<pr> CRE_BASELINE_IMAGE=<develop> \
# ./configs/render-mixed-env.sh configs/mixed-env-aptos-don.toml
#
# Keep in sync with workflow-gateway-don-aptos.toml if that base topology changes.
# Do NOT set CTF_CHAINLINK_IMAGE with this topology (it would force one image on all nodes).

[chip_router]
image = "local-cre-chip-router:v1.0.1"

[[blockchains]]
type = "anvil"
chain_id = "1337"
container_name = "anvil-1337"
docker_cmd_params = ["-b", "0.5", "--mixed-mining"]

[[blockchains]]
type = "aptos"
chain_id = "4"

[jd]
csa_encryption_key = "d1093c0060d50a3c89c189b2e485da5a3ce57f3dcb38ab7e2c0d5f0bb2314a44"
image = "job-distributor:0.28.0"

[infra]
type = "docker"

[[nodesets]]
nodes = 4
name = "workflow"
don_family = "test-don-family"
don_types = ["workflow"]
override_mode = "each"
http_port_range_start = 10100

supported_evm_chains = [1337]
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]"}}' }
capabilities = ["cron", "consensus", "aptos-4", "don-time"]
registry_based_launch_allowlist = ["cron-trigger@1.0.0"]

[nodesets.db]
image = "postgres:12.0"
port = 13000

[[nodesets.node_specs]] # node 0 - PR
roles = ["plugin"]
[nodesets.node_specs.node]
image = "${CRE_PR_IMAGE}"
pull_image = true
user_config_overrides = ""
[[nodesets.node_specs]] # node 1 - PR
roles = ["plugin"]
[nodesets.node_specs.node]
image = "${CRE_PR_IMAGE}"
pull_image = true
user_config_overrides = ""
[[nodesets.node_specs]] # node 2 - develop
roles = ["plugin"]
[nodesets.node_specs.node]
image = "${CRE_BASELINE_IMAGE}"
pull_image = true
user_config_overrides = ""
[[nodesets.node_specs]] # node 3 - develop
roles = ["plugin"]
[nodesets.node_specs.node]
image = "${CRE_BASELINE_IMAGE}"
pull_image = true
user_config_overrides = ""

[[nodesets]]
nodes = 1
name = "bootstrap-gateway"
don_family = "test-don-family"
don_types = ["bootstrap", "gateway"]
override_mode = "each"
http_port_range_start = 10300

supported_evm_chains = [1337]

[nodesets.db]
image = "postgres:12.0"
port = 13200

[[nodesets.node_specs]]
roles = ["bootstrap", "gateway"]
[nodesets.node_specs.node]
image = "${CRE_BASELINE_IMAGE}"
pull_image = true
custom_ports = ["5002:5002", "15002:15002"]
user_config_overrides = ""
Loading
Loading