Skip to content

ci: return of the chef #7843

ci: return of the chef

ci: return of the chef #7843

name: CI + E2E
env:
# Define environment variables for AWS credentials and region
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_EKS_CLUSTER_NAME: ${{ secrets.AWS_EKS_CLUSTER_NAME }}
on:
merge_group:
pull_request:
branches: ["**"]
paths-ignore:
- "changes/**"
workflow_dispatch:
inputs:
force_rebuild:
description: "Force rebuild even if images already exist"
required: false
type: boolean
default: false
# no top level default permissions for security reasons
permissions: {}
concurrency:
group: ${{ github.event_name == 'pull_request' && format('{0}-{1}', github.workflow, github.head_ref) || github.run_id }}
cancel-in-progress: true
jobs:
run:
name: Build node and images (linux/amd64, self-hosted-tier:large, amd64)
permissions:
id-token: write
contents: read
# TEST PR — points at the new self-hosted runner pool to validate end-to-end
# build performance. Revert before merge.
runs-on: [self-hosted, "tier:large"]
env:
FORCE_COLOR: 1
outputs:
sha: ${{ steps.get_sha.outputs.sha }}
node_image_tag: ${{ steps.image_tags.outputs.node_image_tag }}
node_image_tag_no_dev: ${{ steps.image_tags.outputs.node_image_tag_no_dev }}
toolkit_image_tag: ${{ steps.image_tags.outputs.toolkit_image_tag }}
skip_build: ${{ steps.check_images.outputs.skip_build }}
steps:
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
with:
version: v0.8.16
github-token: ${{ github.token }}
# Keep `use-cache: false` — that flag controls whether EarthBuild
# caches state into GitHub Actions cache (which sets up TLS-secured
# buildkitd inside the runner). We don't want that path on
# self-hosted runners; cache comes from the local earthly buildkitd
# the runner manages itself.
use-cache: false
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- name: Get current commit SHA
id: get_sha
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# TEST ONLY — let earthly manage its own buildkitd on the self-hosted
# runner, but without TLS (no certs are provisioned). Earthly defaults
# to TLS for its managed buildkitd, which fails on a fresh runner.
# Appending `tls_enabled: false` to the repo's existing .earthly/config.yml
# keeps the rest of midnight-node's earthly settings intact.
- name: Disable earthly TLS (self-hosted runner has no certs)
run: |
echo " tls_enabled: false" >> .earthly/config.yml
echo "--- updated .earthly/config.yml ---"
cat .earthly/config.yml
# Self-hosted runners share a persistent HOME (/opt/actions-runner) across
# every runner slot on the host, making ~/.docker/config.json shared
# mutable state. Concurrent jobs' `docker login` (read-modify-write) race
# and clobber each other's registry entries — e.g. a Docker Hub login
# wiping the ghcr.io entry — leaving the build's push with no GHCR creds
# (anonymous token -> 403). Pin DOCKER_CONFIG to the per-slot runner temp
# dir so each job gets an isolated docker config that docker/login-action
# writes to and earthly reads from (earthly honors DOCKER_CONFIG). Set via
# $GITHUB_ENV in a step because runner.temp is unavailable in job-level env.
- name: Isolate docker config (self-hosted shared HOME)
run: |
mkdir -p "$RUNNER_TEMP/.docker"
echo "DOCKER_CONFIG=$RUNNER_TEMP/.docker" >> "$GITHUB_ENV"
- name: Login to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
# Earthfile FROMs midnightntwrk/midnight-node-ci and several library/*
# images that resolve to docker.io. With --push, earthly tries to write
# inline cache back to the midnightntwrk Docker Hub namespace and fails
# auth without this login.
# Non-fatal: the +images push targets ghcr.io only (authed by the GHCR
# login above) and the docker.io base images are public, so the build
# still pulls + pushes without these creds. Dependabot runs don't have
# the DOCKERHUB_* secrets, so this step would otherwise hard-fail there.
- name: Login to Docker Hub
continue-on-error: true
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
username: ${{ secrets.DOCKERHUB_MIDNIGHTNTWRK_USER }}
password: ${{ secrets.DOCKERHUB_MIDNIGHTNTWRK_TOKEN }}
# Both logins above wrote to the isolated $DOCKER_CONFIG/config.json (see
# the DOCKER_CONFIG note at job level). Confirm both registries are present
# before the build so an auth regression surfaces here rather than as an
# opaque anonymous-token 403 mid-push.
- name: Verify registry creds visible to earthly
run: |
echo "DOCKER_CONFIG=${DOCKER_CONFIG:-<unset>}"
echo "Registries with creds:"
jq '.auths | keys' "$DOCKER_CONFIG/config.json"
- name: Compute image tags
id: image_tags
run: |
content_hash=$(git rev-parse "HEAD^{tree}" | cut -c1-12)
version=$(grep -m 1 '^version =' node/Cargo.toml | cut -d '"' -f2)
echo "node_image_tag=${version}-dev-${content_hash}-amd64" >> "$GITHUB_OUTPUT"
echo "node_image_tag_no_dev=${version}-${content_hash}-amd64" >> "$GITHUB_OUTPUT"
echo "toolkit_image_tag=${version}-${content_hash}-amd64" >> "$GITHUB_OUTPUT"
- name: Check for existing images
id: check_images
env:
FORCE_REBUILD: ${{ github.event.inputs.force_rebuild }}
run: |
if [ "$FORCE_REBUILD" = "true" ]; then
echo "skip_build=false" >> "$GITHUB_OUTPUT"
exit 0
fi
NODE_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/midnight-node:${{ steps.image_tags.outputs.node_image_tag }}" > /dev/null 2>&1 && echo true || echo false)
TOOLKIT_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ steps.image_tags.outputs.toolkit_image_tag }}" > /dev/null 2>&1 && echo true || echo false)
if [ "$NODE_EXISTS" = "true" ] && [ "$TOOLKIT_EXISTS" = "true" ]; then
echo "skip_build=true" >> "$GITHUB_OUTPUT"
echo "Images already exist, skipping build"
else
echo "skip_build=false" >> "$GITHUB_OUTPUT"
fi
- name: Run build
if: steps.check_images.outputs.skip_build != 'true'
env:
GITHUB_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
# Self-hosted-runner-specific: runner systemd unit has PrivateTmp=true,
# so /tmp is in a per-service mount namespace that dockerd (and therefore
# earthly's sibling buildkitd container) can't see. Force earthly's
# temp dir to live under $RUNNER_TEMP which is outside PrivateTmp.
TMPDIR: ${{ runner.temp }}
# Belt-and-suspenders: an older version of the runner .env set
# EARTHLY_REMOTE_CACHE=local, which earthly resolves to
# docker.io/library/local (unauthenticated, push fails). The .env
# has been cleaned, but force-clear in case any runner process
# still has the stale value cached.
EARTHLY_REMOTE_CACHE: ""
# Same belt-and-suspenders for ACTIONS_CACHE_URL — earthly auto-uses
# it as a cache target if set, and our local cache server doesn't
# accept GHA's ACTIONS_RUNTIME_TOKEN.
ACTIONS_CACHE_URL: ""
ACTIONS_RUNTIME_URL: ""
run: |
mkdir -p "$HOME"/.cargo
echo "[net]" >> "$HOME"/.cargo/config
echo "git-fetch-with-cli = true" >> "$HOME"/.cargo/config
# Retry the earthly invocation up to 3 times. Buildkit's default
# response-header timeout for registry uploads (~30s in the
# underlying containerd resolver) isn't tunable via buildkitd.toml,
# and the self-hosted -> ghcr.io path occasionally drops a layer push
# with "timeout awaiting response headers". Earthly's cache means
# retries skip everything that already succeeded — they essentially
# only retry the failing push.
#
# No ::group:: wrapping — failures need to be visible by default in
# the GHA log, not collapsed.
. ./.envrc
for attempt in 1 2 3; do
echo "----- earthly attempt $attempt/3 -----"
if earthly --secret GITHUB_TOKEN="$GITHUB_TOKEN" -P --push +images; then
exit 0
fi
echo "----- earthly attempt $attempt failed -----"
if [ $attempt -lt 3 ]; then
echo "sleeping 30s before retry"
sleep 30
fi
done
echo "earthly failed after 3 attempts"
exit 1
- name: Upload build artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: (success() || failure()) && steps.check_images.outputs.skip_build != 'true'
with:
name: Wasm Runtime and binaries (amd64)
path: artifacts-amd64/
- name: Upload test artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: (success() || failure()) && steps.check_images.outputs.skip_build != 'true'
with:
name: Test artifacts (amd64)
path: test-artifacts-amd64/
sbom-scan-node:
permissions:
contents: read
packages: write
id-token: write
attestations: write
name: SBOM/Scan Node
needs: [run]
uses: ./.github/workflows/sbom-scan-image.yml
with:
image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
sbom-artifact-name: sbom-midnight-node-ci
skip-attestation: true
secrets: inherit
sbom-scan-toolkit:
permissions:
contents: read
packages: write
id-token: write
attestations: write
name: SBOM/Scan Toolkit
needs: [run]
uses: ./.github/workflows/sbom-scan-image.yml
with:
image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
sbom-artifact-name: sbom-midnight-node-toolkit-ci
skip-attestation: true
secrets: inherit
run-arm64:
name: Build node and images (arm64)
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest-8-core-arm64
env:
FORCE_COLOR: 1
steps:
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- name: Login to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- name: Compute image tags
id: image_tags
run: |
content_hash=$(git rev-parse "HEAD^{tree}" | cut -c1-12)
version=$(grep -m 1 '^version =' node/Cargo.toml | cut -d '"' -f2)
echo "node_image_tag=${version}-dev-${content_hash}-arm64" >> "$GITHUB_OUTPUT"
echo "toolkit_image_tag=${version}-${content_hash}-arm64" >> "$GITHUB_OUTPUT"
- name: Check for existing images
id: check_images
env:
FORCE_REBUILD: ${{ github.event.inputs.force_rebuild }}
run: |
if [ "$FORCE_REBUILD" = "true" ]; then
echo "skip_build=false" >> "$GITHUB_OUTPUT"
exit 0
fi
NODE_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/midnight-node:${{ steps.image_tags.outputs.node_image_tag }}" > /dev/null 2>&1 && echo true || echo false)
TOOLKIT_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ steps.image_tags.outputs.toolkit_image_tag }}" > /dev/null 2>&1 && echo true || echo false)
if [ "$NODE_EXISTS" = "true" ] && [ "$TOOLKIT_EXISTS" = "true" ]; then
echo "skip_build=true" >> "$GITHUB_OUTPUT"
echo "Images already exist, skipping build"
else
echo "skip_build=false" >> "$GITHUB_OUTPUT"
fi
- name: Run build
if: steps.check_images.outputs.skip_build != 'true'
env:
GITHUB_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
run: |
mkdir -p "$HOME"/.cargo
echo "[net]" >> "$HOME"/.cargo/config
echo "git-fetch-with-cli = true" >> "$HOME"/.cargo/config
. ./.envrc && earthly --secret GITHUB_TOKEN="$GITHUB_TOKEN" -P --push +images
- name: Upload build artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: (success() || failure()) && steps.check_images.outputs.skip_build != 'true'
with:
name: Wasm Runtime and binaries (arm64)
path: artifacts-arm64/
- name: Upload test artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: (success() || failure()) && steps.check_images.outputs.skip_build != 'true'
with:
name: Test artifacts (arm64)
path: test-artifacts-arm64/
# Combine the per-platform images (`<tag>-amd64`, `<tag>-arm64`) pushed by
# `run` and `run-arm64` under a single multi-arch tag.
push-combined-manifest:
name: Push combined multi-arch manifest
needs: [run, run-arm64]
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
steps:
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Login to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- name: Compute combined image tags
id: tags
env:
NODE_AMD64_TAG: ${{ needs.run.outputs.node_image_tag_no_dev }}
TOOLKIT_AMD64_TAG: ${{ needs.run.outputs.toolkit_image_tag }}
run: |
node_amd64="$NODE_AMD64_TAG"
toolkit_amd64="$TOOLKIT_AMD64_TAG"
node_combined="${node_amd64%-amd64}"
toolkit_combined="${toolkit_amd64%-amd64}"
node_arm64="${node_combined}-arm64"
toolkit_arm64="${toolkit_combined}-arm64"
{
echo "node_combined=${node_combined}"
echo "node_amd64=${node_amd64}"
echo "node_arm64=${node_arm64}"
echo "toolkit_combined=${toolkit_combined}"
echo "toolkit_amd64=${toolkit_amd64}"
echo "toolkit_arm64=${toolkit_arm64}"
} >> "$GITHUB_OUTPUT"
- name: Push combined manifest for midnight-node
env:
IMAGE: ghcr.io/midnightntwrk/midnight-node
COMBINED_TAG: ${{ steps.tags.outputs.node_combined }}
AMD64_TAG: ${{ steps.tags.outputs.node_amd64 }}
ARM64_TAG: ${{ steps.tags.outputs.node_arm64 }}
run: |
docker buildx imagetools create \
-t "${IMAGE}:${COMBINED_TAG}" \
"${IMAGE}:${AMD64_TAG}" \
"${IMAGE}:${ARM64_TAG}"
docker buildx imagetools inspect "${IMAGE}:${COMBINED_TAG}"
- name: Push combined manifest for midnight-node-toolkit
env:
IMAGE: ghcr.io/midnightntwrk/midnight-node-toolkit
COMBINED_TAG: ${{ steps.tags.outputs.toolkit_combined }}
AMD64_TAG: ${{ steps.tags.outputs.toolkit_amd64 }}
ARM64_TAG: ${{ steps.tags.outputs.toolkit_arm64 }}
run: |
docker buildx imagetools create \
-t "${IMAGE}:${COMBINED_TAG}" \
"${IMAGE}:${AMD64_TAG}" \
"${IMAGE}:${ARM64_TAG}"
docker buildx imagetools inspect "${IMAGE}:${COMBINED_TAG}"
check-unused-deps:
permissions:
contents: read
actions: write
name: Check Unused Dependencies
needs: [run]
if: needs.run.outputs.skip_build != 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
if: steps.guard.outputs.hit != 'true'
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
- name: Check Deps
if: steps.guard.outputs.hit != 'true'
run: |
mkdir -p "$HOME"/.cargo
echo "[net]" >> "$HOME"/.cargo/config
echo "git-fetch-with-cli = true" >> "$HOME"/.cargo/config
. ./.envrc && earthly +check-deps
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
rebuild-genesis:
name: Check Genesis Rebuild
needs: [run]
permissions:
id-token: write
contents: read
actions: write
runs-on: ubuntu-latest
env:
FORCE_COLOR: 1
steps:
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
if: steps.guard.outputs.hit != 'true'
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
- name: Login to GHCR
if: steps.guard.outputs.hit != 'true'
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
- name: Generate dummy genesis seeds
if: steps.guard.outputs.hit != 'true'
run: |
mkdir -p secrets
for cfg in res/cfg/*.toml; do
network=$(basename "$cfg" .toml)
python3 scripts/generate-genesis-seeds.py -c 4 -o "secrets/${network}-genesis-seeds.json"
done
- name: Check Genesis Rebuild
if: steps.guard.outputs.hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
run: |
mkdir -p "$HOME"/.cargo
echo "[net]" >> "$HOME"/.cargo/config
echo "git-fetch-with-cli = true" >> "$HOME"/.cargo/config
. ./.envrc && earthly --secret GITHUB_TOKEN="$GITHUB_TOKEN" \
--build-arg "NODE_IMAGE=ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}" \
--build-arg "TOOLKIT_IMAGE=ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}" \
+rebuild-genesis
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
# Gate job for toolkit E2E tests - if this fails, toolkit E2E tests are skipped
test-toolkit:
permissions:
contents: read
actions: write
name: Test Toolkit
needs: [run]
runs-on: [self-hosted, "tier:large"]
env:
FORCE_COLOR: 1
steps:
- name: Checkout node repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
if: steps.guard.outputs.hit != 'true'
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
# Isolate docker config per runner slot — see the matching step in the
# `run` job. runner.temp is not available in job-level env, so set it here.
- name: Isolate docker config (self-hosted shared HOME)
if: steps.guard.outputs.hit != 'true'
run: |
mkdir -p "$RUNNER_TEMP/.docker"
echo "DOCKER_CONFIG=$RUNNER_TEMP/.docker" >> "$GITHUB_ENV"
- name: Login to GHCR
if: steps.guard.outputs.hit != 'true'
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
# Earthfile FROMs midnightntwrk/midnight-node-ci and other docker.io
# images; earthly pushes inline cache back to those repos under --push,
# which needs Docker Hub auth.
# Non-fatal: pushes target ghcr.io and the docker.io base images are
# public, so the build proceeds without these creds (e.g. Dependabot runs,
# which don't have the DOCKERHUB_* secrets).
- name: Login to Docker Hub
if: steps.guard.outputs.hit != 'true'
continue-on-error: true
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
username: ${{ secrets.DOCKERHUB_MIDNIGHTNTWRK_USER }}
password: ${{ secrets.DOCKERHUB_MIDNIGHTNTWRK_TOKEN }}
- name: Free disk space
if: steps.guard.outputs.hit != 'true' && runner.environment != 'self-hosted'
run: scripts/free-disk-space.sh
# Self-hosted-runner-specific: earthly's managed buildkitd defaults to TLS
# but no certs are provisioned on the runner. Append tls_enabled: false
# to the workspace .earthly/config.yml so earthly skips TLS for its own
# buildkitd container.
- name: Disable earthly TLS (self-hosted runner has no certs)
if: steps.guard.outputs.hit != 'true'
run: |
echo " tls_enabled: false" >> .earthly/config.yml
- name: Run toolkit tests
if: steps.guard.outputs.hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
EVENT_NAME: ${{ github.event_name }}
# Self-hosted-runner-specific: runner systemd unit has PrivateTmp=true.
# Force earthly's tempdir to live under $RUNNER_TEMP which is
# outside the per-service PrivateTmp namespace.
TMPDIR: ${{ runner.temp }}
# Force-clear in case a runner process has stale EARTHLY_REMOTE_CACHE
# from before we cleaned the runner .env.
EARTHLY_REMOTE_CACHE: ""
# The runner's .env redirects ACTIONS_CACHE_URL to a local cache
# server. Earthly auto-detects this and tries to push to it with the
# wrong auth; override to empty for the earthly call.
ACTIONS_CACHE_URL: ""
ACTIONS_RUNTIME_URL: ""
# +test-toolkit pulls in +build-test-toolkit's `target-${CACHE_KEY}`
# cache mount. Pass the PR ref so it's scoped per-branch on this
# shared self-hosted runner — see +test's `Run build` step for the
# full rationale and why EARTHLY_GIT_BRANCH is unsafe here.
GITHUB_REF_RAW: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}
NODE_IMAGE_TAG: ${{ needs.run.outputs.node_image_tag }}
run: |
PUSH_FLAG=""
if [ "$EVENT_NAME" = "merge_group" ]; then
PUSH_FLAG="--push"
fi
CACHE_KEY=$(printf '%s' "$GITHUB_REF_RAW" | tr -c 'A-Za-z0-9._-' '-')
if [ -z "$CACHE_KEY" ]; then
echo "::error::could not derive CACHE_KEY from refs (head_ref=$GITHUB_REF_RAW)"
exit 1
fi
echo "Using CACHE_KEY=$CACHE_KEY"
. ./.envrc && earthly --secret GITHUB_TOKEN="$GITHUB_TOKEN" -P --strict $PUSH_FLAG \
--remote-cache=ghcr.io/midnight-ntwrk/midnight-node:cache-test-toolkit \
+test-toolkit \
--NODE_IMAGE="ghcr.io/midnight-ntwrk/midnight-node:${NODE_IMAGE_TAG}" \
--CACHE_KEY="$CACHE_KEY"
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
toolkit-e2e:
permissions:
contents: read
actions: write
name: Toolkit E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: ./.github/actions/reusable-e2e-tests
if: steps.guard.outputs.hit != 'true'
with:
just-command: toolkit-e2e
node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
toolkit-update-ledger-parameters-e2e:
permissions:
contents: read
actions: write
name: Toolkit Update Ledger Parameters E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: ./.github/actions/reusable-e2e-tests
if: steps.guard.outputs.hit != 'true'
with:
just-command: toolkit-update-ledger-parameters-e2e
node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
toolkit-maintenance-e2e:
permissions:
contents: read
actions: write
name: Toolkit Maintenance E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
# "LEDGER9-TOOLKIT-JS: toolkit-js v9 / compact-js with intent[v7] serializer not yet vendored"
# - uses: ./.github/actions/reusable-e2e-tests
# if: steps.guard.outputs.hit != 'true'
# with:
# just-command: toolkit-maintenance-e2e
# node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
# toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
# ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
toolkit-mint-e2e:
permissions:
contents: read
actions: write
name: Toolkit Mint E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
#"LEDGER9-TOOLKIT-JS: toolkit-js v9 / compact-js with intent[v7] serializer not yet vendored"
# - uses: ./.github/actions/reusable-e2e-tests
# if: steps.guard.outputs.hit != 'true'
# with:
# just-command: toolkit-mint-e2e
# node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
# toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
# ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
toolkit-tokens-minter-e2e:
permissions:
contents: read
actions: write
name: Toolkit Unshielded Token E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
# "LEDGER9-TOOLKIT-JS: toolkit-js v9 / compact-js with intent[v7] serializer not yet vendored"
# - uses: ./.github/actions/reusable-e2e-tests
# if: steps.guard.outputs.hit != 'true'
# with:
# just-command: toolkit-tokens-minter-e2e
# node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
# toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
# ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
metadata-check:
permissions:
contents: read
actions: write
name: Metadata Check
needs: run
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: EarthBuild/actions-setup@cae2d9ab68894d8402751fe42e07c7cca0272f7f
if: steps.guard.outputs.hit != 'true'
with:
version: v0.8.16
github-token: ${{ github.token }}
use-cache: false
- name: Login to GHCR
if: steps.guard.outputs.hit != 'true'
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
- name: Run metadata check
if: steps.guard.outputs.hit != 'true'
run: |
. ./.envrc && earthly --ci -P \
--build-arg "NODE_IMAGE=ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}" \
+check-metadata
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
# Migration to Ledger v9 is not yet supported. Issue #1580.
# mainnet-sync-test:
# continue-on-error: true
# permissions:
# contents: read
# packages: read
# name: Mainnet Sync (1000 blocks)
# needs: [run]
# runs-on: [self-hosted, "tier:medium"]
# steps:
# - name: Checkout
# uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
# # Isolate docker config per runner slot — see the matching step in the
# # `run` job. runner.temp is not available in job-level env, so set it here.
# - name: Isolate docker config (self-hosted shared HOME)
# run: |
# mkdir -p "$RUNNER_TEMP/.docker"
# echo "DOCKER_CONFIG=$RUNNER_TEMP/.docker" >> "$GITHUB_ENV"
# - name: Login to GHCR
# uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
# with:
# registry: ghcr.io
# username: MidnightCI
# password: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
# - name: Sync first 1000 blocks of mainnet
# env:
# NODE_IMAGE: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
# SNAPSHOT: static/sync-test/snapshot.sql.xz
# CFG_PRESET: mainnet
# SYNC_UNTIL: "1000"
# SYNC_TIMEOUT_SECS: "1800"
# run: bash scripts/sync-test/run-sync.sh
# - name: Print sync logs
# if: always()
# run: |
# echo "::group::midnight-node.log"
# cat /tmp/midnight-node.log 2>/dev/null || echo "(no node log)"
# echo "::endgroup::"
# echo "::group::midnight-pg.log"
# cat /tmp/midnight-pg.log 2>/dev/null || echo "(no postgres log)"
# echo "::endgroup::"
# - name: Upload sync logs on failure
# if: failure()
# uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
# with:
# name: mainnet-sync-logs
# path: |
# /tmp/midnight-node.log
# /tmp/midnight-pg.log
# if-no-files-found: ignore
toolkit-contracts-e2e:
permissions:
contents: read
actions: write
name: Toolkit Contracts E2E
needs: [run]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
# "LEDGER9-TOOLKIT-JS: toolkit-js v9 / compact-js with intent[v7] serializer not yet vendored"
# - uses: ./.github/actions/reusable-e2e-tests
# if: steps.guard.outputs.hit != 'true'
# with:
# just-command: toolkit-contracts-e2e
# node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
# toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
# ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
startup-dev-e2e:
permissions:
contents: read
actions: write
name: Startup E2E in dev mode
needs: run
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: ./.github/actions/reusable-e2e-tests
if: steps.guard.outputs.hit != 'true'
with:
just-command: startup-dev-e2e
node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
chainspec-validation:
permissions:
contents: read
name: Chainspec Validation
needs: run
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Login to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee #v4.2.0
with:
registry: ghcr.io
username: MidnightCI
password: ${{ secrets.MIDNIGHTCI_PACKAGES_READ }}
- name: Run chainspec validation harness
env:
MIDNIGHT_NODE_IMAGE: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
run: bash tests/chainspec-validation/run.sh
genesis-undeployed-e2e:
permissions:
contents: read
actions: write
name: Genesis Wallets E2E for Undeployed network
needs: run
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
- uses: ./.github/actions/reusable-e2e-tests
if: steps.guard.outputs.hit != 'true'
with:
just-command: genesis-wallets-undeployed-e2e
node-image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
build-indexer-images:
if: (github.event_name == 'pull_request' && github.event.pull_request.merged == false) || github.event_name == 'merge_group'
runs-on: ubuntu-latest
permissions:
pull-requests: write
packages: read
contents: write
outputs:
indexer_api_image: ${{ steps.image_meta.outputs.indexer_api_image }}
chain_indexer_image: ${{ steps.image_meta.outputs.chain_indexer_image }}
wallet_indexer_image: ${{ steps.image_meta.outputs.wallet_indexer_image }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- name: Login to GHCR
env:
REGISTRY_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
run: echo "$REGISTRY_TOKEN" | docker login ghcr.io -u MidnightCI --password-stdin
- name: Compute content hash and check for existing images
id: image_meta
env:
FORCE_REBUILD: ${{ github.event.inputs.force_rebuild }}
run: |
# Use the indexer submodule's tree hash — indexer images depend on submodule content, not main repo
content_hash=$(git -C indexer rev-parse "HEAD^{tree}" | cut -c1-12)
{
echo "indexer_api_image=ghcr.io/midnight-ntwrk/indexer-api:${content_hash}"
echo "chain_indexer_image=ghcr.io/midnight-ntwrk/chain-indexer:${content_hash}"
echo "wallet_indexer_image=ghcr.io/midnight-ntwrk/wallet-indexer:${content_hash}"
echo "content_hash=${content_hash}"
} >> "$GITHUB_OUTPUT"
if [ "$FORCE_REBUILD" = "true" ]; then
echo "skip_build=false" >> "$GITHUB_OUTPUT"
exit 0
fi
API_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/indexer-api:${content_hash}" > /dev/null 2>&1 && echo true || echo false)
CHAIN_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/chain-indexer:${content_hash}" > /dev/null 2>&1 && echo true || echo false)
WALLET_EXISTS=$(docker manifest inspect "ghcr.io/midnight-ntwrk/wallet-indexer:${content_hash}" > /dev/null 2>&1 && echo true || echo false)
if [ "$API_EXISTS" = "true" ] && [ "$CHAIN_EXISTS" = "true" ] && [ "$WALLET_EXISTS" = "true" ]; then
echo "skip_build=true" >> "$GITHUB_OUTPUT"
echo "Indexer images already exist for ${content_hash}, skipping build and tests"
else
echo "skip_build=false" >> "$GITHUB_OUTPUT"
fi
- name: Free disk space
if: steps.image_meta.outputs.skip_build != 'true' && runner.environment != 'self-hosted'
run: scripts/free-disk-space.sh
- name: Install just
if: steps.image_meta.outputs.skip_build != 'true'
uses: taiki-e/install-action@6ed6112eb9893c58dd600eebccdf6e77ab7bfa9c #v2.79.12
with:
tool: just
- name: Build indexer images
if: steps.image_meta.outputs.skip_build != 'true'
env:
REGISTRY_TOKEN: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
run: |
mkdir -p "$HOME/.cargo"
echo "[net]" >> "$HOME/.cargo/config"
echo "git-fetch-with-cli = true" >> "$HOME/.cargo/config"
# Force AMD64 architecture for all builds
export DOCKER_DEFAULT_PLATFORM=linux/amd64
export DOCKER_BUILDKIT=1
export BUILDX_PLATFORM=linux/amd64
cd indexer || exit 1
. .envrc
DOCKER_DEFAULT_PLATFORM=linux/amd64 just build-docker-image indexer-api
DOCKER_DEFAULT_PLATFORM=linux/amd64 just build-docker-image chain-indexer
DOCKER_DEFAULT_PLATFORM=linux/amd64 just build-docker-image wallet-indexer
# Retag with submodule's content hash
CONTENT_HASH="${{ steps.image_meta.outputs.content_hash }}"
SUBMODULE_COMMIT=$(git rev-parse --short=8 HEAD)
docker tag "midnightntwrk/indexer-api:${SUBMODULE_COMMIT}" "ghcr.io/midnight-ntwrk/indexer-api:${CONTENT_HASH}"
docker tag "midnightntwrk/chain-indexer:${SUBMODULE_COMMIT}" "ghcr.io/midnight-ntwrk/chain-indexer:${CONTENT_HASH}"
docker tag "midnightntwrk/wallet-indexer:${SUBMODULE_COMMIT}" "ghcr.io/midnight-ntwrk/wallet-indexer:${CONTENT_HASH}"
docker push "ghcr.io/midnight-ntwrk/indexer-api:${CONTENT_HASH}"
docker push "ghcr.io/midnight-ntwrk/chain-indexer:${CONTENT_HASH}"
docker push "ghcr.io/midnight-ntwrk/wallet-indexer:${CONTENT_HASH}"
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 #v2.9.1
if: steps.image_meta.outputs.skip_build != 'true'
- name: Configure git for private repos
if: steps.image_meta.outputs.skip_build != 'true'
run: |
git config --global url."https://${GH_PAT}:x-oauth-basic@github.com/".insteadOf "https://github.com/"
env:
GH_PAT: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- name: Install cargo-nextest
if: steps.image_meta.outputs.skip_build != 'true'
run: |
cargo install cargo-nextest@0.9.128 --locked
- name: just test
if: steps.image_meta.outputs.skip_build != 'true'
env:
APP__INFRA__SECRET: ${{ secrets.APP__INFRA__SECRET }}
run: |
. ./.envrc
git config --global url."https://@github.com".insteadOf "ssh://git@github.com"
cd indexer || exit 1
just feature=standalone test
local-environment-tests:
name: Local Environment Tests
if: (github.event_name == 'pull_request' && github.event.pull_request.merged == false) || github.event_name == 'merge_group'
needs: [run, build-indexer-images]
runs-on: [self-hosted, "tier:medium"]
# No concurrency group: the local-env stack now runs INSIDE earthly's nested dockerd
# (+local-env-ci), which gives each invocation its own network namespace. The stack
# no longer binds fixed host ports (1442/1337/8088/4222/5432/30000/32000/9933-9944),
# so concurrent PRs on the same self-hosted host can't collide — the repo-wide
# `local-environment-tests-self-hosted` serialization is gone. Concurrency is now
# RAM-bounded (the shared buildkit/RAM pool), which earthly queues, not hard-serialized.
permissions:
pull-requests: write
packages: read
contents: write
actions: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
submodules: true
- id: guard
uses: ./.github/actions/tree-cache-guard
# Isolate docker config per runner slot — see the matching step in the
# `run` job. Now that this job runs concurrently (no serialization), per-slot
# isolation matters MORE: multiple instances log into GHCR at once and would
# otherwise clobber the shared ~/.docker. Inherited by the composite action's
# docker login and earthly --pull.
- name: Isolate docker config (self-hosted shared HOME)
if: steps.guard.outputs.hit != 'true'
run: |
mkdir -p "$RUNNER_TEMP/.docker"
echo "DOCKER_CONFIG=$RUNNER_TEMP/.docker" >> "$GITHUB_ENV"
- name: Deploy and test against local environment
if: steps.guard.outputs.hit != 'true'
uses: ./.github/actions/local-environment-tests
with:
tag: CI
image: ghcr.io/midnight-ntwrk/midnight-node:${{ needs.run.outputs.node_image_tag }}
toolkit-image: ghcr.io/midnight-ntwrk/midnight-node-toolkit:${{ needs.run.outputs.toolkit_image_tag }}
indexer-api-image: ${{ needs.build-indexer-images.outputs.indexer_api_image }}
chain-indexer-image: ${{ needs.build-indexer-images.outputs.chain_indexer_image }}
wallet-indexer-image: ${{ needs.build-indexer-images.outputs.wallet_indexer_image }}
indexer-tag: unused
sha: ${{ needs.run.outputs.sha }}
tests: premerge
ghcr-password: ${{ secrets.MIDNIGHTCI_PACKAGES_WRITE }}
- uses: ./.github/actions/tree-cache-guard/save
if: steps.guard.outputs.hit != 'true'
with:
key: ${{ steps.guard.outputs.key }}
# ephemeral-environment-tests:
# if: (github.event_name == 'pull_request' && github.event.pull_request.merged == false) || github.event_name == 'merge_group'
# # needs:
# # - hardfork-e2e
# # - ledger-rollback-e2e
# # - tx-generator-e2e
# # - startup-dev-e2e
# # - genesis-undeployed-e2e
#
# runs-on: ubuntu-latest
# permissions:
# id-token: write
# contents: read
# steps:
# - name: Checkout
# uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
#
# - name: Get Version and git commit
# id: meta
# run: |
# echo "short_hash=$(git rev-parse --short=8 HEAD)" >> "$GITHUB_OUTPUT"
# version=$(grep -m 1 '^version =' node/Cargo.toml | cut -d '"' -f2)
# echo "Get Version and git commit"
# echo "version=$version" >> "$GITHUB_OUTPUT"
#
# - name: Configure AWS credentials
# id: aws-credentials
# uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
# with:
# role-to-assume: arn:aws:iam::596662952274:role/MidnightGithubActionsAdminRole
# aws-region: eu-west-1
# role-duration-seconds: 3600
#
# - name: Pull Kubeconfig and Set Locally
# run: |
# aws eks update-kubeconfig \
# --name k0-eks-platform-dev-eu-01 \
# --region eu-west-1 \
# shell: bash
#
# # - name: Deploy and test ephemeral environment
# # uses: ./.github/actions/ephemeral-environment-tests
# # with:
# # sha: ${{ github.sha }}
# # image: ghcr.io/midnight-ntwrk/midnight-node:0.12.1
# # tag: ${{ github.ref_name }}
# # ghcr-password: ${{ secrets.MIDNIGHTBOT_PACKAGES_WRITE }}
# # aws-role-arn: ${{ secrets.AWS_ROLE_ARN }}
# # aws-region: ${{ secrets.AWS_REGION }}
# # aws-eks-cluster-name: ${{ secrets.AWS_EKS_CLUSTER_NAME }}
# # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}