Skip to content

CI Core

CI Core #60444

Workflow file for this run

name: CI Core
run-name: CI Core ${{ inputs.distinct_run_name && inputs.distinct_run_name || '' }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.distinct_run_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 * * *"
workflow_dispatch:
inputs:
distinct_run_name:
description: "A unique identifier for this run, used when running from other repos"
required: false
type: string
evm-ref:
description: The chainlink-evm reference to use when testing against a specific version for compatibliity
required: false
default: ""
type: string
jobs:
filter: # No need to run core tests if there are only changes to the integration-tests
name: Detect Changes
permissions:
pull-requests: read
outputs:
changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.changes }}
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with:
repository: smartcontractkit/chainlink
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
filters: |
changes:
- '!integration-tests/**'
- name: Ignore Filter On Workflow Dispatch
if: ${{ github.event_name == 'workflow_dispatch' }}
id: ignore-filter
run: echo "changes=true" >> $GITHUB_OUTPUT
golangci:
# We don't directly merge dependabot PRs, so let's not waste the resources
if: ${{ (github.event_name == 'pull_request' || github.event_name == 'schedule') && github.actor != 'dependabot[bot]' }}
name: lint
runs-on: ubuntu22.04-8cores-32GB
needs: [filter]
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Golang Lint
uses: ./.github/actions/golangci-lint
if: ${{ needs.filter.outputs.changes == 'true' }}
with:
id: core
name: lint
gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }}
gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
- name: Notify Slack
if: ${{ failure() && github.event.schedule != '' }}
uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0
env:
SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }}
with:
channel-id: "#team-core"
slack-message: "golangci-lint failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}"
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
id: core_unit
- cmd: go_core_race_tests
id: core_race
- cmd: go_core_fuzz
id: core_fuzz
name: Core Tests (${{ matrix.type.cmd }})
# We don't directly merge dependabot PRs, so let's not waste the resources
if: github.actor != 'dependabot[bot]'
needs: [filter]
runs-on: ubuntu-latest-64cores-256GB
steps:
- name: Checkout the repo
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup node
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
- name: Setup NodeJS
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-nodejs
with:
prod: "true"
- name: Setup Go
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-go
- name: Run short tests
if: ${{ needs.filter.outputs.changes == 'true' && matrix.type.cmd == 'go_core_tests' }}
run: go test -short ./...
- name: Setup Solana
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-solana
- name: Setup wasmd
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-wasmd
- name: Setup Postgres
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-postgres
- name: Touching core/web/assets/index.html
if: ${{ needs.filter.outputs.changes == 'true' }}
run: mkdir -p core/web/assets && touch core/web/assets/index.html
- name: Download Go vendor packages
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go mod download
- name: Replace chainlink-evm deps
if: ${{ needs.filter.outputs.changes == 'true' && inputs.evm-ref != ''}}
shell: bash
run: go get github.com/smartcontractkit/chainlink-evm@${{ inputs.evm-ref }}
- name: Build binary
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go build -o chainlink.test .
- name: Setup DB
if: ${{ needs.filter.outputs.changes == 'true' }}
run: ./chainlink.test local db preparetest
env:
CL_DATABASE_URL: ${{ env.DB_URL }}
- name: Install LOOP Plugins
if: ${{ needs.filter.outputs.changes == 'true' }}
run: |
pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds)
go install ./cmd/chainlink-feeds
popd
pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams)
go install ./mercury/cmd/chainlink-mercury
popd
pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana)
go install ./pkg/solana/cmd/chainlink-solana
popd
pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer)
go install ./pkg/chainlink/cmd/chainlink-starknet
popd
- name: Increase Race Timeout
if: ${{ github.event.schedule != '' && needs.filter.outputs.changes == 'true' }}
run: |
echo "TIMEOUT=10m" >> $GITHUB_ENV
echo "COUNT=50" >> $GITHUB_ENV
- name: Install gotestloghelper
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/[email protected]
- name: Run tests
if: ${{ needs.filter.outputs.changes == 'true' }}
id: run-tests
env:
OUTPUT_FILE: ./output.txt
USE_TEE: false
CL_DATABASE_URL: ${{ env.DB_URL }}
run: ./tools/bin/${{ matrix.type.cmd }} ./...
- name: Print Filtered Test Results
if: ${{ failure() && matrix.type.cmd == 'go_core_tests' && needs.filter.outputs.changes == 'true' }}
run: |
cat output.txt | gotestloghelper -ci
- name: Print Races
id: print-races
if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && needs.filter.outputs.changes == 'true' }}
run: |
find race.* | xargs cat > race.txt
if [[ -s race.txt ]]; then
cat race.txt
echo "post_to_slack=true" >> $GITHUB_OUTPUT
else
echo "post_to_slack=false" >> $GITHUB_OUTPUT
fi
echo "github.event_name: ${{ github.event_name }}"
echo "github.ref: ${{ github.ref }}"
- name: Print postgres logs
if: ${{ always() && needs.filter.outputs.changes == 'true' }}
run: docker compose logs postgres | tee ../../../postgres_logs.txt
working-directory: ./.github/actions/setup-postgres
- name: Store logs artifacts
if: ${{ needs.filter.outputs.changes == 'true' && always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: ${{ matrix.type.cmd }}_logs
path: |
./output.txt
./output-short.txt
./race.*
./coverage.txt
./postgres_logs.txt
- name: Notify Slack
if: ${{ failure() && steps.print-races.outputs.post_to_slack == 'true' && matrix.type.cmd == 'go_core_race_tests' && (github.event_name == 'merge_group' || github.ref == 'refs/heads/develop') && needs.filter.outputs.changes == 'true' }}
uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0
env:
SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }}
with:
channel-id: "#topic-data-races"
slack-message: "Race tests failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}"
- name: Collect Path Output
id: collect-path-output
env:
MATRIX_ID: ${{ matrix.type.id }}
run: |
# only push the test result file for the unit tests
if [[ "$MATRIX_ID" == "core_unit" ]]; then
resultsFile='{"testType":"go","filePath":"./output.txt"}'
echo "path_output=${resultsFile}" >> $GITHUB_OUTPUT
fi
- name: Collect Metrics
if: ${{ needs.filter.outputs.changes == 'true' && always() }}
id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1
with:
id: ${{ matrix.type.id }}
org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }}
this-job-name: Core Tests (${{ matrix.type.cmd }})
test-results-file: ${{ steps.collect-path-output.outputs.path_output }}
test-results-batch-split-size: "524288" # 512KB
continue-on-error: true
detect-flakey-tests:
needs: [filter, core]
name: Flakey Test Detection
runs-on: ubuntu-latest
if: ${{ always() && github.actor != 'dependabot[bot]' }}
env:
CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable
steps:
- name: Checkout the repo
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Setup node
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
- name: Setup NodeJS
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-nodejs
with:
prod: "true"
- name: Setup Go
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-go
- name: Setup Postgres
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-postgres
- name: Touching core/web/assets/index.html
if: ${{ needs.filter.outputs.changes == 'true' }}
run: mkdir -p core/web/assets && touch core/web/assets/index.html
- name: Download Go vendor packages
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go mod download
- name: Replace chainlink-evm deps
if: ${{ needs.filter.outputs.changes == 'true' && inputs.evm-ref != ''}}
shell: bash
run: go get github.com/smartcontractkit/chainlink-evm@${{ inputs.evm-ref }}
- name: Build binary
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go build -o chainlink.test .
- name: Setup DB
if: ${{ needs.filter.outputs.changes == 'true' }}
run: ./chainlink.test local db preparetest
- name: Load test outputs
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
path: ./artifacts
- name: Build flakey test runner
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go build ./tools/flakeytests/cmd/runner
- name: Re-run tests
if: ${{ needs.filter.outputs.changes == 'true' }}
env:
GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }}
GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
GITHUB_EVENT_PATH: ${{ github.event_path }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_REPO: ${{ github.repository }}
GITHUB_RUN_ID: ${{ github.run_id }}
run: |
./runner \
-grafana_auth=$GRAFANA_INTERNAL_BASIC_AUTH \
-grafana_host=$GRAFANA_INTERNAL_HOST \
-grafana_org_id=$GRAFANA_INTERNAL_TENANT_ID \
-gh_sha=$GITHUB_SHA \
-gh_event_path=$GITHUB_EVENT_PATH \
-gh_event_name=$GITHUB_EVENT_NAME \
-gh_run_id=$GITHUB_RUN_ID \
-gh_repo=$GITHUB_REPO \
-command=./tools/bin/go_core_tests \
`ls -R ./artifacts/go_core_tests*/output.txt`
- name: Store logs artifacts
if: ${{ needs.filter.outputs.changes == 'true' && always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: flakey_test_runner_logs
path: |
./output.txt
scan:
name: SonarQube Scan
needs: [core]
if: ${{ always() && github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with:
fetch-depth: 0 # fetches all history for all tags and branches to provide more metadata for sonar reports
- name: Download all workflow run artifacts
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
- name: Set SonarQube Report Paths
id: sonarqube_report_paths
shell: bash
run: |
echo "sonarqube_tests_report_paths=$(find go_core_tests_logs -name output.txt | paste -sd "," -)" >> $GITHUB_OUTPUT
echo "sonarqube_coverage_report_paths=$(find go_core_tests_logs -name coverage.txt | paste -sd "," -)" >> $GITHUB_OUTPUT
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@69c1a75940dec6249b86dace6b630d3a2ae9d2a7 # v2.0.1
with:
args: >
-Dsonar.go.tests.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_tests_report_paths }}
-Dsonar.go.coverage.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_coverage_report_paths }}
-Dsonar.go.golangci-lint.reportPaths=golangci-lint-report/golangci-lint-report.xml
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- name: Collect Metrics
if: always()
id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1
with:
id: ci-core-sonarqube
org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }}
this-job-name: SonarQube Scan
continue-on-error: true
clean:
name: Clean Go Tidy & Generate
if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') && github.actor != 'dependabot[bot]' }}
runs-on: ubuntu22.04-8cores-32GB
defaults:
run:
shell: bash
steps:
- name: Check for Skip Tests Label
if: contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests')
run: |
echo "## \`skip-smoke-tests\` label is active, skipping E2E smoke tests" >>$GITHUB_STEP_SUMMARY
exit 0
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with:
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: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- run: make generate # generate install go deps
- name: Ensure clean after generate
run: git diff --stat --exit-code
- run: make gomodtidy
- name: Ensure clean after tidy
run: git diff --minimal --exit-code
- name: Collect Metrics
if: always()
id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1
with:
id: ci-core-generate
org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }}
this-job-name: Clean Go Tidy & Generate
continue-on-error: true