Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.git
.github
.env
.env.*
!.env.example
**/node_modules
**/dist
**/coverage
**/.cache
**/.vite
**/*.log
46 changes: 37 additions & 9 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,22 @@ MAGIC_LOGIN_SECRET=secret
# URL of the data base
MONGO_URL=mongodb://db:27017/abrechnung

# Ports
FRONTEND_PORT=5000
BACKEND_PORT=8000
BACKEND_DEBUG_PORT=9229
INBUCKET_UI_PORT=9000
MONGO_EXPRESS_PORT=8081
# URL of redis
REDIS_URL=redis://redis:6379


##### OPTIONAL SETTINGS #####

# Ports
# FRONTEND_PORT=5000
# BACKEND_PORT=8000
# BACKEND_DEBUG_PORT=9229
# INBUCKET_UI_PORT=9000
# MONGO_EXPRESS_PORT=8081

# COOKIE_MAX_AGE_DAYS=30
# Time to live for magic login tokens in seconds
# MAGIC_LOGIN_TTL_SECONDS=86400

# Maximal size allowed of files being uploaded
# VITE_MAX_FILE_SIZE=16000000
Expand All @@ -50,6 +55,29 @@ MONGO_EXPRESS_PORT=8081
# How many requests to allow
# RATE_LIMIT=

# ⚠️Deprecated⚠️ Use send via mail under connection settings
# If set to 'true', all reports will be saved to `/reports` in the backend container. Uncomment the corresponding backend volume in `docker-compose.yml` to get reports on host machine
# BACKEND_SAVE_REPORTS_ON_DISK=false
# Memory limit for user webhook scripts in MB
# WEBHOOK_SCRIPT_MEMORY_LIMIT_MB=16
# Timeout for compiling user webhook scripts in milliseconds
# WEBHOOK_SCRIPT_COMPILE_TIMEOUT_MS=50
# Timeout for running user webhook scripts in milliseconds
# WEBHOOK_SCRIPT_RUN_TIMEOUT_MS=100
# Timeout webhook HTTP requests in milliseconds
# WEBHOOK_REQUEST_TIMEOUT_MS=5000
# Total number of attempts (including initial) for failed webhook HTTP requests
# WEBHOOK_ATTEMPTS=3
# Delay between webhook retry attempts in milliseconds. BullMQ exponential: 2 ^ (attempts - 1) * delay
# WEBHOOK_RETRY_DELAY=120000
# Concurrency of the integration worker
# WORKER_CONCURRENCY=1

# REDIS_PREFIX=abrechnung

# PROD_INIT_CONNECTION_SETTINGS=
# PROD_INIT_ADMIN_USER=

# USAGE_API_TOKEN=

# Optional host UID/GID mapping for Linux bind mounts (avoid root-owned files in ./backend ./frontend ./common)
# Set with: HOST_UID=$(id -u) and HOST_GID=$(id -g)
# HOST_UID=1000
# HOST_GID=1000
35 changes: 35 additions & 0 deletions .github/actions/setup-development-env/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Setup Development Environment
description: Copy .env.example file and set HOST_UID/HOST_GID for docker compose development runs

runs:
using: 'composite'
steps:
- name: copy .env file
uses: canastro/copy-file-action@ae66602ce7d214dbd2e298c1db67a81388755a0a
with:
source: '.env.example'
target: '.env'
- name: Set host user mapping in .env
shell: bash
run: |
uid="$(id -u)"
gid="$(id -g)"
if [ -n "$(tail -c 1 .env)" ]; then
echo >> .env
fi

if grep -q '^HOST_UID=' .env; then
sed -i "s/^HOST_UID=.*/HOST_UID=${uid}/" .env
elif grep -q '^# HOST_UID=' .env; then
sed -i "s/^# HOST_UID=.*/HOST_UID=${uid}/" .env
else
echo "HOST_UID=${uid}" >> .env
fi

if grep -q '^HOST_GID=' .env; then
sed -i "s/^HOST_GID=.*/HOST_GID=${gid}/" .env
elif grep -q '^# HOST_GID=' .env; then
sed -i "s/^# HOST_GID=.*/HOST_GID=${gid}/" .env
else
echo "HOST_GID=${gid}" >> .env
fi
17 changes: 10 additions & 7 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ jobs:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: copy .env file
uses: canastro/copy-file-action@ae66602ce7d214dbd2e298c1db67a81388755a0a # master
with:
source: '.env.example'
target: '.env'
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-development-env
- name: Start dev Environment
run: docker compose up -d common db ldap inbucket
run: docker compose up -d common db redis ldap inbucket
- name: Run common tests
run: docker compose run common npm run test
# ensures setup runs without error, prevents migration test from failing in next release
- name: Run backend setup
run: docker compose run backend npm run setup
- name: Run backend tests
run: docker compose run backend npm run test
- name: Run frontend tests
run: docker compose run frontend npm run test
- name: Run frontend production build and bundle budgets
run: docker compose run -e NODE_ENV=production frontend npm run build
8 changes: 4 additions & 4 deletions .github/workflows/migration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Build, Test & Migrate

on:
push:
branches: ['main', 'v2']
branches: ["main", "v2"]
pull_request:
branches: ['main', 'v2']
branches: ["main", "v2"]
workflow_call:

