@@ -226,13 +226,34 @@ jobs:
226226 # Runs:
227227 # - on every push to the `main` branch
228228 # - on every release, when it's published
229+ # - on workflow_dispatch for manual deployments
230+
231+ # Determine which networks to deploy based on the trigger
232+
233+
234+
235+ :
236+ runs-on : ubuntu-latest
237+ outputs :
238+ networks : ${{ steps.set-networks.outputs.matrix }}
239+ steps :
240+ - id : set-networks
241+ run : |
242+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
243+ # Manually triggered deployment: output a valid JSON array with the single chosen network.
244+ echo "matrix=[\"${{ inputs.network }}\"]" >> $GITHUB_OUTPUT
245+ else
246+ echo 'matrix=["Mainnet","Testnet"]' >> $GITHUB_OUTPUT
247+ fi
248+
229249 deploy-nodes :
230250 strategy :
231251 matrix :
232- network : [Mainnet, Testnet]
252+ network : ${{ fromJSON(needs.set-matrix.outputs.networks) }}
233253 name : Deploy ${{ matrix.network }} nodes
234254 needs :
235255 [
256+ set-matrix,
236257 build,
237258 versioning,
238259 test-configuration-file,
@@ -247,7 +268,7 @@ jobs:
247268 permissions :
248269 contents : " read"
249270 id-token : " write"
250- if : ${{ !cancelled() && !failure() && ((github.event_name == 'push' && github.ref_name == 'main') || github.event_name == 'release') }}
271+ if : ${{ !cancelled() && !failure() && ((github.event_name == 'push' && github.ref_name == 'main') || github.event_name == 'release' || github.event_name == 'workflow_dispatch' ) }}
251272
252273 steps :
253274 - uses : actions/checkout@v4.2.2
@@ -264,7 +285,7 @@ jobs:
264285 # Labels in GCP are required to be in lowercase, but the blockchain network
265286 # uses sentence case, so we need to downcase the network.
266287 #
267- # Passes the lowercase network to subsequent steps using $NETWORK env variable.
288+ # Passes lowercase network to subsequent steps using $NETWORK env variable.
268289 - name : Downcase network name for labels
269290 run : |
270291 NETWORK_CAPS="${{ matrix.network }}"
@@ -281,13 +302,26 @@ jobs:
281302 - name : Set up Cloud SDK
282303 uses : google-github-actions/setup-gcloud@v2.1.4
283304
305+ - name : Get static IP address for long-running nodes
306+ # Now runs when triggered by a release or a manual workflow_dispatch event.
307+ if : ${{ github.event_name == 'release' || github.event_name == 'workflow_dispatch' }}
308+ run : |
309+ set -e # Exit immediately if a command exits with a non-zero status.
310+ # Attempt to retrieve the static IP address for the network.
311+ echo "IP_ADDRESS=$(gcloud compute addresses describe zebra-${NETWORK} --region ${{ vars.GCP_REGION }} --format='value(address)')" >> "$GITHUB_ENV"
312+
284313 - name : Create instance template for ${{ matrix.network }}
285314 run : |
286315 if [ "${{ github.event_name }}" == "release" ]; then
287316 DISK_NAME="zebrad-cache-${NETWORK}"
288317 else
289318 DISK_NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
290319 fi
320+ if [ -n "${{ env.IP_ADDRESS }}" ]; then
321+ IP_FLAG="--address=${{ env.IP_ADDRESS }}"
322+ else
323+ IP_FLAG=""
324+ fi
291325 DISK_PARAMS="name=${DISK_NAME},device-name=${DISK_NAME},size=400GB,type=pd-balanced"
292326 if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then
293327 DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}"
@@ -297,13 +331,22 @@ jobs:
297331 echo "No cached disk found for ${{ matrix.network }} in main branch"
298332 exit 1
299333 fi
334+
335+ # Set log file based on input or default
336+ if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
337+ LOG_FILE="${{ inputs.log_file }}"
338+ else
339+ LOG_FILE="${{ vars.CD_LOG_FILE }}"
340+ fi
341+
300342 gcloud compute instance-templates create-with-container zebrad-${{ needs.versioning.outputs.major_version || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK} \
301343 --machine-type ${{ vars.GCP_SMALL_MACHINE }} \
302344 --boot-disk-size=10GB \
303345 --boot-disk-type=pd-standard \
304346 --image-project=cos-cloud \
305347 --image-family=cos-stable \
306- --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \
348+ --subnet=${{ vars.GCP_SUBNETWORK }} \
349+ ${IP_FLAG} \
307350 --create-disk="${DISK_PARAMS}" \
308351 --container-mount-disk=mount-path='/home/zebra/.cache/zebra',name=${DISK_NAME},mode=rw \
309352 --container-stdin \
@@ -313,7 +356,7 @@ jobs:
313356 --service-account ${{ vars.GCP_DEPLOYMENTS_SA }} \
314357 --scopes cloud-platform \
315358 --metadata google-logging-enabled=true,google-logging-use-fluentbit=true,google-monitoring-enabled=true \
316- --labels=app=zebrad,environment=staging,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \
359+ --labels=app=zebrad,environment=${{ github.event_name == 'workflow_dispatch' && 'qa' || ' staging' }} ,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \
317360 --tags zebrad
318361
319362 # Check if our destination instance group exists already
@@ -344,95 +387,11 @@ jobs:
344387 --version template="zebrad-${{ needs.versioning.outputs.major_version || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}" \
345388 --region "${{ vars.GCP_REGION }}"
346389
347- # This jobs handles the deployment of a single node (1) in the configured GCP zone
348- # when an instance is required to test a specific commit
349- #
350- # Runs:
351- # - on request, using workflow_dispatch with regenerate-disks
352- #
353- # Note: this instances are not automatically replaced or deleted
354- deploy-instance :
355- name : Deploy single ${{ inputs.network }} instance
356- needs : [build, test-configuration-file, test-zebra-conf-path, get-disk-name]
357- runs-on : ubuntu-latest
358- timeout-minutes : 30
359- env :
360- CACHED_DISK_NAME : ${{ needs.get-disk-name.outputs.cached_disk_name }}
361- permissions :
362- contents : " read"
363- id-token : " write"
364- # Run even if we don't need a cached disk, but only when triggered by a workflow_dispatch
365- if : ${{ !failure() && github.event_name == 'workflow_dispatch' }}
366-
367- steps :
368- - uses : actions/checkout@v4.2.2
369- with :
370- persist-credentials : false
371-
372- - name : Inject slug/short variables
373- uses : rlespinasse/github-slug-action@v5
374- with :
375- short-length : 7
376-
377- # Makes the Zcash network name lowercase.
378- #
379- # Labels in GCP are required to be in lowercase, but the blockchain network
380- # uses sentence case, so we need to downcase the network.
381- #
382- # Passes the lowercase network to subsequent steps using $NETWORK env variable.
383- - name : Downcase network name for labels
384- run : |
385- NETWORK_CAPS="${{ inputs.network }}"
386- echo "NETWORK=${NETWORK_CAPS,,}" >> "$GITHUB_ENV"
387-
388- # Setup gcloud CLI
389- - name : Authenticate to Google Cloud
390- id : auth
391- uses : google-github-actions/auth@v2.1.8
392- with :
393- workload_identity_provider : " ${{ vars.GCP_WIF }}"
394- service_account : " ${{ vars.GCP_DEPLOYMENTS_SA }}"
395-
396- - name : Set up Cloud SDK
397- uses : google-github-actions/setup-gcloud@v2.1.4
398-
399- # Create instance template from container image
400- - name : Manual deploy of a single ${{ inputs.network }} instance running zebrad
401- run : |
402- DISK_NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
403- DISK_PARAMS="name=${DISK_NAME},device-name=${DISK_NAME},size=400GB,type=pd-balanced"
404- if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then
405- DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}"
406- elif [ ${{ !inputs.need_cached_disk && github.event_name == 'workflow_dispatch' }} ]; then
407- echo "No cached disk required"
408- else
409- echo "No cached disk found for ${{ matrix.network }} in main branch"
410- exit 1
411- fi
412- gcloud compute instances create-with-container "zebrad-${{ env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}" \
413- --machine-type ${{ vars.GCP_SMALL_MACHINE }} \
414- --boot-disk-size=10GB \
415- --boot-disk-type=pd-standard \
416- --image-project=cos-cloud \
417- --image-family=cos-stable \
418- --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \
419- --create-disk="${DISK_PARAMS}" \
420- --container-mount-disk=mount-path='/home/zebra/.cache/zebra',name=${DISK_NAME},mode=rw \
421- --container-stdin \
422- --container-tty \
423- --container-image ${{ vars.GAR_BASE }}/zebrad@${{ needs.build.outputs.image_digest }} \
424- --container-env "NETWORK=${{ inputs.network }},LOG_FILE=${{ inputs.log_file }},SENTRY_DSN=${{ vars.SENTRY_DSN }}" \
425- --service-account ${{ vars.GCP_DEPLOYMENTS_SA }} \
426- --scopes cloud-platform \
427- --metadata google-logging-enabled=true,google-monitoring-enabled=true \
428- --labels=app=zebrad,environment=qa,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \
429- --tags zebrad \
430- --zone ${{ vars.GCP_ZONE }}
431-
432390 failure-issue :
433391 name : Open or update issues for release failures
434392 # When a new job is added to this workflow, add it to this list.
435- needs : [versioning, build, deploy-nodes, deploy-instance]
393+ needs : [ versioning, build, deploy-nodes ]
394+
436395 # Only open tickets for failed or cancelled jobs that are not coming from PRs.
437396 # (PR statuses are already reported in the PR jobs list, and checked by GitHub's Merge Queue.)
438397 if : (failure() && github.event.pull_request == null) || (cancelled() && github.event.pull_request == null)
0 commit comments