ci: return of the chef #7843
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 + 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 }} |