Skip to content

Commit 2bbd12e

Browse files
committed
mitch/tmnt-165-create-deploy-eth-devnetyml
1 parent 8ebe8d7 commit 2bbd12e

File tree

11 files changed

+452
-62
lines changed

11 files changed

+452
-62
lines changed

.github/local_workflow.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# Runs a github workflow locally.
4+
# Bind-mounts the local directory into the container, which executes as the current user.
5+
# Attempts to use a GCP service account, which you can download from
6+
# https://console.cloud.google.com/iam-admin/serviceaccounts
7+
8+
# Your workflow may not need a GCP service account, nor a kubeconfig, etc.
9+
# Feel free to send a PR to tweak the script ;)
10+
11+
# example usage:
12+
# export GOOGLE_APPLICATION_CREDENTIALS=/home/mitch/tokens/testnet-helm-sa.json
13+
# alias lwfl=/home/mitch/aztec-clones/alpha/.github/local_workflow.sh
14+
# lwfl deploy_eth_devnet --input cluster=kind --input resource_profile=dev --input namespace=mitch-eth-devnet --input create_static_ips=false
15+
# lwfl deploy_eth_devnet --input cluster=aztec-gke-private --input resource_profile=prod --input namespace=mitch-eth-devnet --input create_static_ips=false
16+
17+
workflow_name=$1
18+
19+
REPO_ROOT=$(git rev-parse --show-toplevel)
20+
21+
if [ -z "$workflow_name" ]; then
22+
echo "Usage: $0 <workflow_name> [args ...]"
23+
exit 1
24+
fi
25+
26+
# get the rest of the args (skip the first one which is the workflow name)
27+
shift
28+
args=("$@")
29+
30+
SA_KEY_JSON=$(cat "$GOOGLE_APPLICATION_CREDENTIALS")
31+
32+
act workflow_dispatch -j $workflow_name \
33+
-s GITHUB_TOKEN="$(gh auth token)" \
34+
-s GCP_SA_KEY="$SA_KEY_JSON" \
35+
-s KUBECONFIG_B64="$(cat $HOME/.kube/config | base64 -w0)" \
36+
--container-options "--user $(id -u):$(id -g)" \
37+
--bind \
38+
--directory $REPO_ROOT "${args[@]}"
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
name: Deploy Eth Devnet
2+
3+
# This workflow is used to deploy the eth devnet to a cluster.
4+
# It can be used to deploy to kind or a GKE cluster.
5+
#
6+
# Set yourself up to run locally with:
7+
# export GOOGLE_APPLICATION_CREDENTIALS=/home/mitch/tokens/testnet-helm-sa.json
8+
# alias lwfl=/home/mitch/aztec-clones/alpha/.github/local_workflow.sh
9+
#
10+
# Then deploy to kind:
11+
# lwfl deploy_eth_devnet --input cluster=kind --input resource_profile=dev --input namespace=mitch-eth-devnet --input create_static_ips=false
12+
#
13+
# Or to a GKE cluster:
14+
# lwfl deploy_eth_devnet --input cluster=aztec-gke-private --input resource_profile=prod --input namespace=mitch-eth-devnet --input create_static_ips=false
15+
16+
on:
17+
workflow_call:
18+
inputs:
19+
cluster:
20+
description: The cluster to deploy to, e.g. aztec-gke-private or kind
21+
required: true
22+
type: string
23+
namespace:
24+
description: The namespace to deploy to
25+
required: true
26+
type: string
27+
ref:
28+
description: The branch name to deploy from
29+
required: false
30+
type: string
31+
default: "next"
32+
chain_id:
33+
description: Ethereum chain ID for genesis generation
34+
required: false
35+
type: number
36+
default: 1337
37+
block_time:
38+
description: Block time in seconds for genesis generation
39+
required: false
40+
type: number
41+
default: 12
42+
gas_limit:
43+
description: Gas limit for blocks in genesis generation
44+
required: false
45+
type: string
46+
default: "32000000"
47+
resource_profile:
48+
description: Resource profile to use (dev or prod)
49+
required: false
50+
type: string
51+
default: "prod"
52+
create_static_ips:
53+
description: Whether to create static IPs as part of the eth devnet for the execution and beacon nodes
54+
required: false
55+
type: string
56+
default: "false"
57+
run_terraform_destroy:
58+
description: Whether to run the terraform destroy
59+
required: false
60+
type: string
61+
default: "false"
62+
secrets:
63+
GCP_SA_KEY:
64+
description: The JSON key for the GCP service account
65+
required: true
66+
KUBECONFIG_B64:
67+
description: The base64 encoded kubeconfig
68+
required: true
69+
70+
workflow_dispatch:
71+
inputs:
72+
cluster:
73+
description: The cluster to deploy to, e.g. aztec-gke-private or kind
74+
required: false
75+
type: string
76+
default: "kind"
77+
namespace:
78+
description: The namespace to deploy to
79+
required: false
80+
type: string
81+
default: "eth-devnet"
82+
ref:
83+
description: The branch name to deploy from.
84+
required: false
85+
type: string
86+
default: "next"
87+
chain_id:
88+
description: Ethereum chain ID for genesis generation
89+
required: false
90+
type: number
91+
default: 1337
92+
block_time:
93+
description: Block time in seconds for genesis generation
94+
required: false
95+
type: number
96+
default: 12
97+
gas_limit:
98+
description: Gas limit for blocks in genesis generation
99+
required: false
100+
type: string
101+
default: "32000000"
102+
resource_profile:
103+
description: Resource profile to use (dev or prod)
104+
required: false
105+
type: string
106+
default: "prod"
107+
create_static_ips:
108+
description: Whether to create static IPs as part of the eth devnet for the execution and beacon nodes
109+
required: false
110+
type: string
111+
default: "false"
112+
run_terraform_destroy:
113+
description: Whether to run the terraform destroy
114+
required: false
115+
type: string
116+
default: "false"
117+
118+
jobs:
119+
deploy_eth_devnet:
120+
runs-on: ubuntu-latest
121+
env:
122+
TF_STATE_BUCKET: aztec-terraform
123+
REGION: us-west1-a
124+
125+
steps:
126+
- name: debug inputs
127+
run: |
128+
echo "cluster: ${{ inputs.cluster }}"
129+
echo "namespace: ${{ inputs.namespace }}"
130+
echo "ref: ${{ inputs.ref }}"
131+
echo "chain_id: ${{ inputs.chain_id }}"
132+
echo "block_time: ${{ inputs.block_time }}"
133+
echo "gas_limit: ${{ inputs.gas_limit }}"
134+
echo "resource_profile: ${{ inputs.resource_profile }}"
135+
echo "create_static_ips: ${{ inputs.create_static_ips }}"
136+
echo "run_terraform_destroy: ${{ inputs.run_terraform_destroy }}"
137+
138+
- name: Check if directory exists
139+
id: check_dir
140+
run: |
141+
if [ -d ".git" ]; then
142+
echo "exists=true" >> $GITHUB_OUTPUT
143+
else
144+
echo "exists=false" >> $GITHUB_OUTPUT
145+
fi
146+
147+
# if running with `act`, skip the checkout since the code is mounted in
148+
- name: Checkout code
149+
if: ${{ steps.check_dir.outputs.exists != 'true' }}
150+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
151+
with:
152+
ref: ${{ inputs.ref || github.ref }}
153+
154+
- name: Authenticate to Google Cloud
155+
uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f
156+
with:
157+
credentials_json: ${{ secrets.GCP_SA_KEY }}
158+
159+
- name: Set up Cloud SDK
160+
uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a
161+
162+
- name: Install GKE Auth Plugin
163+
run: |
164+
gcloud components install gke-gcloud-auth-plugin --quiet
165+
166+
- name: Configure kubectl with GKE cluster
167+
if: ${{ inputs.cluster != 'kind' }}
168+
run: |
169+
gcloud container clusters get-credentials ${{ inputs.cluster }} --region ${{ env.REGION }}
170+
171+
- name: Configure kubectl with kind cluster
172+
if: ${{ inputs.cluster == 'kind' }}
173+
run: |
174+
# fail if kubeconfig is not provided
175+
if [ -z "${{ secrets.KUBECONFIG_B64 }}" ]; then
176+
echo "KUBECONFIG_B64 is not set"
177+
exit 1
178+
fi
179+
mkdir -p $HOME/.kube
180+
echo "${{ secrets.KUBECONFIG_B64 }}" | base64 -d > $HOME/.kube/config
181+
kubectl config use-context kind-kind
182+
183+
- name: Terraform Init
184+
working-directory: ./spartan/terraform/deploy-eth-devnet
185+
run: |
186+
# Clean up any previous backend overrides
187+
rm -f backend_override.tf
188+
189+
if [ "${{ inputs.cluster }}" == "kind" ]; then
190+
# For kind, use local backend with explicit path
191+
cat > backend_override.tf << EOF
192+
terraform {
193+
backend "local" {
194+
path = "state/${{ inputs.cluster }}/${{ inputs.namespace }}/terraform.tfstate"
195+
}
196+
}
197+
EOF
198+
else
199+
# For GKE, use GCS backend with explicit path
200+
cat > backend_override.tf << EOF
201+
terraform {
202+
backend "gcs" {
203+
bucket = "${{ env.TF_STATE_BUCKET }}"
204+
prefix = "deploy-eth-devnet/${{ env.REGION }}/${{ inputs.cluster }}/${{ inputs.namespace }}/terraform.tfstate"
205+
}
206+
}
207+
EOF
208+
fi
209+
210+
terraform init -reconfigure
211+
212+
- name: Terraform Destroy
213+
working-directory: ./spartan/terraform/deploy-eth-devnet
214+
if: ${{ inputs.run_terraform_destroy == 'true' }}
215+
# Destroy fails if the resources are already destroyed, so we continue on error
216+
continue-on-error: true
217+
run: |
218+
# if going to kind, static-ips is not supported
219+
if [ "${{ inputs.cluster }}" == "kind" ]; then
220+
CREATE_STATIC_IPS=false
221+
else
222+
CREATE_STATIC_IPS=${{ inputs.create_static_ips || 'false' }}
223+
fi
224+
225+
CLUSTER_CONTEXT=$(kubectl config current-context)
226+
227+
terraform destroy \
228+
-var="CREATE_STATIC_IPS=${CREATE_STATIC_IPS}" \
229+
-var="K8S_CLUSTER_CONTEXT=${CLUSTER_CONTEXT}" \
230+
-var="NAMESPACE=${{ inputs.namespace || 'eth-devnet' }}" \
231+
-var="CHAIN_ID=${{ inputs.chain_id || 1337 }}" \
232+
-var="BLOCK_TIME=${{ inputs.block_time || 12 }}" \
233+
-var="GAS_LIMIT=${{ inputs.gas_limit || '32000000' }}" \
234+
-var="MNEMONIC_SECRET_NAME=eth-devnet-genesis-mnemonic" \
235+
-var="PREFUNDED_MNEMONIC_INDICES=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1000,1001,1002,1003" \
236+
-var="RESOURCE_PROFILE=${{ inputs.resource_profile || 'prod' }}" \
237+
-auto-approve
238+
239+
- name: Terraform Plan
240+
working-directory: ./spartan/terraform/deploy-eth-devnet
241+
run: |
242+
# if going to kind, static-ips is not supported
243+
if [ "${{ inputs.cluster }}" == "kind" ]; then
244+
CREATE_STATIC_IPS=false
245+
else
246+
CREATE_STATIC_IPS=${{ inputs.create_static_ips || 'false' }}
247+
fi
248+
249+
CLUSTER_CONTEXT=$(kubectl config current-context)
250+
251+
terraform plan \
252+
-var="CREATE_STATIC_IPS=${CREATE_STATIC_IPS}" \
253+
-var="K8S_CLUSTER_CONTEXT=${CLUSTER_CONTEXT}" \
254+
-var="NAMESPACE=${{ inputs.namespace || 'eth-devnet' }}" \
255+
-var="CHAIN_ID=${{ inputs.chain_id || 1337 }}" \
256+
-var="BLOCK_TIME=${{ inputs.block_time || 12 }}" \
257+
-var="GAS_LIMIT=${{ inputs.gas_limit || '32000000' }}" \
258+
-var="MNEMONIC_SECRET_NAME=eth-devnet-genesis-mnemonic" \
259+
-var="PREFUNDED_MNEMONIC_INDICES=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1000,1001,1002,1003" \
260+
-var="RESOURCE_PROFILE=${{ inputs.resource_profile || 'prod' }}" \
261+
-out=tfplan
262+
263+
- name: Terraform Apply
264+
working-directory: ./spartan/terraform/deploy-eth-devnet
265+
run: |
266+
terraform apply tfplan

