Skip to content

HL-861 | Use markdown format to display service terms #4039

HL-861 | Use markdown format to display service terms

HL-861 | Use markdown format to display service terms #4039

Workflow file for this run

name: (BF) Build & Review & Acceptance tests
on:
pull_request:
paths:
- "backend/benefit/**"
- "frontend/benefit/**"
- "frontend/shared/**"
- "frontend/*"
- ".github/workflows/bf-review.yml"
- '!frontend/**/__tests__'
- '!**/README.md'
workflow_dispatch:
inputs:
build_required:
description: "Build images (true/false)"
required: true
default: "false"
pr_number:
description: "Pull request number (if redeploy without build) or own number for environment"
required: true
env:
CONTAINER_REGISTRY: ghcr.io
CONTAINER_REGISTRY_USER: ${{ secrets.GHCR_CONTAINER_REGISTRY_USER }}
CONTAINER_REGISTRY_PASSWORD: ${{ secrets.GHCR_TOKEN }}
CONTAINER_REGISTRY_REPO: ghcr.io/city-of-helsinki/${{ github.event.repository.name }}
REPO_NAME: ${{ github.event.repository.name }}
KUBECONFIG_RAW: ${{ secrets.KUBECONFIG_RAW }}
BUILD_ARTIFACT_FOLDER: "build_artifacts"
SERVICE_ARTIFACT_FOLDER: "service_artifacts"
BASE_DOMAIN: ${{ secrets.BASE_DOMAIN_STAGING }}
DATABASE_USER: user
DATABASE_PASSWORD: testing-password
K8S_REQUEST_CPU: 5m
K8S_REQUEST_RAM: 256Mi
K8S_LIMIT_CPU: 500m
K8S_LIMIT_RAM: 428Mi
K8S_PROBE_FAILURE_THRESHOLD: 30
K8S_PROBE_PERIOD: 20
HELM_BUFFER_TIME: 300
APPLICANT_URL: https://helsinkibenefit-bf-appl-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }}
HANDLER_URL: https://helsinkibenefit-bf-hndl-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }}
NEXT_PUBLIC_BACKEND_URL: https://helsinkibenefit-bf-bknd-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }}
NEXT_PUBLIC_MOCK_FLAG: 1
CORS_ALLOW_ALL_ORIGINS: 1
jobs:
build:
# No building for dependabot PRs
# See https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/automating-dependabot-with-github-actions#handling-pull_request-events
if: ${{ github.actor != 'dependabot[bot]' }}
strategy:
fail-fast: false
matrix:
service: ["bf-bknd", "bf-appl", "bf-hdlr"]
include:
- service: bf-bknd
context: ./backend
dockerfile: ./backend/docker/benefit.Dockerfile
port: 8000
- service: bf-appl
context: ./frontend
dockerfile: ./frontend/Dockerfile
project: benefit
folder: applicant
port: 3000
- service: bf-hdlr
context: ./frontend
dockerfile: ./frontend/Dockerfile
project: benefit
folder: handler
port: 3100
concurrency:
group: ${{ github.event.pull_request.number }}-${{ matrix.service }}
cancel-in-progress: false
runs-on: ubuntu-latest
name: Build
steps:
- uses: actions/checkout@v3
- name: Build ${{ matrix.service }}
if: github.event_name == 'pull_request' || github.event.inputs.build_required == 'true'
# uses: andersinno/kolga-build-action@v2 temporary disabled due to build problem
# https://helsinkisolutionoffice.atlassian.net/browse/DEVOPS-424
uses: docker://ghcr.io/andersinno/kolga:2c6028bb7f478301d53928b0a72d5e87f58c0ac8-production
with:
entrypoint: /app/devops
args: create_images
env:
# Don't need to lint / typecheck for e2e, they're done in another workflow
DOCKER_BUILD_ARG_NEXTJS_IGNORE_ESLINT: true
# TODO we need separate typecheck to bf-*-frontend-test.yml workflow
DOCKER_BUILD_ARG_NEXTJS_IGNORE_TYPECHECK: false
DOCKER_BUILD_ARG_NEXT_DISABLE_SOURCEMAPS: true
DOCKER_BUILD_ARG_NEXT_TELEMETRY_DISABLED: true
DOCKER_BUILD_ARG_NEXTJS_SENTRY_UPLOAD_DRY_RUN: true
DOCKER_BUILD_ARG_NEXT_PUBLIC_BACKEND_URL: ${{ env.NEXT_PUBLIC_BACKEND_URL }}
DOCKER_BUILD_ARG_NEXT_PUBLIC_MOCK_FLAG: ${{ env.NEXT_PUBLIC_MOCK_FLAG }}
DOCKER_BUILD_ARG_NEXTJS_DISABLE_SENTRY: true
DOCKER_BUILD_ARG_NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}
DOCKER_BUILD_ARG_NEXT_PUBLIC_SENTRY_ENVIRONMENT: ${{ secrets.NEXT_PUBLIC_SENTRY_ENVIRONMENT }}
DOCKER_BUILD_ARG_NEXT_PUBLIC_SENTRY_TRACE_SAMPLE_RATE: 1.0
DOCKER_BUILD_ARG_PROJECT: ${{ matrix.project }}
DOCKER_BUILD_ARG_FOLDER: ${{ matrix.folder }}
DOCKER_BUILD_ARG_PORT: ${{ matrix.port }}
DOCKER_BUILD_SOURCE: ${{ matrix.dockerfile }}
DOCKER_BUILD_CONTEXT: ${{ matrix.context }}
DOCKER_IMAGE_NAME: ${{ matrix.service }}
SERVICE_PORT: ${{ matrix.port }}
BUILDKIT_CACHE_DISABLE: true
review:
strategy:
fail-fast: false
matrix:
service: ["bf-bknd", "bf-appl", "bf-hdlr"]
include:
- service: bf-bknd
context: ./backend
dockerfile: ./backend/docker/benefit.Dockerfile
database: true
port: 8000
- service: bf-appl
context: ./frontend
dockerfile: ./frontend/Dockerfile
database: false
project: benefit
folder: applicant
port: 3000
- service: bf-hdlr
context: ./frontend
dockerfile: ./frontend/Dockerfile
database: false
project: benefit
folder: handler
port: 3100
concurrency:
group: ${{ github.event.pull_request.number }}-${{ matrix.service }}
cancel-in-progress: false
runs-on: ubuntu-latest
needs: build
name: Review
steps:
- uses: actions/checkout@v3
- uses: andersinno/kolga-setup-action@v2
with:
pr_number: ${{ github.event.inputs.pr_number }}
- name: Backend variables
if: matrix.database
env:
SECRET_KEY: ${{ secrets.K8S_SECRET_SECRET_KEY_REVIEW }}
K8S_SECRET_ENCRYPTION_KEY: ${{ secrets.K8S_SECRET_ENCRYPTION_KEY_REVIEW }}
K8S_SECRET_SOCIAL_SECURITY_NUMBER_HASH_KEY: ${{ secrets.K8S_SECRET_SOCIAL_SECURITY_NUMBER_HASH_KEY_REVIEW }}
K8S_SECRET_PREVIOUS_BENEFITS_SOCIAL_SECURITY_NUMBER_HASH_KEY: ${{ secrets.K8S_SECRET_SOCIAL_SECURITY_NUMBER_HASH_KEY_REVIEW }}
run: |
echo "K8S_SECRET_LOGOUT_REDIRECT_URL=${{ env.APPLICANT_URL }}/login?logout=true" >> $GITHUB_ENV
echo "K8S_SECRET_ALLOWED_HOSTS=*" >> $GITHUB_ENV
echo "K8S_SECRET_CREATE_SUPERUSER=${{ secrets.K8S_SECRET_CREATE_SUPERUSER_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_ADMIN_USER_PASSWORD=${{ secrets.K8S_SECRET_ADMIN_USER_PASSWORD_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_SECRET_KEY=$SECRET_KEY" >> $GITHUB_ENV
echo "K8S_SECRET_CSRF_COOKIE_DOMAIN=.test.kuva.hel.ninja" >> $GITHUB_ENV
echo "K8S_SECRET_CORS_ALLOWED_ORIGINS=${{ env.APPLICANT_URL }},${{ env.HANDLER_URL }}" >> $GITHUB_ENV
echo "K8S_SECRET_CSRF_TRUSTED_ORIGINS=.test.kuva.hel.ninja" >> $GITHUB_ENV
echo "K8S_SECRET_LOGIN_REDIRECT_URL=${{ env.APPLICANT_URL }}" >> $GITHUB_ENV
echo "K8S_SECRET_LOGIN_REDIRECT_URL_FAILURE=${{ env.APPLICANT_URL }}/login?error=true" >> $GITHUB_ENV
echo "K8S_SECRET_APPLICANT_URL=${{ env.APPLICANT_URL }}" >> $GITHUB_ENV
echo "K8S_SECRET_HANDLER_URL=${{ env.HANDLER_URL }}" >> $GITHUB_ENV
echo "K8S_SECRET_NEXT_PUBLIC_MOCK_FLAG=${{ env.NEXT_PUBLIC_MOCK_FLAG }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_DB=${{ github.event.repository.name }}-${{ matrix.service }}-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_HOST=${{ secrets.K8S_SECRET_DATABASE_HOST_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_PORT=${{ secrets.K8S_SECRET_DATABASE_PORT_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_USERNAME=${{ secrets.K8S_SECRET_DATABASE_USERNAME_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_PASSWORD=${{ secrets.K8S_SECRET_DATABASE_PASSWORD_REVIEW }}" >> $GITHUB_ENV
echo "K8S_SECRET_DATABASE_URL=postgresql://${{ secrets.K8S_SECRET_DATABASE_USERNAME_REVIEW }}:${{ secrets.K8S_SECRET_DATABASE_PASSWORD_REVIEW }}@${{ secrets.K8S_SECRET_DATABASE_HOST_REVIEW}}:${{ secrets.K8S_SECRET_DATABASE_PORT_REVIEW }}/${{ github.event.repository.name }}-${{ matrix.service }}-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
- name: Review-Services
if: matrix.database
uses: City-of-Helsinki/review-services-action@main
with:
database: ${{ github.event.repository.name }}-${{ matrix.service }}-${{ github.event.pull_request.number }}
namespace: ${{ env.K8S_NAMESPACE }}
action: create
db_user: ${{ secrets.K8S_SECRET_DATABASE_ADMIN_USERNAME_REVIEW }}
db_password: ${{ secrets.K8S_SECRET_DATABASE_ADMIN_PASSWORD_REVIEW}}
db_host: ${{ secrets.K8S_SECRET_DATABASE_HOST_REVIEW }}
db_port: ${{ secrets.K8S_SECRET_DATABASE_PORT_REVIEW }}
kubeconfig: ${{ secrets.KUBECONFIG_RAW }}
- name: Service with ingress
run: |
echo "ENVIRONMENT_URL=https://helsinkibenefit-${{ matrix.service }}-${{ github.event.pull_request.number }}.${{ env.BASE_DOMAIN }}" >> $GITHUB_ENV
- name: Deploy
uses: andersinno/kolga-deploy-action@v2
env:
DOCKER_BUILD_SOURCE: ${{ matrix.dockerfile }}
DOCKER_BUILD_CONTEXT: ./${{ matrix.context }}
DOCKER_IMAGE_NAME: ${{ matrix.service }}
PROJECT_NAME: ${{ github.event.repository.name }}-${{ matrix.service }}
K8S_SECRET_VERSION: ${{ github.sha }}
VAULT_JWT_PRIVATE_KEY: ${{ secrets.VAULT_ACCESS_PRIVATE_KEY_REVIEW }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
VAULT_KV_VERSION: "2"
VAULT_JWT_AUTH_PATH: ${{ github.event.repository.name }}-${{ matrix.service }}-review
VAULT_KV_SECRET_MOUNT_POINT: review
SERVICE_PORT: ${{ matrix.port }}
K8S_SECRET_ALLOWED_HOSTS: "*"
APP_MIGRATE_COMMAND: ${{ matrix.database == 'true' && '/app/.prod/on_deploy.sh' || ''}}
CORS_ALLOWED_ORIGINS: ${{ env.ENVIRONMENT_URL }}
CSRF_TRUSTED_ORIGINS: ${{ env.ENVIRONMENT_URL }}
LOGOUT_REDIRECT_URL: ${{ env.APPLICANT_URL }}/login?logout=true
- name: Create PR comment for helsinkibenefit-V${{ matrix.service }}
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
header: deployment-helsinkibenefit-${{ matrix.service }}
message: |
**Helsinkibenefit-${{ matrix.service }} is deployed to: ${{ env.ENVIRONMENT_URL }}** :rocket::rocket::rocket:
acceptance-tests:
name: BF Acceptance tests
runs-on: ubuntu-latest
needs: Review
defaults:
run:
working-directory: ./frontend
strategy:
fail-fast: false
matrix:
service: ["bf-appl"]
include:
- service: bf-appl
dir: benefit/applicant
steps:
- uses: actions/checkout@v3
- name: Setup kubectl
run: |
echo "${{ env.KUBECONFIG_RAW }}" > $(pwd)/kubeconfig
echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV
shell: bash
- name: Setup Node.js environment
uses: actions/setup-node@v3
with:
node-version: "18"
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn --prefer-offline --frozen-lockfile --check-files --production=false
- name: Service with ingress
run: |
echo "ENVIRONMENT_URL=https://helsinkibenefit-${{ matrix.service }}-${{ github.event.pull_request.number }}.${{ env.BASE_DOMAIN }}" >> $GITHUB_ENV
- name: Run Acceptance Tests for ${{ matrix.service }}
id: testcafe
run: yarn --cwd ${{matrix.dir}} browser-test:ci -q attemptLimit=3,successThreshold=1
env:
GITHUB_WORKFLOW_NAME: ${{ github.workflow }}
GITHUB_WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
FRONTEND_URL: ${{ env.ENVIRONMENT_URL }}
APPLICANT_URL: ${{ env.ENVIRONMENT_URL }}
NEXT_PUBLIC_BACKEND_URL: ${{ env.NEXT_PUBLIC_BACKEND_URL }}
NEXT_PUBLIC_MOCK_FLAG: ${{ env.NEXT_PUBLIC_MOCK_FLAG }}
- name: Upload Acceptance Test results for ${{ matrix.service }}
run: |
zip -r report.zip ${{matrix.dir}}/report > no_output 2>&1
curl -s -H "Content-Type: application/zip" -H "Authorization: Bearer ${{ secrets.NETLIFY_AUTH_TOKEN }}" --data-binary "@report.zip" https://api.netlify.com/api/v1/sites > response.json
echo "REPORT_URL=$(cat response.json|python -c "import sys, json; print('https://' + json.load(sys.stdin)['subdomain'] + '.netlify.com')")" >> $GITHUB_ENV
if: always() && steps.testcafe.outcome == 'failure'
- name: Create/update PR comment for Acceptance Test results
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
header: testcafe-results-${{ matrix.service }}
message: |
## TestCafe result is __${{ steps.testcafe.outcome }}__ for ${{ env.ENVIRONMENT_URL }}! ${{steps.testcafe.outcome == 'success' && ':laughing::tada::tada::tada:' || ':crying_cat_face::anger::boom::boom:' }}
if: always() && (steps.testcafe.outcome == 'success' || steps.testcafe.outcome == 'failure')
- name: Create/update PR comment for Acceptance Test results
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
header: testcafe-results-${{ matrix.service }}
append: true
message: |
**Check the report on: [${{ env.REPORT_URL }}](${{ env.REPORT_URL }})**
if: always() && steps.testcafe.outcome == 'failure'
- name: Upload screenshots and videos of failed tests to artifact
uses: actions/upload-artifact@v3
with:
name: report
path: ./frontend/${{matrix.dir}}/report
if: always() && steps.testcafe.outcome == 'failure'