diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ac64d1ae95a..70b0393270e2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -482,37 +482,6 @@ jobs: # For old e2e tests see yarn-project/end-to-end/Earthfile # Semantics are similar to Dockerfile - # NOTE: Unlike other e2e, these will be re-enabled here as currently the logs functionality is not in the new earthfile setup - bench-publish-rollup: - steps: - - *checkout - - *setup_env - - run: - name: "Benchmark" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_publish_rollup.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - bench-process-history: - steps: - - *checkout - - *setup_env - - run: - name: "Benchmark" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_process_history.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - bench-tx-size: - steps: - - *checkout - - *setup_env - - run: - name: "Benchmark" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_tx_size_fees.test.ts ENABLE_GAS=1 DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - e2e-join: docker: - image: cimg/base:2023.09 @@ -531,16 +500,6 @@ jobs: name: "Noop" command: echo Noop - bench-summary: - machine: - image: default - steps: - - *checkout - - *setup_env - - run: - name: "Assemble benchmark summary from uploaded logs" - command: ./scripts/ci/assemble_e2e_benchmark.sh - # Deploy & release jobs. deploy-and-release: machine: @@ -775,16 +734,5 @@ workflows: - e2e-join <<: *defaults - # Benchmark jobs. - - bench-publish-rollup: *e2e_test - - bench-process-history: *e2e_test - - bench-tx-size: *e2e_test - - bench-summary: - requires: - - bench-publish-rollup - - bench-process-history - - bench-tx-size - <<: *defaults - # Production releases. - deploy-and-release: *defaults_deploy diff --git a/.github/ci-setup-action/action.yml b/.github/ci-setup-action/action.yml index 4b1d7da6dbbd..f5d8029f6561 100644 --- a/.github/ci-setup-action/action.yml +++ b/.github/ci-setup-action/action.yml @@ -1,14 +1,14 @@ # Reusable setup workflow for CI tasks name: Setup Workflow -description: 'Reusable setup steps' +description: "Reusable setup steps" inputs: dockerhub_password: required: true - description: 'DockerHub Password' + description: "DockerHub Password" concurrency_key: required: false - description: 'Concurrency key for locking jobs' + description: "Concurrency key for locking jobs" runs: # define an action, runs in OS of caller using: composite @@ -43,11 +43,14 @@ runs: with: # permission issue with spot runners, simpler to leave out use-cache: false - version: 'v0.8.5' + version: "v0.8.5" - name: Setup Env shell: bash run: ./scripts/setup_env.sh ${{ inputs.dockerhub_password }} + env: + PULL_REQUEST: "${{ github.event.pull_request.number }}" + BRANCH: "${{ github.ref_name }}" # As detailed in https://github.com/ben-z/gh-action-mutex # things do not become 'pending' in github actions, and instead just cancel one another diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f2d4ab8783d..586902b443b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,10 +11,12 @@ on: runner_action: description: "The action to take with the self-hosted runner (start, stop, restart)." required: false + concurrency: # force parallelism in master group: ci-${{ github.ref_name == 'master' && github.run_id || github.ref_name }} cancel-in-progress: true + jobs: setup: uses: ./.github/workflows/setup-runner.yml @@ -64,10 +66,8 @@ jobs: matrix: test: ${{ fromJson( needs.build.outputs.e2e_list )}} steps: - - { - uses: actions/checkout@v4, - with: { ref: "${{ github.event.pull_request.head.sha }}" }, - } + - uses: actions/checkout@v4 + with: { ref: "${{ github.event.pull_request.head.sha }}" } - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" @@ -76,10 +76,35 @@ jobs: - name: Test working-directory: ./yarn-project/end-to-end/ timeout-minutes: 25 - run: earthly-ci -P --no-output +${{ matrix.test }} --e2e_mode=cache - # TODO - # - name: Upload logs - # run: BRANCH=${{ github.ref_name }} PULL_REQUEST=${{ github.event.number }} scripts/ci/upload_logs_to_s3 ./yarn-project/end-to-end/log + run: earthly-ci -P --secret AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} --secret AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} --no-output +${{ matrix.test }} --e2e_mode=cache + + bench-summary: + needs: e2e + runs-on: ${{ inputs.username || github.actor }}-x86 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 100 # Downloading base benchmark from master requires access to history + ref: "${{ github.event.pull_request.head.sha }}" + - uses: ./.github/ci-setup-action + with: + dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" + concurrency_key: build-${{ inputs.username || github.actor }}-x86 + - name: "Build and upload bench aggregate file" + working-directory: ./yarn-project/scripts + run: earthly-ci -P --secret AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} --secret AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} +bench-aggregate + - name: "Download base benchmark" + if: ${{ github.event_name == 'pull_request' }} + run: scripts/logs/download_base_benchmark_from_s3.sh + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + BENCH_FOLDER: ./yarn-project/scripts/bench + PULL_REQUEST: "${{ github.event.pull_request.number }}" + - name: "Generate summary comment if pull request" + if: ${{ github.event_name == 'pull_request' }} + working-directory: ./yarn-project/scripts + run: earthly-ci -P --secret AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} --secret AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} --secret AZTEC_BOT_COMMENTER_GITHUB_TOKEN=${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} +bench-comment # barretenberg (prover) native and AVM (public VM) tests # only ran on x86 for resource reasons (memory intensive) diff --git a/.gitignore b/.gitignore index fcee2d1838e1..8e28a8bac2f9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ cmake-build-debug .DS_Store **/*.dockerignore + +# Earthly +.arg +.secret diff --git a/Earthfile b/Earthfile index 65abde37745a..096ac3bac0df 100644 --- a/Earthfile +++ b/Earthfile @@ -32,3 +32,9 @@ bench: release-meta: COPY .release-please-manifest.json /usr/src/.release-please-manifest.json SAVE ARTIFACT /usr/src /usr/src + +scripts: + FROM ubuntu:lunar + RUN apt-get update && apt-get install -y awscli + COPY scripts /usr/src/scripts + SAVE ARTIFACT /usr/src/scripts scripts \ No newline at end of file diff --git a/scripts/ci/assemble_e2e_benchmark.sh b/scripts/ci/assemble_e2e_benchmark.sh deleted file mode 100755 index 90291ffa8b8e..000000000000 --- a/scripts/ci/assemble_e2e_benchmark.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash -# Grabs the log files uploaded in build-system/scripts/upload_logs_to_s3 -# that contain representative benchmarks, extracts whatever metrics are interesting, -# and assembles a single file that shows the current state of the repository. - -[ -n "${BUILD_SYSTEM_DEBUG:-}" ] && set -x # conditionally trace -set -eu - -BUCKET_NAME="aztec-ci-artifacts" -LOG_FOLDER="${LOG_FOLDER:-log}" -BENCH_FOLDER="${BENCH_FOLDER:-bench}" -COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" -BASE_BENCH_PATH="" -BENCHMARK_FILE_JSON="${BENCH_FOLDER}/benchmark.json" -BASE_BENCHMARK_FILE_JSON="${BENCH_FOLDER}/base-benchmark.json" - -# Paths from build-system/scripts/upload_logs_to_s3 -if [ "${CIRCLE_BRANCH:-}" = "master" ]; then - LOG_SOURCE_FOLDER="logs-v1/master/$COMMIT_HASH" - BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/master/$COMMIT_HASH" - BENCHMARK_TARGET_FILE="benchmarks-v1/master/$COMMIT_HASH.json" - BENCHMARK_LATEST_FILE="benchmarks-v1/latest.json" -elif [ -n "${CIRCLE_PULL_REQUEST:-}" ]; then - LOG_SOURCE_FOLDER="logs-v1/pulls/${CIRCLE_PULL_REQUEST##*/}" - BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/pulls/${CIRCLE_PULL_REQUEST##*/}" - BENCHMARK_TARGET_FILE="benchmarks-v1/pulls/${CIRCLE_PULL_REQUEST##*/}.json" -elif [ -n "${CIRCLE_TAG:-}" ]; then - echo "Skipping benchmark run for ${CIRCLE_TAG} tagged release." - exit 0 -else - echo "Skipping benchmark run on branch ${CIRCLE_BRANCH:-unknown}." - exit 0 -fi - -# Download benchmark log files from S3 LOG_SOURCE_FOLDER into local LOG_FOLDER -mkdir -p $LOG_FOLDER -aws s3 cp "s3://${BUCKET_NAME}/${LOG_SOURCE_FOLDER}/" $LOG_FOLDER --exclude '*' --include 'bench*.jsonl' --recursive - -# Only generate the aggregated benchmark if we've managed to retrieve all the needed log files -# If these runs were skipped due to no changes in their rebuild-patterns, then there's no need -# to recompute the aggregated benchmark. Note that if one benchmark did run but others didn't, -# this skips the whole aggregation. For now, that's fine because all benchmark files have the -# same rebuild pattern rules. But if that changes, then we'd need to go up in the commit history -# to find the latest log files for the unchanged benchmarks. -EXPECTED_LOGS_COUNT=$(find yarn-project/end-to-end/src -type f -name "bench*.test.ts" | wc -l) -DOWNLOADED_LOGS_COUNT=$(find $LOG_FOLDER -type f -name "*.jsonl" | wc -l) -if [ "$DOWNLOADED_LOGS_COUNT" -lt "$EXPECTED_LOGS_COUNT" ]; then - echo Found $DOWNLOADED_LOGS_COUNT out of $EXPECTED_LOGS_COUNT benchmark log files in s3://${BUCKET_NAME}/${LOG_SOURCE_FOLDER}/. Exiting. - exit 0 -fi - -# Download barretenberg log files, these are direct benchmarks and separate from the above -aws s3 cp "s3://${BUCKET_NAME}/${BARRETENBERG_BENCH_SOURCE_FOLDER}/" $LOG_FOLDER --exclude '*' --include '*_bench.json' --recursive - -# Generate the aggregated benchmark file -mkdir -p $BENCH_FOLDER -CONTAINER_BENCH_FOLDER="/usr/src/yarn-project/bench" -CONTAINER_LOG_FOLDER="/usr/src/yarn-project/log" -export DOCKER_RUN_OPTS="\ - -v $(realpath $BENCH_FOLDER):${CONTAINER_BENCH_FOLDER}:rw \ - -e BENCH_FOLDER=${CONTAINER_BENCH_FOLDER} \ - -v $(realpath $LOG_FOLDER):${CONTAINER_LOG_FOLDER}:rw \ - -e LOG_FOLDER=${CONTAINER_LOG_FOLDER} \ - -e BASE_BENCH_PATH \ - -e AZTEC_BOT_COMMENTER_GITHUB_TOKEN \ - -e CIRCLE_PULL_REQUEST" -yarn-project/scripts/run_script.sh workspace @aztec/scripts bench-aggregate -echo "generated: $BENCHMARK_FILE_JSON" - -# Upload it to master or pulls -aws s3 cp $BENCHMARK_FILE_JSON "s3://${BUCKET_NAME}/${BENCHMARK_TARGET_FILE}" - -# If on master, also update the "latest" benchmark file -if [ -n "${BENCHMARK_LATEST_FILE:-}" ]; then - aws s3 cp $BENCHMARK_FILE_JSON "s3://${BUCKET_NAME}/${BENCHMARK_LATEST_FILE}" -fi - -# If on a pull request, get the data from the most recent commit on master where it's available, -# generate a markdown comment, and post it on the pull request -if [ -n "${CIRCLE_PULL_REQUEST:-}" ]; then - MASTER_COMMIT_HASH=$(curl -s "https://api.github.com/repos/AztecProtocol/aztec-packages/pulls/${CIRCLE_PULL_REQUEST##*/}" | jq -r '.base.sha') - MASTER_COMMIT_HASHES=($(git log $MASTER_COMMIT_HASH --format="%H" -n 50)) - - set +e - echo "Searching for base benchmark data starting from commit $MASTER_COMMIT_HASH" - for commit_hash in "${MASTER_COMMIT_HASHES[@]}"; do - aws s3 cp "s3://${BUCKET_NAME}/benchmarks-v1/master/$commit_hash.json" $BASE_BENCHMARK_FILE_JSON - if [ $? -eq 0 ]; then - echo "Downloaded base data from commit $commit_hash" - export BASE_BENCH_PATH=master/$commit_hash - break; - fi - done - set -e - - if [ -z "${BASE_BENCH_PATH:-}" ]; then - echo "No base commit data found" - fi - - (yarn-project/scripts/run_script.sh workspace @aztec/scripts bench-comment && echo "commented on pr $CIRCLE_PULL_REQUEST") || echo "failed commenting on pr" -fi diff --git a/scripts/logs/check_logs_for_benchmark.sh b/scripts/logs/check_logs_for_benchmark.sh new file mode 100755 index 000000000000..69075d4160de --- /dev/null +++ b/scripts/logs/check_logs_for_benchmark.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Checks that all logs needed for assembling aggregate benchmarks have been retrieved. + +[ -n "${BUILD_SYSTEM_DEBUG:-}" ] && set -x # conditionally trace +set -eu + +LOG_FOLDER="${LOG_FOLDER:-log}" +E2E_SRC_FOLDER=/usr/src/yarn-project/end-to-end/src + +echo "Checking log files in $LOG_FOLDER" + +# Only generate the aggregated benchmark if we've managed to retrieve all the needed log files +# If these runs were skipped due to no changes in their rebuild-patterns, then there's no need +# to recompute the aggregated benchmark. Note that if one benchmark did run but others didn't, +# this skips the whole aggregation. For now, that's fine because all benchmark files have the +# same rebuild pattern rules. But if that changes, then we'd need to go up in the commit history +# to find the latest log files for the unchanged benchmarks. +EXPECTED_LOGS_COUNT=$(find $E2E_SRC_FOLDER -type f -name "bench*.test.ts" | wc -l) +DOWNLOADED_LOGS_COUNT=$(find $LOG_FOLDER -type f -name "*.jsonl" | wc -l) +if [ "$DOWNLOADED_LOGS_COUNT" -lt "$EXPECTED_LOGS_COUNT" ]; then + echo Found only $DOWNLOADED_LOGS_COUNT out of $EXPECTED_LOGS_COUNT benchmark log files in S3. + echo Files found: $(find $LOG_FOLDER -type f -name "*.jsonl") + exit 1 +fi + diff --git a/scripts/logs/download_base_benchmark_from_s3.sh b/scripts/logs/download_base_benchmark_from_s3.sh new file mode 100755 index 000000000000..dfe5d631ab47 --- /dev/null +++ b/scripts/logs/download_base_benchmark_from_s3.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Downloads base benchmarks from S3 to compare with the current benchmarks via bench-comment + +[ -n "${BUILD_SYSTEM_DEBUG:-}" ] && set -x # conditionally trace +set -eu + +BUCKET_NAME="aztec-ci-artifacts" +BENCH_FOLDER="${BENCH_FOLDER:-bench}" +COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" +BASE_BENCHMARK_FILE_JSON="${BENCH_FOLDER}/base-benchmark.json" + +# If on a pull request, get the data from the most recent commit on master where it's available to generate a comment comparing them +if [ -n "${PULL_REQUEST:-}" ]; then + MASTER_COMMIT_HASH=$(curl -s "https://api.github.com/repos/AztecProtocol/aztec-packages/pulls/${PULL_REQUEST##*/}" | jq -r '.base.sha') + MASTER_COMMIT_HASHES=($(git log $MASTER_COMMIT_HASH --format="%H" -n 50)) + + mkdir -p $BENCH_FOLDER + + set +e + echo "Searching for base benchmark data starting from commit $MASTER_COMMIT_HASH" + for commit_hash in "${MASTER_COMMIT_HASHES[@]}"; do + aws s3 cp "s3://${BUCKET_NAME}/benchmarks-v1/master/$commit_hash.json" $BASE_BENCHMARK_FILE_JSON + if [ $? -eq 0 ]; then + echo "Downloaded base data from commit $commit_hash" + exit 0 + fi + done + set -e + + echo "No base commit data found" +else + echo "Not on a pull request, skipping download of base benchmark data" +fi diff --git a/scripts/logs/download_logs_from_s3.sh b/scripts/logs/download_logs_from_s3.sh new file mode 100755 index 000000000000..a31979e3968c --- /dev/null +++ b/scripts/logs/download_logs_from_s3.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Downloads the log files uploaded in upload_logs_to_s3 + +set -eu + +BUCKET_NAME="aztec-ci-artifacts" +LOG_FOLDER="${LOG_FOLDER:-log}" +COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" + +echo "Downloading logs from S3 for commit $COMMIT_HASH in branch ${BRANCH:-} at pull request ${PULL_REQUEST:-none}" + +# Paths from upload_logs_to_s3 +if [ "${BRANCH:-}" = "master" ]; then + LOG_SOURCE_FOLDER="logs-v1/master/$COMMIT_HASH" + BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/master/$COMMIT_HASH" + BENCHMARK_TARGET_FILE="benchmarks-v1/master/$COMMIT_HASH.json" + BENCHMARK_LATEST_FILE="benchmarks-v1/latest.json" +elif [ -n "${PULL_REQUEST:-}" ]; then + LOG_SOURCE_FOLDER="logs-v1/pulls/${PULL_REQUEST##*/}" + BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/pulls/${PULL_REQUEST##*/}" + BENCHMARK_TARGET_FILE="benchmarks-v1/pulls/${PULL_REQUEST##*/}.json" +else + echo "Skipping benchmark run on branch ${BRANCH:-unknown}." + exit 0 +fi + +mkdir -p $LOG_FOLDER + +# Download benchmark log files from S3 LOG_SOURCE_FOLDER into local LOG_FOLDER +echo "Downloading benchmark log files from $BUCKET_NAME/$LOG_SOURCE_FOLDER to $LOG_FOLDER" +aws s3 cp "s3://${BUCKET_NAME}/${LOG_SOURCE_FOLDER}/" $LOG_FOLDER --exclude '*' --include 'bench*.jsonl' --recursive + +# Download barretenberg log files, these are direct benchmarks and separate from the above +aws s3 cp "s3://${BUCKET_NAME}/${BARRETENBERG_BENCH_SOURCE_FOLDER}/" $LOG_FOLDER --exclude '*' --include '*_bench.json' --recursive + +echo "Downloaded log files $(ls $LOG_FOLDER)" \ No newline at end of file diff --git a/scripts/logs/upload_aggregated_benchmarks_to_s3.sh b/scripts/logs/upload_aggregated_benchmarks_to_s3.sh new file mode 100755 index 000000000000..76b00122c89c --- /dev/null +++ b/scripts/logs/upload_aggregated_benchmarks_to_s3.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Uploads aggregated benchmark logs to S3 + +[ -n "${BUILD_SYSTEM_DEBUG:-}" ] && set -x # conditionally trace +set -eu + +BUCKET_NAME="aztec-ci-artifacts" +LOG_FOLDER="${LOG_FOLDER:-log}" +BENCH_FOLDER="${BENCH_FOLDER:-bench}" +COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" +BENCHMARK_FILE_JSON="${BENCH_FOLDER}/benchmark.json" + +# Paths from upload_logs_to_s3 +if [ "${BRANCH:-}" = "master" ]; then + LOG_SOURCE_FOLDER="logs-v1/master/$COMMIT_HASH" + BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/master/$COMMIT_HASH" + BENCHMARK_TARGET_FILE="benchmarks-v1/master/$COMMIT_HASH.json" + BENCHMARK_LATEST_FILE="benchmarks-v1/latest.json" +elif [ -n "${PULL_REQUEST:-}" ]; then + LOG_SOURCE_FOLDER="logs-v1/pulls/${PULL_REQUEST##*/}" + BARRETENBERG_BENCH_SOURCE_FOLDER="barretenberg-bench-v1/pulls/${PULL_REQUEST##*/}" + BENCHMARK_TARGET_FILE="benchmarks-v1/pulls/${PULL_REQUEST##*/}.json" +elif [ -n "${CIRCLE_TAG:-}" ]; then + echo "Skipping benchmark run for ${CIRCLE_TAG} tagged release." + exit 0 +else + echo "Skipping benchmark run on branch ${BRANCH:-unknown}." + exit 0 +fi + +# Upload it to master or pulls +aws s3 cp $BENCHMARK_FILE_JSON "s3://${BUCKET_NAME}/${BENCHMARK_TARGET_FILE}" + +# If on master, also update the "latest" benchmark file +if [ -n "${BENCHMARK_LATEST_FILE:-}" ]; then + aws s3 cp $BENCHMARK_FILE_JSON "s3://${BUCKET_NAME}/${BENCHMARK_LATEST_FILE}" +fi diff --git a/scripts/logs/upload_logs_to_s3.sh b/scripts/logs/upload_logs_to_s3.sh new file mode 100755 index 000000000000..a5e46f5a9680 --- /dev/null +++ b/scripts/logs/upload_logs_to_s3.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Uploads to S3 the contents of the log file mounted on the end-to-end container, +# which contains log entries with an associated event and metrics for it. +# Logs are uploaded to aztec-ci-artifacts/logs-v1/master/$COMMIT/$JOB.jsonl +# or to aztec-ci-artifacts/logs-v1/pulls/$PRNUMBER/$JOB.jsonl if on a PR + +[ -n "${BUILD_SYSTEM_DEBUG:-}" ] && set -x # conditionally trace +set -eu + +LOG_FOLDER=$1 +BUCKET_NAME="aztec-ci-artifacts" +COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" +E2E_MODE="${E2E_MODE:-local}" + +echo "Uploading logs to S3 in mode $E2E_MODE for commit $COMMIT_HASH in branch ${BRANCH:-} at pull request ${PULL_REQUEST:-none}" + +if [ ! -d "$LOG_FOLDER" ] || [ -z "$(ls -A "$LOG_FOLDER")" ]; then + echo "No logs in folder $LOG_FOLDER to upload" + exit 0 +fi + +if [ "$E2E_MODE" == "local" ]; then + echo "Skipping upload since running in local mode" + exit 0 +fi + +# Paths used in scripts/ci/assemble_e2e_benchmark.sh +if [ "${BRANCH:-}" = "master" ]; then + TARGET_FOLDER="logs-v1/master/$COMMIT_HASH/" +elif [ -n "${PULL_REQUEST:-}" ]; then + TARGET_FOLDER="logs-v1/pulls/${PULL_REQUEST##*/}" +fi + +if [ -n "${TARGET_FOLDER:-}" ]; then + aws s3 cp $LOG_FOLDER "s3://${BUCKET_NAME}/${TARGET_FOLDER}" --include "*.jsonl" --recursive +else + echo Skipping upload since no target folder was defined +fi \ No newline at end of file diff --git a/scripts/setup_env.sh b/scripts/setup_env.sh index 70ecf9d7654c..7ad729fdda9e 100755 --- a/scripts/setup_env.sh +++ b/scripts/setup_env.sh @@ -1,8 +1,11 @@ #!/bin/bash +COMMIT_HASH=$(git rev-parse HEAD) + # Setup environment variables echo "Setting up environment variables..." -echo FORCE_COLOR=1 >> $GITHUB_ENV +echo "FORCE_COLOR=1" >> $GITHUB_ENV +echo "EARTHLY_BUILD_ARGS=PULL_REQUEST=$PULL_REQUEST,BRANCH=$BRANCH,COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV # Docker login echo "Logging in to Docker..." diff --git a/yarn-project/end-to-end/Earthfile b/yarn-project/end-to-end/Earthfile index 59403a2400c8..d59b9222d0ed 100644 --- a/yarn-project/end-to-end/Earthfile +++ b/yarn-project/end-to-end/Earthfile @@ -9,10 +9,12 @@ E2E_TEST_LOCAL: ARG compose_file=./scripts/docker-compose.yml ARG enable_gas="" ARG debug="aztec:*" + ARG EARTHLY_TARGET_NAME LOCALLY ENV ENABLE_GAS=$enable_gas ENV TEST=$test ENV DEBUG=$debug + ENV JOB_NAME=$EARTHLY_TARGET_NAME WITH DOCKER \ --load aztecprotocol/aztec:latest=../+aztec \ --load aztecprotocol/end-to-end:latest=../+end-to-end \ @@ -29,13 +31,15 @@ E2E_TEST_FROM_CACHE: ARG enable_gas="" ARG debug="aztec:*" ARG aztec_docker_tag + ARG EARTHLY_TARGET_NAME LOCALLY ENV ENABLE_GAS=$enable_gas ENV TEST=$test ENV DEBUG=$debug ENV AZTEC_DOCKER_TAG=$aztec_docker_tag + ENV JOB_NAME=$EARTHLY_TARGET_NAME # need a different project name for each to run in parallel - LET project_name=$(echo $test | sed 's/\./_/g') + LET project_name=$(echo $test | sed 's/[./]/_/g') IF docker compose > /dev/null 2>&1 LET CMD="docker compose" ELSE @@ -51,10 +55,12 @@ E2E_TEST_FROM_BUILD: ARG compose_file=./scripts/docker-compose.yml ARG enable_gas="" ARG debug="aztec:*" + ARG EARTHLY_TARGET_NAME FROM earthly/dind:alpine-3.19-docker-25.0.2-r0 ENV ENABLE_GAS=$enable_gas ENV TEST=$test ENV DEBUG=$debug + ENV JOB_NAME=$EARTHLY_TARGET_NAME COPY $compose_file $compose_file # For ARM, we do use WITH DOCKER as we don't have many e2e tests, but note E2E_TEST_FROM_CACHE WITH DOCKER \ @@ -81,6 +87,22 @@ E2E_TEST: DO +E2E_TEST_FROM_BUILD --test=$test --compose_file=$compose_file --enable_gas=$enable_gas --debug=$debug END +UPLOAD_LOGS: + FUNCTION + ARG e2e_mode=cache + ARG PULL_REQUEST + ARG BRANCH + ARG COMMIT_HASH + LOCALLY + LET COMMIT_HASH="${COMMIT_HASH:-$(git rev-parse HEAD)}" + FROM ../../+scripts + COPY ./log /usr/var/log + ENV PULL_REQUEST=$PULL_REQUEST + ENV BRANCH=$BRANCH + ENV COMMIT_HASH=$COMMIT_HASH + ENV E2E_MODE=$e2e_mode + RUN --secret AWS_ACCESS_KEY_ID --secret AWS_SECRET_ACCESS_KEY /usr/src/scripts/logs/upload_logs_to_s3.sh /usr/var/log + # Define e2e tests e2e-tests: FROM ../+end-to-end @@ -124,24 +146,34 @@ guides-dapp-testing: # TODO intermittent failure # guides-sample-dapp: -# ARG e2e_mode=local -# DO +E2E_TEST --test=sample-dapp --e2e_mode=$e2e_mode +# ARG e2e_mode=local +# DO +E2E_TEST --test=sample-dapp --e2e_mode=$e2e_mode # TODO currently hangs for hour+ # guides-up-quick-start: # ARG e2e_mode=local # DO +E2E_TEST --test=guides/up_quick_start.test.ts --e2e_mode=$e2e_mode -# TODO hanging -# bench-publish-rollup: -# ARG e2e_mode=local -# DO +E2E_TEST --test=benchmarks/bench_publish_rollup.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml +bench-publish-rollup: + ARG e2e_mode=local + ARG PULL_REQUEST + ARG BRANCH + ARG COMMIT_HASH + DO +E2E_TEST --test=benchmarks/bench_publish_rollup.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml + DO +UPLOAD_LOGS --e2e_mode=$e2e_mode --PULL_REQUEST=$PULL_REQUEST --BRANCH=$BRANCH --COMMIT_HASH=$COMMIT_HASH -# TODO hanging -# bench-process-history: -# ARG e2e_mode=local -# DO +E2E_TEST --test=benchmarks/bench_process_history.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml +bench-process-history: + ARG e2e_mode=local + ARG PULL_REQUEST + ARG BRANCH + ARG COMMIT_HASH + DO +E2E_TEST --test=benchmarks/bench_process_history.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml + DO +UPLOAD_LOGS --e2e_mode=$e2e_mode --PULL_REQUEST=$PULL_REQUEST --BRANCH=$BRANCH --COMMIT_HASH=$COMMIT_HASH -# bench-tx-size: -# ARG e2e_mode=local -# DO +E2E_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --enable_gas=1 --compose_file=./scripts/docker-compose-no-sandbox.yml +bench-tx-size: + ARG e2e_mode=local + ARG PULL_REQUEST + ARG BRANCH + ARG COMMIT_HASH + DO +E2E_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --enable_gas=1 --compose_file=./scripts/docker-compose-no-sandbox.yml + DO +UPLOAD_LOGS --e2e_mode=$e2e_mode --PULL_REQUEST=$PULL_REQUEST --BRANCH=$BRANCH --COMMIT_HASH=$COMMIT_HASH diff --git a/yarn-project/scripts/Earthfile b/yarn-project/scripts/Earthfile new file mode 100644 index 000000000000..37aba4bda90c --- /dev/null +++ b/yarn-project/scripts/Earthfile @@ -0,0 +1,70 @@ +VERSION 0.8 +FROM node:18.19.0 + +build: + FROM ../+scripts-prod + RUN apt-get update && apt-get install awscli -y + COPY ../../+scripts/scripts /usr/src/scripts + WORKDIR /usr/src + +download-logs: + # Downloads logs for the current PR and saves them as an artifact, to be consumed by bench-aggregate. + ARG COMMIT_HASH + ARG PULL_REQUEST + ARG BRANCH + FROM +build + LET LOG_FOLDER=/usr/var/logs + LET BENCH_FOLDER=/usr/var/bench + ENV LOG_FOLDER=$LOG_FOLDER + ENV BENCH_FOLDER=$BENCH_FOLDER + ENV COMMIT_HASH=$COMMIT_HASH + ENV PULL_REQUEST=$PULL_REQUEST + ENV BRANCH=$BRANCH + RUN --secret AWS_ACCESS_KEY_ID --secret AWS_SECRET_ACCESS_KEY ./scripts/logs/download_logs_from_s3.sh + SAVE ARTIFACT $LOG_FOLDER logs + +bench-aggregate: + # Copies logs downloaded from download-logs and aggregates them using bench-aggregate. + # No aggregation is done if there is a log missing from the benchmark jobs. + ARG COMMIT_HASH + ARG PULL_REQUEST + ARG BRANCH + FROM +build + LET LOG_FOLDER=/usr/var/logs + LET BENCH_FOLDER=/usr/var/bench + ENV LOG_FOLDER=$LOG_FOLDER + ENV BENCH_FOLDER=$BENCH_FOLDER + ENV COMMIT_HASH=$COMMIT_HASH + ENV PULL_REQUEST=$PULL_REQUEST + ENV BRANCH=$BRANCH + COPY +download-logs/logs $LOG_FOLDER + RUN --secret AWS_ACCESS_KEY_ID --secret AWS_SECRET_ACCESS_KEY \ + ./scripts/logs/check_logs_for_benchmark.sh \ + && ((cd /usr/src/yarn-project/scripts && yarn bench-aggregate) && ./scripts/logs/upload_aggregated_benchmarks_to_s3.sh) \ + || (echo "Not all log files from benchmark jobs found"; mkdir -p $BENCH_FOLDER) + SAVE ARTIFACT $BENCH_FOLDER bench + +bench-comment: + # Use the scripts image to run bench comment after loading the benchmark from bench-aggregate. + # Requires base-benchmark to be downloaded outside of this target. Note we cannot run it within + # an Earthly container because it needs access to the .git folder, and we cannot run it with a + # LOCALLY statement because Earthly does not support secrets when running locally (and we need) + # the AWS access keys to access S3. This step is then manually run in the ci.yml. + ARG COMMIT_HASH + ARG PULL_REQUEST + ARG BRANCH + FROM +build + LET BENCH_FOLDER=/usr/var/bench + ENV BENCH_FOLDER=$BENCH_FOLDER + ENV COMMIT_HASH=$COMMIT_HASH + ENV PULL_REQUEST=$PULL_REQUEST + ENV PR_NUMBER=$PULL_REQUEST + ENV BRANCH=$BRANCH + COPY ./bench $BENCH_FOLDER/ + COPY +bench-aggregate/bench $BENCH_FOLDER + RUN echo "Bench folder contents $(ls $BENCH_FOLDER)" + RUN --secret AZTEC_BOT_COMMENTER_GITHUB_TOKEN \ + [ -f $BENCH_FOLDER/benchmark.json ] \ + && (cd /usr/src/yarn-project/scripts && AZTEC_BOT_COMMENTER_GITHUB_TOKEN=$AZTEC_BOT_COMMENTER_GITHUB_TOKEN yarn bench-comment) \ + || echo "No benchmark file found in $BENCH_FOLDER" + \ No newline at end of file