diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52575ccc1f0..fabb93ea4fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,9 @@ env: GIT_BRANCH: ${{ github.head_ref || github.ref_name }} GIT_REPO_OWNER: ${{ github.repository_owner }} GIT_REPO: ${{ github.repository }} + GIT_REPO_NAME: ${{ github.event.repository.name }} AWS_ROLE_ARN: arn:aws:iam::024848458133:role/github_oidc_FuelLabs_fuel-core - AWS_ECR_ORG: q2z3y3a7 + AWS_ECR_ORG: fuellabs CARGO_TERM_COLOR: always RUST_VERSION: 1.79.0 RUST_VERSION_FMT: nightly-2023-10-29 @@ -40,7 +41,7 @@ jobs: rustfmt: runs-on: buildjet-4vcpu-ubuntu-2204 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install latest nightly uses: dtolnay/rust-toolchain@master with: @@ -53,7 +54,7 @@ jobs: lint-toml-files: runs-on: buildjet-4vcpu-ubuntu-2204 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.RUST_VERSION }} @@ -85,7 +86,7 @@ jobs: prevent-openssl: runs-on: buildjet-4vcpu-ubuntu-2204 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # ensure openssl hasn't crept into the dep tree - name: Check if openssl is included run: ./.github/workflows/scripts/verify_openssl.sh @@ -156,7 +157,7 @@ jobs: timeout-minutes: 45 continue-on-error: ${{ matrix.skip-error || false }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.RUST_VERSION }} @@ -183,11 +184,12 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} slack_webhook: ${{ secrets.SLACK_WEBHOOK_NOTIFY_BUILD }} + publish-crates-check: runs-on: buildjet-4vcpu-ubuntu-2204 steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.RUST_VERSION }} @@ -202,7 +204,6 @@ jobs: cargo-test-kms: if: github.event.repository.fork == false needs: - - cargo-verifications - rustfmt - check-changelog runs-on: buildjet-4vcpu-ubuntu-2204 @@ -219,7 +220,7 @@ jobs: with: role-to-assume: arn:aws:iam::249945542445:role/github_oidc_FuelLabs_fuel-core aws-region: us-east-1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.RUST_VERSION }} @@ -244,7 +245,7 @@ jobs: permissions: # Write access to push changes to pages contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: @@ -258,7 +259,7 @@ jobs: run: cargo +${{ env.RUST_VERSION_COV }} llvm-cov --all-features --html --branch - name: Checkout the repo again for pushing pages revision - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: 'codecov-pages' path: 'pages-branch' @@ -282,18 +283,20 @@ jobs: needs: - cargo-verifications - publish-crates-check - runs-on: buildjet-4vcpu-ubuntu-2204 + - build-docker-images + - cargo-test-kms + runs-on: ubuntu-latest steps: - run: echo "pass" verify-tag-version: # Only do this job if publishing a release if: github.event_name == 'release' && github.event.action == 'published' - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Verify tag version run: | @@ -312,7 +315,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install toolchain uses: dtolnay/rust-toolchain@master @@ -332,17 +335,127 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} slack_webhook: ${{ secrets.SLACK_WEBHOOK_NOTIFY_BUILD }} + build-docker-images: + needs: + - publish-crates-check + strategy: + matrix: + arch: [ + # build on native runners instead of using emulation + {platform: linux/amd64, runner: buildjet-8vcpu-ubuntu-2204}, + {platform: linux/arm64, runner: buildjet-16vcpu-ubuntu-2204-arm} + ] + runs-on: ${{ matrix.arch.runner }} + permissions: + contents: read + packages: write + steps: + - name: Setup environment + run: | + echo "REGISTRY_URL=${REGISTRY@L}/${GIT_REPO@L}" >>${GITHUB_ENV} + platform=${{ matrix.arch.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the ghcr.io registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to the docker.io registry + uses: docker/login-action@v3 + with: + username: fuellabs + password: ${{ secrets.DOCKER_IO_READ_ONLY_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_URL }} + + - name: Setup Rust build cache + id: cache + uses: buildjet/cache@v3 + with: + path: | + home-cargo-bin + home-cargo-registry-index + home-cargo-registry-cache + home-cargo-git-db + target + key: ${{ env.PLATFORM_PAIR }}-${{ hashFiles('**/Cargo.lock') }} + + - name: Inject cache into docker + uses: reproducible-containers/buildkit-cache-dance@v3.1.2 + with: + cache-map: | + { + "home-cargo-bin": "/usr/local/cargo/bin", + "home-cargo-registry-index": "/usr/local/cargo/registry/index", + "home-cargo-registry-cache": "/usr/local/cargo/registry/cache", + "home-cargo-git-db": "/usr/local/cargo/git/db", + "target": "/build/target" + } + skip-extraction: ${{ steps.cache.outputs.cache-hit }} + + - name: Build Docker image + id: build + uses: docker/build-push-action@v6 + with: + context: . + platforms: ${{ matrix.arch.platform }} + file: deployment/Dockerfile + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache:latest-${{ matrix.arch.runner }} + cache-to: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache:latest-${{ matrix.arch.runner }},mode=max,image-manifest=true,oci-mediatypes=true + outputs: | + type=image,name=${{ env.REGISTRY_URL }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + publish-docker-image: needs: + - build-docker-images - verifications-complete - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Setup environment + run: | + echo "REGISTRY_URL=${REGISTRY@L}/${GIT_REPO@L}" >>${GITHUB_ENV} + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Configure AWS credentials for ECR publishing uses: aws-actions/configure-aws-credentials@v4 @@ -356,49 +469,43 @@ jobs: with: registry-type: public - - name: Docker meta - id: meta - uses: docker/metadata-action@v3 - with: - images: | - ghcr.io/fuellabs/fuel-core - ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/fuel-core - tags: | - type=sha - type=ref,event=branch - type=ref,event=tag - type=semver,pattern={{raw}} - type=raw,value=sha-{{sha}}-{{date 'YYYYMMDDhhmmss'}} - flavor: | - latest=${{ github.ref == 'refs/heads/master' }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Log in to the ghcr.io registry - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Log in to the docker.io registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: fuellabs password: ${{ secrets.DOCKER_IO_READ_ONLY_TOKEN }} - - name: Build and push the image to ghcr.io - uses: docker/build-push-action@v4 + - name: Docker metadata + id: meta + uses: docker/metadata-action@v5 with: - context: . - platforms: linux/amd64,linux/arm64 - file: deployment/Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=registry,ref=ghcr.io/fuellabs/fuel-core-build-cache:latest - cache-to: type=registry,ref=ghcr.io/fuellabs/fuel-core-build-cache:latest,mode=max + images: | + ${{ env.REGISTRY_URL }} + ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/${{ env.GIT_REPO_NAME }} + tags: | + type=sha + type=ref,event=branch + type=ref,event=tag + type=semver,pattern={{raw}} + type=raw,value=sha-{{sha}}-{{date 'YYYYMMDDhhmmss'}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Create manifest list and push to all registries + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY_URL }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY_URL }}:${{ steps.meta.outputs.version }} # duplicate of publish-docker-image, but with profiling features enabled # this is split into a separate action since it takes longer to build @@ -411,8 +518,15 @@ jobs: packages: write id-token: write steps: + - name: Setup environment + run: | + echo "REGISTRY_URL=${REGISTRY@L}/${GIT_REPO@L}" >>${GITHUB_ENV} + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Configure AWS credentials for ECR publishing uses: aws-actions/configure-aws-credentials@v4 @@ -426,34 +540,62 @@ jobs: with: registry-type: public + - name: Log in to the ghcr.io registry + uses: docker/login-action@v1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to the docker.io registry + uses: docker/login-action@v2 + with: + username: fuellabs + password: ${{ secrets.DOCKER_IO_READ_ONLY_TOKEN }} + - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v5 with: images: | - ghcr.io/fuellabs/fuel-core-debug - ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/fuel-core-debug + ${{ env.REGISTRY_URL }}-debug + ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/${{ env.GIT_REPO_NAME }}-debug tags: | type=sha type=ref,event=branch type=ref,event=tag type=semver,pattern={{raw}} type=raw,value=sha-{{sha}}-{{date 'YYYYMMDDhhmmss'}} - flavor: | - latest=${{ github.ref == 'refs/heads/master' }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + type=raw,value=latest,enable={{is_default_branch}} - - name: Log in to the ghcr.io registry - uses: docker/login-action@v1 + - name: Setup Rust build cache + id: cache + uses: buildjet/cache@v3 with: - registry: ${{ env.REGISTRY }} - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push the image to ghcr.io - uses: docker/build-push-action@v2 + path: | + home-cargo-bin + home-cargo-registry-index + home-cargo-registry-cache + home-cargo-git-db + target + key: publish-docker-image-profiling-${{ hashFiles('**/Cargo.lock') }} + + - name: Inject cache into docker + uses: reproducible-containers/buildkit-cache-dance@v3.1.2 + with: + cache-map: | + { + "home-cargo-bin": "/usr/local/cargo/bin", + "home-cargo-registry-index": "/usr/local/cargo/registry/index", + "home-cargo-registry-cache": "/usr/local/cargo/registry/cache", + "home-cargo-git-db": "/usr/local/cargo/git/db", + "target": "/build/target" + } + skip-extraction: ${{ steps.cache.outputs.cache-hit }} + + - name: Build & push Docker image + id: build + uses: docker/build-push-action@v6 with: context: . file: deployment/Dockerfile @@ -461,8 +603,8 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=registry,ref=ghcr.io/fuellabs/fuel-core-debug-build-cache:latest - cache-to: type=registry,ref=ghcr.io/fuellabs/fuel-core-debug-build-cache:latest,mode=max + cache-from: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache-debug:latest + cache-to: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache-debug:latest,mode=max,image-manifest=true,oci-mediatypes=true - uses: FuelLabs/.github/.github/actions/slack-notify-template@master if: always() && (github.ref == 'refs/heads/master' || github.ref_type == 'tag') @@ -479,8 +621,15 @@ jobs: packages: write id-token: write steps: + - name: Setup environment + run: | + echo "REGISTRY_URL=${REGISTRY@L}/${GIT_REPO@L}" >>${GITHUB_ENV} + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Configure AWS credentials for ECR publishing uses: aws-actions/configure-aws-credentials@v4 @@ -494,25 +643,6 @@ jobs: with: registry-type: public - - name: Docker meta - id: meta - uses: docker/metadata-action@v3 - with: - images: | - ghcr.io/fuellabs/fuel-core-e2e-client - ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/fuel-core-e2e-client - tags: | - type=sha - type=ref,event=branch - type=ref,event=tag - type=semver,pattern={{raw}} - type=raw,value=sha-{{sha}}-{{date 'YYYYMMDDhhmmss'}} - flavor: | - latest=${{ github.ref == 'refs/heads/master' }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Log in to the ghcr.io registry uses: docker/login-action@v1 with: @@ -526,16 +656,57 @@ jobs: username: fuellabs password: ${{ secrets.DOCKER_IO_READ_ONLY_TOKEN }} - - name: Build and push the image to ghcr.io - uses: docker/build-push-action@v2 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.REGISTRY_URL }}-e2e-client + ${{ steps.login-ecr-public.outputs.registry }}/${{ env.AWS_ECR_ORG }}/${{ env.GIT_REPO_NAME }}-e2e-client + tags: | + type=sha + type=ref,event=branch + type=ref,event=tag + type=semver,pattern={{raw}} + type=raw,value=sha-{{sha}}-{{date 'YYYYMMDDhhmmss'}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Setup Rust build cache + id: cache + uses: buildjet/cache@v3 + with: + path: | + home-cargo-bin + home-cargo-registry-index + home-cargo-registry-cache + home-cargo-git-db + target + key: publish-e2e-client-docker-image-${{ hashFiles('**/Cargo.lock') }} + + - name: Inject cache into docker + uses: reproducible-containers/buildkit-cache-dance@v3.1.2 + with: + cache-map: | + { + "home-cargo-bin": "/usr/local/cargo/bin", + "home-cargo-registry-index": "/usr/local/cargo/registry/index", + "home-cargo-registry-cache": "/usr/local/cargo/registry/cache", + "home-cargo-git-db": "/usr/local/cargo/git/db", + "target": "/build/target" + } + skip-extraction: ${{ steps.cache.outputs.cache-hit }} + + - name: Build & push Docker image + id: build + uses: docker/build-push-action@v6 with: context: . file: deployment/e2e-client.Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=registry,ref=ghcr.io/fuellabs/fuel-core-e2e-build-cache:latest - cache-to: type=registry,ref=ghcr.io/fuellabs/fuel-core-e2e-build-cache:latest,mode=max + cache-from: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache-e2e:latest + cache-to: type=registry,ref=${{ env.REGISTRY_URL }}-build-cache-e2e:latest,mode=max,image-manifest=true,oci-mediatypes=true - uses: FuelLabs/.github/.github/actions/slack-notify-template@master if: always() && (github.ref == 'refs/heads/master' || github.ref_type == 'tag') @@ -572,7 +743,7 @@ jobs: target: aarch64-apple-darwin steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Docker Buildx if: matrix.job.cross_image @@ -721,7 +892,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/deployment/Dockerfile b/deployment/Dockerfile index 262c95b4b66..4a9c7219af3 100644 --- a/deployment/Dockerfile +++ b/deployment/Dockerfile @@ -36,17 +36,28 @@ COPY --from=planner /build/recipe.json recipe.json RUN echo $CARGO_PROFILE_RELEASE_DEBUG RUN echo $BUILD_FEATURES # Build our project dependencies, not our application! -RUN xx-cargo chef cook --release --no-default-features --features "${BUILD_FEATURES}" -p fuel-core-bin --recipe-path recipe.json +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo chef cook --release --no-default-features --features "${BUILD_FEATURES}" -p fuel-core-bin --recipe-path recipe.json # Up to this point, if our dependency tree stays the same, # all layers should be cached. COPY . . # download latest chain-configuration repo after cache to ensure most recent version RUN git clone --depth=1 https://github.com/FuelLabs/chain-configuration.git /chain-config # build application -RUN xx-cargo build --release --no-default-features --features "$BUILD_FEATURES" -p fuel-core-bin \ +# note this puts the builds outside of the cache dirs so the run image can copy them +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + xx-cargo build --release --no-default-features --features "$BUILD_FEATURES" -p fuel-core-bin \ && xx-verify ./target/$(xx-cargo --print-target-triple)/release/fuel-core \ - && mv ./target/$(xx-cargo --print-target-triple)/release/fuel-core ./target/release/fuel-core \ - && mv ./target/$(xx-cargo --print-target-triple)/release/fuel-core.d ./target/release/fuel-core.d + && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-core /root/fuel-core \ + && cp ./target/$(xx-cargo --print-target-triple)/release/fuel-core.d /root/fuel-core.d # Stage 2: Run FROM ubuntu:22.04 AS run @@ -69,8 +80,8 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /build/target/release/fuel-core . -COPY --from=builder /build/target/release/fuel-core.d . +COPY --from=builder /root/fuel-core . +COPY --from=builder /root/fuel-core.d . COPY --from=builder /chain-config ./config EXPOSE ${PORT} diff --git a/deployment/e2e-client.Dockerfile b/deployment/e2e-client.Dockerfile index 5f07ea2e089..b6b7be89842 100644 --- a/deployment/e2e-client.Dockerfile +++ b/deployment/e2e-client.Dockerfile @@ -16,12 +16,25 @@ RUN cargo chef prepare --recipe-path recipe.json FROM chef as builder ENV CARGO_NET_GIT_FETCH_WITH_CLI=true COPY --from=planner /build/recipe.json recipe.json + # Build our project dependencies, not our application! -RUN cargo chef cook --release -p fuel-core-e2e-client --recipe-path recipe.json +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + cargo chef cook --release -p fuel-core-e2e-client --recipe-path recipe.json # Up to this point, if our dependency tree stays the same, # all layers should be cached. COPY . . -RUN cargo build --release -p fuel-core-e2e-client +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/build/target \ + cargo build --release -p fuel-core-e2e-client \ + && cp ./target/release/fuel-core-e2e-client /root/fuel-core-e2e-client \ + && cp ./target/release/fuel-core-e2e-client.d /root/fuel-core-e2e-client.d # Stage 2: Run FROM ubuntu:22.04 as run @@ -35,7 +48,7 @@ RUN apt-get update -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /build/target/release/fuel-core-e2e-client . -COPY --from=builder /build/target/release/fuel-core-e2e-client.d . +COPY --from=builder /root/fuel-core-e2e-client . +COPY --from=builder /root/fuel-core-e2e-client.d . CMD exec ./fuel-core-e2e-client