Deploy to Novu Cloud #38
Workflow file for this run
This file contains hidden or 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: Deploy to Novu Cloud | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: 'Environment to deploy to' | |
required: true | |
type: choice | |
default: staging | |
options: | |
- staging | |
- production-us | |
- production-eu | |
- production-both | |
deploy_api: | |
description: 'Deploy API' | |
required: true | |
type: boolean | |
default: true | |
deploy_worker: | |
description: 'Deploy Worker' | |
required: true | |
type: boolean | |
default: false | |
deploy_ws: | |
description: 'Deploy WS' | |
required: true | |
type: boolean | |
default: false | |
deploy_webhook: | |
description: 'Deploy Webhook' | |
required: true | |
type: boolean | |
default: false | |
jobs: | |
prepare-matrix: | |
runs-on: ubuntu-latest | |
outputs: | |
env_matrix: ${{ steps.set-matrix.outputs.env_matrix }} | |
service_matrix: ${{ steps.set-matrix.outputs.service_matrix }} | |
deploy_matrix: ${{ steps.set-matrix.outputs.deploy_matrix }} | |
steps: | |
- name: Generate Environment, Service, and Deploy Matrices | |
id: set-matrix | |
env: | |
WORKER_SERVICE: ${{ secrets.WORKER_SERVICE }} | |
run: | | |
envs=() | |
services=() | |
deploy_matrix=() | |
# Collect selected environments | |
if [ "${{ github.event.inputs.environment }}" == "staging" ]; then | |
envs+=("\"staging-eu\"") | |
fi | |
if [ "${{ github.event.inputs.environment }}" == "production-us" ]; then | |
envs+=("\"prod\"") | |
fi | |
if [ "${{ github.event.inputs.environment }}" == "production-eu" ]; then | |
envs+=("\"prod-eu\"") | |
fi | |
if [ "${{ github.event.inputs.environment }}" == "production-both" ]; then | |
envs+=("\"prod\"") | |
envs+=("\"prod-eu\"") | |
fi | |
# Collect selected services | |
if [ "${{ github.event.inputs.deploy_api }}" == "true" ]; then | |
services+=("\"api\"") | |
fi | |
if [ "${{ github.event.inputs.deploy_worker }}" == "true" ]; then | |
services+=("\"worker\"") | |
fi | |
if [ "${{ github.event.inputs.deploy_ws }}" == "true" ]; then | |
services+=("\"ws\"") | |
fi | |
if [ "${{ github.event.inputs.deploy_webhook }}" == "true" ]; then | |
services+=("\"webhook\"") | |
fi | |
# Parse service secrets and generate deploy_matrix | |
for service in "${services[@]}"; do | |
if [ "$service" == "\"worker\"" ]; then | |
IFS=',' read -r -a worker_services <<< "$WORKER_SERVICE" | |
for worker_service in "${worker_services[@]}"; do | |
cluster_name=$(echo "$worker_service" | jq -r '.cluster_name') | |
container_name=$(echo "$worker_service" | jq -r '.container_name') | |
service_name=$(echo "$worker_service" | jq -r '.service') | |
task_name=$(echo "$worker_service" | jq -r '.task_name') | |
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\"}") | |
done | |
elif [ "$service" == "\"api\"" ]; then | |
cluster_name=api-cluster | |
container_name=api-container | |
service_name=api-service | |
task_name=api-task | |
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\"}") | |
elif [ "$service" == "\"ws\"" ]; then | |
cluster_name=ws-cluster | |
container_name=ws-container | |
service_name=ws-service | |
task_name=ws-task | |
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\"}") | |
elif [ "$service" == "\"webhook\"" ]; then | |
cluster_name=webhook-cluster | |
container_name=webhook-container | |
service_name=webhook-service | |
task_name=webhook-task | |
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\"}") | |
fi | |
done | |
env_matrix="{\"environment\": [$( | |
IFS=','; echo "${envs[*]}" | |
)]}" | |
service_matrix="{\"service\": [$( | |
IFS=','; echo "${services[*]}" | |
)]}" | |
deploy_matrix="[$( | |
IFS=','; echo "${deploy_matrix[*]}" | |
)]" | |
echo "env_matrix=$env_matrix" >> $GITHUB_OUTPUT | |
echo "service_matrix=$service_matrix" >> $GITHUB_OUTPUT | |
echo "deploy_matrix=$deploy_matrix" >> $GITHUB_OUTPUT | |
build: | |
needs: prepare-matrix | |
timeout-minutes: 60 | |
runs-on: ubuntu-latest | |
environment: ${{ fromJson(needs.prepare-matrix.outputs.env_matrix).environment[0] }} | |
outputs: | |
registry: ${{ steps.build-image.outputs.registry }} | |
strategy: | |
matrix: | |
service: ${{ fromJson(needs.prepare-matrix.outputs.service_matrix).service }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
submodules: true | |
fetch-depth: 0 | |
token: ${{ secrets.SUBMODULES_TOKEN }} | |
- name: Install pnpm | |
uses: pnpm/action-setup@v4 | |
with: | |
version: 9.11.0 | |
run_install: false | |
- name: Setup Node Version | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20.8.1' | |
cache: 'pnpm' | |
- name: Install Dependencies | |
shell: bash | |
run: pnpm install --frozen-lockfile | |
- name: Set Up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
with: | |
driver-opts: 'image=moby/buildkit:v0.13.1' | |
- name: Prepare Variables | |
run: echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID}} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ vars.AWS_REGION }} | |
- name: Login to Amazon ECR | |
id: login-ecr | |
uses: aws-actions/amazon-ecr-login@v2 | |
- name: Build, tag, and push image to Amazon ECR | |
id: build-image | |
env: | |
REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
REPOSITORY: ${{ vars.ECR_REPO_PREFIX }} | |
SERVICE: ${{ matrix.service }} | |
IMAGE_TAG: ${{ github.sha }} | |
DOCKER_BUILD_ARGUMENTS: > | |
--platform=linux/amd64 | |
--output=type=image,name=$REGISTRY/$REPOSITORY/$SERVICE,push-by-digest=true,name-canonical=true | |
run: | | |
cp scripts/dotenvcreate.mjs apps/$SERVICE/src/dotenvcreate.mjs | |
cd apps/$SERVICE && pnpm run docker:build | |
docker tag novu-$SERVICE $REGISTRY/$REPOSITORY/$SERVICE:latest | |
docker tag novu-$SERVICE $REGISTRY/$REPOSITORY/$SERVICE:$IMAGE_TAG | |
docker push $REGISTRY/$REPOSITORY/$SERVICE:latest | |
docker push $REGISTRY/$REPOSITORY/$SERVICE:$IMAGE_TAG | |
echo "registry=$REGISTRY/$REPOSITORY" >> $GITHUB_OUTPUT | |
deploy: | |
needs: [build, prepare-matrix] | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
env: ${{ fromJson(needs.prepare-matrix.outputs.env_matrix).environment }} | |
service: ${{ fromJson(needs.prepare-matrix.outputs.deploy_matrix) }} | |
steps: | |
- name: Print Important Info | |
env: | |
IMAGE_TAG: ${{ github.sha }} | |
REGISTRY: ${{ needs.build.outputs.registry }} | |
run: | | |
echo "Deploying to cluster: ${{matrix.env}}-${{ matrix.service.cluster_name }}" | |
echo "Deploying to service: ${{matrix.env}}-${{ matrix.service.service_name }}" | |
echo "Deploying to container: ${{ matrix.service.container_name }}" | |
echo "Deploying to task: ${{ matrix.service.task_name }}" | |
echo "Deploying to environment: ${{ matrix.env }}" | |
echo "Deploying to image: $REGISTRY/$IMAGE_TAG" |