.github/workflows/publish-bb-mac.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ jobs:
4343
optional: false
4444
- label: amd64-darwin-starknet
4545
runner: macos-13
46-
cmake_flags: "-DCMAKE_CXX_FLAGS=\"-DSTARKNET_GARAGA_FLAVORS=1\""
46+
cmake_flags: '-DCMAKE_CXX_FLAGS="-DSTARKNET_GARAGA_FLAVORS=1"'
4747
optional: true
4848
- label: arm64-darwin-starknet
4949
runner: macos-14
50-
cmake_flags: "-DCMAKE_CXX_FLAGS=\"-DSTARKNET_GARAGA_FLAVORS=1\""
50+
cmake_flags: '-DCMAKE_CXX_FLAGS="-DSTARKNET_GARAGA_FLAVORS=1"'
5151
optional: true
5252
steps:
5353
- name: Checkout
@@ -69,22 +69,22 @@ jobs:
6969
7070
- name: Compile Barretenberg
7171
working-directory: barretenberg/cpp
72-
continue-on-error: ${{ matrix.optional }}
72+
continue-on-error: ${{ matrix.optional }}
7373
run: |
7474
cmake --preset homebrew ${{ matrix.cmake_flags }}
7575
cmake --build --preset homebrew --target bb
7676
7777
- name: Package barretenberg artifact (${{ matrix.label }})
7878
working-directory: barretenberg/cpp/build/bin
79-
continue-on-error: ${{ matrix.optional }}
79+
continue-on-error: ${{ matrix.optional }}
8080
run: |
8181
mkdir dist
8282
cp ./bb ./dist/bb
8383
7z a -ttar -so -an ./dist/* | 7z a -si ./barretenberg-${{ matrix.label }}.tar.gz
8484
8585
- name: Upload artifact (${{ matrix.label }})
8686
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
87-
continue-on-error: ${{ matrix.optional }}
87+
continue-on-error: ${{ matrix.optional }}
8888
with:
8989
name: barretenberg-${{ matrix.label }}.tar.gz
9090
path: ./barretenberg/cpp/build/bin/barretenberg-${{ matrix.label }}.tar.gz

spartan/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
*.tgz
22
scripts/logs
33
scripts/LICENSE
4+
tfplan
5+
*_override.tf

spartan/scripts/cleanup_helm.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
3+
# Script to manually clean up stuck Helm releases
4+
# Usage: ./cleanup_helm.sh [release-name] [namespace]
5+
6+
RELEASE_NAME=${1:-"eth-devnet"}
7+
NAMESPACE=${2:-"eth-devnet"}
8+
9+
echo "=== Cleaning up stuck Helm release: $RELEASE_NAME in namespace: $NAMESPACE ==="
10+
11+
# Check current state
12+
echo "Current Helm releases:"
13+
helm list -n $NAMESPACE -a
14+
15+
echo "Current Helm secrets:"
16+
kubectl get secrets -n $NAMESPACE -l owner=helm
17+
18+
# Look for pending operations
19+
echo "Checking for pending operations..."
20+
kubectl get secrets -n $NAMESPACE -l owner=helm -o json | jq -r '.items[] | select(.metadata.labels.status == "pending-install" or .metadata.labels.status == "pending-upgrade" or .metadata.labels.status == "pending-rollback") | "\(.metadata.name) - \(.metadata.labels.status)"'
21+
22+
# Force cleanup
23+
echo "Force deleting pending Helm secrets..."
24+
kubectl delete secrets -n $NAMESPACE -l owner=helm,status=pending-install --ignore-not-found=true
25+
kubectl delete secrets -n $NAMESPACE -l owner=helm,status=pending-upgrade --ignore-not-found=true
26+
kubectl delete secrets -n $NAMESPACE -l owner=helm,status=pending-rollback --ignore-not-found=true
27+
28+
# Try to uninstall
29+
echo "Attempting to uninstall release..."
30+
helm uninstall $RELEASE_NAME -n $NAMESPACE --wait --timeout=60s || echo "Uninstall failed or no release found"
31+
32+
# Nuclear option: delete all Helm secrets for this release
33+
echo "Force deleting all Helm secrets for release $RELEASE_NAME..."
34+
kubectl delete secrets -n $NAMESPACE -l name=$RELEASE_NAME,owner=helm --ignore-not-found=true
35+
36+
# Clean up all resources in namespace
37+
echo "Cleaning up all resources in namespace..."
38+
kubectl delete all --all -n $NAMESPACE --ignore-not-found=true
39+
40+
echo "=== Cleanup complete! ==="
41+
echo "You can now retry your deployment."

0 commit comments

Comments
 (0)