Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"amannn",
"analagous",
"Angularjs",
"sinch",
"evalsha",
"antd",
"anthonybaxter",
Expand Down Expand Up @@ -768,7 +769,8 @@
"smsmode",
"BLKTM",
"Novuand",
"kobalte"
"kobalte",
"jsonrepair"
],
"flagWords": [],
"patterns": [
Expand Down
92 changes: 72 additions & 20 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,42 @@ description: |
It builds Docker images, pushes them to Amazon ECR, and deploys them to Amazon ECS.
Additionally, it creates Sentry releases and New Relic deployment markers.

env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}

on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy to'
description: "Environment to deploy to"
required: true
type: choice
default: staging
options:
- staging
- staging-apse1
- production-us
- production-eu
- production-both
- production-apse1
- production-us-and-eu

deploy_api:
description: 'Deploy API'
description: "Deploy API"
required: true
type: boolean
default: true
deploy_worker:
description: 'Deploy Worker'
description: "Deploy Worker"
required: true
type: boolean
default: false
deploy_ws:
description: 'Deploy WS'
description: "Deploy WS"
required: true
type: boolean
default: false
deploy_webhook:
description: 'Deploy Webhook'
description: "Deploy Webhook"
required: true
type: boolean
default: false
Expand Down Expand Up @@ -84,13 +89,19 @@ jobs:
if [ "${{ github.event.inputs.environment }}" == "staging" ]; then
envs+=("\"staging-eu\"")
fi
if [ "${{ github.event.inputs.environment }}" == "staging-apse1" ]; then
envs+=("\"staging-apse1\"")
fi
if [ "${{ github.event.inputs.environment }}" == "production-us" ]; then
envs+=("\"prod-us\"")
fi
if [ "${{ github.event.inputs.environment }}" == "production-eu" ]; then
envs+=("\"prod-eu\"")
fi
if [ "${{ github.event.inputs.environment }}" == "production-both" ]; then
if [ "${{ github.event.inputs.environment }}" == "production-apse1" ]; then
envs+=("\"prod-apse1\"")
fi
if [ "${{ github.event.inputs.environment }}" == "production-us-and-eu" ]; then
envs+=("\"prod-us\"")
envs+=("\"prod-eu\"")
fi
Expand Down Expand Up @@ -121,7 +132,28 @@ jobs:
service_name=$(echo "$worker_service" | jq -r '.service')
task_name=$(echo "$worker_service" | jq -r '.task_name')
image=$(echo "$worker_service" | jq -r '.image')
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\", \"image\": \"$image\"}")

# Check if service has environments filter, otherwise deploy to all
allowed_envs=$(echo "$worker_service" | jq -r '.environments // empty')
should_deploy=false

if [ -z "$allowed_envs" ]; then
# No environment filter, deploy to all environments
should_deploy=true
else
# Check if any of the selected environments match the allowed environments
for env in "${envs[@]}"; do
env_clean=$(echo "$env" | tr -d '"')
if echo "$allowed_envs" | jq -e --arg env "$env_clean" 'index($env) != null' > /dev/null; then
should_deploy=true
break
fi
done
fi

if [ "$should_deploy" == "true" ]; then
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\", \"image\": \"$image\"}")
fi
done
elif [ "$service" == "\"api\"" ]; then
for api_service in $(echo "$API_SERVICE" | jq -c '.[]'); do
Expand All @@ -130,7 +162,28 @@ jobs:
service_name=$(echo "$api_service" | jq -r '.service')
task_name=$(echo "$api_service" | jq -r '.task_name')
image=$(echo "$api_service" | jq -r '.image')
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\", \"image\": \"$image\"}")

# Check if service has environments filter, otherwise deploy to all
allowed_envs=$(echo "$api_service" | jq -r '.environments // empty')
should_deploy=false

if [ -z "$allowed_envs" ]; then
# No environment filter, deploy to all environments
should_deploy=true
else
# Check if any of the selected environments match the allowed environments
for env in "${envs[@]}"; do
env_clean=$(echo "$env" | tr -d '"')
if echo "$allowed_envs" | jq -e --arg env "$env_clean" 'index($env) != null' > /dev/null; then
should_deploy=true
break
fi
done
fi

if [ "$should_deploy" == "true" ]; then
deploy_matrix+=("{\"cluster_name\": \"$cluster_name\", \"container_name\": \"$container_name\", \"service_name\": \"$service_name\", \"task_name\": \"$task_name\", \"image\": \"$image\"}")
fi
done
elif [ "$service" == "\"ws\"" ]; then
cluster_name=ws-cluster
Expand Down Expand Up @@ -192,8 +245,8 @@ jobs:
- name: Setup Node Version
uses: actions/setup-node@v4
with:
node-version: '20.19.0'
cache: 'pnpm'
node-version: "20.19.0"
cache: "pnpm"

- name: Install Dependencies
shell: bash
Expand All @@ -202,7 +255,7 @@ jobs:
- name: Set Up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: 'image=moby/buildkit:v0.13.1'
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
Expand Down Expand Up @@ -303,7 +356,7 @@ jobs:
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
SENTRY_PROJECT: ${{ matrix.service }}
with:
version: '${{ github.sha }}'
version: "${{ github.sha }}"
version_prefix: v
environment: ${{vars.SENTRY_ENV}}
ignore_empty: true
Expand All @@ -326,9 +379,9 @@ jobs:
region: EU
apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
guid: ${{ matrix.nr == 'api' && secrets.NEW_RELIC_API_GUID || matrix.nr == 'worker' && secrets.NEW_RELIC_Worker_GUID }}
version: '${{ github.sha }}'
user: '${{ github.actor }}'
description: 'Novu Cloud Deployment'
version: "${{ github.sha }}"
user: "${{ github.actor }}"
description: "Novu Cloud Deployment"

