Skip to content

Merge pull request #3797 from finnishtransportagency/HARJA-1207_toolt… #873

Merge pull request #3797 from finnishtransportagency/HARJA-1207_toolt…

Merge pull request #3797 from finnishtransportagency/HARJA-1207_toolt… #873

# Security hardening for GitHub Actions
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions
name: 'Harja: Build and deploy to ECS'
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
# Anna edellisen deploymentin mennä rauhassa loppuun, koska mahdollisesti käynnissä olevaa AWS migration lambdaa ei pysty canceloimaan
# Jos edellinen deployment on ehtinyt migraatioiden ajon vaiheeseen, canceloiminen voi aiheuttaa ongelmia.
cancel-in-progress: false
on:
workflow_dispatch:
inputs:
environment:
description: 'Valitse deploy-ympäristö'
type: environment
required: true
push:
branches:
- develop
env:
GH_DOCKER_REGISTRY: ghcr.io
# Testit ja build ajetaan rinnakkain, jotta ne suorituisivat mahdollisimman nopeasti
jobs:
tests:
uses: ./.github/workflows/reusable_run_app_tests.yml
# Permissions
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
# https://docs.github.com/en/actions/using-workflows/reusing-workflows#access-and-permissions
permissions:
# Contents read lupaa tarvitaan checkout actionissa
contents: read
# Packages read lupaa tarvitaan Harjan testaukseen tarkoitettujen Docker imageiden pullaamiseen
packages: read
# Actions write oikeudella voidaan esim. listata ja poistaa artifacteja
actions: write
# Tarvitaan test-reportin julkaisuun PR:ssä
checks: write
strategy:
# Halutaan, että kaikki testit käydään läpi.
# Yksittäinen flaky testi ei saa kaataa koko testimatriisia.
fail-fast: false
max-parallel: 2
matrix:
# Katso saatavilla olevat harjadb servicet docker-compose.yml:stä
configs: [
{ testDBService: "harjadb-latest", e2eBrowsers: [ 'chrome' ], artifactPrefix: 'harjadb-latest_' }
]
with:
test-db-service: ${{ matrix.configs.testDBService }}
e2e-browsers: ${{ toJSON(matrix.configs.e2eBrowsers) }}
# Artifactien nimet täytyy prefixata, jotta jokainen matrix-job tuottaa uniikit build artifactit
# ja nimeltään toisistaan erottuvat Test Reportit
artifact-prefix: ${{ matrix.configs.artifactPrefix }}
# Ei tehdä turhaan lint-testausta develop-branchille. Löydökset käsitellään PR:ien yhteydessä.
lint-clj: 'false'
# Ei tehdä turhaan ylimääristä skannausta testipatterin osana. Skannaus on osa deployment prosessia alla.
scan-docker-image: 'false'
build-harja: 'light'
# Tarkistaa testijobin yleisen statuksen ja lähettää notifikaation, mikäli jotain meni pieleen
check-tests-status-and-notify:
needs: tests
if: always()
runs-on: ubuntu-latest
steps:
- name: Send deploy failure message to Slack
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d
# Lähetetään virheviesti, mikäli tämä tai tests-jobi ei palauta success ja sitä ei ole manuaalisesti canceloitu
if: ${{ (job.status != 'success' || needs.tests.result != 'success') && needs.tests.result != 'cancelled' }}
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
# Slack Block Kit -tyyppinen rikastettu viesti
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":alert-slow: Develop-branchin testeissä tapahtui virhe! Deploymenttia ei tehdä!\n${{ env.JOB_RUN_URL }}"
}
}
]
}
env:
JOB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Send cancel message to Slack
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d
if: ${{ needs.tests.result == 'cancelled' }}
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
# Slack Block Kit -tyyppinen rikastettu viesti
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":warning: Deployment peruttu manuaalisesti.\n${{ env.JOB_RUN_URL }}"
}
}
]
}
env:
JOB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
build-harja:
runs-on: ubuntu-latest
# README: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
# Contents read lupaa tarvitaan checkout actionissa
contents: read
# Packages read lupaa tarvitaan Harjan testaukseen tarkoitettujen Docker imageiden pullaamiseen
packages: read
steps:
- name: Checkout code
uses: actions/checkout@v4
# Testitietokantaa tarvitaan buildin yhteydessä
- name: Start test database
uses: ./.github/actions/start-test-db
with:
registry: ${{ env.GH_DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Katso saatavilla olevat harjadb servicet docker-compose.yml:stä (esim. harjadb-latest)
# Käytetään uusinta saatavilla olevaa testidb:tä AWS buildeissa.
service-name: harjadb-latest
# Huom: Build-action tarvitsee testitietokannan taustalle ennen buildin ajoa
- name: Build Harja Uberjar
uses: ./.github/actions/build-harja-app
with:
build-laadunseuranta: 'false'
# Uploadaa build-artifact. Deploy-workflow lataa sen myöhemmässä vaiheessa.
- name: Upload uberjar as artifact
uses: actions/upload-artifact@v4
with:
name: harja-uberjar
path: ./target/harja-0.0.1-SNAPSHOT-standalone.jar
if-no-files-found: error
# Poistetaan vanhat artifactit, jotta vanhoja tiedostoja ei säilötä turhaan.
# Jos build tehdään esim. perjantai-aamuna ja deployment maanantaina, niin retentio pitää olla kolme vuorokautta.
# Jätetään jonkin verran pelivaraa, mikäli deploymentin kanssa tulee ongelmia.
retention-days: 7
# Docs: https://github.com/slackapi/slack-github-action
- name: Send deploy failure message to Slack
id: slack
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d
if: failure()
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
# Slack Block Kit -tyyppinen rikastettu viesti
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":alert-slow: Harjan build epäonnistui! Automaattista deploymenttia ei tehdä.\n${{ env.JOB_RUN_URL }}"
}
}
]
}
env:
JOB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
# -- Scan Harja image -- #
scan-and-test-image:
runs-on: ubuntu-latest
needs: build-harja
# README: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
# Contents is needed for the checkout action
contents: read
# Sarif-upload
security-events: write
# Packages write lupaa tarvitaan image cachen pushaamiseen GH Docker Registryyn
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download uberjar artifact
uses: actions/download-artifact@v4
with:
name: harja-uberjar
# Download to the same directory as the uberjar is built to
path: ./target
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.GH_DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and tag Harja app test image
id: build-test-image
uses: docker/build-push-action@v6
env:
IMAGE_TAG: ${{ github.sha }}
DOCKERFILE_PATH: 'aws/fargate/Dockerfile'
BUILD_PLATFORMS: linux/amd64
with:
context: .
file: ${{ env.DOCKERFILE_PATH }}
platforms: ${{ env.BUILD_PLATFORMS }}
tags: ${{ env.GH_DOCKER_REGISTRY }}/finnishtransportagency/harja_buildtest:${{ env.IMAGE_TAG }}
labels: |
"commit=${{ github.sha }}"
org.opencontainers.image.title=harja_buildtest
org.opencontainers.image.source=https://github.com/finnishtransportagency/harja
# Cacheta, jotta tulevaisuuden buildit ovat nopeampia.
cache-from: type=registry,ref=${{ env.GH_DOCKER_REGISTRY }}/finnishtransportagency/harja_buildtest:buildcache
cache-to: type=registry,ref=${{ env.GH_DOCKER_REGISTRY }}/finnishtransportagency/harja_buildtest:buildcache,mode=max
# On myös mahdollista käyttää (experimental) GH Actions cachea: https://docs.docker.com/build/cache/backends/gha/
#cache-from: type=gha
#cache-to: type=gha,mode=max
# Disabloi provenance attestations: https://github.com/docker/build-push-action/issues/820
provenance: false
# Lataa buildattu image paikallisesti 'docker images':iin tämän jobin käyttöön
load: true
- name: Run Trivy vulnerability scanner
uses: ./.github/actions/scan-docker-image
env:
DOCKERFILE_PATH: 'aws/fargate/Dockerfile'
TRIVY_IGNORES_PATH: 'aws/fargate/.trivyignore'
with:
# Hae viittaus buildattuun imageen build-test-image stepin outputeista
image-ref: ${{ steps.build-test-image.outputs.imageid }}
dockerfile-path-for-sarif: ${{ env.DOCKERFILE_PATH }}
trivyignores: ${{ env.TRIVY_IGNORES_PATH }}
# TODO: Toistaiseksi ei failata deploymenttia, ainakaan ennen kuin vakaa baseline on saatu muodostettua
fail-job-on-severities: false
#fail-job-on-severities: 'CRITICAL,HIGH'
#ignore-unfixed: true
upload-sarif: true
# -- Deployment -- #
deploy-to-ecs-manually:
uses: ./.github/workflows/reusable_deploy-harja-image-to-ecs.yml
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [ tests, scan-and-test-image ]
# Huom. parametrit ja salaisudet on määritelty GitHub environmenteissa
# README: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
# OIDC tokenia tarvitaan AWS jobeissa roolin omaksumiseen
id-token: write
# Contents read lupaa tarvitaan checkout actionissa
contents: read
# Actions read lupaa tarvitaan actions/download-artifact actionissa
actions: read
with:
environment: ${{ github.event.inputs.environment }}
# Määrittele mistä DB-migraatiot ja build-artifact haetaan. Näiden pitää olla yhteensopivia keskenään.
commit-sha: ${{ github.sha }}
artifact-run-id: ${{ github.run_id }}
# Huom. Tietoturvasyistä johtuen, salaisuuksia ei voi hakea automaattisesti envinronmentista reusable workfloweissa
# Tässä määritetään mitkä yksittäiset salaisuudet reusable workflow saa lukea GitHub environmentista.
# Vaihtoehtoisesti, voi käyttää secrets: inherit toimintoa, jolloin reusable workflow saa kaikki salaisuudet
# kuin kutsuva workflowikin.
secrets:
aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Automaattinen matrix-deployment useaan testiympäristöön (Kun develop-branchiin on pushattu uusi muutos)
deploy-to-ecs-matrix:
uses: ./.github/workflows/reusable_deploy-harja-image-to-ecs.yml
if: ${{ github.event_name == 'push' }}
needs: [ tests, scan-and-test-image ]
# Deployment ajetaan automaattisesti dev ympäristöön ja stg ympäristöön
# TODO: Suunniteltava miten prod-deployment hoidetaan automaattisesti
# tai semi-automaattisesti hyväksyntäprosessilla (github environment protection rules)
strategy:
matrix:
environment: [ dev, stg ]
# Huom. parametrit ja salaisudet on määritelty GitHub environmenteissa
# README: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
# OIDC tokenia tarvitaan AWS jobeissa roolin omaksumiseen
id-token: write
# Contents read lupaa tarvitaan checkout actionissa
contents: read
# Actions read lupaa tarvitaan actions/download-artifact actionissa
actions: read
with:
environment: ${{ matrix.environment }}
# Määrittele mistä DB-migraatiot ja build-artifact haetaan. Näiden pitää olla yhteensopivia keskenään.
commit-sha: ${{ github.sha }}
artifact-run-id: ${{ github.run_id }}
# Huom. Tietoturvasyistä johtuen, salaisuuksia ei voi hakea automaattisesti envinronmentista reusable workfloweissa
# Tässä määritetään mitkä yksittäiset salaisuudet reusable workflow saa lukea GitHub environmentista.
# Vaihtoehtoisesti, voi käyttää secrets: inherit toimintoa, jolloin reusable workflow saa kaikki salaisuudet
# kuin kutsuva workflowikin.
secrets:
aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}