Skip to content

Scout game admin

Scout game admin #928

Workflow file for this run

# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Webapp CI
on:
push:
branches: [main]
paths-ignore:
- 'apps/**'
pull_request:
branches: ['**']
paths-ignore:
- 'apps/**'
workflow_dispatch:
inputs:
core_pkg_version:
description: 'Core pkg version to update to'
required: true
concurrency:
group: webapp-${{ github.event_name }}-${{ github.ref }}
env:
SELECTED_PERMISSION_API_TAG: latest
jobs:
build-app:
name: Build app
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
- name: Build app
uses: ./.github/actions/build
# 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"
validate-code:
name: Validate code
runs-on: ubuntu-latest
needs: build-app
if: ${{ !contains(needs.build-app.outputs.head-commit-message, 'skip-tests') }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Restore dependencies from cache
uses: ./.github/actions/install
- name: Restore app from cache
uses: ./.github/actions/build
- run: npm run typecheck
- run: npm run verifydeps
- name: Run eslint on changed files
uses: tj-actions/eslint-changed-files@v25
with:
escape_paths: 'false'
skip_annotations: 'true' # do not annotate code in the PR
extra_args: '--ignore-pattern apps,packages'
file_extensions: '**/*.{ts,tsx}'
test-matrix:
name: Tests
runs-on: ubuntu-latest
needs: build-app
if: ${{ !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
strategy:
max-parallel: 10
fail-fast: false
matrix:
include:
- test_name: 'Tests for tests'
test_command: 'npm run test:ci -- --config="./testing/jest.config.ts"'
- test_name: 'Library tests #1'
test_command: 'npm run test:ci -- --config="./lib/jest.config.ts" --shard 1/3'
- test_name: 'Library tests #2'
test_command: 'npm run test:ci -- --config="./lib/jest.config.ts" --shard 2/3'
- test_name: 'Library tests #3'
test_command: 'npm run test:ci -- --config="./lib/jest.config.ts" --shard 3/3'
- test_name: 'Server integration tests #1'
test_command: 'npm run start:test:ci & npm run test:server:ci -- --shard 1/2'
- test_name: 'Server integration tests #2'
test_command: 'npm run start:test:ci & npm run test:server:ci -- --shard 2/2'
- test_name: 'Browser tests'
test_command: 'npm run test:browser'
- test_name: 'Serverless tests'
test_command: 'npm run serverless:start & sleep 10 && npm run test:serverless'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- 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: 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
mask-aws-account-id: 'no'
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: true
- name: Run permissions api docker image
id: run_permissions_api
run: |
docker inspect postgres
docker network ls
cat /etc/hosts
echo "network ${{ job.services.postgres.network }}"
docker run -d --name permissions-api \
-h permissions-api \
-p "3001:3001" \
-e HOST=0.0.0.0 \
-e PORT=3001 \
-v $PWD/nodes_modules/@charmverse/core:/apps/node_modules/@charmverse/core \
--network "${{ job.services.postgres.network }}" \
-e DATABASE_URL=postgres://postgres:postgres@postgres:5432/charmversetest \
${{ steps.login-ecr.outputs.registry }}/charmverse-permissions-api:${{ env.SELECTED_PERMISSION_API_TAG }} \
node --experimental-specifier-resolution=node ./dist/main.js
sleep_loop_ct=0
until curl localhost:3001/api/health || [[ $sleep_loop_ct > 30 ]]; do
docker ps
docker logs permissions-api
docker inspect permissions-api
echo "permission api not up in loop $sleep_loop_ct ... sleeping"
sleep_loop_ct=$((sleep_loop_ct + 1))
sleep 10
done
- name: Restore app from cache
uses: ./.github/actions/build
- name: Run ${{matrix.test_name}}
env:
SERVERLESS_ACCESS_KEY: ${{ secrets.SERVERLESS_ACCESS_KEY }}
REACT_APP_APP_ENV: 'test'
run: ${{matrix.test_command}}
e2e-test-matrix:
name: Tests
runs-on: ubuntu-latest
needs: build-app
if: ${{ !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
strategy:
max-parallel: 10
fail-fast: false
matrix:
include:
- test_name: 'Browser e2e test #1'
test_command: 'npm run test:e2e:ci -- --shard=1/3'
- test_name: 'Browser e2e test #2'
test_command: 'npm run test:e2e:ci -- --shard=2/3'
- test_name: 'Browser e2e test #3'
test_command: 'npm run test:e2e:ci -- --shard=3/3'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- 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: 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
mask-aws-account-id: 'no'
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: true
- name: Run permissions api docker image
id: run_permissions_api
run: |
docker inspect postgres
docker network ls
cat /etc/hosts
echo "network ${{ job.services.postgres.network }}"
docker run -d --name permissions-api \
-h permissions-api \
-p "3001:3001" \
-e HOST=0.0.0.0 \
-e PORT=3001 \
-v $PWD/nodes_modules/@charmverse/core:/apps/node_modules/@charmverse/core \
--network "${{ job.services.postgres.network }}" \
-e DATABASE_URL=postgres://postgres:postgres@postgres:5432/charmversetest \
${{ steps.login-ecr.outputs.registry }}/charmverse-permissions-api:${{ env.SELECTED_PERMISSION_API_TAG }} \
node --experimental-specifier-resolution=node ./dist/main.js
sleep_loop_ct=0
until curl localhost:3001/api/health || [[ $sleep_loop_ct > 30 ]]; do
docker ps
docker logs permissions-api
docker inspect permissions-api
echo "permission api not up in loop $sleep_loop_ct ... sleeping"
sleep_loop_ct=$((sleep_loop_ct + 1))
sleep 1
done
- name: Restore app from cache
uses: ./.github/actions/build
- name: Start services
run: |
npm run start:test:ci &> connect.log &
sleep_loop_ct=0
until curl localhost:3335/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
# this doesnt seem to be any faster than pulling from Docker registry
# - name: Cache Playwright Docker image
# uses: ScribeMD/docker-cache@0.4.0
# with:
# # include the version we want to cache
# key: docker-${{ runner.os }}-v1.42.1-jammy
- name: Run ${{matrix.test_name}}
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.47.1-jammy \
${{matrix.test_command}}
# uses: docker://mcr.microsoft.com/playwright:v1.34.3-jammy
# with:
# args: ${{matrix.test_command}}
deploy-docker:
name: Upload Docker image and assets
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: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.x
- name: Install dependencies
uses: ./.github/actions/install
- name: Calculate Build ID
id: get_build_id
run: |
build_id=${{ hashFiles('package-lock.json', 'pages/api/**/*.[jt]s', 'lib/**/*.[jt]s') }}
echo "build_id=$build_id" >> $GITHUB_OUTPUT
- name: Build app
uses: ./.github/actions/build
with:
REACT_APP_APP_ENV: 'production'
- 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-web3-workspace
- 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 .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 .next/static \
--service=webapp \
--release-version=${{ steps.get_build_id.outputs.build_id }} \
--minified-path-prefix=https://cdn.charmverse.io/_next/static
deploy-main:
name: Deploy to production
runs-on: ubuntu-latest
# run whether previous jobs were successful or skipped
if: github.ref == 'refs/heads/main' && !(failure() || cancelled())
needs: [validate-code, test-matrix, e2e-test-matrix, deploy-docker]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4.x
with:
short-length: 7
- name: Install dependencies
uses: ./.github/actions/install
- name: Calculate Build ID and add to env file
id: get_build_id
run: |
build_id=${{ hashFiles('package-lock.json', 'pages/api/**/*.[jt]s', 'lib/**/*.[jt]s') }}
echo "REACT_APP_BUILD_ID=$build_id" >> ./.ebstalk.apps.env/webapp.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";
.NODE_ENV = "production" |
.IMGTAG = "${{ github.run_id }}-${{ env.GITHUB_SHA_SHORT }}")
' .ebextensions/webapp/00_env_vars.config
yq -I 4 -i '
with(.option_settings."aws:elasticbeanstalk:application:environment";
.IMGTAG = "${{ github.run_id }}-${{ env.GITHUB_SHA_SHORT }}")
' .ebextensions/websockets/00_env_vars.config
- name: Package webapp
run: |
mv .ebextensions .ebextensions_tmp
mv .ebextensions_tmp/webapp .ebextensions
cat files_to_zip.txt | zip --symlinks -r@ deploy.zip
- name: Deploy webapp to Beanstalk
id: webapp_deploy
uses: einaregilsson/beanstalk-deploy@v21
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: web3-workspace
environment_name: prd-charmverse-webapp
version_label: ${{ github.sha }}
region: us-east-1
deployment_package: deploy.zip
use_existing_version_if_available: true # allows triggering re-deploys with same version
wait_for_deployment: false # set to false to save sweet Github minutes
- name: Deploy websockets to Beanstalk
if: steps.pkg_websocket.outputs.deploy_websocket == 'true'
uses: einaregilsson/beanstalk-deploy@v21
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: prd-charmverse-websockets
environment_name: prd-charmverse-websockets
version_label: ${{ github.sha }}
region: us-east-1
deployment_package: deploy_websockets.zip
use_existing_version_if_available: true # allows triggering re-deploys with same version
wait_for_deployment: false # set to false to save sweet Github
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: [build-app, validate-code, test-matrix, e2e-test-matrix, deploy-docker, deploy-main]
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: 'Webapp 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'