CI Core #109371
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI Core | |
run-name: CI Core ${{ inputs.distinct_run_name && inputs.distinct_run_name || '' }} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} | |
cancel-in-progress: true | |
# Run on key branches to make sure integration is good, otherwise run on all PR's | |
on: | |
push: | |
branches: | |
- develop | |
- "release/*" | |
merge_group: | |
pull_request: | |
schedule: | |
- cron: "0 0,6,12,18 * * *" | |
workflow_dispatch: | |
jobs: | |
filter: | |
name: Detect Changes | |
permissions: | |
pull-requests: read | |
outputs: | |
affected-modules: ${{ steps.resolved-modules.outputs.module_names }} | |
# Runs on workflow changes, any deployment change, or any (non-ignored) core change | |
should-run-deployment-tests: >- | |
${{ | |
steps.match-some.outputs.workflow == 'true' || | |
steps.match-some.outputs.deployment == 'true' || | |
steps.match-every.outputs.core-non-ignored == 'true' || | |
github.event_name == 'schedule' || | |
github.event_name == 'workflow_dispatch' | |
}} | |
# Runs on workflow changes, and any (non-ignored) core changes | |
should-run-core-tests: >- | |
${{ | |
steps.match-some.outputs.workflow == 'true' || | |
steps.match-every.outputs.core-non-ignored == 'true' || | |
github.event_name == 'schedule' || | |
github.event_name == 'workflow_dispatch' | |
}} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout the repo | |
uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
repository: smartcontractkit/chainlink | |
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
id: match-some | |
with: | |
# "if any changed file matches one or more of the conditions" (https://github.com/dorny/paths-filter/issues/225) | |
predicate-quantifier: some | |
# deployment - any changes in the deployment module | |
# workflow - any changes that could affect this workflow definition | |
# - Assume any repository action changes affect this workflow | |
filters: | | |
deployment: | |
- 'deployment/**' | |
workflow: | |
- '.github/workflows/ci-core.yml' | |
- '.github/actions/**' | |
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
id: match-every | |
with: | |
# "if any changed file match all of the conditions" (https://github.com/dorny/paths-filter/issues/225) | |
# - Enables listing of files matching each filter. | |
# - Paths to files will be available in `${FILTER_NAME}_files` output variable. | |
# - Paths will be formatted as JSON array | |
predicate-quantifier: every | |
# core-non-ignored - all changes except for paths which do not affect core module | |
# - This is opt-in on purpose. To be safe, new files are assumed to have an affect on core unless listed here specifically. | |
# - For example: core module does not depend on deployment or integration-tests module. | |
# all - changes in any directory | |
# - This is used resolve all affected modules based on changed files | |
list-files: json | |
filters: | | |
core-non-ignored: | |
- '**' | |
- '!deployment/**' | |
- '!integration-tests/**' | |
- '!tools/secrets/**' | |
- '!tools/docker/**' | |
- '!tools/benchmark/**' | |
- '!**/README.md' | |
- '!**/CHANGELOG.md' | |
- '!*.nix' | |
- '!sonar-project.properties' | |
- '!nix.conf' | |
- '!nix-darwin-shell-hook.sh' | |
- '!LICENSE' | |
- '!.github/**' | |
- '!core/scripts/cre/environment/examples/workflows/**' | |
all: | |
- '**' | |
- name: Resolve affected files to affected modules | |
id: resolved-modules | |
shell: bash | |
env: | |
GH_EVENT_NAME: ${{ github.event_name }} | |
run: | | |
# if scheduled, run for all modules (apart from the CRE workflow examples). Otherwise, run for only affected modules. | |
if [[ "$GH_EVENT_NAME" == "schedule" || "$GH_EVENT_NAME" == "workflow_dispatch" ]]; then | |
json_array=$(find . -name 'go.mod' -not -path './core/scripts/cre/environment/examples/workflows/*' -exec dirname {} \; | sed 's|^./||' | uniq | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
echo "module_names=$json_array" >> "$GITHUB_OUTPUT" | |
else | |
# Ensure the step uses `with.list-files: json` to get the list of files in JSON format | |
bash ./.github/scripts/map-affected-files-to-modules.sh '${{ steps.match-every.outputs.all_files }}' '["core/scripts/cre/environment/examples/workflows"]' | |
fi | |
golangci: | |
name: GolangCI Lint | |
needs: [filter, run-frequency, runner-config] | |
# We don't directly merge dependabot PRs to not waste the resources. | |
if: ${{ (github.event_name == 'pull_request' || github.event_name == 'schedule') && github.actor != 'dependabot[bot]' }} | |
permissions: | |
# To annotate code in the PR. | |
checks: write | |
contents: read | |
# For golangci-lint-action's `only-new-issues` option. | |
pull-requests: read | |
runs-on: ${{ needs.runner-config.outputs.lint-runner }} | |
strategy: | |
fail-fast: false | |
matrix: | |
modules: ${{ fromJson(needs.filter.outputs.affected-modules) }} | |
steps: | |
- name: Enable S3 Cache for Self-Hosted Runners | |
# these env vars are set (and exposed) when it is a self-hosted runner with extras=s3-cache | |
if: ${{ env.RUNS_ON_INSTANCE_ID != '' && env.ACTIONS_CACHE_URL != '' }} | |
uses: runs-on/action@66d4449b717b5462159659523d1241051ff470b9 # v1 | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
- name: Golang Lint (${{ matrix.modules }}) | |
id: golang-lint | |
uses: ./.github/actions/golangci-lint | |
timeout-minutes: 20 | |
with: | |
go-directory: ${{ matrix.modules }} | |
- name: Notify Slack | |
if: ${{ failure() && needs.run-frequency.outputs.one-per-day-frequency == 'true' }} | |
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 | |
with: | |
method: chat.postMessage | |
token: ${{ secrets.QA_SLACK_API_KEY }} | |
payload: | | |
channel: ${{ secrets.SLACK_TEAM_CORE_CHANNEL_ID}} | |
text: "golangci-lint failed (${{ matrix.modules }}): <${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}|Run> - <${{ steps.golang-lint.outputs.golang-report-artifact-url }}|Report>" | |
# Fails if any golangci-lint matrix jobs fails and silently succeeds otherwise | |
# Consolidates golangci-lint matrix job results under one required `lint` check | |
# Inclusive check: all (new) modules are analyzed, but no need to enable "required" checks for each one | |
golangci-matrix-results-validation: | |
name: lint | |
if: ${{ always() && needs.golangci.result != 'skipped' && !contains(join(github.event.pull_request.labels.*.name, ' '), 'allow-lint-issues') }} | |
needs: [golangci] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check Golangci-lint Matrix Results | |
if: ${{ needs.golangci.result != 'success' }} | |
run: | | |
echo "At least one 'GolangCI Lint' matrix job failed. Check the failed lint jobs." | |
exit 1 | |
core: | |
env: | |
# We explicitly have this env var not be "CL_DATABASE_URL" to avoid having it be used by core related tests | |
# when they should not be using it, while still allowing us to DRY up the setup | |
DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable | |
strategy: | |
fail-fast: false | |
matrix: | |
type: | |
- cmd: go_core_tests | |
os: ${{ needs.runner-config.outputs.core-tests-runner }} | |
should-run: ${{ needs.filter.outputs.should-run-core-tests }} | |
trunk-auto-quarantine: "true" | |
- cmd: go_core_tests_integration | |
os: ${{ needs.runner-config.outputs.core-tests-integration-runner }} | |
should-run: ${{ needs.filter.outputs.should-run-core-tests }} | |
setup-solana: "true" | |
install-loopps: "true" | |
- cmd: go_core_fuzz | |
os: ${{ needs.runner-config.outputs.core-fuzz-tests-runner }} | |
should-run: ${{ needs.filter.outputs.should-run-core-tests }} | |
- cmd: go_core_race_tests | |
os: ${{ needs.runner-config.outputs.core-race-tests-runner }} | |
should-run: ${{ needs.filter.outputs.should-run-core-tests }} | |
- cmd: go_core_ccip_deployment_tests | |
os: ${{ needs.runner-config.outputs.deployment-tests-runner }} | |
should-run: ${{ needs.filter.outputs.should-run-deployment-tests }} | |
trunk-auto-quarantine: "true" | |
go-mod-directory: "deployment/" | |
setup-solana: "true" | |
setup-aptos: "true" | |
install-loopps: "true" | |
setup-sui: "true" | |
name: Core Tests (${{ matrix.type.cmd }}) # Be careful modifying the job name, as it is used to fetch the job URL | |
# We don't directly merge dependabot PRs, so let's not waste the resources | |
if: ${{ github.actor != 'dependabot[bot]' }} | |
needs: [filter, run-frequency, runner-config] | |
timeout-minutes: ${{ github.event_name == 'schedule' && 40 || 25 }} # 40 minute timeout for scheduled events (race tests) | |
runs-on: ${{ matrix.type.os }} | |
permissions: | |
id-token: write | |
contents: read | |
actions: read | |
steps: | |
- name: Enable S3 Cache for Self-Hosted Runners | |
# these env vars are set (and exposed) when it is a self-hosted runner with extras=s3-cache | |
if: ${{ env.RUNS_ON_INSTANCE_ID != '' && env.ACTIONS_CACHE_URL != '' }} | |
uses: runs-on/action@66d4449b717b5462159659523d1241051ff470b9 # v1 | |
- name: Checkout the repo | |
if: ${{ matrix.type.should-run == 'true' }} | |
uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
- name: Setup Go | |
if: ${{ matrix.type.should-run == 'true' }} | |
uses: ./.github/actions/setup-go | |
with: | |
# race/fuzz tests don't benefit repeated caching, so restore from develop's build cache | |
restore-build-cache-only: ${{ matrix.type.cmd == 'go_core_fuzz' || matrix.type.cmd == 'go_core_race_tests' }} | |
build-cache-version: ${{ matrix.type.cmd }} | |
go-version-file: ${{ matrix.type.go-mod-directory }}go.mod | |
go-module-file: ${{ matrix.type.go-mod-directory }}go.sum | |
- name: Setup Solana | |
if: ${{ matrix.type.should-run == 'true' && matrix.type.setup-solana == 'true' }} | |
uses: ./.github/actions/setup-solana | |
- name: Setup Aptos | |
if: ${{ matrix.type.should-run == 'true' && matrix.type.setup-aptos == 'true' }} | |
uses: aptos-labs/actions/install-aptos-cli@63740b290d839b87ecfafbcf75ed03a36a54a29f # jan 15, 2025 | |
with: | |
CLI_VERSION: 7.8.1 | |
- name: Setup Sui CLI v1.57.2 | |
if: ${{ matrix.type.should-run == 'true' && matrix.type.setup-sui == 'true' }} | |
uses: ./.github/actions/setup-sui | |
with: | |
version: mainnet-1.57.2 | |
- name: Setup wasmd | |
if: ${{ matrix.type.should-run == 'true' }} | |
uses: ./.github/actions/setup-wasmd | |
- name: Setup Postgres | |
if: ${{ matrix.type.should-run == 'true' }} | |
uses: smartcontractkit/.github/actions/setup-postgres@setup-postgres/v1 | |
with: | |
tmpfs: "true" | |
image-tag: "16-alpine" | |
- name: Touching core/web/assets/index.html | |
if: ${{ matrix.type.should-run == 'true' }} | |
run: mkdir -p core/web/assets && touch core/web/assets/index.html | |
- name: Download Go vendor packages | |
if: ${{ matrix.type.should-run == 'true' }} | |
run: go mod download | |
- name: Setup DB | |
if: ${{ matrix.type.should-run == 'true' }} | |
run: go run ./core/store/cmd/preparetest | |
env: | |
CL_DATABASE_URL: ${{ env.DB_URL }} | |
- name: Install LOOP Plugins | |
if: ${{ matrix.type.should-run == 'true' && matrix.type.install-loopps == 'true' }} | |
run: make install-plugins | |
- name: Increase Timeouts for Fuzz/Race | |
# Increase timeouts for scheduled runs only | |
if: ${{ github.event.schedule != '' && matrix.type.should-run == 'true' }} | |
run: | | |
echo "TIMEOUT=10m" >> $GITHUB_ENV | |
echo "COUNT=50" >> $GITHUB_ENV | |
echo "FUZZ_TIMEOUT_MINUTES=10">> $GITHUB_ENV | |
- name: Run tests | |
if: ${{ matrix.type.should-run == 'true' }} | |
timeout-minutes: ${{ github.event_name == 'schedule' && 37 || 22 }} # leave time for remaining steps | |
continue-on-error: ${{ matrix.type.trunk-auto-quarantine == 'true' }} | |
id: run-tests | |
shell: bash | |
env: | |
CL_DATABASE_URL: ${{ env.DB_URL }} | |
OUTPUT_FILE: ./output.txt | |
PRODUCE_JUNIT_XML: ${{ matrix.type.trunk-auto-quarantine }} | |
TRUNK_AUTO_QUARANTINE: ${{ matrix.type.trunk-auto-quarantine }} | |
RUN_QUARANTINED_TESTS: "true" # always run quarantined tests in CI | |
JUNIT_FILE: ${{ github.workspace }}/junit.xml | |
run: | | |
GODEBUG=goindex=0 ./tools/bin/${{ matrix.type.cmd }} ./... | |
# See: https://github.com/golang/go/issues/69179 | |
- name: Run branch-out-upload | |
if: ${{ matrix.type.should-run == 'true' && matrix.type.trunk-auto-quarantine == 'true' && !cancelled() }} | |
uses: smartcontractkit/.github/actions/branch-out-upload@branch-out-upload/0.1.0 | |
with: | |
junit-file-path: "./junit.xml" | |
trunk-org-slug: chainlink | |
trunk-token: ${{ secrets.TRUNK_API_KEY }} | |
trunk-previous-step-outcome: ${{ steps.run-tests.outcome }} | |
trunk-job-url: ${{ format('https://github.com/{0}/actions/runs/{1}/job/{2}/attempts/{3}', github.repository, github.run_id, job.check_run_id, github.run_attempt) }} | |
# when auto-quarantine is enabled, allow this to determine test failures | |
trunk-upload-only: ${{ matrix.type.trunk-auto-quarantine != 'true' }} | |
- name: Print Races | |
id: print-races | |
if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && matrix.type.should-run == 'true' }} | |
env: | |
GH_REPO: ${{ github.repository }} | |
GH_RUN_ID: ${{ github.run_id }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
find race.* | xargs cat > race.txt | |
if [[ -s race.txt ]]; then | |
cat race.txt | |
echo "post_to_slack=true" | tee -a "$GITHUB_OUTPUT" | |
else | |
echo "post_to_slack=false" | tee -a "$GITHUB_OUTPUT" | |
fi | |
echo "github.event_name: ${{ github.event_name }}" | |
echo "github.ref: ${{ github.ref }}" | |
- name: Print postgres logs | |
if: ${{ always() && matrix.type.should-run == 'true' }} | |
uses: smartcontractkit/.github/actions/setup-postgres@setup-postgres/v1 | |
with: | |
print-logs: "true" | |
- name: Store logs artifacts | |
if: ${{ always() && matrix.type.should-run == 'true' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.type.cmd }}_logs | |
path: | | |
./output.txt | |
./output-short.txt | |
./race.* | |
./coverage.txt | |
./postgres_logs.txt | |
./junit.xml | |
./deployment/junit.xml | |
retention-days: 7 | |
- name: Notify Slack on Race Test Failure | |
if: | | |
failure() && | |
matrix.type.cmd == 'go_core_race_tests' && | |
steps.print-races.outputs.post_to_slack == 'true' && | |
(github.event_name == 'merge_group' || github.ref == 'refs/heads/develop') && | |
matrix.type.should-run == 'true' | |
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 | |
with: | |
method: chat.postMessage | |
token: ${{ secrets.QA_SLACK_API_KEY }} | |
payload: | | |
channel: ${{ secrets.SLACK_TOPIC_DATA_RACES_CHANNEL_ID}} | |
text: "Race Tests Failed: <${{ format('https://github.com/{0}/actions/runs/{1}/job/{2}', github.repository, github.run_id, job.check_run_id) }}|Run>" | |
core-scripts-tests: | |
name: test-scripts | |
needs: [filter] | |
runs-on: ubuntu-latest | |
if: ${{ needs.filter.outputs.should-run-core-tests == 'true' }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Setup Go | |
uses: ./.github/actions/setup-go | |
with: | |
go-version-file: core/scripts/go.mod | |
go-module-file: core/scripts/go.sum | |
- name: Run Tests | |
env: | |
OUTPUT_FILE: ./output.txt | |
run: ./tools/bin/go_core_scripts_tests ./... | |
- name: Store test report artifacts | |
if: ${{ always() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: go_core_scripts_tests_logs | |
path: | | |
./output.txt | |
./coverage.txt | |
retention-days: 7 | |
scan: | |
name: SonarQube Scan | |
needs: [golangci, core, core-scripts-tests] | |
# If core is cancelled, skip this to not delay the cancellation of the workflow. | |
if: ${{ always() && !cancelled() && github.actor != 'dependabot[bot]' }} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout the repo | |
uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
fetch-depth: 0 # fetches all history for all tags and branches to provide more metadata for sonar reports | |
- name: Download all workflow artifacts | |
uses: actions/download-artifact@v4 | |
- name: Check and Set SonarQube Report Paths | |
shell: bash | |
run: | | |
# Check and assign paths for coverage/test reports in go_core_tests_logs | |
core_artifact="go_core_tests_logs" | |
if [ -d "$core_artifact" ]; then | |
echo "Found $core_artifact" | |
sonarqube_coverage_report_paths=$(find "$core_artifact" -name coverage.txt | paste -sd "," -) | |
sonarqube_tests_report_paths=$(find "$core_artifact" -name output.txt | paste -sd "," -) | |
echo "Coverage report paths: $sonarqube_coverage_report_paths" | |
echo "Tests report paths: $sonarqube_tests_report_paths" | |
else | |
echo "Did not find $core_artifact" | |
sonarqube_coverage_report_paths="" | |
sonarqube_tests_report_paths="" | |
fi | |
# Check and assign paths for coverage/test reports in go_core_tests_integration_logs | |
integration_tests_artifact="go_core_tests_integration_logs" | |
if [ -d "$integration_tests_artifact" ]; then | |
echo "Found $integration_tests_artifact" | |
integration_coverage_paths=$(find "$integration_tests_artifact" -name coverage.txt | paste -sd "," -) | |
integration_tests_paths=$(find "$integration_tests_artifact" -name output.txt | paste -sd "," -) | |
# Append to existing paths if they are set, otherwise assign directly | |
sonarqube_coverage_report_paths="${sonarqube_coverage_report_paths:+$sonarqube_coverage_report_paths,}$integration_coverage_paths" | |
sonarqube_tests_report_paths="${sonarqube_tests_report_paths:+$sonarqube_tests_report_paths,}$integration_tests_paths" | |
fi | |
# Check and assign paths for coverage/test reports in go_core_scripts_tests_logs | |
scripts_tests_artifact="go_core_scripts_tests_logs" | |
if [ -d "$scripts_tests_artifact" ]; then | |
echo "Found $scripts_tests_artifact" | |
scripts_coverage_paths=$(find "$scripts_tests_artifact" -name coverage.txt | paste -sd "," -) | |
scripts_tests_paths=$(find "$scripts_tests_artifact" -name output.txt | paste -sd "," -) | |
# Append to existing paths if they are set, otherwise assign directly | |
sonarqube_coverage_report_paths="${sonarqube_coverage_report_paths:+$sonarqube_coverage_report_paths,}$scripts_coverage_paths" | |
sonarqube_tests_report_paths="${sonarqube_tests_report_paths:+$sonarqube_tests_report_paths,}$scripts_tests_paths" | |
fi | |
# Check and assign paths for lint reports | |
# To find reports in the folders named differently (because of the matrix strategy), | |
# We need to loop through the artifacts. It allows usage of RegExp folders (skipped if not found). | |
for golang_lint_artifact in golangci-lint-report* | |
do | |
echo "Found golangci-lint-report artifacts" | |
sonarqube_lint_report_paths=$(find -type f -name 'golangci-lint-report.xml' -printf "%p,") | |
echo "Lint report paths: $sonarqube_lint_report_paths" | |
break | |
done | |
ARGS="" | |
if [[ -z "$sonarqube_tests_report_paths" ]]; then | |
echo "::warning::No test report paths found, will not pass to sonarqube" | |
else | |
echo "Found test report paths: $sonarqube_tests_report_paths" | |
ARGS="$ARGS -Dsonar.go.tests.reportPaths=$sonarqube_tests_report_paths" | |
fi | |
if [[ -z "$sonarqube_coverage_report_paths" ]]; then | |
echo "::warning::No coverage report paths found, will not pass to sonarqube" | |
else | |
echo "Found coverage report paths: $sonarqube_coverage_report_paths" | |
ARGS="$ARGS -Dsonar.go.coverage.reportPaths=$sonarqube_coverage_report_paths" | |
fi | |
if [[ -z "$sonarqube_lint_report_paths" ]]; then | |
echo "::warning::No lint report paths found, will not pass to sonarqube" | |
else | |
echo "Found lint report paths: $sonarqube_lint_report_paths" | |
ARGS="$ARGS -Dsonar.go.golangci-lint.reportPaths=$sonarqube_lint_report_paths" | |
fi | |
echo "Final SONARQUBE_ARGS: $ARGS" | |
echo "SONARQUBE_ARGS=$ARGS" >> $GITHUB_ENV | |
- name: SonarQube Scan | |
if: ${{ env.SONARQUBE_ARGS != '' }} | |
uses: sonarsource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 # v2.3.0 | |
with: | |
args: ${{ env.SONARQUBE_ARGS }} | |
env: | |
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} | |
SONAR_SCANNER_OPTS: "-Xms6g -Xmx8g" | |
clean: | |
name: Clean Go Tidy & Generate | |
if: ${{ github.actor != 'dependabot[bot]' }} | |
runs-on: ubuntu22.04-8cores-32GB | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
fetch-depth: 0 | |
- name: Setup Go | |
uses: ./.github/actions/setup-go | |
with: | |
only-modules: "true" | |
- name: Install protoc-gen-go-wsrpc | |
run: curl https://github.com/smartcontractkit/wsrpc/raw/main/cmd/protoc-gen-go-wsrpc/protoc-gen-go-wsrpc --output $HOME/go/bin/protoc-gen-go-wsrpc && chmod +x $HOME/go/bin/protoc-gen-go-wsrpc | |
- name: make generate | |
run: | | |
make rm-mocked | |
make generate | |
- name: Ensure clean after generate | |
run: | | |
git add --all | |
git diff --stat --cached --exit-code | |
- run: make gomodtidy | |
- name: Ensure clean after tidy | |
run: | | |
git add --all | |
git diff --minimal --cached --exit-code | |
run-frequency: | |
name: Run frequency | |
outputs: | |
one-per-day-frequency: ${{ steps.check-time.outputs.one-per-day-frequency || 'false' }} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check time and set frequencies | |
id: check-time | |
shell: bash | |
run: | | |
if [ "$GITHUB_EVENT_NAME" != "schedule" ]; then | |
# Not a scheduled event - no frequencies to set. They default to false. | |
exit 0 | |
fi | |
# Scheduled event, check current time for frequencies | |
current_hour=$(date +"%H") | |
# Check if the current hour is 00 (one per day) | |
if [ "$current_hour" -eq "00" ]; then | |
echo "one-per-day-frequency=true" | tee -a $GITHUB_OUTPUT | |
fi | |
# This chooses which runner labels we pass for the matrix jobs above. | |
# General Criteria: | |
# 1. If we are going to 'skip' a test suite, we use the base Github-hosted runner. | |
# - This is based off `should-run-core-tests`, and `should-run-deployment-tests` | |
# 2. If we are not skipping, we check if the PR has the "runs-on-opt-out" label. | |
# - If the PR has the label, we use the larger Github-hosted runners. | |
# - If the PR does not have the label, we use the self-hosted runners. | |
runner-config: | |
name: Runner Config | |
needs: [filter] | |
runs-on: ubuntu-latest | |
env: | |
# include unique label (core/deployment/etc...) to ensure jobs are not competing for the same runner | |
SH_TEST_RUNNER: runs-on=${{ github.run_id }}-core/cpu=48/ram=96/family=c6i/spot=false/image=ubuntu24-full-x64/extras=s3-cache+tmpfs | |
SH_DEPLOYMENT_TEST_RUNNER: runs-on=${{ github.run_id }}-deployment/cpu=48/ram=96/family=c6id/spot=false/image=ubuntu24-full-x64/extras=s3-cache | |
SH_FUZZ_RUNNER: runs-on=${{ github.run_id}}-fuzz/cpu=8+16/ram=32+64/family=c6id+m6id+m6idn/spot=false/image=ubuntu24-full-x64/extras=s3-cache | |
SH_RACE_TEST_RUNNER: runs-on=${{ github.run_id}}-race/cpu=64+128/ram=128+128/family=c7+m7/disk=large/spot=false/image=ubuntu24-full-x64/extras=s3-cache | |
SH_LINT_RUNNER: runs-on=${{ github.run_id }}-lint/cpu=16/ram=32/family=c6gd/spot=false/image=ubuntu24-full-arm64/extras=s3-cache | |
GH_TEST_RUNNER: ubuntu22.04-32cores-128GB | |
GH_FUZZ_RUNNER: ubuntu22.04-8cores-32GB | |
GH_BASE_RUNNER: ubuntu-latest | |
GH_LINT_RUNNER: ubuntu-24.04-8cores-32GB-ARM | |
outputs: | |
# go_core_tests / go_core_race_tests / go_core_tests_integration | |
core-tests-runner: ${{ steps.core-tests.outputs.core-tests-runner }} | |
core-tests-integration-runner: ${{ steps.core-tests.outputs.core-tests-integration-runner }} | |
core-fuzz-tests-runner: ${{ steps.core-tests.outputs.core-fuzz-tests-runner }} | |
core-race-tests-runner: ${{ steps.core-tests.outputs.core-race-tests-runner }} | |
# go_core_ccip_deployment_tests | |
deployment-tests-runner: ${{ steps.deployment-tests.outputs.deployment-tests-runner }} | |
# linting | |
lint-runner: ${{ steps.linting.outputs.lint-runner }} | |
steps: | |
- name: Get PR Labels | |
id: pr-labels | |
uses: smartcontractkit/.github/actions/get-pr-labels@get-pr-labels/v1 | |
with: | |
check-label: "runs-on-opt-out" | |
- name: Select runners for deployment tests | |
id: deployment-tests | |
shell: bash | |
env: | |
OPT_OUT: ${{ steps.pr-labels.outputs.check-label-found || 'false' }} | |
SHOULD_RUN_DEPLOYMENT_TESTS: ${{ needs.filter.outputs.should-run-deployment-tests }} | |
run: | | |
if [[ "${SHOULD_RUN_DEPLOYMENT_TESTS}" == "false" ]]; then | |
echo "Deployment tests will be skipped, using base Github-hosted runner." | |
echo "deployment-tests-runner=${GH_BASE_RUNNER}" | tee -a $GITHUB_OUTPUT | |
exit 0 | |
fi | |
if [[ "$OPT_OUT" == "true" ]]; then | |
echo "Opt-out is true for current run. Using gh-hosted runner for deployment tests." | |
echo "deployment-tests-runner=${GH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
exit 0 | |
fi | |
echo "Opt-out is false for current run. Using self-hosted runner for deployment tests." | |
echo "deployment-tests-runner=${SH_DEPLOYMENT_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
- name: Select runners for core tests | |
id: core-tests | |
shell: bash | |
env: | |
OPT_OUT: ${{ steps.pr-labels.outputs.check-label-found || 'false' }} | |
SHOULD_RUN_CORE_TESTS: ${{ needs.filter.outputs.should-run-core-tests }} | |
run: | | |
if [[ "${SHOULD_RUN_CORE_TESTS}" == "false" ]]; then | |
echo "Core tests will be skipped, using base Github-hosted runner." | |
echo "core-tests-runner=${GH_BASE_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-tests-integration-runner=${GH_BASE_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-fuzz-tests-runner=${GH_BASE_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-race-tests-runner=${GH_BASE_RUNNER}" | tee -a $GITHUB_OUTPUT | |
exit 0 | |
fi | |
if [[ "$OPT_OUT" == "true" ]]; then | |
echo "Opt-out is true for current run. Using gh-hosted runner for core tests." | |
echo "core-tests-runner=${GH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-tests-integration-runner=${GH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-fuzz-tests-runner=${GH_FUZZ_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-race-tests-runner=${GH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
exit 0 | |
fi | |
echo "Opt-out is false for current run. Using self-hosted runner for core tests." | |
echo "core-tests-runner=${SH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-tests-integration-runner=${SH_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-fuzz-tests-runner=${SH_FUZZ_RUNNER}" | tee -a $GITHUB_OUTPUT | |
echo "core-race-tests-runner=${SH_RACE_TEST_RUNNER}" | tee -a $GITHUB_OUTPUT | |
- name: Select runners for linting | |
id: linting | |
shell: bash | |
env: | |
OPT_OUT: ${{ steps.pr-labels.outputs.check-label-found || 'false' }} | |
run: | | |
if [[ "$OPT_OUT" == "true" ]]; then | |
echo "Opt-out is true for current run. Using gh-hosted runner for linting." | |
echo "lint-runner=${GH_LINT_RUNNER}" | tee -a $GITHUB_OUTPUT | |
exit 0 | |
fi | |
echo "Opt-out is false for current run. Using self-hosted runner for linting." | |
echo "lint-runner=${SH_LINT_RUNNER}" | tee -a $GITHUB_OUTPUT | |
misc: | |
# Catchall job for miscellaneous steps. | |
name: Misc | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
persist-credentials: false | |
- name: Setup go | |
uses: ./.github/actions/setup-go | |
## | |
# Plugins (LOOPPs) are defined in ./plugins/plugins.*.yaml files. | |
# Some plugins such as chainlink-data-streams, chainlink-feeds, | |
# and chainlink-solana are also dependencies in the go.mod file. | |
# This job is to ensure that the versions defined in the go.mod file are | |
# in sync with the gitRef field in the plugins YAML files. | |
# | |
# If you update the version of a module in the go.mod file, you must | |
# update the gitRef for the corresponding module in the plugins YAML file | |
# to match. | |
## | |
- name: Plugins Sync Check (Plugout) | |
run: | | |
echo "Check for out of sync plugins" | |
go run ./tools/plugout/ \ | |
--go-mod ./go.mod \ | |
--plugin-file ./plugins/plugins.public.yaml |