HL-891: Fix CSRF token issues #2125
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: (TET) Build & Review & Acceptance tests | |
on: | |
pull_request: | |
paths: | |
- 'backend/tet/**' | |
- 'frontend/tet/**' | |
- 'frontend/shared/**' | |
- 'frontend/*' | |
- '.github/workflows/te-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 | |
YOUTH_URL: https://te-yout-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }} | |
ADMIN_URL: https://te-admn-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }} | |
NEXT_PUBLIC_BACKEND_URL: https://te-bknd-${{ github.event.pull_request.number }}.${{ secrets.BASE_DOMAIN_STAGING }} | |
NEXT_PUBLIC_MOCK_FLAG: 1 | |
CORS_ALLOW_ALL_ORIGINS: 1 | |
NEXT_SHARP_PATH: /app/node_modules/sharp | |
jobs: | |
build: | |
if: ${{ github.actor != 'dependabot[bot]' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
service: [ 'te-bknd', 'te-admn', 'te-yout' ] | |
include: | |
- service: te-bknd | |
context: ./backend | |
dockerfile: ./backend/docker/tet.Dockerfile | |
port: 8000 | |
- service: te-yout | |
context: ./frontend | |
dockerfile: ./frontend/Dockerfile | |
project: tet | |
folder: youth | |
port: 3000 | |
- service: te-admn | |
context: ./frontend | |
dockerfile: ./frontend/Dockerfile | |
project: tet | |
folder: admin | |
port: 3000 | |
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 te-*-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_NEXTJS_DISABLE_SENTRY: true | |
DOCKER_BUILD_ARG_NEXT_PUBLIC_BACKEND_URL: ${{ env.NEXT_PUBLIC_BACKEND_URL }} | |
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_NEXT_PUBLIC_MOCK_FLAG: ${{ env.NEXT_PUBLIC_MOCK_FLAG }} | |
DOCKER_BUILD_ARG_NEXT_SHARP_PATH: ${{ env.NEXT_SHARP_PATH }} | |
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: [ 'te-bknd', 'te-admn', 'te-yout' ] | |
include: | |
- service: te-bknd | |
context: ./backend | |
dockerfile: ./backend/docker/tet.Dockerfile | |
database: true | |
port: 8000 | |
- service: te-yout | |
context: ./frontend | |
dockerfile: ./frontend/Dockerfile | |
database: false | |
project: tet | |
folder: youth | |
port: 3000 | |
- service: te-admn | |
context: ./frontend | |
dockerfile: ./frontend/Dockerfile | |
database: false | |
project: tet | |
folder: admin | |
port: 3000 | |
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 }} | |
run: | | |
echo "K8S_SECRET_ALLOWED_HOSTS=*" >> $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.YOUTH_URL }},${{ env.ADMIN_URL }}" >> $GITHUB_ENV | |
echo "K8S_SECRET_CSRF_TRUSTED_ORIGINS=.test.kuva.hel.ninja" >> $GITHUB_ENV | |
echo "K8S_SECRET_NEXT_PUBLIC_MOCK_FLAG=${{ env.NEXT_PUBLIC_MOCK_FLAG }}" >> $GITHUB_ENV | |
echo "K8S_SECRET_LOGIN_REDIRECT_URL=${{ env.ADMIN_URL }}" >> $GITHUB_ENV | |
echo "K8S_SECRET_LOGIN_REDIRECT_URL_FAILURE=${{ env.ADMIN_URL }}/login?error=true" >> $GITHUB_ENV | |
echo "K8S_SECRET_AD_LOGIN_REDIRECT_URL=${{ env.ADMIN_URL }}" >> $GITHUB_ENV | |
echo "K8S_SECRET_AD_LOGIN_REDIRECT_URL_FAILURE=${{ env.ADMIN_URL }}/login?error=true" >> $GITHUB_ENV | |
echo "K8S_SECRET_LOGOUT_REDIRECT_URL=${{ env.ADMIN_URL }}/login?logout=true" >> $GITHUB_ENV | |
echo "K8S_SECRET_EAUTH_REDIRECT_URL=${{ env.ADMIN_URL }}" >> $GITHUB_ENV | |
echo "K8S_SECRET_EAUTH_REDIRECT_URL_FAILURE=${{ env.ADMIN_URL }}/login?error=true" >> $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://${{ 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.YOUTH_URL }},${{ env.ADMIN_URL }} | |
CSRF_TRUSTED_ORIGINS: ${{ env.YOUTH_URL }},${{ env.ADMIN_URL }} | |
AD_LOGIN_REDIRECT_URL: ${{ env.ADMIN_URL }} | |
AD_LOGIN_REDIRECT_URL_FAILURE: ${{ env.ADMIN_URL }}/login?error=true | |
EAUTH_REDIRECT_URL: ${{ env.ADMIN_URL }} | |
EAUTH_REDIRECT_URL_FAILURE: ${{ env.ADMIN_URL }}/login?error=true | |
LOGOUT_REDIRECT_URL: ${{ env.ADMIN_URL }}/login?logout=true | |
NEXT_SHARP_PATH: ${ env.NEXT_SHARP_PATH } | |
- name: Create PR comment for ${{ matrix.service }} | |
uses: marocchino/sticky-pull-request-comment@v2 | |
with: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
header: deployment-te-${{ matrix.service }} | |
message: | | |
**${{ matrix.service }} is deployed to: ${{ env.ENVIRONMENT_URL }}** :rocket::rocket::rocket: | |
acceptance-tests: | |
name: TET Acceptance tests | |
runs-on: ubuntu-latest | |
needs: Review | |
defaults: | |
run: | |
working-directory: ./frontend | |
strategy: | |
fail-fast: false | |
matrix: | |
service: [ 'te-admn', 'te-yout' ] | |
include: | |
- service: te-admn | |
dir: tet/admin | |
- service: te-yout | |
dir: tet/youth | |
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://${{ 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 }} | |
YOUTH_URL: ${{ env.YOUTH_URL }} | |
ADMIN_URL: ${{ env.ADMIN_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' |