sync_novu_state:
needs: [deploy, prepare-matrix]
Expand All @@ -350,22 +403,21 @@ jobs:
needs.deploy.result == 'success' &&
(contains(github.event.inputs.environment, 'production'))
environment: ${{ fromJson(needs.prepare-matrix.outputs.env_matrix).environment[0] }}

steps:
- name: Send webhook notification for US production
if: |
github.event.inputs.environment == 'production-us' ||
github.event.inputs.environment == 'production-both'
github.event.inputs.environment == 'production-us-and-eu'
run: |
curl -X POST https://webhooks.bug0.com/integrations/test/run \
-H "Content-Type: application/json" \
-H "x-api-key: ${{ secrets.BUG0_SECRET_KEY }}" \
-d '{"url": "https://dashboard.novu.co", "source": "novuhq-novu", "prod": "true"}'

- name: Send webhook notification for EU production
if: |
github.event.inputs.environment == 'production-eu' ||
github.event.inputs.environment == 'production-both'
github.event.inputs.environment == 'production-us-and-eu'
run: |
curl -X POST https://webhooks.bug0.com/integrations/test/run \
-H "Content-Type: application/json" \
Expand Down
29 changes: 21 additions & 8 deletions .github/workflows/manual-post-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ on:
required: true
type: boolean
default: false
mark_as_latest:
description: 'Mark the packages as latest'
required: true
type: boolean
default: true

env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
Expand All @@ -33,11 +38,11 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
ref: next
ref: ${{ github.ref_name }}

- name: Pull latest changes
run: |
git pull origin next
git pull origin ${{ github.ref_name }}

- name: Install pnpm
uses: pnpm/action-setup@v4
Expand All @@ -63,8 +68,8 @@ jobs:
- name: Publish packages to NPM
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NX_PUBLISH_ARGS: ${{ github.event.inputs.mark_as_latest == 'true' && '--tag latest' || '' }}
run: |
export NX_RELEASE_TAG=latest
pnpm nx run-many -t nx-release-publish --projects=${{ github.event.inputs.packages }}

- name: Create and push tags
Expand Down Expand Up @@ -122,10 +127,18 @@ jobs:
done

# Create the GitHub release
gh release create "$tag_name" \
--title "$tag_name" \
--notes "$release_body" \
--target next

if [ "${{ github.event.inputs.mark_as_latest }}" = "true" ]; then
gh release create "$tag_name" \
--title "$tag_name" \
--notes "$release_body" \
--target next
else
gh release create "$tag_name" \
--title "$tag_name" \
--notes "$release_body" \
--target next \
--latest=false
fi

echo "✅ Created GitHub release for $tag_name"
done
13 changes: 7 additions & 6 deletions .github/workflows/release-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
ref: ${{ github.ref_name }}

- name: Install pnpm
uses: pnpm/action-setup@v4
Expand Down Expand Up @@ -101,9 +102,9 @@ jobs:
- name: Publish packages (nightly only)
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NX_PUBLISH_ARGS: --tag nightly
run: |
if [ "${{ github.event.inputs.nightly }}" = "true" ]; then
export NX_RELEASE_TAG=nightly
pnpm nx run-many -t nx-release-publish --projects=${{ github.event.inputs.packages }}
else
echo "Skipping publish for non-nightly release"
Expand All @@ -118,20 +119,20 @@ jobs:
title: "🚀 Release ${{ github.event.inputs.version }} - ${{ github.event.inputs.packages }}"
body: |
## 🚀 Release ${{ github.event.inputs.version }}

This PR contains the release changes for version **${{ github.event.inputs.version }}**

### 📦 Packages Released:
```
${{ github.event.inputs.packages }}
```

### 🔄 Changes:
- Updated package versions to ${{ github.event.inputs.version }}
- Generated changelogs from ${{ github.event.inputs.previous_tag }}
- Built packages for release

**Please review the changes and merge when ready for the release to be tagged and GitHub releases to be created.**
branch: release-${{ github.event.inputs.version }}
base: next
base: ${{ github.ref_name }}
delete-branch: false
2 changes: 1 addition & 1 deletion .source
2 changes: 1 addition & 1 deletion apps/api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ RUN --mount=type=cache,id=pnpm-store-api,target=/root/.pnpm-store\
ENV NEW_RELIC_NO_CONFIG_FILE=true

WORKDIR /usr/src/app/apps/api
ENTRYPOINT [ "sh", "-c", "node dist/dotenvcreate.mjs -s=novu/api -r=$NOVU_REGION -e=$NOVU_ENTERPRISE -v=$NODE_ENV -h=$IS_SELF_HOSTED && pm2-runtime start dist/main.js -i max" ]
ENTRYPOINT [ "sh", "-c", "node dist/dotenvcreate.mjs -s=$SECRET_NAME -r=$NOVU_REGION -e=$NOVU_ENTERPRISE -v=$NODE_ENV -h=$IS_SELF_HOSTED && pm2-runtime start dist/main.js -i max" ]
2 changes: 1 addition & 1 deletion apps/api/e2e/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async function getDatabaseConnection(): Promise<Connection> {
async function dropDatabase(): Promise<void> {
try {
const conn = await getDatabaseConnection();
await conn.db.dropDatabase();
await conn.dropDatabase();
} catch (error) {
console.error('Error dropping the database:', error);
}
Expand Down
Loading
Loading