From fe827601f1dda1a2e56be1df5cb257717fc2c047 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 25 Mar 2026 16:39:08 -0400 Subject: [PATCH 01/20] cache-scope and max mode --- actions/ctf-build-image/action.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 5493da3a..fbb0df1a 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -108,6 +108,14 @@ inputs: go get github.com/smartcontractkit/chainlink-solana@abc123 go get github.com/smartcontractkit/chainlink-evm@def456 + cache-scope: + required: false + description: | + Custom scope for Docker build cache. Separates caches when multiple + Dockerfiles build on the same architecture (e.g. "core" vs "plugins"). + If not set, defaults to runner OS and architecture. + default: "" + outputs: docker-image-sha-digest-amd64: description: "Docker image SHA digest for platform: amd64" @@ -189,11 +197,11 @@ runs: docker-restore-cache: ${{ github.event_name != 'schedule' && github.event_name != 'push' }} docker-build-cache-to: - "type=gha,timeout=10m,mode=min,ignore-error=true,scope=ctf-build-image-${{ - runner.os }}-${{ runner.arch }}" + "type=gha,timeout=10m,mode=max,ignore-error=true,scope=ctf-build-image-${{ + inputs.cache-scope || format('{0}-{1}', runner.os, runner.arch) }}" docker-build-cache-from: - "type=gha,timeout=10m,scope=ctf-build-image-${{ runner.os }}-${{ - runner.arch }}" + "type=gha,timeout=10m,scope=ctf-build-image-${{ inputs.cache-scope || + format('{0}-{1}', runner.os, runner.arch) }}" tags: type=raw,value=${{ inputs.image-tag }} aws-account-number: ${{ inputs.aws-account-number }} From 07725cd65ff88cee52d9ea1294a35f66618f4a59 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 25 Mar 2026 17:02:52 -0400 Subject: [PATCH 02/20] Fix --- .github/workflows/run-e2e-tests.yml | 14 +++++++------- .github/workflows/solidity-review-artifacts.yml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index cd6afc6d..4ada3982 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -955,13 +955,13 @@ jobs: - name: Upload trace data as artifact if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 with: name: trace-data path: ./integration-tests/smoke/traces/trace-data.json - name: Upload test log as artifact - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 if: failure() with: name: test_log_${{ env.TEST_ID }} @@ -971,7 +971,7 @@ jobs: - name: Upload cl node coverage data as artifact if: inputs.upload_cl_node_coverage_artifact - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 timeout-minutes: 2 continue-on-error: true with: @@ -988,7 +988,7 @@ jobs: - name: Upload test result as artifact if: ${{ always() }} - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 with: name: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_${{ env.TEST_ID }} @@ -997,7 +997,7 @@ jobs: - name: Upload custom test artifacts if: failure() && matrix.tests.test_artifacts_on_failure != '' - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 with: name: custom_test_artifacts_${{ env.TEST_ID }}_${{ needs.load-test-configurations.outputs.workflow_id }} @@ -1256,7 +1256,7 @@ jobs: test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} - name: Upload test log as artifact - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 if: failure() with: name: test_log_${{ env.TEST_ID }} @@ -1266,7 +1266,7 @@ jobs: - name: Upload custom test artifacts if: failure() && matrix.tests.test_artifacts_on_failure != '' - uses: actions/upload-artifact@v4.4.3 + uses: actions/upload-artifact@v7 with: name: ${{ format('custom_test_artifacts_{0}_{1}', env.TEST_ID, needs.load-test-configurations.outputs.workflow_id) }} path: ${{ matrix.tests.test_artifacts_on_failure }} diff --git a/.github/workflows/solidity-review-artifacts.yml b/.github/workflows/solidity-review-artifacts.yml index bb4013cf..f3499786 100644 --- a/.github/workflows/solidity-review-artifacts.yml +++ b/.github/workflows/solidity-review-artifacts.yml @@ -184,7 +184,7 @@ jobs: done - name: Upload basic info and modified contracts list - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7 timeout-minutes: 2 continue-on-error: true with: @@ -284,7 +284,7 @@ jobs: inputs.foundry_profile_override || inputs.product }} - name: Upload Artifacts for product contracts - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7 timeout-minutes: 2 continue-on-error: true with: @@ -401,7 +401,7 @@ jobs: ./dot_github/tools/scripts/solidity/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ env.head_ref }}/" "$SLITHER_CONFIG_FILE_PATH" "$CONTRACTS_DIRECTORY" "$contract_list" "${{ env.artifacts_dir }}/slither-reports" "--solc-remaps @=$CONTRACTS_DIRECTORY/node_modules/@" - name: Upload UMLs and Slither reports - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7 timeout-minutes: 10 continue-on-error: true with: @@ -437,7 +437,7 @@ jobs: merge-multiple: true - name: Upload all artifacts as single package - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7 with: name: review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ env.head_ref }} From 4180e789ed614707e353674386286deebbfa9792 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 25 Mar 2026 17:51:35 -0400 Subject: [PATCH 03/20] Setup debugging --- actions/ctf-build-image/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index fbb0df1a..af13eb49 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -190,8 +190,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: - ${{ github.event_name == 'schedule' || github.event_name == 'push' }} + docker-save-cache: ${{ github.event_name == 'schedule' || + github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: pull_request to test # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: From f0275754cf0d07a831a0d8d8f5b09fba033051c9 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 10:08:40 -0400 Subject: [PATCH 04/20] Remove extra go mod download --- actions/ctf-build-image/action.yml | 33 +++++++++++------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index af13eb49..d5cc0e66 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -127,12 +127,6 @@ outputs: runs: using: composite steps: - - uses: actions/setup-go@v6 - with: - go-version-file: "go.mod" - check-latest: true - cache: false - - name: Setup GitHub token using GATI if: inputs.gati-role-arn != '' && inputs.gati-lambda-url != '' id: github-token @@ -144,13 +138,6 @@ runs: aws-role-duration-seconds: "1800" set-git-config: "true" - - name: Process go get overrides - shell: bash - env: - GO_OVERRIDES: ${{ inputs.go-get-overrides }} - ACTIONS_PATH: ${{ github.action_path }} - run: ${ACTIONS_PATH}/scripts/go-get-overrides.sh - - name: Process plugin manifest overrides (public) shell: bash env: @@ -160,16 +147,19 @@ runs: ACTIONS_PATH: ${{ github.action_path }} run: ${ACTIONS_PATH}/scripts/plugin-overrides.sh - - name: Tidy and Output go.mod + - name: Encode go-get overrides for Docker build arg + id: encode-overrides shell: bash + env: + GO_OVERRIDES: ${{ inputs.go-get-overrides }} run: | - echo "::group::Tidy go.mod" - go mod tidy - echo "::endgroup::" - - echo "::group::cat go.mod" - cat go.mod - echo "::endgroup::" + if [ -z "$GO_OVERRIDES" ]; then + echo "encoded=" >> "$GITHUB_OUTPUT" + exit 0 + fi + ENCODED=$(echo "$GO_OVERRIDES" | sed '/^$/d' | paste -sd ',' -) + echo "encoded=$ENCODED" >> "$GITHUB_OUTPUT" + echo "::info::Encoded go-get overrides: $ENCODED" - name: Free up disk space (to avoid 'no space left on device' errors) uses: smartcontractkit/.github/actions/free-disk-space@free-disk-space/v1 @@ -185,6 +175,7 @@ runs: docker-build-args: | COMMIT_SHA=${{ github.sha }} CHAINLINK_USER=chainlink + GO_OVERRIDE_DEPS=${{ steps.encode-overrides.outputs.encoded }} ${{ inputs.docker-additional-build-args }} docker-attestations: "false" docker-registry-url: ${{ inputs.docker-registry-url }} From 263166dac5ffd957c4eed47b5782d2d7141416bb Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 11:45:08 -0400 Subject: [PATCH 05/20] Optimize Docker caching --- actions/ctf-build-image/action.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index d5cc0e66..3fadae8e 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -116,6 +116,13 @@ inputs: If not set, defaults to runner OS and architecture. default: "" + free-disk-space: + required: false + description: | + Whether to run the free-disk-space step before building. Set to "false" + on runners with sufficient disk (e.g. RunsOn with 100GB+) to save ~30-60s. + default: "true" + outputs: docker-image-sha-digest-amd64: description: "Docker image SHA digest for platform: amd64" @@ -162,6 +169,7 @@ runs: echo "::info::Encoded go-get overrides: $ENCODED" - name: Free up disk space (to avoid 'no space left on device' errors) + if: inputs.free-disk-space == 'true' uses: smartcontractkit/.github/actions/free-disk-space@free-disk-space/v1 - name: Build push docker image @@ -181,14 +189,15 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: ${{ github.event_name == 'schedule' || - github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: pull_request to test + docker-save-cache: + ${{ github.event_name == 'schedule' || github.event_name == 'push' || + github.event_name == 'workflow_dispatch' }} # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: ${{ github.event_name != 'schedule' && github.event_name != 'push' }} docker-build-cache-to: - "type=gha,timeout=10m,mode=max,ignore-error=true,scope=ctf-build-image-${{ + "type=gha,timeout=10m,mode=max,ignore-error=true,compression=zstd,compression-level=3,scope=ctf-build-image-${{ inputs.cache-scope || format('{0}-{1}', runner.os, runner.arch) }}" docker-build-cache-from: "type=gha,timeout=10m,scope=ctf-build-image-${{ inputs.cache-scope || From ab75dfeec614d828544435a2f64e52a7e60188ff Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 11:46:34 -0400 Subject: [PATCH 06/20] Optimize Docker caching --- actions/ctf-build-image/action.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 3fadae8e..e1252ba4 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -189,9 +189,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: - ${{ github.event_name == 'schedule' || github.event_name == 'push' || - github.event_name == 'workflow_dispatch' }} + docker-save-cache: ${{ github.event_name == 'schedule' || + github.event_name == 'push' || github.event_name == 'pull_request' }} # TODO: pull_request to test # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: From c1f5756c9900743b92536ae5627c312e7fb763b3 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 12:37:22 -0400 Subject: [PATCH 07/20] Cleanup --- actions/ctf-build-image/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index e1252ba4..304982d0 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -189,8 +189,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: ${{ github.event_name == 'schedule' || - github.event_name == 'push' || github.event_name == 'pull_request' }} # TODO: pull_request to test + docker-save-cache: + ${{ github.event_name == 'schedule' || github.event_name == 'push' }} # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: From 59a2a0558563f5f6c2e60a5446366a08c0086bfe Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 14:27:14 -0400 Subject: [PATCH 08/20] Verify image --- actions/ctf-build-image/action.yml | 44 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 304982d0..4d6c9729 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -189,8 +189,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: - ${{ github.event_name == 'schedule' || github.event_name == 'push' }} + docker-save-cache: ${{ github.event_name == 'schedule' || + github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: Testing cache # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: @@ -208,3 +208,43 @@ runs: aws-region: ${{ inputs.aws-region }} github-token: ${{ steps.github-token.outputs.access-token || '' }} + + # DEBUG: Inspect built image + - name: Inspect built image + if: inputs.inspect-image == 'true' + shell: bash + env: + IMAGE: + "${{ inputs.docker-registry-url }}/${{ inputs.docker-repository-name + }}:${{ inputs.image-tag }}" + run: | + echo "::group::Pull image" + docker pull "$IMAGE" + echo "::endgroup::" + + echo "::group::Installed binaries" + docker run --rm --user root --entrypoint ls "$IMAGE" -lahS /usr/local/bin/ + echo "::endgroup::" + + echo "::group::Binary checksums (SHA256)" + docker run --rm --user root --entrypoint sh "$IMAGE" \ + -c 'find /usr/local/bin -maxdepth 1 -type f | sort | xargs sha256sum' + echo "::endgroup::" + + echo "::group::Shared libraries" + docker run --rm --user root --entrypoint sh "$IMAGE" \ + -c 'ls -la /usr/lib/lib* 2>/dev/null || echo "No shared libraries found"' + echo "::endgroup::" + + echo "::group::Chainlink version" + docker run --rm "$IMAGE" --version || true + echo "::endgroup::" + + echo "::group::Environment variables" + docker inspect "$IMAGE" --format '{{range .Config.Env}}{{println .}}{{end}}' + echo "::endgroup::" + + echo "::group::Image config" + docker inspect "$IMAGE" --format '{{json .Config}}' | python3 -m json.tool 2>/dev/null \ + || docker inspect "$IMAGE" --format '{{json .Config}}' + echo "::endgroup::" From 425f86d37ae9b549bba3a7dde06fe8c9f35a680b Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 14:33:25 -0400 Subject: [PATCH 09/20] Add image inspection --- actions/ctf-build-image/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 4d6c9729..bea1d28f 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -211,7 +211,6 @@ runs: # DEBUG: Inspect built image - name: Inspect built image - if: inputs.inspect-image == 'true' shell: bash env: IMAGE: From 6fe95caf127a3b7fafef911def2ec76495fc0352 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 15:10:58 -0400 Subject: [PATCH 10/20] Remove DEBUG --- actions/ctf-build-image/action.yml | 43 ++---------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index bea1d28f..304982d0 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -189,8 +189,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: ${{ github.event_name == 'schedule' || - github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: Testing cache + docker-save-cache: + ${{ github.event_name == 'schedule' || github.event_name == 'push' }} # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: @@ -208,42 +208,3 @@ runs: aws-region: ${{ inputs.aws-region }} github-token: ${{ steps.github-token.outputs.access-token || '' }} - - # DEBUG: Inspect built image - - name: Inspect built image - shell: bash - env: - IMAGE: - "${{ inputs.docker-registry-url }}/${{ inputs.docker-repository-name - }}:${{ inputs.image-tag }}" - run: | - echo "::group::Pull image" - docker pull "$IMAGE" - echo "::endgroup::" - - echo "::group::Installed binaries" - docker run --rm --user root --entrypoint ls "$IMAGE" -lahS /usr/local/bin/ - echo "::endgroup::" - - echo "::group::Binary checksums (SHA256)" - docker run --rm --user root --entrypoint sh "$IMAGE" \ - -c 'find /usr/local/bin -maxdepth 1 -type f | sort | xargs sha256sum' - echo "::endgroup::" - - echo "::group::Shared libraries" - docker run --rm --user root --entrypoint sh "$IMAGE" \ - -c 'ls -la /usr/lib/lib* 2>/dev/null || echo "No shared libraries found"' - echo "::endgroup::" - - echo "::group::Chainlink version" - docker run --rm "$IMAGE" --version || true - echo "::endgroup::" - - echo "::group::Environment variables" - docker inspect "$IMAGE" --format '{{range .Config.Env}}{{println .}}{{end}}' - echo "::endgroup::" - - echo "::group::Image config" - docker inspect "$IMAGE" --format '{{json .Config}}' | python3 -m json.tool 2>/dev/null \ - || docker inspect "$IMAGE" --format '{{json .Config}}' - echo "::endgroup::" From 9930ffdbfa683ce5b57b4dec9edad9a7d7a9cf00 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 26 Mar 2026 16:53:12 -0400 Subject: [PATCH 11/20] Comments --- actions/ctf-build-image/action.yml | 2 +- .../scripts/go-get-overrides.sh | 59 ------------------- 2 files changed, 1 insertion(+), 60 deletions(-) delete mode 100755 actions/ctf-build-image/scripts/go-get-overrides.sh diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 304982d0..903b8333 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -165,7 +165,7 @@ runs: exit 0 fi ENCODED=$(echo "$GO_OVERRIDES" | sed '/^$/d' | paste -sd ',' -) - echo "encoded=$ENCODED" >> "$GITHUB_OUTPUT" + tee -a "$GITHUB_OUTPUT" echo "::info::Encoded go-get overrides: $ENCODED" - name: Free up disk space (to avoid 'no space left on device' errors) diff --git a/actions/ctf-build-image/scripts/go-get-overrides.sh b/actions/ctf-build-image/scripts/go-get-overrides.sh deleted file mode 100755 index 888c221b..00000000 --- a/actions/ctf-build-image/scripts/go-get-overrides.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -set -e - -# Check if running in dry run mode -DRY_RUN=${DRY_RUN:-false} - -# Check for dependencies -if ! command -v go &> /dev/null; then - echo "::error::'go' command not found." - exit 1 -fi - -# Validate environment variables -if [[ -z "${GO_OVERRIDES}" ]]; then - echo "::info:: No go get overrides specified, skipping." - exit 0 -fi - -echo "::info:: Processing go get overrides..." - -while IFS= read -r line || [[ -n "$line" ]]; do - # Skip empty lines - [[ -z "$line" ]] && continue - - # Check if line contains '=' character - if [[ "$line" != *"="* ]]; then - echo "::warning::Invalid format for line '$line', expected 'dependency=sha', skipping." - continue - fi - - # Extract dependency name and SHA - dependency="${line%%=*}" - sha="${line#*=}" - - # Skip if SHA is empty - if [[ -z "$sha" ]]; then - echo "::warning::Empty SHA for dependency $dependency, skipping." - continue - fi - - echo "::info:: Replacing $dependency dependency with SHA: $sha" - - if [[ "$DRY_RUN" == "true" ]]; then - echo "[DRY RUN] Would execute: go get \"github.com/smartcontractkit/${dependency}@${sha}\"" - else - # Set GOPRIVATE if provided - if [[ -n "${GOPRIVATE}" ]]; then - export GOPRIVATE="${GOPRIVATE}" - fi - - go get "github.com/smartcontractkit/${dependency}@${sha}" || { - echo "Error: Failed to get dependency github.com/smartcontractkit/${dependency}@${sha}" - exit 1 - } - echo "::info::Successfully updated ${dependency} to ${sha}" - fi -done <<< "$GO_OVERRIDES" - -echo "Go get overrides processing completed." From 00e02e67e3ffe75c935b25e1d6002c71db950fdd Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 09:44:16 -0400 Subject: [PATCH 12/20] tee it up --- actions/ctf-build-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 903b8333..a7e20e4e 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -165,7 +165,7 @@ runs: exit 0 fi ENCODED=$(echo "$GO_OVERRIDES" | sed '/^$/d' | paste -sd ',' -) - tee -a "$GITHUB_OUTPUT" + echo "encoded-overides=$ENCODED" | tee -a "$GITHUB_OUTPUT" echo "::info::Encoded go-get overrides: $ENCODED" - name: Free up disk space (to avoid 'no space left on device' errors) From 0c5a0aedf2a14bb1909992a12f2d42bdf6231b0e Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 11:29:14 -0400 Subject: [PATCH 13/20] Plugin caching + debug --- actions/ctf-build-image/action.yml | 47 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index a7e20e4e..c71bd404 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -168,6 +168,26 @@ runs: echo "encoded-overides=$ENCODED" | tee -a "$GITHUB_OUTPUT" echo "::info::Encoded go-get overrides: $ENCODED" + - name: Compute remote plugin cache key + id: plugin-cache + shell: bash + run: | + HASH=$(cat \ + plugins/plugins.public.yaml \ + plugins/plugins.private.yaml \ + plugins/plugins.testing.yaml \ + plugins/scripts/* \ + | sha256sum | cut -d' ' -f1) + echo "key=remote-plugins-${HASH}" >> "$GITHUB_OUTPUT" + mkdir -p .plugin-cache + + - name: Restore cached remote plugin binaries + id: plugin-cache-restore + uses: actions/cache/restore@v4 + with: + key: ${{ steps.plugin-cache.outputs.key }} + path: .plugin-cache/ + - name: Free up disk space (to avoid 'no space left on device' errors) if: inputs.free-disk-space == 'true' uses: smartcontractkit/.github/actions/free-disk-space@free-disk-space/v1 @@ -185,12 +205,16 @@ runs: CHAINLINK_USER=chainlink GO_OVERRIDE_DEPS=${{ steps.encode-overrides.outputs.encoded }} ${{ inputs.docker-additional-build-args }} + docker-build-contexts: >- + ${{ steps.plugin-cache-restore.outputs.cache-hit == 'true' + && 'build-remote-plugins=.plugin-cache/' + || '' }} docker-attestations: "false" docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: - ${{ github.event_name == 'schedule' || github.event_name == 'push' }} + docker-save-cache: ${{ github.event_name == 'schedule' || + github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: pull_request to test # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: @@ -208,3 +232,22 @@ runs: aws-region: ${{ inputs.aws-region }} github-token: ${{ steps.github-token.outputs.access-token || '' }} + + - name: Extract remote plugin binaries for caching + if: steps.plugin-cache-restore.outputs.cache-hit != 'true' + shell: bash + env: + DOCKERFILE: ${{ inputs.dockerfile }} + run: | + echo "Extracting remote plugin binaries for caching..." + docker buildx build \ + --target export-remote-plugins \ + --output type=local,dest=.plugin-cache \ + -f "$DOCKERFILE" . + + - name: Save remote plugin cache + if: steps.plugin-cache-restore.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: ${{ steps.plugin-cache.outputs.key }} + path: .plugin-cache/ From 826ceff8bf66444cc4773403daa910958551fb9b Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 12:51:38 -0400 Subject: [PATCH 14/20] Fixes --- .github/workflows/run-e2e-tests.yml | 2 +- actions/apidiff-go/README.md | 4 ++-- actions/ctf-build-image/action.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 4ada3982..fc6d331c 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -427,7 +427,7 @@ jobs: persist-credentials: false - name: Setup Go - uses: actions/setup-go@v5.0.2 + uses: actions/setup-go@v6 with: go-version: "1.24.0" check-latest: true diff --git a/actions/apidiff-go/README.md b/actions/apidiff-go/README.md index ac4df704..4937ef6f 100644 --- a/actions/apidiff-go/README.md +++ b/actions/apidiff-go/README.md @@ -67,7 +67,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: "go.mod" cache: false @@ -140,7 +140,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 # uses: ./.github/actions/setup-go with: go-version-file: ${{matrix.modules}}/go.mod diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index c71bd404..a58e8296 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -183,7 +183,7 @@ runs: - name: Restore cached remote plugin binaries id: plugin-cache-restore - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: key: ${{ steps.plugin-cache.outputs.key }} path: .plugin-cache/ @@ -247,7 +247,7 @@ runs: - name: Save remote plugin cache if: steps.plugin-cache-restore.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: key: ${{ steps.plugin-cache.outputs.key }} path: .plugin-cache/ From b04165ca30e43f354a78081417410694c69e0d95 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 12:55:52 -0400 Subject: [PATCH 15/20] Fix encoding --- actions/ctf-build-image/action.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index a58e8296..abd54076 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -155,18 +155,17 @@ runs: run: ${ACTIONS_PATH}/scripts/plugin-overrides.sh - name: Encode go-get overrides for Docker build arg - id: encode-overrides + id: encode-go-overrides shell: bash env: GO_OVERRIDES: ${{ inputs.go-get-overrides }} run: | if [ -z "$GO_OVERRIDES" ]; then - echo "encoded=" >> "$GITHUB_OUTPUT" + echo "encoded=" | tee -a "$GITHUB_OUTPUT" exit 0 fi ENCODED=$(echo "$GO_OVERRIDES" | sed '/^$/d' | paste -sd ',' -) - echo "encoded-overides=$ENCODED" | tee -a "$GITHUB_OUTPUT" - echo "::info::Encoded go-get overrides: $ENCODED" + echo "encoded=$ENCODED" | tee -a "$GITHUB_OUTPUT" - name: Compute remote plugin cache key id: plugin-cache @@ -203,7 +202,7 @@ runs: docker-build-args: | COMMIT_SHA=${{ github.sha }} CHAINLINK_USER=chainlink - GO_OVERRIDE_DEPS=${{ steps.encode-overrides.outputs.encoded }} + GO_OVERRIDE_DEPS=${{ steps.encode-go-overrides.outputs.encoded }} ${{ inputs.docker-additional-build-args }} docker-build-contexts: >- ${{ steps.plugin-cache-restore.outputs.cache-hit == 'true' @@ -213,8 +212,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: ${{ github.event_name == 'schedule' || - github.event_name == 'push' || github.event_name == 'pull_request' }} # DEBUG: pull_request to test + docker-save-cache: + ${{ github.event_name == 'schedule' || github.event_name == 'push' }} # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: From 5004a95ed94c1d8d5eb2f401cc55552a277473d8 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 13:45:02 -0400 Subject: [PATCH 16/20] Changeset --- .changeset/proud-owls-lick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/proud-owls-lick.md diff --git a/.changeset/proud-owls-lick.md b/.changeset/proud-owls-lick.md new file mode 100644 index 00000000..5323f6f7 --- /dev/null +++ b/.changeset/proud-owls-lick.md @@ -0,0 +1,5 @@ +--- +"ctf-build-image": minor +--- + +Adds inputs and tweaks docker caching strategy for better performance From 7b30d4f8fb2f24b81e7ecc2eb2a6e8af272da2a8 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 15:16:31 -0400 Subject: [PATCH 17/20] Comments --- actions/ctf-build-image/action.yml | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index abd54076..e63248e3 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -154,18 +154,29 @@ runs: ACTIONS_PATH: ${{ github.action_path }} run: ${ACTIONS_PATH}/scripts/plugin-overrides.sh - - name: Encode go-get overrides for Docker build arg - id: encode-go-overrides + - name: Setup Go for dependency overrides + if: inputs.go-get-overrides != '' + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: false + + - name: Apply go-get dependency overrides + if: inputs.go-get-overrides != '' shell: bash env: GO_OVERRIDES: ${{ inputs.go-get-overrides }} run: | - if [ -z "$GO_OVERRIDES" ]; then - echo "encoded=" | tee -a "$GITHUB_OUTPUT" - exit 0 - fi - ENCODED=$(echo "$GO_OVERRIDES" | sed '/^$/d' | paste -sd ',' -) - echo "encoded=$ENCODED" | tee -a "$GITHUB_OUTPUT" + set -e + while IFS= read -r line; do + [ -z "$line" ] && continue + dep="${line%%=*}" + sha="${line#*=}" + [ -z "$dep" ] || [ -z "$sha" ] && continue + echo "Overriding: github.com/smartcontractkit/${dep}@${sha}" + go get "github.com/smartcontractkit/${dep}@${sha}" + done <<< "$GO_OVERRIDES" + go mod tidy - name: Compute remote plugin cache key id: plugin-cache @@ -202,7 +213,6 @@ runs: docker-build-args: | COMMIT_SHA=${{ github.sha }} CHAINLINK_USER=chainlink - GO_OVERRIDE_DEPS=${{ steps.encode-go-overrides.outputs.encoded }} ${{ inputs.docker-additional-build-args }} docker-build-contexts: >- ${{ steps.plugin-cache-restore.outputs.cache-hit == 'true' From b40f786e1e91b32879bbdd0aa10b133d7d9e8f73 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 15:19:12 -0400 Subject: [PATCH 18/20] pr debug --- actions/ctf-build-image/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index e63248e3..a79eeb72 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -222,8 +222,8 @@ runs: docker-registry-url: ${{ inputs.docker-registry-url }} docker-repository-name: ${{ inputs.docker-repository-name }} # only save on events which are expected to be from the default branch - docker-save-cache: - ${{ github.event_name == 'schedule' || github.event_name == 'push' }} + docker-save-cache: ${{ github.event_name == 'schedule' || + github.event_name == 'push' || github.event_name == 'pull_request' }} # TODO: Remove pull_request after testing # dont use cache on events which are expected to be from the default branch # this is to create a fresh cache/snapshot unpolluted by previous cache entries docker-restore-cache: From 1d912f18e2e2f1f899faa2380ab27df2cb9dcae9 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 15:24:37 -0400 Subject: [PATCH 19/20] Don't cache plugins on PRs --- actions/ctf-build-image/action.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index a79eeb72..6c29fe10 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -243,7 +243,9 @@ runs: github-token: ${{ steps.github-token.outputs.access-token || '' }} - name: Extract remote plugin binaries for caching - if: steps.plugin-cache-restore.outputs.cache-hit != 'true' + if: steps.plugin-cache-restore.outputs.cache-hit != 'true' && + (github.event_name == 'schedule' || github.event_name == 'push' || + github.event_name == 'pull_request') # TODO: Remove pull_request after testing shell: bash env: DOCKERFILE: ${{ inputs.dockerfile }} @@ -255,7 +257,9 @@ runs: -f "$DOCKERFILE" . - name: Save remote plugin cache - if: steps.plugin-cache-restore.outputs.cache-hit != 'true' + if: steps.plugin-cache-restore.outputs.cache-hit != 'true' && + (github.event_name == 'schedule' || github.event_name == 'push' || + github.event_name == 'pull_request') # TODO: Remove pull_request after testing uses: actions/cache/save@v5 with: key: ${{ steps.plugin-cache.outputs.key }} From 82d89c79d10064ad8b31d1f8112af1b80b92a6a8 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 27 Mar 2026 15:37:31 -0400 Subject: [PATCH 20/20] Update actions --- actions/build-push-docker/action.yml | 8 ++++---- actions/ctf-build-image/action.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/actions/build-push-docker/action.yml b/actions/build-push-docker/action.yml index 04f0fed7..53d3f759 100644 --- a/actions/build-push-docker/action.yml +++ b/actions/build-push-docker/action.yml @@ -203,14 +203,14 @@ runs: - name: Login to private ECR registries for base images if: ${{ steps.dockerfile-ecr-parse.outputs.needs-ecr-login == 'true' }} - uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1 + uses: aws-actions/amazon-ecr-login@183a1442edf41672e66566b7fc560e297a290896 # v2.1.1 with: registries: ${{ steps.dockerfile-ecr-parse.outputs.ecr-registries }} - name: Login to ECR for publishing if: ${{ inputs.docker-push == 'true' }} id: login-ecr - uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1 + uses: aws-actions/amazon-ecr-login@183a1442edf41672e66566b7fc560e297a290896 # v2.1.1 with: registry-type: >- ${{ @@ -221,13 +221,13 @@ runs: registries: ${{ inputs.aws-account-number }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 with: version: latest - name: Docker meta id: docker-meta - uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: ${{ format('{0}/{1}', inputs.docker-registry-url, diff --git a/actions/ctf-build-image/action.yml b/actions/ctf-build-image/action.yml index 6c29fe10..f132b795 100644 --- a/actions/ctf-build-image/action.yml +++ b/actions/ctf-build-image/action.yml @@ -156,7 +156,7 @@ runs: - name: Setup Go for dependency overrides if: inputs.go-get-overrides != '' - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod cache: false