fix(ci): use service matrix to pass results to deploy #70
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and Deploy Docker Images | |
on: | |
push: | |
branches: ['main'] | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
service: | |
[ | |
api, | |
app, | |
app-lite, | |
backend, | |
indexer-balance, | |
indexer-base, | |
indexer-events, | |
indexer-dex, | |
indexer-multichain, | |
explorer-selector, | |
aggregates, | |
] | |
fail-fast: false | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: linux/amd64 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Docker Login | |
uses: docker/[email protected] | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and push | |
id: docker_build | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: apps/${{ matrix.service }}/Dockerfile | |
platforms: linux/amd64 | |
push: true | |
tags: | | |
ghcr.io/nearblocks/${{ matrix.service }}:latest | |
ghcr.io/nearblocks/${{ matrix.service }}:${{ github.sha }} | |
cache-from: type=registry,ref=ghcr.io/nearblocks/${{ matrix.service }}:latest | |
cache-to: type=inline | |
- name: Set image output | |
id: set_image_output | |
run: | | |
echo "${{ matrix.service }}=${{ github.sha }}" >> services.json | |
- name: Save Matrix Result as Artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: matrix-result | |
path: services.json | |
deploy: | |
needs: build | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Download Matrix Result Artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: matrix-result | |
path: . | |
- name: Set up kubectl | |
uses: azure/setup-kubectl@v3 | |
with: | |
version: 'v1.28.0' | |
- name: Configure kubectl | |
run: | | |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig | |
echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV | |
- name: Deploy and verify testnet | |
run: | | |
kubectl config set-context --current --namespace=nearblocks-testnet | |
# Define the list of services for testnet deployment (without app-lite) | |
services=(api app backend indexer-balance indexer-base indexer-events explorer-selector aggregates) | |
failed_deployments=() | |
for service in "${services[@]}"; do | |
service_sha=$(echo '${{ needs.build.outputs.matrix-result }}' | jq -r ".[\"$service\"]") | |
# Ensure service_sha is valid before updating deployment | |
if [[ -n "$service" && -n "$service_sha" && "$service_sha" != "false" && "$service_sha" != "null" ]]; then | |
deployment_name="testnet-$service" | |
image_name="ghcr.io/nearblocks/$service:$service_sha" | |
echo "Updating deployment for $deployment_name with image: $image_name" | |
kubectl set image deployment/$deployment_name $service=$image_name | |
echo "Verifying rollout for $deployment_name" | |
if ! kubectl rollout status deployment/$deployment_name --timeout=600s; then | |
echo "Rollout failed for $deployment_name" | |
failed_deployments+=("$deployment_name") | |
fi | |
else | |
echo "Skipping deployment for testnet-$service (no updates or invalid SHA)" | |
fi | |
done | |
if [ ${#failed_deployments[@]} -ne 0 ]; then | |
echo "The following deployments failed:" | |
printf '%s\n' "${failed_deployments[@]}" | |
exit 1 | |
fi | |
- name: Rollback failed testnet deployments | |
if: failure() | |
run: | | |
kubectl config set-context --current --namespace=nearblocks-testnet | |
# Services to rollback for testnet | |
services=(api app backend indexer-balance indexer-base indexer-events explorer-selector aggregates) | |
for service in "${services[@]}"; do | |
service_sha=$(echo '${{ needs.build.outputs.matrix-result }}' | jq -r ".[\"$service\"]") | |
if [[ "$service_sha" != "false" && "$service_sha" != "null" ]]; then | |
deployment_name="testnet-$service" | |
echo "Attempting rollback for $deployment_name" | |
kubectl rollout undo deployment/$deployment_name | |
fi | |
done | |
- name: Deploy and verify mainnet | |
run: | | |
kubectl config set-context --current --namespace=nearblocks | |
# Define the list of services for mainnet deployment (includes app-lite) | |
services=(api app app-lite backend indexer-balance indexer-base indexer-events indexer-dex indexer-multichain explorer-selector aggregates) | |
failed_deployments=() | |
for service in "${services[@]}"; do | |
service_sha=$(echo '${{ needs.build.outputs.matrix-result }}' | jq -r ".[\"$service\"]") | |
# Ensure service_sha is valid before updating deployment | |
if [[ -n "$service" && -n "$service_sha" && "$service_sha" != "false" && "$service_sha" != "null" ]]; then | |
# Adjust the deployment name for app-lite specifically | |
if [[ "$service" == "app-lite" ]]; then | |
deployment_name="mainnet-lite-lite" | |
else | |
deployment_name="mainnet-$service" | |
fi | |
image_name="ghcr.io/nearblocks/$service:$service_sha" | |
echo "Updating deployment for $deployment_name with image: $image_name" | |
kubectl set image deployment/$deployment_name $service=$image_name | |
echo "Verifying rollout for $deployment_name" | |
if ! kubectl rollout status deployment/$deployment_name --timeout=600s; then | |
echo "Rollout failed for $deployment_name" | |
failed_deployments+=("$deployment_name") | |
fi | |
else | |
echo "Skipping deployment for mainnet-$service (no updates or invalid SHA)" | |
fi | |
done | |
if [ ${#failed_deployments[@]} -ne 0 ]; then | |
echo "The following deployments failed:" | |
printf '%s\n' "${failed_deployments[@]}" | |
exit 1 | |
fi | |
- name: Rollback failed mainnet deployments | |
if: failure() | |
run: | | |
kubectl config set-context --current --namespace=nearblocks | |
# Services to rollback for mainnet (includes app-lite with specific name) | |
services=(api app app-lite backend indexer-balance indexer-base indexer-events indexer-dex indexer-multichain explorer-selector aggregates) | |
for service in "${services[@]}"; do | |
service_sha=$(echo '${{ needs.build.outputs.matrix-result }}' | jq -r ".[\"$service\"]") | |
# Adjust rollback deployment name for app-lite specifically | |
if [[ "$service" == "app-lite" ]]; then | |
deployment_name="mainnet-lite-lite" | |
else | |
deployment_name="mainnet-$service" | |
fi | |
if [[ "$service_sha" != "false" && "$service_sha" != "null" ]]; then | |
echo "Attempting rollback for $deployment_name" | |
kubectl rollout undo deployment/$deployment_name | |
fi | |
done | |
- name: Notify on failure | |
if: failure() | |
run: | | |
echo "Deployment failed. Manual intervention may be required." |