From f8cef99877109325a6cf0c14a1607f1dffa4b52a Mon Sep 17 00:00:00 2001 From: Himanshu Garg Date: Wed, 30 Oct 2024 15:11:55 +0530 Subject: [PATCH] feat(root): move docker images from github packages to aws ecr (#6792) --- .github/actions/docker/build-api/action.yml | 91 +++++------- .../actions/docker/build-worker/action.yml | 95 +++++------- .github/workflows/cloud-deploy.yml | 105 -------------- .../cloud-deploy/cloud-deploy-api.yml | 136 ------------------ .../cloud-deploy/cloud-deploy-embed.yml | 28 ---- .../cloud-deploy-web-components.yml | 40 ------ .../cloud-deploy/cloud-deploy-web.yml | 45 ------ .../cloud-deploy/cloud-deploy-webhook.yml | 41 ------ .../cloud-deploy/cloud-deploy-widget.yml | 38 ----- .../cloud-deploy/cloud-deploy-worker.yml | 136 ------------------ .../cloud-deploy/cloud-deploy-ws.yml | 116 --------------- .github/workflows/dev-deploy-api.yml | 11 +- .github/workflows/dev-deploy-dashboard.yml | 12 -- .github/workflows/dev-deploy-inbound-mail.yml | 77 +++++----- .github/workflows/dev-deploy-web.yml | 12 -- .github/workflows/dev-deploy-webhook.yml | 3 +- .github/workflows/dev-deploy-worker.yml | 22 ++- .github/workflows/dev-deploy-ws.yml | 78 +++++----- .github/workflows/prod-deploy-api.yml | 66 ++++----- .github/workflows/prod-deploy-webhook.yml | 2 + .github/workflows/prod-deploy-worker.yml | 65 ++++----- .github/workflows/prod-deploy-ws.yml | 71 ++++----- .github/workflows/reusable-docker.yml | 91 ++++++------ 23 files changed, 285 insertions(+), 1096 deletions(-) delete mode 100644 .github/workflows/cloud-deploy.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-api.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-embed.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-web-components.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-web.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-webhook.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-widget.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-worker.yml delete mode 100644 .github/workflows/cloud-deploy/cloud-deploy-ws.yml diff --git a/.github/actions/docker/build-api/action.yml b/.github/actions/docker/build-api/action.yml index 44756bac497..1014040be21 100644 --- a/.github/actions/docker/build-api/action.yml +++ b/.github/actions/docker/build-api/action.yml @@ -10,8 +10,11 @@ inputs: description: 'Push the image to the registry' required: false default: 'false' - github_token: - description: 'The token to use for logging into ghcr.io' + aws-access-key-id: + description: 'Access Key for AWS' + required: true + aws-secret-access-key: + description: 'Secret Access Key for AWS' required: true fork: description: 'Whether this is being triggered from a forked repo' @@ -20,10 +23,6 @@ inputs: docker_name: description: 'Name for docker image' required: true - environment: - required: false - type: string - bullmq_secret: description: 'Bullmq secret api token' required: true @@ -36,29 +35,6 @@ outputs: runs: using: composite steps: - - name: ⛏️ build api - shell: bash - run: pnpm build:api - - # TODO Removed when migrated to action matrix for each build type - - uses: ./.github/actions/free-space - - uses: ./.github/actions/cache - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -70,13 +46,16 @@ runs: service=${{ matrix.name }} echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - - name: Login To Registry - shell: bash - env: - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} - run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ inputs.aws-access-key-id }} + aws-secret-access-key: ${{ inputs.aws-secret-access-key }} + aws-region: eu-west-2 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 - name: Set Bull MQ Env variable for EE shell: bash @@ -87,16 +66,12 @@ runs: - name: Build with Buildx, tag, and test shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.environment }} - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.environment }},mode=max --platform=linux/amd64 --provenance=false - --output=type=image,name=ghcr.io/novuhq/${{ inputs.docker_name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | set -x cd apps/api && pnpm run docker:build @@ -105,45 +80,43 @@ runs: id: build-image shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} run: | echo "Built image" - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker tag novu-api $REGISTRY/$REPOSITORY:$IMAGE_TAG - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker run --network=host --name api -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1337/v1/health-check | grep 'ok' - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - name: Optionally tag docker image if: ${{ inputs.tag }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} run: | - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:${{ inputs.tag }} + docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:${{ inputs.tag }} - name: Push PR tag image if: ${{ inputs.push == 'true' }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} run: | - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG - name: Push custom tag image if: ${{ inputs.push == 'true' && inputs.tag }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/api run: | - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:${{ inputs.tag }} + docker push $REGISTRY/$REPOSITORY:${{ inputs.tag }} diff --git a/.github/actions/docker/build-worker/action.yml b/.github/actions/docker/build-worker/action.yml index 9f51fcaaa80..6986429664d 100644 --- a/.github/actions/docker/build-worker/action.yml +++ b/.github/actions/docker/build-worker/action.yml @@ -10,8 +10,11 @@ inputs: description: 'Push the image to the registry' required: false default: 'false' - github_token: - description: 'The token to use for logging into ghcr.io' + aws-access-key-id: + description: 'Access Key for AWS' + required: true + aws-secret-access-key: + description: 'Secret Access Key for AWS' required: true fork: description: 'Whether this is being triggered from a forked repo' @@ -20,10 +23,6 @@ inputs: docker_name: description: 'Name for docker image' required: true - environment: - required: false - type: string - bullmq_secret: description: 'Bullmq secret api token' required: true @@ -36,29 +35,6 @@ outputs: runs: using: composite steps: - - name: ⛏️ build worker - shell: bash - run: pnpm build:worker - - # TODO Removed when migrated to action matrix for each build type - - uses: ./.github/actions/free-space - - uses: ./.github/actions/cache - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -70,13 +46,16 @@ runs: service=${{ matrix.name }} echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - - name: Login To Registry - shell: bash - env: - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} - run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ inputs.aws-access-key-id }} + aws-secret-access-key: ${{ inputs.aws-secret-access-key }} + aws-region: eu-west-2 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 - name: Set Bull MQ Env variable for EE shell: bash @@ -87,16 +66,12 @@ runs: - name: Build with Buildx, tag, and test shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.environment }} - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.environment }},mode=max --platform=linux/amd64 --provenance=false - --output=type=image,name=ghcr.io/novuhq/${{ inputs.docker_name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | set -x cd apps/worker && pnpm run docker:build @@ -105,47 +80,43 @@ runs: id: build-image shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ inputs.github_token }} run: | - echo "Tag image" - docker images --all - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + echo "Built image" + docker tag novu-worker $REGISTRY/$REPOSITORY:$IMAGE_TAG - echo "Run image" - docker run --network=host --name worker -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker run --network=host --name worker -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1342/v1/health-check | grep 'ok' - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - name: Optionally tag docker image if: ${{ inputs.tag }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} run: | - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:${{ inputs.tag }} + docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:${{ inputs.tag }} - name: Push PR tag image if: ${{ inputs.push == 'true' }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} run: | - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG - name: Push custom tag image if: ${{ inputs.push == 'true' && inputs.tag }} shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ inputs.docker_name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/worker run: | - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:${{ inputs.tag }} + docker push $REGISTRY/$REPOSITORY:${{ inputs.tag }} diff --git a/.github/workflows/cloud-deploy.yml b/.github/workflows/cloud-deploy.yml deleted file mode 100644 index f9d847ac31f..00000000000 --- a/.github/workflows/cloud-deploy.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: Release Prod -on: - workflow_dispatch: - push: - branches: - - prod - -jobs: - pre-release: - runs-on: ubuntu-latest - steps: - - - name: Start Deployment Notification - uses: actions/slack@master - with: - channel: '#eng-feed-deployments' - message: 'Release has started' - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - - release-api: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-api.yml - - release-embed: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-embed.yml - - release-web: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-web.yml - - release-web-components: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-web-components.yml - - release-webhook: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-webhook.yml - - release-widget: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-widget.yml - - release-worker: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-worker.yml - - release-ws: - needs: [pre-release] - runs-on: ubuntu-latest - steps: - - uses: ./.github/workflows/cloud-deploy/cloud-deploy-ws.yml - - post-release: - if: ${{ always() }} - needs: [ - release-api, - release-embed, - release-web, - release-web-components, - release-webhook, - release-widget, - release-worker, - release-ws - ] - runs-on: ubuntu-latest - steps: - - name: Deploy API Documentation - uses: fjogeleit/http-request-action@v1 - with: - url: ${{ secrets.API_DOCS_BUILD_WEBHOOK }} - method: 'POST' - - - name: Start Deployment Notification - if: ${{ failure() }} # This step runs only if any of the previous jobs fail. - uses: actions/slack@master - with: - channel: '#eng-feed-deployments' - message: 'Release has failed' - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - - - name: Start Deployment Notification - if: ${{ success() }} # This step runs only if all the previous jobs succeed. - uses: actions/slack@master - with: - channel: '#eng-feed-deployments' - message: 'Release has finished' - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/cloud-deploy/cloud-deploy-api.yml b/.github/workflows/cloud-deploy/cloud-deploy-api.yml deleted file mode 100644 index 79e6a446705..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-api.yml +++ /dev/null @@ -1,136 +0,0 @@ -name: Deploy PROD API - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -on: - workflow_call: - -jobs: - - build_prod_image: - runs-on: ubuntu-latest - timeout-minutes: 15 - environment: Production - strategy: - matrix: - name: [ 'novu/api-ee' ] - outputs: - docker_image: ${{ steps.build-image.outputs.IMAGE }} - permissions: - contents: read - packages: write - deployments: write - id-token: write - steps: - - uses: actions/checkout@v4 - with: - submodules: ${{ contains (matrix.name,'-ee') }} - token: ${{ secrets.SUBMODULES_TOKEN }} - - uses: ./.github/actions/setup-project - with: - submodules: ${{ contains (matrix.name,'-ee') }} - - - name: build api - run: pnpm build:api - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - - name: Set Up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: 'image=moby/buildkit:v0.13.1' - - - name: Prepare - shell: bash - run: | - service=${{ matrix.name }} - echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - - - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') - shell: bash - run: | - echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} - IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} - DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max - --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true - run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - cd apps/api && pnpm --silent --workspace-root pnpm-context -- apps/api/Dockerfile | BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN --build-arg PACKAGE_PATH=apps/api - -t novu-api --load $DOCKER_BUILD_ARGUMENTS - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1337/v1/health-check | grep 'ok' - - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT - - deploy_prod_api_eu: - needs: build_prod_image - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: api - terraform_workspace: novu-prod-eu - docker_image: ghcr.io/novuhq/novu/api-ee:${{ github.sha }} - - deploy_prod_api_us: - needs: - - build_prod_image - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: api - terraform_workspace: novu-prod - docker_image: ghcr.io/novuhq/novu/api-ee:${{ github.sha }} - deploy_sentry_release: true - sentry_project: api - - newrelic: - runs-on: ubuntu-latest - name: New Relic Deploy - needs: deploy_prod_api_us - environment: Production - steps: - # This step builds a var with the release tag value to use later - - name: Set Release Version from Tag - run: echo "RELEASE_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV - # This step creates a new Change Tracking Marker - - name: New Relic Application Deployment Marker - uses: newrelic/deployment-marker-action@v2.3.0 - with: - region: EU - apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" diff --git a/.github/workflows/cloud-deploy/cloud-deploy-embed.yml b/.github/workflows/cloud-deploy/cloud-deploy-embed.yml deleted file mode 100644 index 9dec8db9117..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-embed.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Deploy PROD EMBED - -on: - workflow_call: - -jobs: - deploy_embed_eu: - uses: ./.github/workflows/reusable-embed-deploy.yml - with: - environment: Production - widget_url: https://eu.widget.novu.co - netlify_deploy_message: Production deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 0c830b50-df83-480b-ba36-a7f3176efcc8 - secrets: inherit - - deploy_embed_us: - uses: ./.github/workflows/reusable-embed-deploy.yml - with: - environment: Production - widget_url: https://widget.novu.co - netlify_deploy_message: Production deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 0689c015-fca0-4940-a26d-3e33f561bc48 - secrets: inherit - diff --git a/.github/workflows/cloud-deploy/cloud-deploy-web-components.yml b/.github/workflows/cloud-deploy/cloud-deploy-web-components.yml deleted file mode 100644 index e70078d5529..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-web-components.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Deploy PROD Notification Center Web Component - -on: - workflow_call: - -jobs: - build: - uses: ./.github/workflows/reusable-notification-center.yml - - deploy_web_component: - needs: build - runs-on: ubuntu-latest - timeout-minutes: 15 - if: "!contains(github.event.head_commit.message, 'ci skip')" - environment: Production - - steps: - - uses: actions/checkout@v4 - - - name: Download the artifact - uses: actions/download-artifact@v4 - with: - name: notification-center-web-component - path: packages/notification-center/dist/umd - - - name: Deploy Notification Center Web Component to PROD - uses: scopsy/actions-netlify@develop - with: - publish-dir: packages/notification-center/dist/umd - github-token: ${{ secrets.GITHUB_TOKEN }} - deploy-message: prod - production-deploy: true - alias: prod - github-deployment-environment: Production - github-deployment-description: Notification Center Web Component Deployment - netlify-config-path: packages/notification-center/netlify.toml - env: - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} - NETLIFY_SITE_ID: 468165e2-bd64-4f33-9fd9-4b93ef8a0be0 - timeout-minutes: 1 diff --git a/.github/workflows/cloud-deploy/cloud-deploy-web.yml b/.github/workflows/cloud-deploy/cloud-deploy-web.yml deleted file mode 100644 index 1ae021f9f28..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-web.yml +++ /dev/null @@ -1,45 +0,0 @@ - -name: Deploy PROD WEB - -on: - workflow_call: - -jobs: - - deploy_web_eu: - uses: ./.github/workflows/reusable-web-deploy.yml - with: - environment: Production - react_app_api_url: https://eu.api.novu.co - react_app_ws_url: https://eu.ws.novu.co - react_app_webhook_url: https://eu.webhook.novu.co - react_app_widget_embed_path: https://eu.embed.novu.co/embed.umd.min.js - react_app_sentry_dsn: https://2b5160da86384949be4cc66679c54e79@o1161119.ingest.sentry.io/6250907 - react_app_environment: production - react_app_mail_server_domain: eu.inbound-mail.novu.co - react_app_hubspot_embed: 44416662 - netlify_deploy_message: Prod deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: d2e8b860-7016-4202-9256-ebca0f13259a - secrets: inherit - - deploy_web_us: - needs: - - deploy_web_eu - uses: ./.github/workflows/reusable-web-deploy.yml - with: - environment: Production - react_app_api_url: https://api.novu.co - react_app_ws_url: https://ws.novu.co - react_app_webhook_url: https://webhook.novu.co - react_app_widget_embed_path: https://embed.novu.co/embed.umd.min.js - react_app_sentry_dsn: https://2b5160da86384949be4cc66679c54e79@o1161119.ingest.sentry.io/6250907 - react_app_environment: production - react_app_mail_server_domain: inbound-mail.novu.co - react_app_hubspot_embed: 44416662 - netlify_deploy_message: Prod deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 8639d8b9-81f9-44c3-b885-585a7fd2b5ff - secrets: inherit diff --git a/.github/workflows/cloud-deploy/cloud-deploy-webhook.yml b/.github/workflows/cloud-deploy/cloud-deploy-webhook.yml deleted file mode 100644 index 9e76df656e3..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-webhook.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Deploy PROD WEBHOOK - -on: - workflow_call: - -jobs: - - publish_docker_image_webhook: - needs: test_webhook - uses: ./.github/workflows/reusable-docker.yml - with: - environment: Production - package_name: novu/webhook - project_path: apps/webhook - test_port: 1341 - health_check: true - local_tag: novu-webhook - env_tag: prod - secrets: inherit - - deploy_prod_webhook_eu: - needs: - - publish_docker_image_webhook - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: webhook - terraform_workspace: novu-prod-eu - docker_image: ${{ needs.publish_docker_image_webhook.outputs.docker_image_ee }} - - deploy_prod_webhook_us: - needs: - - publish_docker_image_webhook - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: webhook - terraform_workspace: novu-prod - docker_image: ${{ needs.publish_docker_image_webhook.outputs.docker_image_ee }} diff --git a/.github/workflows/cloud-deploy/cloud-deploy-widget.yml b/.github/workflows/cloud-deploy/cloud-deploy-widget.yml deleted file mode 100644 index 649b79d2254..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-widget.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Deploy PROD Widget - -on: - workflow_call: - -jobs: - - deploy_widget_eu: - uses: ./.github/workflows/reusable-widget-deploy.yml - with: - environment: Production - react_app_api_url: https://eu.api.novu.co - react_app_ws_url: https://eu.ws.novu.co - react_app_webhook_url: https://eu.webhook.novu.co - react_app_sentry_dsn: https://02189965b1bb4cf8bb4776f417f80b92@o1161119.ingest.sentry.io/625116 - react_app_environment: production - netlify_deploy_message: Prod deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 20a64bdd-1934-4284-875f-862410c69a3b - secrets: inherit - - deploy_widget_us: - needs: - - test_widget - uses: ./.github/workflows/reusable-widget-deploy.yml - with: - environment: Production - react_app_api_url: https://api.novu.co - react_app_ws_url: https://ws.novu.co - react_app_webhook_url: https://webhook.novu.co - react_app_sentry_dsn: https://02189965b1bb4cf8bb4776f417f80b92@o1161119.ingest.sentry.io/625116 - react_app_environment: production - netlify_deploy_message: Prod deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 6f927fd4-dcb0-4cf3-8c0b-8c5539d0d034 - secrets: inherit diff --git a/.github/workflows/cloud-deploy/cloud-deploy-worker.yml b/.github/workflows/cloud-deploy/cloud-deploy-worker.yml deleted file mode 100644 index d48ef7306e0..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-worker.yml +++ /dev/null @@ -1,136 +0,0 @@ -name: Deploy PROD Worker - -on: - workflow_call: - -jobs: - - build_prod_image: - if: "!contains(github.event.head_commit.message, 'ci skip')" - # The type of runner that the job will run on - runs-on: ubuntu-latest - timeout-minutes: 15 - environment: Production - strategy: - # The order is important for ee to be first, otherwise outputs not work correctly - matrix: - name: [ 'novu/worker-ee' ] - outputs: - docker_image: ${{ steps.build-image.outputs.IMAGE }} - permissions: - contents: read - packages: write - deployments: write - id-token: write - steps: - - uses: actions/checkout@v4 - with: - submodules: ${{ contains (matrix.name,'-ee') }} - token: ${{ secrets.SUBMODULES_TOKEN }} - - uses: ./.github/actions/setup-project - with: - submodules: ${{ contains (matrix.name,'-ee') }} - - - name: build worker - run: pnpm build:worker - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - - name: Set Up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: 'image=moby/buildkit:v0.13.1' - - - name: Prepare - shell: bash - run: | - service=${{ matrix.name }} - echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - - - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') - shell: bash - run: | - echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} - IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} - DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max - --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true - run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - cd apps/worker && pnpm --silent --workspace-root pnpm-context -- apps/worker/Dockerfile | BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN --build-arg PACKAGE_PATH=apps/worker - -t novu-worker --load $DOCKER_BUILD_ARGUMENTS - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - - docker run --network=host --name worker -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1342/v1/health-check | grep 'ok' - - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT - - deploy_prod_workers_eu: - needs: build_prod_image - uses: ./.github/workflows/reusable-workers-service-deploy.yml - secrets: inherit - with: - environment: Production - terraform_workspace: novu-prod-eu - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/worker-ee:${{ github.sha }} - - deploy_prod_workers_us: - needs: build_prod_image - uses: ./.github/workflows/reusable-workers-service-deploy.yml - secrets: inherit - with: - environment: Production - terraform_workspace: novu-prod - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/worker-ee:${{ github.sha }} - deploy_sentry_release: true - sentry_project: worker - - newrelic: - runs-on: ubuntu-latest - name: New Relic Deploy - needs: deploy_prod_workers_us - environment: Production - steps: - # This step builds a var with the release tag value to use later - - name: Set Release Version from Tag - run: echo "RELEASE_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV - # This step creates a new Change Tracking Marker - - name: New Relic Application Deployment Marker - uses: newrelic/deployment-marker-action@v2.3.0 - with: - region: EU - apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" diff --git a/.github/workflows/cloud-deploy/cloud-deploy-ws.yml b/.github/workflows/cloud-deploy/cloud-deploy-ws.yml deleted file mode 100644 index c897be24428..00000000000 --- a/.github/workflows/cloud-deploy/cloud-deploy-ws.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: Deploy PROD WS - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -on: - workflow_call: - -jobs: - - # This workflow contains a single job called "build" - build_prod_image: - # The type of runner that the job will run on - runs-on: ubuntu-latest - timeout-minutes: 15 - environment: Production - strategy: - matrix: - name: [ 'novu/ws-ee' ] - outputs: - docker_image: ${{ steps.build-image.outputs.IMAGE }} - steps: - - uses: actions/checkout@v4 - with: - submodules: ${{ contains (matrix.name,'-ee') }} - token: ${{ secrets.SUBMODULES_TOKEN }} - - uses: ./.github/actions/setup-project - with: - submodules: ${{ contains (matrix.name,'-ee') }} - - - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') - shell: bash - run: | - echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - - - name: build api - run: pnpm build:ws - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - - name: Set Up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: 'image=moby/buildkit:v0.13.1' - - - name: Prepare - shell: bash - run: | - service=${{ matrix.name }} - echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} - IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} - DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max - --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true - run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN -t ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG --load -f apps/ws/Dockerfile . $DOCKER_BUILD_ARGUMENTS - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1340/v1/health-check | grep 'ok' - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT - - deploy_prod_ws_eu: - needs: - - build_prod_image - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: ws - terraform_workspace: novu-prod-eu - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/ws-ee:${{ github.sha }} - deploy_sentry_release: true - sentry_project: ws - - deploy_prod_ws_us: - needs: - - build_prod_image - uses: ./.github/workflows/reusable-app-service-deploy.yml - secrets: inherit - with: - environment: Production - service_name: ws - terraform_workspace: novu-prod - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/ws-ee:${{ github.sha }} - deploy_sentry_release: true - sentry_project: ws diff --git a/.github/workflows/dev-deploy-api.yml b/.github/workflows/dev-deploy-api.yml index 598e0b83995..bd1a011fd1b 100644 --- a/.github/workflows/dev-deploy-api.yml +++ b/.github/workflows/dev-deploy-api.yml @@ -20,17 +20,13 @@ env: jobs: test_api: - strategy: - matrix: - name: ['novu/api-ee', 'novu/api'] uses: ./.github/workflows/reusable-api-e2e.yml with: - ee: ${{ contains (matrix.name,'-ee') }} - job-name: ${{ matrix.name }} + ee: true + job-name: 'novu/api-ee' secrets: inherit deploy_dev_api: - # The type of runner that the job will run on runs-on: ubuntu-latest needs: test_api timeout-minutes: 80 @@ -54,7 +50,8 @@ jobs: with: tag: dev push: 'true' - github_token: ${{ secrets.GH_PACKAGES }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} docker_name: 'novu/api-ee' bullmq_secret: ${{ secrets.BULL_MQ_PRO_NPM_TOKEN }} environment: dev diff --git a/.github/workflows/dev-deploy-dashboard.yml b/.github/workflows/dev-deploy-dashboard.yml index a18654002b9..3a65f97f4ee 100644 --- a/.github/workflows/dev-deploy-dashboard.yml +++ b/.github/workflows/dev-deploy-dashboard.yml @@ -43,15 +43,3 @@ jobs: clerk_publishable_key: pk_live_Y2xlcmsubm92dS1zdGFnaW5nLmNvJA clerk_is_ee_auth_enabled: true secrets: inherit - - # publish_docker_image_dashboard: - # needs: test_dashboard - # if: "!contains(github.event.head_commit.message, 'ci skip')" - # uses: ./.github/workflows/reusable-docker.yml - # with: - # environment: Development - # package_name: novu/dashboard - # project_path: apps/dashboard - # local_tag: novu-dashboard - # env_tag: dev - # secrets: inherit diff --git a/.github/workflows/dev-deploy-inbound-mail.yml b/.github/workflows/dev-deploy-inbound-mail.yml index da3bf9e0cad..fbe4859bd96 100644 --- a/.github/workflows/dev-deploy-inbound-mail.yml +++ b/.github/workflows/dev-deploy-inbound-mail.yml @@ -47,26 +47,22 @@ jobs: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-project - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: driver-opts: 'image=moby/buildkit:v0.13.1' + - 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: eu-west-2 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + - name: Prepare shell: bash run: | @@ -79,30 +75,41 @@ jobs: echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV if: ${{contains(matrix.name, 'ee')}} - - name: Build, tag, and push image to Amazon ECR - id: build-image + - name: Build with Buildx, tag, and test + shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ matrix.name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/inbound-mail IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-dev - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-dev,mode=max --platform=linux/amd64 --provenance=false - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - cd apps/inbound-mail && pnpm --silent --workspace-root pnpm-context -- apps/inbound-mail/Dockerfile | BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN --build-arg PACKAGE_PATH=apps/inbound-mail - -t novu-inbound-mail --load $DOCKER_BUILD_ARGUMENTS - docker tag novu-inbound-mail ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:dev - docker tag novu-inbound-mail ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + set -x + cd apps/inbound-mail && pnpm run docker:build - docker run --network=host --name inbound-mail -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + - name: Tag and test + id: build-image + shell: bash + env: + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/inbound-mail + IMAGE_TAG: ${{ github.sha }} + run: | + echo "Built image" + docker tag novu-inbound-mail $REGISTRY/$REPOSITORY:$IMAGE_TAG + + docker run --network=host --name inbound-mail -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:dev - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + - name: Push PR tag image + shell: bash + env: + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/inbound-mail + IMAGE_TAG: ${{ github.sha }} + run: | + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG - name: Checkout cloud infra uses: actions/checkout@master @@ -111,12 +118,6 @@ jobs: token: ${{ secrets.GH_PACKAGES }} path: cloud-infra - - 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: eu-west-2 - name: Terraform setup uses: hashicorp/setup-terraform@v3 diff --git a/.github/workflows/dev-deploy-web.yml b/.github/workflows/dev-deploy-web.yml index fd779235a27..092906d424a 100644 --- a/.github/workflows/dev-deploy-web.yml +++ b/.github/workflows/dev-deploy-web.yml @@ -43,15 +43,3 @@ jobs: clerk_publishable_key: pk_live_Y2xlcmsubm92dS1zdGFnaW5nLmNvJA clerk_is_ee_auth_enabled: true secrets: inherit - - publish_docker_image_web: - needs: test_web - if: "!contains(github.event.head_commit.message, 'ci skip')" - uses: ./.github/workflows/reusable-docker.yml - with: - environment: Development - package_name: novu/web - project_path: apps/web - local_tag: novu-web - env_tag: dev - secrets: inherit diff --git a/.github/workflows/dev-deploy-webhook.yml b/.github/workflows/dev-deploy-webhook.yml index a6f8ecb7fdf..6b4be494f52 100644 --- a/.github/workflows/dev-deploy-webhook.yml +++ b/.github/workflows/dev-deploy-webhook.yml @@ -25,12 +25,13 @@ jobs: uses: ./.github/workflows/reusable-docker.yml with: environment: Development - package_name: novu/webhook + package_name: novu-dev/webhook project_path: apps/webhook test_port: 1341 health_check: true local_tag: novu-webhook env_tag: dev + aws-region: eu-west-2 secrets: inherit deploy_dev_webhook: diff --git a/.github/workflows/dev-deploy-worker.yml b/.github/workflows/dev-deploy-worker.yml index c9d6c72a768..54c4783d242 100644 --- a/.github/workflows/dev-deploy-worker.yml +++ b/.github/workflows/dev-deploy-worker.yml @@ -23,12 +23,9 @@ env: jobs: test_worker: - strategy: - matrix: - name: ['novu/worker', 'novu/worker-ee'] uses: ./.github/workflows/reusable-worker-e2e.yml with: - ee: ${{ contains (matrix.name,'-ee') }} + ee: true secrets: inherit build_dev_worker: @@ -37,30 +34,30 @@ jobs: needs: test_worker timeout-minutes: 80 environment: Development + outputs: + docker_image: ${{ steps.docker_build.outputs.IMAGE }} permissions: contents: read packages: write deployments: write id-token: write - strategy: - matrix: - name: ['novu/worker-ee', 'novu/worker'] steps: - uses: actions/checkout@v4 with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - uses: ./.github/actions/setup-project with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true - uses: ./.github/actions/docker/build-worker id: docker_build with: tag: dev push: 'true' - github_token: ${{ secrets.GH_PACKAGES }} - docker_name: ${{ matrix.name }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + docker_name: 'novu/worker-ee' bullmq_secret: ${{ secrets.BULL_MQ_PRO_NPM_TOKEN }} environment: dev @@ -71,8 +68,7 @@ jobs: with: environment: Development terraform_workspace: novu-dev - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/worker-ee:${{ github.sha }} + docker_image: ${{ needs.build_dev_worker.outputs.docker_image }} newrelic: runs-on: ubuntu-latest diff --git a/.github/workflows/dev-deploy-ws.yml b/.github/workflows/dev-deploy-ws.yml index 69cfa87d52e..b54bf88aba0 100644 --- a/.github/workflows/dev-deploy-ws.yml +++ b/.github/workflows/dev-deploy-ws.yml @@ -15,12 +15,9 @@ env: jobs: test_ws: - strategy: - matrix: - name: ['novu/ws-ee', 'novu/ws'] uses: ./.github/workflows/reusable-ws-e2e.yml with: - ee: ${{ contains (matrix.name,'-ee') }} + ee: true secrets: inherit # This workflow contains a single job called "build" @@ -31,29 +28,16 @@ jobs: timeout-minutes: 80 environment: Development if: "!contains(github.event.head_commit.message, 'ci skip')" - strategy: - matrix: - name: ['novu/ws-ee'] # Steps represent a sequence of tasks that will be executed as part of the job steps: - uses: actions/checkout@v4 with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - uses: ./.github/actions/setup-project with: - submodules: ${{ contains (matrix.name,'-ee') }} - - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } + submodules: true - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -63,7 +47,7 @@ jobs: - name: Prepare shell: bash run: | - service=${{ matrix.name }} + service="novu/ws-ee" echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - name: Configure AWS credentials @@ -73,6 +57,10 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: eu-west-2 + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + - name: Checkout cloud infra uses: actions/checkout@master with: @@ -109,30 +97,43 @@ jobs: shell: bash run: | echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - if: ${{contains(matrix.name, 'ee')}} - - - name: Build, tag, and push image to Amazon ECR - id: build-image + + - name: Build with Buildx, tag, and test + shell: bash env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ matrix.name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/ws IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-dev - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-dev,mode=max --platform=linux/amd64 --provenance=false - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true + run: | + set -x + cd apps/ws && pnpm run docker:build + + - name: Tag and test + id: build-image + shell: bash + env: + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/ws + IMAGE_TAG: ${{ github.sha }} run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build -t ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG --load --secret id=BULL_MQ_PRO_NPM_TOKEN -f apps/ws/Dockerfile . $DOCKER_BUILD_ARGUMENTS - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + echo "Built image" + docker tag novu-ws $REGISTRY/$REPOSITORY:$IMAGE_TAG + + docker run --network=host --name ws -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1340/v1/health-check | grep 'ok' - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:dev - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:dev - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT + + - name: Push PR tag image + shell: bash + env: + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu-dev/ws + IMAGE_TAG: ${{ github.sha }} + run: | + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG - name: Render Amazon ECS task definition id: render-container @@ -143,7 +144,6 @@ jobs: image: ${{ steps.build-image.outputs.IMAGE }} - name: Deploy to Amazon ECS service - if: ${{contains(matrix.name, 'ee')}} uses: aws-actions/amazon-ecs-deploy-task-definition@3e7310352de91b71a906e60c22af629577546002 with: task-definition: ${{ steps.render-container.outputs.task-definition }} diff --git a/.github/workflows/prod-deploy-api.yml b/.github/workflows/prod-deploy-api.yml index b881bf82f8c..93a20d74802 100644 --- a/.github/workflows/prod-deploy-api.yml +++ b/.github/workflows/prod-deploy-api.yml @@ -11,9 +11,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 80 environment: Production - strategy: - matrix: - name: [ 'novu/api-ee' ] outputs: docker_image: ${{ steps.build-image.outputs.IMAGE }} permissions: @@ -24,25 +21,15 @@ jobs: steps: - uses: actions/checkout@v4 with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - uses: ./.github/actions/setup-project with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true - name: build api run: pnpm build:api --skip-nx-cache - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -51,42 +38,47 @@ jobs: - name: Prepare shell: bash run: | - service=${{ matrix.name }} + service="novu/api-ee" echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') shell: bash 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: us-east-1 + + - 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_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu/api IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin cd apps/api && pnpm --silent --workspace-root pnpm-context -- apps/api/Dockerfile | BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN --build-arg PACKAGE_PATH=apps/api - -t novu-api --load $DOCKER_BUILD_ARGUMENTS - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag novu-api ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker tag novu-api $REGISTRY/$REPOSITORY:latest + docker tag novu-api $REGISTRY/$REPOSITORY:prod + docker tag novu-api $REGISTRY/$REPOSITORY:$IMAGE_TAG - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker run --network=host --name api -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1337/v1/health-check | grep 'ok' - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + docker push $REGISTRY/$REPOSITORY:prod + docker push $REGISTRY/$REPOSITORY:latest + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT deploy_prod_api_eu: needs: build_prod_image @@ -96,8 +88,7 @@ jobs: environment: Production service_name: api terraform_workspace: novu-prod-eu - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/api-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_prod_api_us: needs: @@ -108,8 +99,7 @@ jobs: environment: Production service_name: api terraform_workspace: novu-prod - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/api-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_sentry_release: true sentry_project: api diff --git a/.github/workflows/prod-deploy-webhook.yml b/.github/workflows/prod-deploy-webhook.yml index 93730a0a056..d976bea4a30 100644 --- a/.github/workflows/prod-deploy-webhook.yml +++ b/.github/workflows/prod-deploy-webhook.yml @@ -16,6 +16,8 @@ jobs: health_check: true local_tag: novu-webhook env_tag: prod + aws-region: us-east-1 + secrets: inherit deploy_prod_webhook_eu: diff --git a/.github/workflows/prod-deploy-worker.yml b/.github/workflows/prod-deploy-worker.yml index cfac8ce4f93..b584bbe0936 100644 --- a/.github/workflows/prod-deploy-worker.yml +++ b/.github/workflows/prod-deploy-worker.yml @@ -11,10 +11,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 80 environment: Production - strategy: - # The order is important for ee to be first, otherwise outputs not work correctly - matrix: - name: [ 'novu/worker-ee', 'novu/worker' ] outputs: docker_image: ${{ steps.build-image.outputs.IMAGE }} permissions: @@ -25,25 +21,15 @@ jobs: steps: - uses: actions/checkout@v4 with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - uses: ./.github/actions/setup-project with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true - name: build worker run: pnpm build:worker --skip-nx-cache - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -52,42 +38,47 @@ jobs: - name: Prepare shell: bash run: | - service=${{ matrix.name }} + service="novu/worker-ee" echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $GITHUB_ENV - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') shell: bash 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: us-east-1 + + - 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_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu/worker IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin cd apps/worker && pnpm --silent --workspace-root pnpm-context -- apps/worker/Dockerfile | BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN --build-arg PACKAGE_PATH=apps/worker - -t novu-worker --load $DOCKER_BUILD_ARGUMENTS - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag novu-worker ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker tag novu-worker $REGISTRY/$REPOSITORY:latest + docker tag novu-worker $REGISTRY/$REPOSITORY:prod + docker tag novu-worker $REGISTRY/$REPOSITORY:$IMAGE_TAG - docker run --network=host --name worker -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker run --network=host --name worker -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1342/v1/health-check | grep 'ok' - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + docker push $REGISTRY/$REPOSITORY:prod + docker push $REGISTRY/$REPOSITORY:latest + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT deploy_prod_workers_eu: needs: build_prod_image @@ -96,8 +87,7 @@ jobs: with: environment: Production terraform_workspace: novu-prod-eu - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/worker-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_prod_workers_us: needs: build_prod_image @@ -106,8 +96,7 @@ jobs: with: environment: Production terraform_workspace: novu-prod - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/worker-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_sentry_release: true sentry_project: worker diff --git a/.github/workflows/prod-deploy-ws.yml b/.github/workflows/prod-deploy-ws.yml index fecccfca75e..e5d2040463b 100644 --- a/.github/workflows/prod-deploy-ws.yml +++ b/.github/workflows/prod-deploy-ws.yml @@ -12,44 +12,25 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 80 environment: Production - strategy: - matrix: - name: [ 'novu/ws-ee' ] outputs: docker_image: ${{ steps.build-image.outputs.IMAGE }} steps: - uses: actions/checkout@v4 with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - uses: ./.github/actions/setup-project with: - submodules: ${{ contains (matrix.name,'-ee') }} + submodules: true - name: Set Bull MQ Env variable for EE - if: contains(matrix.name, 'ee') shell: bash run: | echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - - name: build api + - name: build ws run: pnpm build:ws - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -58,33 +39,39 @@ jobs: - name: Prepare shell: bash run: | - service=${{ matrix.name }} + service="novu/ws-ee" echo "SERVICE_NAME=$(basename "${service//-/-}")" >> $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: us-east-1 + + - 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_OWNER: novuhq - DOCKER_NAME: ${{matrix.name}} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: novu/ws IMAGE_TAG: ${{ github.sha }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-prod,mode=max --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN -t ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG --load -f apps/ws/Dockerfile . $DOCKER_BUILD_ARGUMENTS - docker run --network=host --name api -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + BULL_MQ_PRO_NPM_TOKEN=${BULL_MQ_PRO_NPM_TOKEN} docker buildx build --secret id=BULL_MQ_PRO_NPM_TOKEN -t $REGISTRY/$REPOSITORY:$IMAGE_TAG --load -f apps/ws/Dockerfile . $DOCKER_BUILD_ARGUMENTS + docker run --network=host --name api -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:1340/v1/health-check | grep 'ok' - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker tag ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:prod - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - echo "IMAGE=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:prod + docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:latest + docker push $REGISTRY/$REPOSITORY:prod + docker push $REGISTRY/$REPOSITORY:latest + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG + echo "IMAGE=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT deploy_prod_ws_eu: needs: @@ -95,8 +82,7 @@ jobs: environment: Production service_name: ws terraform_workspace: novu-prod-eu - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/ws-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_sentry_release: true sentry_project: ws @@ -110,7 +96,6 @@ jobs: environment: Production service_name: ws terraform_workspace: novu-prod - # This is a workaround to an issue with matrix outputs - docker_image: ghcr.io/novuhq/novu/ws-ee:${{ github.sha }} + docker_image: ${{ needs.build_prod_image.outputs.docker_image }} deploy_sentry_release: true sentry_project: ws diff --git a/.github/workflows/reusable-docker.yml b/.github/workflows/reusable-docker.yml index 977205e0603..7da9ec7d7d4 100644 --- a/.github/workflows/reusable-docker.yml +++ b/.github/workflows/reusable-docker.yml @@ -35,6 +35,11 @@ on: env_tag: required: false type: string + aws-region: + description: 'Region for AWS' + required: true + type: string + outputs: docker_image: description: 'The image that was built' @@ -59,7 +64,7 @@ jobs: id-token: write strategy: matrix: - name: [ '${{ inputs.package_name }}-ee', '${{ inputs.package_name }}' ] + name: [ '${{ inputs.package_name }}-ee'] steps: - uses: actions/checkout@v4 with: @@ -77,101 +82,89 @@ jobs: slim: 'true' submodules: ${{ contains (matrix.name,'-ee') }} - - uses: crazy-max/ghaction-setup-docker@v2 - with: - version: v24.0.6 - daemon-config: | - { - "features": { - "containerd-snapshotter": true - } - } - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64,linux/arm64 - - name: Set Up Docker Buildx uses: docker/setup-buildx-action@v3 with: driver-opts: 'image=moby/buildkit:v0.13.1' - - name: Build, tag, and push image to ghcr.io + + - 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: ${{ inputs.aws-region }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build, tag, and push image to ECR id: build-image if: ${{ inputs.env_tag == 'dev' || inputs.env_tag == 'stg' }} env: - REGISTRY_OWNER: novuhq + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: ${{ inputs.package_name }} DOCKER_NAME: ${{ matrix.name }} LOCAL_TAG: ${{ inputs.local_tag }} IMAGE_TAG: ${{ github.sha }} ENV_TAG: ${{ inputs.env_tag }} PROJECT_PATH: ${{ inputs.project_path }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.env_tag }} - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.env_tag }},mode=max --platform=linux/amd64 --provenance=false - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin cd $PROJECT_PATH && npm run docker:build - docker tag $LOCAL_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker tag $LOCAL_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$ENV_TAG - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$ENV_TAG + docker tag $LOCAL_TAG $REGISTRY/$REPOSITORY:$IMAGE_TAG + docker tag $LOCAL_TAG $REGISTRY/$REPOSITORY:$ENV_TAG + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG + docker push $REGISTRY/$REPOSITORY:$ENV_TAG - - name: Production build, tag, and push image to ghcr.io + - name: Production build, tag, and push image to ECR id: build-prod-image if: ${{ inputs.env_tag == 'prod' }} env: - REGISTRY_OWNER: novuhq + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: ${{ inputs.package_name }} DOCKER_NAME: ${{ matrix.name }} LOCAL_TAG: ${{ inputs.local_tag }} IMAGE_TAG: ${{ github.sha }} ENV_TAG: ${{ inputs.env_tag }} PROJECT_PATH: ${{ inputs.project_path }} - GH_ACTOR: ${{ github.actor }} - GH_PASSWORD: ${{ secrets.GH_PACKAGES }} DOCKER_BUILD_ARGUMENTS: > - --cache-from type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.env_tag }} - --cache-to type=registry,ref=ghcr.io/novuhq/cache:build-cache-${{ env.SERVICE_NAME }}-${{ inputs.env_tag }},mode=max --platform=linux/amd64 - --output=type=image,name=ghcr.io/novuhq/${{ matrix.name }},push-by-digest=true,name-canonical=true + --output=type=image,name=$REGISTRY/$REPOSITORY,push-by-digest=true,name-canonical=true run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin cd $PROJECT_PATH && npm run docker:build - docker tag $LOCAL_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker tag $LOCAL_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$ENV_TAG - docker tag $LOCAL_TAG ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$ENV_TAG - docker push ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:latest + docker tag $LOCAL_TAG $REGISTRY/$REPOSITORY:$IMAGE_TAG + docker tag $LOCAL_TAG $REGISTRY/$REPOSITORY:$ENV_TAG + docker tag $LOCAL_TAG $REGISTRY/$REPOSITORY:latest + docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG + docker push $REGISTRY/$REPOSITORY:$ENV_TAG + docker push $REGISTRY/$REPOSITORY:latest - name: Save image to output id: save-image-to-output env: - REGISTRY_OWNER: novuhq + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: ${{ inputs.package_name }} DOCKER_NAME: ${{ matrix.name }} IMAGE_TAG: ${{ github.sha }} OUTPUT_NAME: ${{ contains(matrix.name,'-ee') && 'IMAGE_EE' || 'IMAGE' }} run: | - echo "$OUTPUT_NAME=ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "$OUTPUT_NAME=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - name: Health check test id: health-check if: ${{ inputs.health_check == 'true' && (steps.build-image.outcome == 'success' || steps.build-prod-image.outcome == 'success') }} env: - REGISTRY_OWNER: novuhq - DOCKER_NAME: ${{ matrix.name }} + REGISTRY: ${{ steps.login-ecr.outputs.registry }} + REPOSITORY: ${{ inputs.package_name }} LOCAL_TAG: ${{ inputs.local_tag }} IMAGE_TAG: ${{ github.sha }} TEST_PORT: ${{ inputs.test_port }} GH_ACTOR: ${{ github.actor }} GH_PASSWORD: ${{ secrets.GH_PACKAGES }} run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - - docker run --network=host --name $LOCAL_TAG -dit --env NODE_ENV=test ghcr.io/$REGISTRY_OWNER/$DOCKER_NAME:$IMAGE_TAG + docker run --network=host --name $LOCAL_TAG -dit --env NODE_ENV=test $REGISTRY/$REPOSITORY:$IMAGE_TAG docker run --network=host appropriate/curl --retry 10 --retry-delay 5 --retry-connrefused http://127.0.0.1:$TEST_PORT/v1/health-check | grep 'ok'