From 298be0b2a4ea60e0f47f5f6843b2b0fd10d79b5b Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 14 May 2026 07:35:18 +0000 Subject: [PATCH] fix(ci): use full image tag for prover-agent in deploy-network --- .github-new/workflows/deploy-network.yml | 290 +++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 .github-new/workflows/deploy-network.yml diff --git a/.github-new/workflows/deploy-network.yml b/.github-new/workflows/deploy-network.yml new file mode 100644 index 000000000000..5692431f4ae0 --- /dev/null +++ b/.github-new/workflows/deploy-network.yml @@ -0,0 +1,290 @@ +# Low-level workflow to deploy a single network +# This is called by other deployment workflows +name: Deploy Network + +on: + workflow_call: + inputs: + network: + description: "Network to deploy (e.g., staging-public, testnet, next-net)" + required: true + type: string + semver: + description: "Semver version (e.g., 2.3.4). Used to construct docker image if aztec_docker_image is not set." + required: false + type: string + aztec_docker_image: + description: "Full Aztec docker image (e.g., aztecprotocol/aztec:2.3.4). If not set, constructed from semver." + required: false + type: string + ref: + description: "Git ref to checkout" + required: false + type: string + namespace: + description: "Kubernetes namespace override (optional, defaults to env file value)" + required: false + type: string + deploy_contracts: + description: "Whether to deploy contracts fresh (true for first patch, false to read from network config)" + required: false + type: boolean + default: false + ha_docker_image: + description: "Full docker image for HA validator nodes (optional, defaults to aztec docker image)" + required: false + type: string + source_tag: + description: "Source tag that triggered this deploy" + required: false + type: string + workflow_dispatch: + inputs: + network: + description: "Network to deploy (e.g., staging-public, staging-ignition, testnet, next-net)" + required: true + type: choice + options: + - next-net + - staging-public + - testnet + - mainnet + semver: + description: "Semver version (e.g., 2.3.4). Used to construct docker image if aztec_docker_image is not set." + required: false + type: string + aztec_docker_image: + description: "Full Aztec docker image (e.g., aztecprotocol/aztec:2.3.4). If not set, constructed from semver." + required: false + type: string + namespace: + description: "Kubernetes namespace override (optional, defaults to env file value)" + required: false + type: string + deploy_contracts: + description: "Whether to deploy contracts fresh (true for first patch, false to read from network config)" + required: false + type: boolean + default: false + ha_docker_image: + description: "Full docker image for HA validator nodes (optional, defaults to aztec docker image)" + required: false + type: string + source_tag: + description: "Source tag that triggered this deploy" + required: false + type: string + +concurrency: + group: deploy-network-${{ inputs.network }}-${{ inputs.namespace || inputs.network }}-${{ inputs.aztec_docker_image || inputs.semver }}-${{ github.ref || github.ref_name }} + cancel-in-progress: true + +jobs: + deploy-network: + runs-on: ubuntu-latest + env: + GOOGLE_APPLICATION_CREDENTIALS: /tmp/gcp-key.json + outputs: + cluster: ${{ steps.deploy-network.outputs.cluster }} + steps: + - name: Determine checkout ref + id: checkout-ref + run: | + # Use inputs.ref if provided (workflow_call), otherwise use github.ref + if [[ -n "${{ inputs.ref }}" ]]; then + echo "ref=${{ inputs.ref }}" >> $GITHUB_OUTPUT + else + echo "ref=${{ github.ref }}" >> $GITHUB_OUTPUT + fi + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: ${{ steps.checkout-ref.outputs.ref }} + fetch-depth: 1 + persist-credentials: false + submodules: recursive # Initialize git submodules for l1-contracts dependencies + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Validate inputs + run: | + # Validate network + if [[ ! -f "spartan/environments/${{ inputs.network }}.env" ]]; then + echo "Error: Environment file not found for network '${{ inputs.network }}'" + echo "Available networks:" + ls -1 spartan/environments/ | grep -v '\.local\.env$' || echo "No environment files found" + exit 1 + fi + + # Require at least one of aztec_docker_image or semver + if [[ -z "${{ inputs.aztec_docker_image }}" && -z "${{ inputs.semver }}" ]]; then + echo "Error: Either 'aztec_docker_image' or 'semver' must be provided" + exit 1 + fi + + # Validate semver format if provided + if [[ -n "${{ inputs.semver }}" ]]; then + if ! echo "${{ inputs.semver }}" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$'; then + echo "Error: Invalid semver format '${{ inputs.semver }}'. Expected format: X.Y.Z or X.Y.Z-suffix" + exit 1 + fi + fi + + # Resolve the docker image + if [[ -n "${{ inputs.aztec_docker_image }}" ]]; then + AZTEC_DOCKER_IMAGE="${{ inputs.aztec_docker_image }}" + else + AZTEC_DOCKER_IMAGE="aztecprotocol/aztec:${{ inputs.semver }}" + fi + echo "AZTEC_DOCKER_IMAGE=$AZTEC_DOCKER_IMAGE" >> $GITHUB_ENV + + # Construct prover-agent image using the same tag as the aztec image, + # since both are published together for official builds (incl. nightlies). + # Using bare `inputs.semver` dropped the `-nightly.YYYYMMDD-amd64` suffix + # and made the prover-agent ImagePullBackOff every nightly deploy. + IMAGE_TAG="${AZTEC_DOCKER_IMAGE##*:}" + echo "PROVER_AGENT_DOCKER_IMAGE=aztecprotocol/aztec-prover-agent:$IMAGE_TAG" >> $GITHUB_ENV + + - name: Store the GCP key in a file + env: + GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} + run: | + set +x + umask 077 + printf '%s' "$GCP_SA_KEY" > "$GOOGLE_APPLICATION_CREDENTIALS" + jq -e . "$GOOGLE_APPLICATION_CREDENTIALS" >/dev/null + + - name: Setup GCP authentication + run: | + gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS" + + - name: Setup gcloud and install GKE auth plugin + uses: google-github-actions/setup-gcloud@v2 + with: + install_components: "gke-gcloud-auth-plugin" + + - name: Setup Terraform + uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 + with: + terraform_version: "1.7.5" + terraform_wrapper: false # Disable the wrapper that adds debug output, this messes with reading terraform output + + - name: Setup SSH key for CI Redis + env: + BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }} + run: | + if [ -n "${BUILD_INSTANCE_SSH_KEY:-}" ]; then + mkdir -p ~/.ssh + echo "${BUILD_INSTANCE_SSH_KEY}" | base64 --decode > ~/.ssh/build_instance_key + chmod 600 ~/.ssh/build_instance_key + fi + + - name: Deploy network + id: deploy-network + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + RUN_ID: ${{ github.run_id }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ env.GOOGLE_APPLICATION_CREDENTIALS }} + REF_NAME: ${{ inputs.semver && format('v{0}', inputs.semver) || '' }} + GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + NAMESPACE: ${{ inputs.namespace }} + AZTEC_DOCKER_IMAGE: ${{ env.AZTEC_DOCKER_IMAGE }} + CREATE_ROLLUP_CONTRACTS: ${{ inputs.deploy_contracts == true && 'true' || '' }} + PROVER_AGENT_DOCKER_IMAGE: ${{ env.PROVER_AGENT_DOCKER_IMAGE || env.AZTEC_DOCKER_IMAGE }} + VALIDATOR_HA_DOCKER_IMAGE: ${{ inputs.ha_docker_image || '' }} + run: | + echo "Deploying network: ${{ inputs.network }}" + echo "Using image: $AZTEC_DOCKER_IMAGE" + echo "Using prover image: $PROVER_AGENT_DOCKER_IMAGE" + echo "Using branch/ref: ${{ steps.checkout-ref.outputs.ref }}" + + cd spartan + ./scripts/install_deps.sh + ./scripts/network_deploy.sh "${{ inputs.network }}" + + # need to source this for CLUSTER + source "./environments/${{ inputs.network }}.env" + + if [ -n "$CLUSTER" ]; then + echo "cluster=$CLUSTER" >> $GITHUB_OUTPUT + else + echo "cluster=" >> $GITHUB_OUTPUT + fi + + - name: Step summary + if: always() + run: | + { + echo "## Deploy Network" + echo "" + echo "| Item | Value |" + echo "|------|-------|" + echo "| Network | \`${{ inputs.network }}\` |" + echo "| Docker Image | \`${{ env.AZTEC_DOCKER_IMAGE }}\` |" + echo "| Ref | \`${{ steps.checkout-ref.outputs.ref }}\` |" + if [[ -n "${{ inputs.source_tag }}" ]]; then + echo "| Source Tag | [\`${{ inputs.source_tag }}\`](https://github.com/${{ github.repository }}/releases/tag/${{ inputs.source_tag }}) |" + fi + } >> "$GITHUB_STEP_SUMMARY" + + - name: Notify Slack and dispatch ClaudeBox on failure + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} + run: | + if [ -z "${SLACK_BOT_TOKEN:-}" ]; then + echo "No SLACK_BOT_TOKEN, skipping notification" + exit 0 + fi + + CHANNEL="#alerts-${{ inputs.network }}" + RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + TEXT="Deploy Network workflow FAILED for *${{ inputs.network }}* (image ${{ env.AZTEC_DOCKER_IMAGE }}): <${RUN_URL}|View Run> (🤖)" + + # Post to Slack and capture timestamp for permalink + RESP=$(curl -sS -X POST https://slack.com/api/chat.postMessage \ + -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ + -H "Content-type: application/json" \ + -d "$(jq -n --arg c "$CHANNEL" --arg t "$TEXT" '{channel:$c, text:$t}')") + echo "Slack response: $RESP" + + TS=$(echo "$RESP" | jq -r '.ts // empty') + CHANNEL_ID=$(echo "$RESP" | jq -r '.channel // empty') + + LINK="" + if [[ -n "$TS" && -n "$CHANNEL_ID" ]]; then + LINK="https://aztecprotocol.slack.com/archives/$CHANNEL_ID/p${TS//./}" + fi + + # Dispatch ClaudeBox to investigate the failure + PROMPT="Deployment of ${{ inputs.network }} (image ${{ env.AZTEC_DOCKER_IMAGE }}) failed. \ + Follow .claude/claudebox/deploy-investigation.md to investigate. \ + GitHub Actions run: ${RUN_URL}. \ + Network: ${{ inputs.network }}. \ + Docker image: ${{ env.AZTEC_DOCKER_IMAGE }}. \ + Git ref: ${{ steps.checkout-ref.outputs.ref }}. \ + Namespace: ${{ inputs.namespace || inputs.network }}. \ + Deploy contracts: ${{ inputs.deploy_contracts }}." + + gh workflow run claudebox.yml \ + -f prompt="$PROMPT" \ + -f link="${LINK:-$RUN_URL}" \ + -f target_ref="${{ steps.checkout-ref.outputs.ref }}" || true + + update-irm: + needs: deploy-network + if: inputs.network == 'testnet' || inputs.network == 'mainnet' + uses: ./.github/workflows/deploy-irm.yml + secrets: inherit + with: + network: ${{ inputs.network }} + l1_network: ${{ inputs.network == 'mainnet' && 'mainnet' || 'sepolia' }} + cluster: ${{ needs.deploy-network.outputs.cluster }}