jobs:
Expand All @@ -16,9 +16,9 @@ jobs:
needs: [build-and-test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-production-env
- name: Start previous release
run: docker compose -f deploy-compose.yml run backend npm run setup
- name: Run Migration
run: docker compose run backend npm run setup
run: docker compose run backend node dist/setup.js
27 changes: 23 additions & 4 deletions .github/workflows/production-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup Biome
uses: biomejs/setup-biome@454fa0d884737805f48d7dc236c1761a0ac3cc13 # v2.6.0
uses: biomejs/setup-biome@4c91541eaada48f67d7dbd7833600ce162b68f51 # v2.7.1
with:
working-dir: backend
- name: Run Biome
Expand All @@ -24,11 +24,30 @@ jobs:
needs: [code-quality]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-production-env
- name: Build common
run: docker compose build common
- name: Build backend
run: docker compose build backend
- name: Build frontend
run: docker compose build frontend && docker run abrechnung-frontend "npm run build"
run: docker compose build frontend
- name: Smoke-test immutable frontend image with runtime configuration
shell: bash
run: |
set -euo pipefail
cleanup() { docker rm -f frontend-smoke-a frontend-smoke-b >/dev/null 2>&1 || true; }
trap cleanup EXIT
image_id="$(docker image inspect abrechnung-frontend --format '{{.Id}}')"
docker run -d --name frontend-smoke-a -p 18080:8080 \
-e VITE_FRONTEND_URL=http://localhost:18080 -e VITE_BACKEND_URL=http://backend-a.test abrechnung-frontend
docker run -d --name frontend-smoke-b -p 18081:8080 \
-e VITE_FRONTEND_URL=http://localhost:18081 -e VITE_BACKEND_URL=http://backend-b.test abrechnung-frontend
for port in 18080 18081; do
for _ in {1..30}; do curl --fail --silent "http://127.0.0.1:${port}/" >/dev/null && break; sleep 1; done
done
test "$(docker inspect frontend-smoke-a --format '{{.Image}}')" = "$image_id"
test "$(docker inspect frontend-smoke-b --format '{{.Image}}')" = "$image_id"
curl --fail --silent http://127.0.0.1:18080/runtime-config.js | grep -q 'http://backend-a.test'
curl --fail --silent http://127.0.0.1:18081/runtime-config.js | grep -q 'http://backend-b.test'
curl --fail --silent --head http://127.0.0.1:18080/runtime-config.js | grep -qi 'cache-control: no-store'
4 changes: 2 additions & 2 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
contents: write

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-production-env
- name: Build
run: docker compose up -d --build backend
Expand All @@ -29,7 +29,7 @@ jobs:
spec-file: swagger.json
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: swagger-ui
86 changes: 38 additions & 48 deletions .github/workflows/publish-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,76 @@ name: Publish Images
on:
workflow_dispatch:
push:
branches:
- main
- dev
tags: ['**']
branches: ['main']

permissions:
contents: read
packages: write

jobs:
build-test-migrate:
uses: ./.github/workflows/migration-test.yml
#disabled build-test-migrate job for now
#build-test-migrate:
# uses: ./.github/workflows/migration-test.yml

build_and_publish_platform_containers:
name: Build and publish platform containers
needs: [build-test-migrate]
name: Build and publish ${{ matrix.image }} container
#needs: [build-test-migrate]
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
include:
- image: backend
dockerfile: ./backend/Dockerfile.production
- image: frontend
dockerfile: ./frontend/Dockerfile.production

env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ${{ github.repository }}

steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1

- name: Login to DockerHub
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

- name: Login to GitHub Container Registry
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
with:
registry: ghcr.io
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker meta for backend
id: meta-backend
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
images: |
davidloe/abrechnung-backend
ghcr.io/david-loe/abrechnung-backend
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha

- name: Docker meta for frontend
id: meta-frontend
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
- name: Docker meta
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
davidloe/abrechnung-frontend
ghcr.io/david-loe/abrechnung-frontend
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.image }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha

- name: Build and push backend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./backend/Dockerfile.production
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta-backend.outputs.tags }}

- name: Build and push frontend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
- name: Build and push ${{ matrix.image }} image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
file: ./frontend/Dockerfile.production
file: ${{ matrix.dockerfile }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta-frontend.outputs.tags }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.image }}
cache-to: type=gha,mode=max,scope=${{ matrix.image }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.env
.codex

# copy from backend/.gitignore
backend/node_modules
Expand Down
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"recommendations": ["Vue.volar", "biomejs.biome", "esbenp.prettier-vscode", "streetsidesoftware.code-spell-checker"]
"recommendations": ["Vue.volar", "biomejs.biome", "streetsidesoftware.code-spell-checker"]
}
14 changes: 3 additions & 11 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,14 @@
"source.organizeImports.biome": "explicit",
"source.fixAll.biome": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.defaultFormatter": "biomejs.biome",
"biome.lsp.bin": {
"linux-arm64": "./backend/node_modules/@biomejs/cli-linux-arm64-musl/biome",
"linux-x64": "./backend/node_modules/@biomejs/cli-linux-x64-musl/biome",
"darwin-arm64": "./backend/node_modules/@biomejs/cli-darwin-arm64/biome",
"darwin-x64": "./backend/node_modules/@biomejs/cli-darwin-x64/biome",
"win32-x64": "./backend/node_modules/@biomejs/cli-win32-x64/biome.exe",
"win32-arm64": "./backend/node_modules/@biomejs/cli-win32-arm64/biome.exe"
}
},
"js/ts.tsdk.path": "./backend/node_modules/typescript/lib"
}
Loading