diff --git a/.github/actions/build-and-deploy-api/action.yml b/.github/actions/build-and-deploy-api/action.yml
index 7d1efcf9..9a3a8520 100644
--- a/.github/actions/build-and-deploy-api/action.yml
+++ b/.github/actions/build-and-deploy-api/action.yml
@@ -1,19 +1,13 @@
name: 'build-and-deploy-api'
-description: 'Builds API Project for Production and Deploys it to a given WA Slot'
+description: 'Builds API project for production and deploys it to a given environment'
inputs:
releaseVersion:
required: true
description: "Release Version (Commit or Tag)"
- slot:
+ deploymentEnv:
required: true
- description: "Slot Identifier"
- mongoUri:
- required: true
- description: "Mongo Connection URI"
- sentryKey:
- required: true
- description: "Sentry DSN Key"
+ description: "Deployment Environment"
sentryAuthToken:
required: true
description: "Sentry Auth Token"
@@ -26,6 +20,9 @@ inputs:
containerRegistryPassword:
required: true
description: "Container registry password"
+ containerTag:
+ required: true
+ description: "Container tag"
outputs:
url:
description: "API URL"
@@ -42,6 +39,11 @@ runs:
registry: ${{ inputs.containerRegistryUrl }}
username: ${{ inputs.containerRegistryUsername }}
password: ${{ inputs.containerRegistryPassword }}
+ - name: Create Environment
+ run: envsubst < apps/api/src/app/environment.template > apps/api/src/app/environment.ts
+ shell: bash
+ env:
+ RELEASE_VERSION: ${{ inputs.releaseVersion }}
- name: Build app
run: |
npx nx build api --prod
@@ -55,20 +57,12 @@ runs:
context: ./
file: ./apps/api/Dockerfile
build-args: |
- NODE_VERSION=${{ steps.node-version-check.outputs.node-version}}
+ NODE_VERSION=${{ steps.node-version-check.outputs.node-version }}
push: true
tags: |
- ghcr.io/kordis-leitstelle/kordis-api:${{ inputs.releaseVersion}}
+ ${{ inputs.containerTag }}
cache-from: type=gha
cache-to: type=gha,mode=max
- - name: Set environment for deployment
- run: envsubst < apps/api/src/.env.template > dist/apps/api/.env
- env:
- MONGODB_URI: ${{ inputs.mongoUri }}
- ENVIRONMENT_NAME: ${{ inputs.slot }}
- RELEASE_VERSION: ${{ inputs.releaseVersion }}
- SENTRY_KEY: ${{ inputs.sentryKey }}
- shell: bash
- name: Deploy API
id: wa-deployment
run: echo "url=placeholder" >> $GITHUB_OUTPUT
@@ -80,6 +74,6 @@ runs:
SENTRY_ORG: kordis-leitstelle
SENTRY_PROJECT: kordis-api
with:
- environment: ${{ inputs.slot }}
+ environment: ${{ inputs.deploymentEnv }}
version: ${{ inputs.releaseVersion }}
sourcemaps: ./dist/apps/api
diff --git a/.github/actions/build-and-deploy-spa/action.yml b/.github/actions/build-and-deploy-spa/action.yml
index 5d69b9b8..858485e1 100644
--- a/.github/actions/build-and-deploy-spa/action.yml
+++ b/.github/actions/build-and-deploy-spa/action.yml
@@ -1,25 +1,28 @@
name: 'build-and-deploy-spa'
-description: 'Builds SPA Project for Production and Deploys it to a given SWA Environment'
+description: 'Builds SPA project for production and deploys it to a given environment'
inputs:
- apiUrl:
- required: true
- description: "Base URL of the API"
- oauthConfig:
- required: true
- description: "OAuthConfig from the angular-oauth2-oidc package"
releaseVersion:
required: true
description: "Release Version (Commit or Tag)"
deploymentEnv:
required: true
description: "Deployment Environment"
- sentryKey:
- required: true
- description: "Sentry DSN Key"
sentryAuthToken:
required: true
description: "Sentry Auth Token"
+ containerRegistryUrl:
+ required: true
+ description: "Container registry url"
+ containerRegistryUsername:
+ required: true
+ description: "Container registry username"
+ containerRegistryPassword:
+ required: true
+ description: "Container registry password"
+ containerTag:
+ required: true
+ description: "Container tag"
outputs:
url:
description: "SPA URL"
@@ -28,25 +31,38 @@ outputs:
runs:
using: "composite"
steps:
- - name: Generate Third-Party Licenses
- run: npx --yes generate-license-file@3.0.0-beta.1 --input package.json --output apps/spa/src/assets/third-party-licenses.txt --ci
- shell: bash
- - run: |
- envsubst < apps/spa/src/environments/environment.template > apps/spa/src/environments/environment.prod.ts
- npx nx build spa --prod
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ inputs.containerRegistryUrl }}
+ username: ${{ inputs.containerRegistryUsername }}
+ password: ${{ inputs.containerRegistryPassword }}
+ - run: envsubst < apps/spa/src/environments/environment.template > apps/spa/src/environments/environment.ts
shell: bash
env:
IS_PRODUCTION: true
- ENVIRONMENT_NAME: ${{ inputs.deploymentEnv }}
- API_URL: ${{ inputs.apiUrl }}
- OAUTH_CONFIG: ${{ inputs.oauthConfig }}
RELEASE_VERSION: ${{ inputs.releaseVersion }}
- SENTRY_KEY: ${{ inputs.sentryKey }}
+ - run: |
+ npx nx build spa --prod
+ npx --yes generate-license-file@3.0.1 --input package.json --output dist/apps/spa/browser/assets/third-party-licenses.txt --ci
+ shell: bash
+ - name: Build and push image
+ uses: docker/build-push-action@v5
+ with:
+ context: ./
+ file: ./apps/spa/docker/Dockerfile
+ push: true
+ tags: |
+ ${{ inputs.containerTag }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
- name: Deploy SPA
id: spa-deployment
shell: bash
run: echo "url=placeholder" >> $GITHUB_OUTPUT
- - name: Build SPA with source maps
+ - name: Build SPA with source maps for sentry
run: npx nx build spa --prod --source-map=true
shell: bash
- name: Create Sentry release
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 080ec578..9a5baf04 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
with:
fetch-depth: 0
- name: Ensure Conventional Commits
- uses: webiny/action-conventional-commits@v1.2.0
+ uses: webiny/action-conventional-commits@v1.3.0
- name: Setup node
uses: actions/setup-node@v4
with:
@@ -34,33 +34,42 @@ jobs:
- name: Lint
run: npx nx affected --target=lint --parallel=3
- - name: Run Tests with Code Coverage
- run: npx nx affected --target=test --parallel=3 --ci --coverage --coverageReporters=lcov
+ - name: Run all tests
+ if: github.event_name == 'push'
+ run: npx nx run-many --all --target=test --parallel --ci --coverage --coverageReporters=lcov
+ - name: Run affected tests
+ if: github.event_name == 'pull_request'
+ run: npx nx affected --target=test --parallel --ci --coverage --coverageReporters=lcov
- name: Merge Coverage files
run: '[ -d "./coverage/" ] && ./node_modules/.bin/lcov-result-merger ./coverage/**/lcov.info ./coverage/lcov.info || exit 0'
- - name: Create SPA Environment File
- run: envsubst < apps/spa/src/environments/environment.template > apps/spa/src/environments/environment.prod.ts
+ - name: Create Environments
+ run: |
+ envsubst < apps/spa/src/environments/environment.template > apps/spa/src/environments/environment.ts
+ envsubst < apps/api/src/app/environment.template > apps/api/src/app/environment.ts
env:
IS_PRODUCTION: true
ENVIRONMENT_NAME: 'ci'
RELEASE_VERSION: ${{ github.sha }}
- API_URL: http://localhost:3000/
- OAUTH_CONFIG: undefined
- name: Build
- run: npx nx run-many -t build --all --parallel=3
+ run: |
+ npx nx run-many -t build --all --parallel=3
+ docker build -t kordis-api:${{ github.sha }} -f ./apps/api/Dockerfile --build-arg NODE_VERSION=$(cat .nvmrc | tr -cd '[:digit:].') . &
+ docker build -t kordis-spa:${{ github.sha }} -f ./apps/spa/docker/Dockerfile . &
+ wait
+ - name: Install Chromium for E2Es
+ run: npx -y playwright install chromium
- name: Start and prepare MongoDB for E2Es
run: ./tools/db/kordis-db.sh init e2edb
+ - name: Start API and SPA containers
+ run: |
+ docker run -d -p 3000:3333 -e MONGODB_URI=mongodb://host.docker.internal:27017/e2edb kordis-api:${{ github.sha }}
+ docker run -d -p 4200:8080 -e API_URL=http://localhost:3000 kordis-spa:${{ github.sha }}
- name: Run E2Es
- run: npm run serve:all:prod & (npx wait-on tcp:3000 && npx wait-on http://localhost:4200 && npx nx e2e spa-e2e)
+ run: npx wait-on -t 30s tcp:3000 && npx wait-on -t 30s http://localhost:4200 && npx nx e2e spa-e2e --skipInstall
env:
E2E_BASE_URL: http://localhost:4200/
- MONGODB_URI: mongodb://127.0.0.1:27017/e2edb
- ENVIRONMENT_NAME: 'ci'
- RELEASE_VERSION: ${{ github.sha }}
- SENTRY_KEY: ${{ secrets.SENTRY_KEY }}
- PORT: 3000
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-test-results
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index ddcd631c..4df4f77d 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -27,11 +27,11 @@ jobs:
uses: actions/checkout@v4
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
with:
category: '/language:${{matrix.language}}'
diff --git a/.github/workflows/next-deployment.yml b/.github/workflows/next-deployment.yml
index ea89e308..b2719f8a 100644
--- a/.github/workflows/next-deployment.yml
+++ b/.github/workflows/next-deployment.yml
@@ -29,14 +29,13 @@ jobs:
id: api-deployment
uses: ./.github/actions/build-and-deploy-api
with:
- slot: "next"
+ deploymentEnv: "next"
releaseVersion: ${{ github.sha }}
- mongoUri: ${{ secrets.DEV_MONGODB_URI }}
- sentryKey: ${{ secrets.API_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
containerRegistryUrl: ghcr.io
containerRegistryUsername: ${{ github.actor }}
containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-api:${{ github.sha }}
- name: Apply Database Migrations
run: echo "add again once infrastructure is set up" # ./tools/db/kordis-db.sh apply-pending-migrations
env:
@@ -47,12 +46,13 @@ jobs:
id: spa-deployment
uses: ./.github/actions/build-and-deploy-spa
with:
- apiUrl: ${{ steps.api-deployment.outputs.url }}
- oauthConfig: ${{ secrets.DEV_OAUTH_CONFIG }}
releaseVersion: ${{ github.sha }}
deploymentEnv: "next"
- sentryKey: ${{ secrets.SPA_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ containerRegistryUrl: ghcr.io
+ containerRegistryUsername: ${{ github.actor }}
+ containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-spa:${{ github.sha }}
e2e:
needs: deployment
@@ -69,7 +69,7 @@ jobs:
env:
E2E_BASE_URL: ${{ needs.deployment.outputs.spaUrl }}
AADB2C_TEST_USERS: ${{ secrets.E2E_TEST_USERS }}
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-test-results
diff --git a/.github/workflows/nx-migration-checker.yml b/.github/workflows/nx-migration-checker.yml
index fe4dfcbd..6ab56567 100644
--- a/.github/workflows/nx-migration-checker.yml
+++ b/.github/workflows/nx-migration-checker.yml
@@ -17,7 +17,7 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- - uses: timonmasberg/nx-migration-gh-action@v1.1.8
+ - uses: timonmasberg/nx-migration-gh-action@v1.1.12
with:
repoToken: ${{ secrets.WORKFLOW_PAT }}
prTitle: 'chore(deps): migrate nx to $VERSION'
diff --git a/.github/workflows/preview-deployment.yml b/.github/workflows/preview-deployment.yml
index c9d27501..2f6bbef8 100644
--- a/.github/workflows/preview-deployment.yml
+++ b/.github/workflows/preview-deployment.yml
@@ -69,7 +69,7 @@ jobs:
cache: 'npm'
- run: npm ci --ignore-scripts
- name: Initial Deployment Preview Comment
- uses: peter-evans/create-or-update-comment@v3.1.0
+ uses: peter-evans/create-or-update-comment@v4.0.0
id: pr-preview-comment
with:
issue-number: ${{ github.event.issue.number }}
@@ -81,25 +81,27 @@ jobs:
id: api-deployment
uses: ./.github/actions/build-and-deploy-api
with:
- slot: "pr${{ github.event.issue.number }}"
+ deploymentEnv: "pr${{ github.event.issue.number }}"
releaseVersion: ${{ steps.set-pr-sha.outputs.head_sha }}
- sentryKey: ${{ secrets.API_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
containerRegistryUrl: ghcr.io
containerRegistryUsername: ${{ github.actor }}
containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-api:${{ steps.set-pr-sha.outputs.head_sha }}
+
- name: Build and Deploy SPA
id: spa-deployment
uses: ./.github/actions/build-and-deploy-spa
with:
- apiUrl: ${{ steps.api-deployment.outputs.url }}
- oauthConfig: ${{ secrets.DEV_OAUTH_CONFIG }}
releaseVersion: ${{ steps.set-pr-sha.outputs.head_sha }}
deploymentEnv: "pr${{ github.event.issue.number }}"
- sentryKey: ${{ secrets.SPA_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ containerRegistryUrl: ghcr.io
+ containerRegistryUsername: ${{ github.actor }}
+ containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-spa:${{ steps.set-pr-sha.outputs.head_sha }}
- name: Update PR Preview Comment
- uses: peter-evans/create-or-update-comment@v3.1.0
+ uses: peter-evans/create-or-update-comment@v4.0.0
with:
comment-id: ${{ steps.pr-preview-comment.outputs.comment-id }}
edit-mode: replace
@@ -110,7 +112,7 @@ jobs:
Commit SHA: ${{ steps.set-pr-sha.outputs.head_sha }}
reactions: "rocket"
- name: AZ B2C Tenant Login
- uses: azure/login@v1.5.0
+ uses: azure/login@v1.6.1
with:
creds: '${{ secrets.AZURE_AADB2C_CREDENTIALS }}'
allow-no-subscriptions: true
@@ -143,7 +145,7 @@ jobs:
cache: 'npm'
- run: npm ci --ignore-scripts
- name: Find PR Preview Comment
- uses: peter-evans/find-comment@v2
+ uses: peter-evans/find-comment@v3
id: deploy-preview-comment
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -151,7 +153,7 @@ jobs:
body-includes: Deployment Preview
- name: Update PR Preview Comment
if: steps.deploy-preview-comment.outputs.comment-id != ''
- uses: peter-evans/create-or-update-comment@v3.1.0
+ uses: peter-evans/create-or-update-comment@v4.0.0
with:
comment-id: ${{ steps.deploy-preview-comment.outputs.comment-id }}
edit-mode: replace
@@ -163,25 +165,27 @@ jobs:
id: api-deployment
uses: ./.github/actions/build-and-deploy-api
with:
- slot: "pr${{ github.event.pull_request.number }}"
+ deploymentEnv: "pr${{ github.event.pull_request.number }}"
releaseVersion: ${{ github.event.pull_request.head.sha }}
- sentryKey: ${{ secrets.API_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
containerRegistryUrl: ghcr.io
containerRegistryUsername: ${{ github.actor }}
containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-api:${{ github.event.pull_request.head.sha }}
- name: Build and Deploy SPA
id: spa-deployment
uses: ./.github/actions/build-and-deploy-spa
with:
- apiUrl: ${{ steps.api-deployment.outputs.url }}
- oauthConfig: ${{ secrets.DEV_OAUTH_CONFIG }}
- releaseVersion: ${{ github.event.pull_request.head.sha }}
+ releaseVersion: ${{ github.event.pull_request.head.sha }}
deploymentEnv: "pr${{ github.event.pull_request.number }}"
- sentryKey: ${{ secrets.SPA_SENTRY_KEY }}
sentryAuthToken: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ containerRegistryUrl: ghcr.io
+ containerRegistryUsername: ${{ github.actor }}
+ containerRegistryPassword: ${{ secrets.GITHUB_TOKEN }}
+ containerTag: ghcr.io/kordis-leitstelle/kordis-spa:${{ github.event.pull_request.head.sha }}
+
- name: Update PR Preview Comment
- uses: peter-evans/create-or-update-comment@v3.1.0
+ uses: peter-evans/create-or-update-comment@v4.0.0
with:
comment-id: ${{ steps.deploy-preview-comment.outputs.comment-id }}
edit-mode: replace
@@ -200,7 +204,7 @@ jobs:
(needs.has-deployment.outputs.has-swa == 'true' || needs.has-deployment.outputs.has-wa == 'true') && false
steps:
- name: Find PR Preview Comment
- uses: peter-evans/find-comment@v2
+ uses: peter-evans/find-comment@v3
id: deploy-preview-comment
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -208,7 +212,7 @@ jobs:
body-includes: Deployment Preview
- name: Update PR Preview Comment
if: steps.deploy-preview-comment.outputs.comment-id != ''
- uses: peter-evans/create-or-update-comment@v3.1.0
+ uses: peter-evans/create-or-update-comment@v4.0.0
with:
comment-id: ${{ steps.deploy-preview-comment.outputs.comment-id }}
edit-mode: replace
@@ -217,7 +221,7 @@ jobs:
🏁 This PR has been closed. No deployment preview is available.
reactions: "hooray"
- name: AZ B2C Tenant Login
- uses: azure/login@v1.5.0
+ uses: azure/login@v1.6.1
with:
creds: '${{ secrets.AZURE_AADB2C_CREDENTIALS }}'
allow-no-subscriptions: true
diff --git a/.gitignore b/.gitignore
index 419a1d55..923e59f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,8 +45,7 @@ Thumbs.db
playwright/.auth
# Environments
-apps/api/src/.env
+apps/api/.env
apps/spa-e2e/.env
-apps/spa/src/environments/environment.prod.ts
-.nx/cache
\ No newline at end of file
+.nx/cache
diff --git a/.prettierignore b/.prettierignore
index 41bf6f4e..e2388480 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -8,7 +8,9 @@ package-lock.json
.angular
apps/api/src/main.ts
+apps/spa/src/assets/config.template.json
+libs/spa/observability/src/lib/services/sentry-observability.service.spec.ts
/.nx/cache
-migrations.json
\ No newline at end of file
+migrations.json
diff --git a/.prettierrc b/.prettierrc
index 99afd194..091d14c8 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -6,15 +6,10 @@
"proseWrap": "always",
"overrides": [
{
- "files": [
- "*.ts"
- ],
+ "files": ["*.ts"],
"options": {
"parser": "typescript",
- "importOrder": [
- "^@kordis/(.*)$",
- "^[./]"
- ],
+ "importOrder": ["^@kordis/(.*)$", "^[./]"],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"importOrderParserPlugins": [
@@ -25,9 +20,5 @@
}
}
],
- "plugins": [
- "prettier-plugin-tailwindcss",
- "@trivago/prettier-plugin-sort-imports"
- ],
- "tailwindConfig": "./apps/spa/tailwind.config.js"
+ "plugins": ["@trivago/prettier-plugin-sort-imports"]
}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fd942c16..ec7b0a2b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -73,6 +73,11 @@ Please try to stick to this as much as possible. You can serve the SPA with
you will get redirected to a login page where you can choose a persona. This
will set a JWT in the local storage.
+We agreed on supporting only Chromium based browsers with their 2 latest major
+versions. This allows us to use features that are available for these browsers
+regardless of their support in other browsers. Therefore, please use Chrome or
+Edge for development.
+
### API
The API is a NestJS application serving a GraphQL API. Please use the NX CLI to
@@ -84,7 +89,7 @@ information about the folder and code structure please also read the
[architecture documentation](docs/architecture.md).
Before you can run the API application, you need to create a .env file from the
-[.env.example](apps/api/src/.env.template) file. There you have to specify the
+[.env.example](apps/api/.env.template) file. There you have to specify the
MongoDB connection URI and more configurations. You can ignore some values as
they are only used in production (they have a comment to clarify this). If you
want to test the API directly without the SPA, you can use one of the
diff --git a/README.md b/README.md
index d15a8af0..92d7da40 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@