Skip to content

ADM-909:[frontend]change with comments #3231

ADM-909:[frontend]change with comments

ADM-909:[frontend]change with comments #3231

name: Build and Deploy
on:
push:
branches: ["*"]
pull_request:
branches: ["main"]
workflow_dispatch:
jobs:
shellcheck:
name: Shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
with:
scandir: "./ops"
fossa-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: FOSSA Check
run: |
curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install-latest.sh | bash
export FOSSA_API_KEY=${{secrets.FOSSA_API_KEY}}
fossa analyze
credential-check:
name: Credential Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
# - name: Trufflehog scan
# uses: trufflesecurity/trufflehog@main
# with:
# path: ./
# base: ${{ github.event.repository.default_branch }}
# head: HEAD
# extra_args: --only-verified
- name: Run Gitleaks check
run: |
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
-v "${PWD}:/path" \
ghcr.io/gitleaks/gitleaks:latest \
detect \
--source="/path" \
-v --redact
security-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
ignore-unfixed: true
exit-code: "1"
severity: "CRITICAL"
trivyignores: .trivyignore
- name: Run Trivy vulnerability scanner in IaC mode
uses: aquasecurity/trivy-action@master
with:
scan-type: "config"
exit-code: "1"
ignore-unfixed: true
severity: "CRITICAL"
trivyignores: .trivyignore
backend-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: ${{ vars.JAVA_VERSION }}
distribution: "adopt"
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
- name: Set up Gradle
uses: gradle/[email protected]
- name: Test and check
run: ./gradlew clean check
- name: Build
run: ./gradlew clean build
- name: Upload Test Report to Codacy
run: |
export CODACY_PROJECT_TOKEN=${{secrets.CODACY_PROJECT_TOKEN}}
bash <(curl -Ls https://coverage.codacy.com/get.sh)
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN_BACKEND }}
run: ./gradlew build sonar --info
backend-license-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: ${{ vars.JAVA_VERSION }}
distribution: "adopt"
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
- name: Set up Gradle
uses: gradle/[email protected]
- name: License check
run: ./gradlew clean checkLicense
- uses: actions/upload-artifact@v4
if: ${{ failure() }}
with:
name: backend-license-report
path: backend/build/reports/dependency-license/
retention-days: ${{ vars.RETENTION_DAYS }}
deny-dot-star-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Java .*; check
shell: bash {0}
run: ./ops/check.sh dot-star
deny-px-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: CSS unit `px` check
shell: bash {0}
run: ./ops/check.sh px
deny-css-hex-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: CSS hex check
shell: bash {0}
run: ./ops/check.sh hex
deny-css-rgba-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: CSS rgba check
shell: bash {0}
run: ./ops/check.sh rgba
frontend-type-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ vars.NODE_VERSION }}
- name: Install & Lint
run: |
npm install -g pnpm
pnpm install --no-frozen-lockfile
pnpm run type-check
frontend-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ vars.NODE_VERSION }}
- name: Install & Lint
run: |
npm install -g pnpm
pnpm install --no-frozen-lockfile
pnpm lint
- name: Audit for vulnerabilities
run: pnpm dlx audit-ci@^6 --critical --report-type full
- name: Testing and coverage
run: |
pnpm coverage:silent
- name: Building
run: pnpm build
- name: Upload Test Report to Codacy
run: |
export CODACY_PROJECT_TOKEN=${{secrets.CODACY_PROJECT_TOKEN}}
bash <(curl -Ls https://coverage.codacy.com/get.sh)
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
with:
projectBaseDir: frontend
args: >
-Dsonar.organization=au-heartbeat
-Dsonar.projectKey=au-heartbeat-heartbeat-frontend
-Dsonar.javascript.lcov.reportPaths=./coverage/lcov.info
-Dsonar.sources=src/
-Dsonar.tests=__tests__
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN_FRONTEND }}
frontend-license-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ vars.NODE_VERSION }}
- name: License compliance check
run: |
./ops/check.sh frontend-license
check-buildkite-status:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check BuildKite status
env:
BUILDKITE_TOKEN: ${{ secrets.BUILDKITE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
CURRENT_ACTOR: ${{ github.actor }}
EVENT_NAME: ${{ github.event_name }}
CURRENT_BRANCH_NAME: ${{ github.ref }}
PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }}
run: |
./ops/check.sh buildkite-status
images-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Build and tag
run: |
docker build -t frontend:latest ./ -f ./ops/infra/Dockerfile.frontend
docker build -t backend:latest ./ -f ./ops/infra/Dockerfile.backend
- name: Run Trivy vulnerability scanner for frontend
uses: aquasecurity/trivy-action@master
with:
image-ref: frontend:latest
format: "table"
exit-code: "1"
ignore-unfixed: true
severity: "CRITICAL,HIGH"
trivyignores: ".trivyignore"
- name: Run Trivy vulnerability scanner for backend
uses: aquasecurity/trivy-action@master
with:
image-ref: backend:latest
format: "table"
exit-code: "1"
ignore-unfixed: true
severity: "CRITICAL,HIGH"
trivyignores: ".trivyignore"
deploy-infra:
if: ${{ github.ref == 'refs/heads/main' }}
needs:
- fossa-check
- frontend-check
- deny-px-check
- deny-css-hex-check
- deny-css-rgba-check
- frontend-type-check
- backend-check
- deny-dot-star-check
- security-check
- images-check
- shellcheck
- credential-check
- frontend-license-check
- backend-license-check
- check-buildkite-status
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout repo
uses: actions/checkout@v4
# - name: Configure AWS credentials
# if: ${{ contains(github.event.head_commit.message, '[infra]') }}
# uses: aws-actions/configure-aws-credentials@v4
# with:
# role-to-assume: ${{ secrets.AWS_GITHUB_ACTION_ROLE }}
# aws-region: ${{ secrets.AWS_REGION}}
# role-session-name: MySessionName
# - name: Deploy infra
# if: ${{ contains(github.event.head_commit.message, '[infra]') }}
# env:
# SSHPublicKey: ${{ secrets.AWS_EC2_SSH_PUBLIC_KEY}}
# AWSHost: ${{ secrets.AWS_HOST }}
# AWSAccountId: ${{ secrets.AWS_ACCOUNT_ID }}
# AWSRegion: ${{ secrets.AWS_REGION }}
# BuildKiteToken: ${{ secrets.BUILDKITE_TOKEN }}
# SSHPrivateKey: ${{ secrets.AWS_EC2_SSH_PRIVATE_KEY}}
# run: |
# sh ./ops/infra/updateAwsResource.sh
build-backend:
if: ${{ github.ref == 'refs/heads/main' }}
needs:
- deploy-infra
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_GITHUB_ACTION_ROLE }}
aws-region: ${{ secrets.AWS_REGION}}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push for Backend
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: heartbeat_backend
IMAGE_TAG: "hb${{ github.run_number }}"
run: |
docker build -t $REGISTRY/$REPOSITORY:latest ./ -f ./ops/infra/Dockerfile.backend
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG ./ -f ./ops/infra/Dockerfile.backend
# - name: Push for Backend
# env:
# REGISTRY: ${{ steps.login-ecr.outputs.registry }}
# REPOSITORY: heartbeat_backend
# IMAGE_TAG: "hb${{ github.run_number }}"
# run: |
# docker push $REGISTRY/$REPOSITORY:latest
# docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
build-frontend:
if: ${{ github.ref == 'refs/heads/main' }}
needs:
- deploy-infra
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_GITHUB_ACTION_ROLE }}
aws-region: ${{ secrets.AWS_REGION}}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push for Frontend
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: heartbeat_frontend
IMAGE_TAG: "hb${{ github.run_number }}"
run: |
docker build -t $REGISTRY/$REPOSITORY:latest ./ -f ./ops/infra/Dockerfile.frontend
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG ./ -f ./ops/infra/Dockerfile.frontend
# - name: Push for Frontend
# env:
# REGISTRY: ${{ steps.login-ecr.outputs.registry }}
# REPOSITORY: heartbeat_frontend
# IMAGE_TAG: "hb${{ github.run_number }}"
# run: |
# docker push $REGISTRY/$REPOSITORY:latest
# docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
deploy-e2e:
runs-on: ubuntu-latest
needs:
- build-backend
- build-frontend
steps:
- name: Checkout repo
# uses: actions/checkout@v4
run: echo "This is an empty step"
# - name: Update docker-compose.yaml
# run: |
# sed -i -e 's/heartbeat_backend:latest/${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}\/heartbeat_backend:hb${{ github.run_number }}/g' ops/infra/docker-compose.yml
# sed -i -e 's/heartbeat_frontend:latest/${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}\/heartbeat_frontend:hb${{ github.run_number }}/g' ops/infra/docker-compose.yml
# - name: Copy docker-compose to ec2
# uses: appleboy/scp-action@master
# with:
# host: ${{ secrets.AWS_EC2_IP_E2E }}
# username: ${{ secrets.AWS_USERNAME }}
# key: ${{ secrets.AWS_PRIVATE_KEY }}
# port: ${{ secrets.AWS_SSH_PORT }}
# source: "./ops/infra/docker-compose.yml"
# target: "./"
# strip_components: 1
# - name: Deploy
# uses: appleboy/ssh-action@master
# env:
# REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}
# IMAGE_TAG: "hb${{ github.run_number }}"
# with:
# host: ${{ secrets.AWS_EC2_IP_E2E }}
# username: ${{ secrets.AWS_USERNAME }}
# key: ${{ secrets.AWS_PRIVATE_KEY }}
# port: ${{ secrets.AWS_SSH_PORT }}
# script: |
# aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}
# cp "./ops/infra/docker-compose.yml" ./
# # docker-compose down
# if [[ -n $(docker images -f label=arch=Backend -q) ]]; then docker rmi -f $(docker images -f label=arch=Backend -q); fi
# if [[ -n $(docker images -f label=arch=Frontend -q) ]]; then docker rmi -f $(docker images -f label=arch=Frontend -q); fi
# docker pull $REGISTRY/heartbeat_backend:$IMAGE_TAG
# docker pull $REGISTRY/heartbeat_frontend:$IMAGE_TAG
# export SPRING_PROFILES_ACTIVE="e2e"
# docker-compose up -d frontend
e2e:
runs-on: ubuntu-latest
needs:
- deploy-e2e
container:
image: mcr.microsoft.com/playwright:latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
node-version: ${{ vars.NODE_VERSION }}
- name: Install
run: |
npm install -g pnpm
- name: Set env
run: echo "HOME=/root" >> $GITHUB_ENV
- name: Install shell deps
run: |
apt-get update && apt-get install -y jq
jq --version
- name: Check e2e deployment
env:
BUILDKITE_TOKEN: ${{ secrets.BUILDKITE_TOKEN }}
COMMIT_SHA: ${{ github.sha }}
run: ./ops/check.sh buildkite-e2e-deployed
- name: Run E2E
env:
APP_ORIGIN: ${{ vars.APP_HTTP_SCHEDULE }}://${{ secrets.AWS_EC2_IP_E2E }}:${{ secrets.AWS_EC2_IP_E2E_FRONTEND_PORT }}
E2E_TOKEN_JIRA: ${{ secrets.E2E_TOKEN_JIRA }}
E2E_TOKEN_BUILD_KITE: ${{ secrets.E2E_TOKEN_BUILD_KITE }}
E2E_TOKEN_GITHUB: ${{ secrets.E2E_TOKEN_GITHUB }}
E2E_TOKEN_PIPELINE_NO_ORG_CONFIG_BUILDKITE: ${{ secrets.E2E_TOKEN_PIPELINE_NO_ORG_CONFIG_BUILDKITE }}
shell: bash {0}
run: ./ops/check.sh e2e
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: frontend/e2e/reports/
retention-days: 30
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: always()
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_ICON_EMOJI: ":heart-beat:"
SLACK_COLOR: ${{ job.status }}
SLACK_USERNAME: "Heartbeat E2E Status"
deploy:
runs-on: ubuntu-latest
needs:
- e2e
steps:
- name: Checkout repo
# uses: actions/checkout@v4
run: echo "This is an empty step"
# - name: Update docker-compose.yaml
# run: |
# sed -i -e 's/heartbeat_backend:latest/${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}\/heartbeat_backend:hb${{ github.run_number }}/g' ops/infra/docker-compose.yml
# sed -i -e 's/heartbeat_frontend:latest/${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}\/heartbeat_frontend:hb${{ github.run_number }}/g' ops/infra/docker-compose.yml
# - name: Copy docker-compose to ec2
# uses: appleboy/scp-action@master
# with:
# host: ${{ secrets.AWS_EC2_IP }}
# username: ${{ secrets.AWS_USERNAME }}
# key: ${{ secrets.AWS_PRIVATE_KEY }}
# port: ${{ secrets.AWS_SSH_PORT }}
# source: "./ops/infra/docker-compose.yml"
# target: "./"
# strip_components: 1
# - name: Deploy
# uses: appleboy/ssh-action@master
# env:
# REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}
# IMAGE_TAG: "hb${{ github.run_number }}"
# with:
# host: ${{ secrets.AWS_EC2_IP }}
# username: ${{ secrets.AWS_USERNAME }}
# key: ${{ secrets.AWS_PRIVATE_KEY }}
# port: ${{ secrets.AWS_SSH_PORT }}
# script: |
# aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}
# cp "./ops/infra/docker-compose.yml" ./
# # docker-compose down
# if [[ -n $(docker images -f label=app=Heartbeat -q) ]]; then docker rmi -f $(docker images -f label=app=Heartbeat -q); fi
# docker pull ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}/heartbeat_backend:$IMAGE_TAG
# docker pull ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_HOST }}/heartbeat_frontend:$IMAGE_TAG
# docker-compose up -d frontend