Skip to content

Update E2E tests for latest bookee page UI changes (#1234) #639

Update E2E tests for latest bookee page UI changes (#1234)

Update E2E tests for latest bookee page UI changes (#1234) #639

name: deploy-staging-and-create-release
concurrency:
group: deploy-staging
cancel-in-progress: true
on:
push:
branches:
- main
permissions:
id-token: write # required for OIDC connecting to AWS
contents: write # This is required to create a release
jobs:
deploy-stage-iac:
environment: staging
runs-on: ubuntu-latest
env:
TF_VAR_region: ${{ vars.AWS_REGION }}
TF_VAR_environment: ${{ vars.ENV_SHORT_NAME }}
TF_VAR_name_prefix: "tb-${{ vars.PROJECT_SHORT_NAME }}-${{ vars.ENV_SHORT_NAME }}"
TF_VAR_frontend_url: ${{ vars.FRONTEND_URL }}
TF_VAR_ssl_cert_arn: ${{ vars.SSL_CERT_ARN }}
steps:
- uses: actions/checkout@v4
- name: install opentofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: ${{ vars.TF_VERSION }}
tofu_wrapper: false
- name: install terragrunt
run: |
sudo wget -q -O /bin/terragrunt "https://github.com/gruntwork-io/terragrunt/releases/download/v${{ vars.TG_VERSION }}/terragrunt_linux_amd64"
sudo chmod +x /bin/terragrunt
terragrunt -v
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
role-session-name: Appointment_GitHub_to_AWS_via_FederatedOIDC
aws-region: ${{ vars.AWS_REGION }}
- name: vpc
working-directory: ./tofu/environments/stage/network/vpc
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -out tfplan
terragrunt apply tfplan
- name: backend-infra
working-directory: ./tofu/environments/stage/services/backend-infra
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -out tfplan
terragrunt apply tfplan
- name: cache
working-directory: ./tofu/environments/stage/data-store/cache
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -out tfplan
terragrunt apply tfplan
- name: database
working-directory: ./tofu/environments/stage/data-store/database
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -out tfplan
terragrunt apply tfplan
- name: frontend-infra
working-directory: ./tofu/environments/stage/services/frontend-infra
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -out tfplan
terragrunt apply tfplan
build-and-deploy-stage-frontend:
needs:
- deploy-stage-iac
if: |
always() &&
(needs.deploy-stage-iac.result == 'success' || needs.deploy-stage-iac.result == 'skipped')
environment: staging
runs-on: ubuntu-latest
env:
TF_VAR_region: ${{ vars.AWS_REGION }}
TF_VAR_environment: ${{ vars.ENV_SHORT_NAME }}
TF_VAR_name_prefix: "tb-${{ vars.PROJECT_SHORT_NAME }}-${{ vars.ENV_SHORT_NAME }}"
TF_VAR_frontend_url: ${{ vars.FRONTEND_URL }}
TF_VAR_ssl_cert_arn: ${{ vars.SSL_CERT_ARN }}
steps:
- uses: actions/checkout@v4
- name: Setup NPM
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: cd frontend && npm install
- name: Build stage frontend
run: |
cp frontend/.env.stage.example frontend/.env.stage
cd frontend && npm run build -- --mode ${{ vars.APP_ENV }}
- name: install opentofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: ${{ vars.TF_VERSION }}
tofu_wrapper: false
- name: install terragrunt
run: |
sudo wget -q -O /bin/terragrunt "https://github.com/gruntwork-io/terragrunt/releases/download/v${{ vars.TG_VERSION }}/terragrunt_linux_amd64"
sudo chmod +x /bin/terragrunt
terragrunt -v
- name: Install AWS CLI
uses: unfor19/install-aws-cli-action@v1
with:
version: 2
arch: amd64
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
role-session-name: Appointment_GitHub_to_AWS_via_FederatedOIDC
aws-region: ${{ vars.AWS_REGION }}
- name: Get frontend bucket & distribution
id: get-frontend-resources
working-directory: ./tofu/environments/stage/services/frontend-infra
run: |
terragrunt init -upgrade
echo "bucket=$(terragrunt output bucket_name | tr -d '"')" >> $GITHUB_OUTPUT
echo "distribution=$(terragrunt output cloudfront_id)" >> $GITHUB_OUTPUT
- name: Deploy frontend to S3
run: |
aws s3 sync frontend/dist "s3://${{ steps.get-frontend-resources.outputs.bucket }}"
aws cloudfront create-invalidation --distribution-id ${{ steps.get-frontend-resources.outputs.distribution }} --paths "/*"
build-and-deploy-stage-frontend-pulumi:
environment: staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-central-1
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_PULUMI }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_PULUMI }}
- name: Setup NPM
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: cd frontend && npm install
- name: Build stage frontend
run: |
rm -rf frontend/dist # Clean up from previous build
cp frontend/.env.pulumistage.example frontend/.env.stage
cd frontend && npm run build -- --mode ${{ vars.APP_ENV }}
- name: Deploy frontend to S3
run: |
aws s3 sync frontend/dist s3://${{ secrets.FRONTEND_BUCKET }}
aws cloudfront create-invalidation --distribution-id ${{ secrets.FRONTEND_CF_DISTRO_ID }} --paths '/*'
build-backend-image:
environment: staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
role-session-name: Appointment_GitHub_to_AWS_via_FederatedOIDC
aws-region: ${{ vars.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- name: Build, tag, and push backend image to Amazon ECR
id: build-backend
env:
ECR_TAG: '${{ steps.login-ecr.outputs.registry }}/${{ vars.PROJECT }}:backend-${{ github.sha }}'
RELEASE_VERSION: ${{ github.sha }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build --build-arg "RELEASE_VERSION=$RELEASE_VERSION" -t $ECR_TAG ./backend -f ./backend/Dockerfile
docker push $ECR_TAG
echo "image_backend=$ECR_TAG" >> $GITHUB_OUTPUT
echo $ECR_TAG > ecr_tag.txt
- name: Archive ECR tag
uses: actions/upload-artifact@v4
with:
name: ecr_tag
path: ecr_tag.txt
build-backend-image-pulumi:
environment: staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials (Pulumi)
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-central-1
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_PULUMI }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_PULUMI }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- name: Build, tag, and push backend image to Amazon ECR
id: build-backend
env:
ECR_TAG: '${{ steps.login-ecr.outputs.registry }}/thunderbird/appointment:${{ github.sha }}'
RELEASE_VERSION: ${{ github.sha }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build --build-arg "RELEASE_VERSION=$RELEASE_VERSION" -t $ECR_TAG ./backend -f ./backend/Dockerfile
docker push $ECR_TAG
echo "image_backend=$ECR_TAG" >> $GITHUB_OUTPUT
echo $ECR_TAG > new_ecr_tag.txt
- name: Archive ECR tag
uses: actions/upload-artifact@v4
with:
name: new_ecr_tag
path: new_ecr_tag.txt
deploy-stage-backend:
needs:
- build-backend-image
- deploy-stage-iac
if: |
always() &&
(needs.deploy-stage-iac.result == 'success' || needs.deploy-stage-iac.result == 'skipped')
environment: staging
runs-on: ubuntu-latest
env:
TF_VAR_region: ${{ vars.AWS_REGION }}
TF_VAR_environment: ${{ vars.ENV_SHORT_NAME }}
TF_VAR_name_prefix: "tb-${{ vars.PROJECT_SHORT_NAME }}-${{ vars.ENV_SHORT_NAME }}"
TF_VAR_app_env: ${{ vars.APP_ENV }}
TF_VAR_db_enc_secret: ${{ vars.DB_ENCRYPTED_SECRET }}
TF_VAR_frontend_url: ${{ vars.FRONTEND_URL }}
TF_VAR_fxa_secret: ${{ vars.FXA_SECRET }}
TF_VAR_google_oauth_secret: ${{ vars.GOOGLE_OAUTH_SECRET }}
TF_VAR_log_level: ${{ vars.LOG_LEVEL }}
TF_VAR_short_base_url: ${{ vars.SHORT_BASE_URL }}
TF_VAR_smtp_secret: ${{ vars.SMTP_SECRET }}
TF_VAR_zoom_callback: ${{ vars.ZOOM_CALLBACK }}
TF_VAR_zoom_secret: ${{ vars.ZOOM_SECRET }}
TF_VAR_sentry_dsn: ${{ vars.SENTRY_DSN }}
TF_VAR_ssl_cert_arn: ${{ vars.SSL_CERT_ARN }}
steps:
- uses: actions/checkout@v4
- name: install opentofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: ${{ vars.TF_VERSION }}
tofu_wrapper: false
- name: install terragrunt
run: |
sudo wget -q -O /bin/terragrunt "https://github.com/gruntwork-io/terragrunt/releases/download/v${{ vars.TG_VERSION }}/terragrunt_linux_amd64"
sudo chmod +x /bin/terragrunt
terragrunt -v
- name: download ecr tag
uses: actions/download-artifact@v4
with:
name:
ecr_tag
- name: Unzip ECR tag
id: get_ecr_tag
run: |
output=$(cat ecr_tag.txt)
echo ecr_tag=$output >> $GITHUB_OUTPUT
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
role-session-name: Appointment_GitHub_to_AWS_via_FederatedOIDC
aws-region: ${{ vars.AWS_REGION }}
- name: deploy backend-service
working-directory: ./tofu/environments/stage/services/backend-service
run: |
terragrunt init -upgrade
terragrunt validate
terragrunt plan -var 'image=${{ steps.get_ecr_tag.outputs.ecr_tag }}' -out tfplan
terragrunt apply tfplan
deploy-stage-backend-pulumi:
needs:
- build-backend-image-pulumi
if: needs.build-backend-image-pulumi.result == 'success'
environment: staging
runs-on: ubuntu-latest
steps:
# Pulumi steps
- uses: actions/checkout@v4
- name: Download ecr tag
uses: actions/download-artifact@v4
with:
name:
new_ecr_tag
- name: Configure AWS credentials for Pulumi
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-central-1
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_PULUMI }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_PULUMI }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: "true"
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.13
- name: Set up virtual environment
shell: bash
run: |
python -m pip install virtualenv
cd pulumi
virtualenv ./venv
source ./venv/bin/activate
pip install -r requirements.txt
- name: Unpack ECR tag
id: get_ecr_tag_pulumi
run: |
output=$(cat new_ecr_tag.txt)
echo new_ecr_tag=$output >> $GITHUB_OUTPUT
# Deploy to stage
- name: Deploy new image to stage
shell: bash
env:
ECR_TAG: "${{ steps.get_ecr_tag_pulumi.outputs.new_ecr_tag }}"
PULUMI_ACCESS_TOKEN: "${{ secrets.PULUMI_ACCESS_TOKEN }}"
run: |
# Update the PATH to include the right version of Pulumi; this is non-trivial or impossible
# to do with the GHA workflow "env" settings above.
export PATH="/home/runner/.pulumi/bin:$PATH"
cd pulumi
# Create a YAML config stump containing only the nested tree leading to the image tag update
cat << EOF > newimage.yaml
resources:
tb:fargate:FargateClusterWithLogging:
backend:
task_definition:
container_definitions:
backend:
image: "$ECR_TAG"
EOF
# Use yq to merge the stump into the main config
yq -i '. *= load("newimage.yaml")' config.stage.yaml
# Set up the Pulumi environment and update the service
export PULUMI_CONFIG_PASSPHRASE="${{ secrets.PULUMI_PASSPHRASE }}"
pulumi login
pulumi stack select stage
pulumi up -y --diff --target \
'urn:pulumi:stage::appointment::tb:fargate:FargateClusterWithLogging$aws:ecs/taskDefinition:TaskDefinition::appointment-stage-fargate-backend-taskdef' \
--target-dependents
create-release:
needs:
- build-backend-image
- build-and-deploy-stage-frontend
- build-and-deploy-stage-frontend-pulumi
- deploy-stage-iac
- deploy-stage-backend
- deploy-stage-backend-pulumi
if: |
always() &&
contains(join(needs.*.result, ','), 'success') &&
! contains(join(needs.*.result, ','), 'failure')
environment: production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup NPM
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: cd frontend && npm install
- name: Build prod frontend
run: |
cp frontend/.env.prod.example frontend/.env.prod
cd frontend && npm run build -- --mode ${{ vars.APP_ENV }}
zip -r ../frontend.zip dist
- name: Build prod frontend (Pulumi)
run: |
rm -rf frontend/dist # Clean up from previous build
cp frontend/.env.pulumiprod.example frontend/.env.prod
cd frontend && npm run build -- --mode ${{ vars.APP_ENV }}
zip -r ../pulumifrontend.zip dist
- name: Download ECR tag
uses: actions/download-artifact@v4
with:
name:
ecr_tag
- name: Download ECR tag (Pulumi)
uses: actions/download-artifact@v4
with:
name:
new_ecr_tag
- name: Zip IaC
run: zip -r iac.zip tofu -x "tofu/environments/stage/*" "tofu/environments/prod/*/*/.terragrunt-cache/*"
- name: Zip Pulumi
run: |
# Remove any lingering build pieces that may exist
pushd pulumi
rm -rf appointment_pulumi.egg-info build __pycache__ .ruff_cache venv
popd
# Tarbizz the Pulumi IaC
tar -cvjf pulumi.tbz pulumi/
- name: Create release tag
id: create-release-tag
run: echo "tag_name=r-$(printf %04d $GITHUB_RUN_NUMBER)" >> $GITHUB_OUTPUT
- name: Create draft release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.create-release-tag.outputs.tag_name }}
name: Release ${{ steps.create-release-tag.outputs.tag_name }}
body: |
## Info
Commit ${{ github.sha }} was deployed to `stage`. [See code diff](${{ github.event.compare }}).
It was initialized by [${{ github.event.sender.login }}](${{ github.event.sender.html_url }}).
## How to Promote?
In order to promote this to prod, edit the draft and press **"Publish release"**.
draft: true
files: |
ecr_tag.txt
new_ecr_tag.txt
frontend.zip
pulumifrontend.zip
iac.zip
pulumi.tbz
e2e-tests-browserstack-stage:
name: e2e-tests-browserstack-stage
needs: create-release
if: false
# if: ${{ !failure() || !cancelled() }}
runs-on: ubuntu-latest
environment: staging
env:
APPT_LOGIN_EMAIL: ${{ secrets.E2E_APPT_STAGE_LOGIN_EMAIL }}
APPT_LOGIN_PWORD: ${{ secrets.E2E_APPT_STAGE_LOGIN_PASSWORD }}
APPT_DISPLAY_NAME: ${{ secrets.E2E_APPT_STAGE_DISPLAY_NAME }}
APPT_MY_SHARE_LINK: ${{ secrets.E2E_APPT_STAGE_MY_SHARE_LINK }}
APPT_BOOKEE_EMAIL: ${{ secrets.E2E_APPT_STAGE_BOOKEE_EMAIL }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: 'test/e2e/package-lock.json'
- name: Install dependencies
run: |
cd ./test/e2e
npm install
- name: BrowserStack Env Setup
uses: browserstack/github-actions/setup-env@master
with:
username: ${{ secrets.BROWSERSTACK_USERNAME }}
access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
project-name: 'Thunderbird Appointment'
build-name: 'E2E Tests: BUILD_INFO'
- name: Run E2E Tests on stage via Browserstack
run: |
cd ./test/e2e
cp .env.stage.example .env
npm run e2e-test-browserstack-gha