Share reviews #364
Workflow file for this run
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: Connect CI | |
on: | |
push: | |
branches: [main] | |
paths: | |
- '.ebextensions*/**' | |
- '.ebstalk.apps.env/**' | |
- '.github/**' | |
- 'package.json' | |
- 'package-lock.json' | |
- 'apps/connect/**' | |
- 'apps/sunnyawards/**' | |
- '@connect-shared/**' | |
- 'abis/**' | |
- 'adapters/**' | |
- 'config/**' | |
- 'connectors/**' | |
- 'lib/**' | |
- 'hooks/**' | |
- 'models/**' | |
pull_request: | |
types: [labeled, opened, synchronize] | |
branches: ['**'] | |
paths: | |
- '.ebextensions*/**' | |
- '.ebstalk.apps.env/**' | |
- '.github/**' | |
- 'package.json' | |
- 'package-lock.json' | |
- 'apps/connect/**' | |
- '@connect-shared/**' | |
- 'abis/**' | |
- 'adapters/**' | |
- 'config/**' | |
- 'connectors/**' | |
- 'lib/**' | |
- 'hooks/**' | |
- 'models/**' | |
workflow_dispatch: | |
inputs: | |
core_pkg_version: | |
description: 'Core pkg version to update to' | |
required: true | |
concurrency: | |
group: ci-connect-${{ github.event_name }}-${{ github.ref }} | |
jobs: | |
build-app: | |
name: Build apps | |
runs-on: ubuntu-latest | |
outputs: | |
head-commit-message: ${{ steps.get_head_commit_message.outputs.commit_message }} | |
steps: | |
- name: Print Triggering event context payload | |
env: | |
workflow_event_context: ${{ toJSON(github.event) }} | |
run: | | |
echo "$workflow_event_context" | |
echo "Workflow and code ref: ${{github.ref}}" | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Install dependencies | |
uses: ./.github/actions/install | |
with: | |
core_pkg_version: ${{ inputs.core_pkg_version }} | |
commit_core_pkg_upgrade: true | |
save_cache: true | |
- name: Build apps | |
uses: ./.github/actions/build_connect | |
# source https://github.com/orgs/community/discussions/28474 | |
- name: Print head git commit message | |
id: get_head_commit_message | |
run: echo "commit_message=$(git show -s --format=%s)" >> "$GITHUB_OUTPUT" | |
test-connect: | |
name: Test apps | |
runs-on: ubuntu-latest | |
needs: build-app | |
if: ${{ github.event.action != 'labeled' && !contains(needs.build-app.outputs.head-commit-message, 'skip-tests') }} | |
# Postgres setup copied from https://gist.github.com/2color/537f8ef13ecec80059abb007839a6878 | |
services: | |
postgres: | |
image: postgres | |
env: | |
POSTGRES_USER: postgres | |
POSTGRES_PASSWORD: postgres | |
options: >- | |
--health-cmd pg_isready | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
--hostname postgres | |
ports: | |
# Maps tcp port 5432 on service container to the host | |
- 5432:5432 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Restore dependencies from cache | |
uses: ./.github/actions/install | |
- name: Setup test database | |
run: npx dotenv -e .env.test.local -- npm run prisma:reset | |
- name: Restore app from cache | |
uses: ./.github/actions/build_connect | |
- name: Validate Webapp | |
run: | | |
npm run lint -w apps/connect | |
npm run typecheck -w apps/connect | |
- name: Validate Connect API | |
run: | | |
npm run lint -w apps/connect-api | |
# We need to fix jest transpilation before we can run connect API tests | |
# - name: 'Test Connect API' | |
# run: 'npm run connect-api:test' | |
- name: Validate Sunny Awards | |
run: | | |
npm run lint -w apps/sunnyawards | |
npm run typecheck -w apps/sunnyawards | |
test-connect-e2e: | |
name: Test Connect e2e | |
runs-on: ubuntu-latest | |
needs: build-app | |
if: ${{ github.event.action != 'labeled' && !contains(needs.build-app.outputs.head-commit-message, 'skip-tests') }} | |
# Postgres setup copied from https://gist.github.com/2color/537f8ef13ecec80059abb007839a6878 | |
services: | |
postgres: | |
image: postgres | |
env: | |
POSTGRES_USER: postgres | |
POSTGRES_PASSWORD: postgres | |
options: >- | |
--health-cmd pg_isready | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
--hostname postgres | |
ports: | |
# Maps tcp port 5432 on service container to the host | |
- 5432:5432 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Restore dependencies from cache | |
uses: ./.github/actions/install | |
- name: Setup test database | |
run: npx dotenv -e .env.test.local -- npm run prisma:reset | |
- name: Restore app from cache | |
uses: ./.github/actions/build_connect | |
- name: Start connect app | |
run: | | |
npm run connect:start:test:ci &> connect.log & | |
sleep_loop_ct=0 | |
until curl localhost:3337/api/health || [[ $sleep_loop_ct > 30 ]]; do | |
echo "webapp not up in loop $sleep_loop_ct ... sleeping" | |
sleep_loop_ct=$((sleep_loop_ct + 1)) | |
sleep 1 | |
done | |
- name: Run Connect E2E tests | |
env: | |
REACT_APP_APP_ENV: 'test' | |
# we have to run docker command ourselves to set network=host so that playwright can access the server | |
run: | | |
[[ "${{ runner.debug }}" = "1" ]] && tail -f connect.log & | |
docker run --name mcrmicrosoftcomplaywrightv1343jammy_68c205 \ | |
--workdir /github/workspace --rm \ | |
-e "REACT_APP_APP_ENV" -e CI=true \ | |
-v "/var/run/docker.sock":"/var/run/docker.sock" \ | |
-v "/home/runner/work/_temp/_github_home":"/github/home" \ | |
-v "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ | |
-v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" \ | |
-v "/home/runner/work/app.charmverse.io/app.charmverse.io":"/github/workspace" \ | |
--network "host" \ | |
--ipc=host \ | |
mcr.microsoft.com/playwright:v1.42.1-jammy \ | |
npm run connect:test:e2e:ci | |
test-sunnyawards-e2e: | |
name: Test Sunny Awards e2e | |
runs-on: ubuntu-latest | |
needs: build-app | |
if: ${{ github.event.action != 'labeled' && !contains(needs.build-app.outputs.head-commit-message, 'skip-tests') }} | |
# Postgres setup copied from https://gist.github.com/2color/537f8ef13ecec80059abb007839a6878 | |
services: | |
postgres: | |
image: postgres | |
env: | |
POSTGRES_USER: postgres | |
POSTGRES_PASSWORD: postgres | |
options: >- | |
--health-cmd pg_isready | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
--hostname postgres | |
ports: | |
# Maps tcp port 5432 on service container to the host | |
- 5432:5432 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Restore dependencies from cache | |
uses: ./.github/actions/install | |
- name: Setup test database | |
run: npx dotenv -e .env.test.local -- npm run prisma:reset | |
- name: Restore app from cache | |
uses: ./.github/actions/build_connect | |
- name: Start Sunny Awards app | |
run: | | |
npm run sunnyawards:start:test:ci &> connect.log & | |
sleep_loop_ct=0 | |
until curl localhost:3337/api/health || [[ $sleep_loop_ct > 30 ]]; do | |
echo "webapp not up in loop $sleep_loop_ct ... sleeping" | |
sleep_loop_ct=$((sleep_loop_ct + 1)) | |
sleep 1 | |
done | |
- name: Run Sunny Awards E2E tests | |
env: | |
REACT_APP_APP_ENV: 'test' | |
# we have to run docker command ourselves to set network=host so that playwright can access the server | |
run: | | |
[[ "${{ runner.debug }}" = "1" ]] && tail -f connect.log & | |
docker run --name mcrmicrosoftcomplaywrightv1343jammy_68c205 \ | |
--workdir /github/workspace --rm \ | |
-e "REACT_APP_APP_ENV" -e CI=true \ | |
-v "/var/run/docker.sock":"/var/run/docker.sock" \ | |
-v "/home/runner/work/_temp/_github_home":"/github/home" \ | |
-v "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ | |
-v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" \ | |
-v "/home/runner/work/app.charmverse.io/app.charmverse.io":"/github/workspace" \ | |
--network "host" \ | |
--ipc=host \ | |
mcr.microsoft.com/playwright:v1.42.1-jammy \ | |
npm run sunnyawards:test:e2e:ci | |
upload-docker: | |
name: Upload Docker image | |
runs-on: ubuntu-latest | |
# run whether previous jobs were successful or skipped | |
if: | | |
github.ref == 'refs/heads/main' || | |
(github.event.action == 'labeled' && github.event.label.name == ':rocket: deploy-connect') || | |
(github.event.action == 'labeled' && github.event.label.name == ':rocket: deploy-sunnyawards') || | |
(github.event.action != 'labeled' && (contains(github.event.pull_request.labels.*.name, ':rocket: deploy-connect') || contains(github.event.pull_request.labels.*.name, ':rocket: deploy-sunnyawards'))) | |
needs: build-app | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Install dependencies | |
uses: ./.github/actions/install | |
- name: Build app | |
uses: ./.github/actions/build_connect | |
- name: Update Dockerfile | |
run: | | |
rm Dockerfile && mv apps/connect/Dockerfile Dockerfile | |
- name: Build and Push Docker image | |
id: docker_build_push | |
uses: ./.github/actions/build_docker_image | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
AWS_REGION: us-east-1 | |
with: | |
ecr_registry: charmverse-connect | |
upload-static-assets: | |
name: Upload assets in production | |
runs-on: ubuntu-latest | |
# run whether previous jobs were successful or skipped | |
if: github.ref == 'refs/heads/main' && !(failure() || cancelled()) | |
needs: build-app | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Install dependencies | |
uses: ./.github/actions/install | |
- name: Calculate Build ID | |
id: get_build_id | |
run: | | |
build_id=${{ hashFiles('package-lock.json', 'apps/**/*.[jt]s', 'lib/**/*.[jt]s') }} | |
echo "build_id=$build_id" >> $GITHUB_OUTPUT | |
- name: Build app | |
uses: ./.github/actions/build_connect | |
- 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: Upload static assets to S3 | |
run: | | |
aws s3 sync apps/connect/.next/static/ s3://charm.cdn/webapp-assets/_next/static/ | |
aws s3 sync apps/sunnyawards/.next/static/ s3://charm.cdn/webapp-assets/_next/static/ | |
- name: Upload JS source maps to Datadog | |
env: | |
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} | |
run: | | |
npm install -g @datadog/datadog-ci | |
datadog-ci sourcemaps upload apps/connect/.next/static \ | |
--service=connect \ | |
--release-version=${{ steps.get_build_id.outputs.build_id }} \ | |
--minified-path-prefix=https://cdn.charmverse.io/_next/static | |
deploy-production: | |
name: Deploy ${{ matrix.name }} | |
# run whether previous jobs were successful or skipped | |
if: github.ref == 'refs/heads/main' && !(failure() || cancelled()) | |
needs: [test-connect, test-connect-e2e, test-sunnyawards-e2e, upload-docker, upload-static-assets] | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
include: | |
- name: Connect App | |
stack: prd-connect | |
ebextensions: .ebextensions_connect | |
- name: Connect API | |
stack: prd-connect-api | |
ebextensions: .ebextensions_connect_api | |
- name: Sunny Awards | |
stack: prd-sunnyawards | |
ebextensions: .ebextensions_sunnyawards | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Inject slug/short variables | |
uses: rlespinasse/[email protected] | |
with: | |
short-length: 7 | |
# we need to bring back node_modules which includes tsconfig-paths which is used by CDK files | |
- name: Install dependencies | |
uses: ./.github/actions/install | |
- name: Set the docker compose env variables | |
uses: mikefarah/yq@master | |
with: | |
cmd: | | |
yq -I 4 -i ' | |
with(.option_settings."aws:elasticbeanstalk:application:environment"; | |
.IMGTAG = "${{ github.run_id }}-${{ env.GITHUB_SHA_SHORT }}") | |
' ${{ matrix.ebextensions }}/00_env_vars.config | |
rm -rf .ebextensions && mv ${{ matrix.ebextensions }} .ebextensions | |
- 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: Package and deploy | |
run: | | |
cat files_to_zip.txt | zip --symlinks -r@ ${{ matrix.stack }}.zip | |
npx aws-cdk deploy --method=direct -c name=${{ matrix.stack }} | |
deploy-staging: | |
name: Deploy to staging | |
if: | | |
(github.event.action == 'labeled' && github.event.label.name == ':rocket: deploy-connect') || | |
(github.event.action == 'labeled' && github.event.label.name == ':rocket: deploy-sunnyawards') || | |
(github.event.action != 'labeled' && (contains(github.event.pull_request.labels.*.name, ':rocket: deploy-connect') || contains(github.event.pull_request.labels.*.name, ':rocket: deploy-sunnyawards'))) | |
runs-on: ubuntu-latest | |
# prevent workflows running in parallel | |
concurrency: deploy-staging-${{ github.head_ref }} | |
needs: [upload-docker] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Inject slug/short variables | |
uses: rlespinasse/[email protected] | |
with: | |
short-length: 7 | |
- name: Calculate Stage env var | |
run: | | |
if ${{contains(github.event.pull_request.labels.*.name, ':rocket: deploy-connect')}}; then stack='stg-connect'; fi | |
if ${{contains(github.event.pull_request.labels.*.name, ':rocket: deploy-sunnyawards')}}; then stack='stg-sunnyawards'; fi | |
full_stage_name="$stack-${{ github.event.number }}-${{ env.GITHUB_HEAD_REF_SLUG }}" | |
# sanitize and trim string so that it can be used as a valid subdomain. Includes removing hyphens at the start and end of the name | |
stage_name=`echo "$full_stage_name" | sed -E -e 's/[^a-zA-Z0-9-]+//g' -e 's/(.{40}).*/\1/' -e 's/^-/0/' -e 's/-$/0/'` | |
# export the stage name so that it can be used in other steps | |
echo "STAGE_NAME=$stage_name" >> $GITHUB_ENV | |
# we need to bring back node_modules which includes tsconfig-paths which is used by CDK files | |
- name: Install dependencies | |
uses: ./.github/actions/install | |
- name: Replace env_var with staging settings | |
run: | | |
ebextension_files=$(ls .ebextensions*/00_env_vars.config) | |
ebstalk_apps_env_files=$(ls .ebstalk.apps.env/*) | |
for conf_file in $ebextension_files $ebstalk_apps_env_files; do | |
sed -i 's/prd/stg/g' $conf_file | |
sed -i 's/production/staging/g' $conf_file | |
done | |
# modifying cloudformation alarm to send alerts to test sns topic. | |
# leaving it in even if we're deleting the config before deploying | |
# Useful to avoid accidental triggering to system-status channel. | |
for conf_file in .ebextensions*/06_cloudwatch_alarm.config; do | |
sed -i 's/Production-Alerts/lambda-test-debug/g' $conf_file | |
done | |
rm .ebextensions*/06_cloudwatch_alarm.config | |
# substituting the connect api domain name | |
sed -i 's/REACT_APP_CONNECT_API_HOST=.*/REACT_APP_CONNECT_API_HOST=https:\/\/${{env.STAGE_NAME}}.charmverse.co:4000/g' .ebstalk.apps.env/connect.env | |
- name: Set the docker compose env variables | |
uses: mikefarah/yq@master | |
with: | |
cmd: | | |
yq -I 4 -i ' | |
with(.option_settings."aws:elasticbeanstalk:application:environment"; | |
.COMPOSE_PROJECT_NAME = "pr${{ github.event.number }}" | | |
.IMGTAG = "${{ github.run_id }}-${{ env.GITHUB_SHA_SHORT }}") | |
' .ebextensions_connect/00_env_vars.config | |
yq -I 4 -i ' | |
with(.option_settings."aws:elasticbeanstalk:application:environment"; | |
.COMPOSE_PROJECT_NAME = "pr${{ github.event.number }}" | | |
.IMGTAG = "${{ github.run_id }}-${{ env.GITHUB_SHA_SHORT }}") | |
' .ebextensions_sunnyawards/00_env_vars.config | |
- name: Parse compose profile to see if we need to enable datadog | |
id: get_compose_profiles | |
uses: mikefarah/yq@master | |
with: | |
cmd: yq -r '.option_settings."aws:elasticbeanstalk:application:environment".COMPOSE_PROFILES' .ebextensions/00_env_vars.config | |
- name: Set DDENABLED variable in environment for build and deploy steps | |
run: | | |
cat .ebextensions/00_env_vars.config | |
COMPOSE_PROFILES=${{ steps.get_compose_profiles.outputs.result }} | |
if [[ "$COMPOSE_PROFILES" =~ ddtst ]]; then | |
echo "DDENABLED=true" >> $GITHUB_ENV | |
fi | |
- name: Create a github deployment | |
uses: bobheadxi/deployments@v1 | |
id: deployment | |
with: | |
step: start | |
token: ${{ secrets.GITHUB_TOKEN }} | |
env: ${{ env.STAGE_NAME }} | |
ref: ${{ github.head_ref }} | |
override: true | |
- 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: Override config with Connect app | |
# wrap the condition in "${{}}" because the string includes a colon | |
# see https://github.com/actions/runner/issues/1019 | |
if: "${{ contains(github.event.pull_request.labels.*.name, ':rocket: deploy-connect') }}" | |
# aws s3 sync apps/connect/.next/static/ s3://charm.cdn/webapp-assets/_next/static/ | |
run: | | |
rm -rf .ebextensions && mv .ebextensions_connect .ebextensions | |
- name: Override config with Sunny Awards | |
if: "${{ contains(github.event.pull_request.labels.*.name, ':rocket: deploy-sunnyawards') }}" | |
# aws s3 sync apps/sunnyawards/.next/static/ s3://charm.cdn/webapp-assets/_next/static/ | |
run: | | |
rm -rf .ebextensions && mv .ebextensions_sunnyawards .ebextensions | |
- name: Deploy to staging | |
id: cdk_deploy | |
run: | | |
cat files_to_zip.txt | zip --symlinks -r@ ${{env.STAGE_NAME}}.zip | |
npx aws-cdk deploy -c name=${{env.STAGE_NAME}} --method=direct --outputs-file cdk.out.json | |
env_url=$(jq --raw-output '.[$ENV.STAGE_NAME].DeploymentUrl' ./cdk.out.json) | |
echo "env_url=$env_url" >> $GITHUB_OUTPUT | |
- name: update the github deployment status | |
uses: bobheadxi/deployments@v1 | |
if: always() | |
with: | |
env: ${{ steps.deployment.outputs.env }} | |
step: finish | |
override: false | |
token: ${{ secrets.GITHUB_TOKEN }} | |
status: ${{ job.status }} | |
deployment_id: ${{ steps.deployment.outputs.deployment_id }} | |
env_url: ${{ steps.cdk_deploy.outputs.env_url }} | |
discord-alert: | |
name: Notify Discord of failure | |
runs-on: ubuntu-latest | |
if: github.ref == 'refs/heads/main' && failure() | |
# pass in all steps so we can check if any failed | |
needs: | |
[ | |
test-connect, | |
test-connect-e2e, | |
test-sunnyawards-e2e, | |
upload-docker, | |
upload-static-assets, | |
upload-docker, | |
deploy-production | |
] | |
steps: | |
- name: If any of prev jobs failed notify discord | |
if: contains(needs.*.result, 'failure') | |
uses: sarisia/actions-status-discord@v1 | |
with: | |
webhook: ${{ secrets.DISCORD_WARNINGS_WEBHOOK }} | |
status: 'failure' | |
content: 'Hey <@&1027309276454207519>' | |
title: 'Connect deploy workflow failed' | |
description: | | |
Failed workflow URL: https://github.com/charmverse/app.charmverse.io/actions/runs/${{ github.run_id }} | |
color: '16515843' | |
url: 'https://github.com/charmverse/app.charmverse.io/actions/runs/${{ github.run_id }}' | |
username: GitHub Actions | |
avatar_url: 'https://github.githubassets.com/images/modules/logos_page/Octocat.png' |