Files
Anthony LC 4d20941bda 🏷️(yhub) migrate yhub-server to typescript
Convert the yhub-server source and tests from plain JS/mjs to
TypeScript: move sources under src/, add tsconfig, tsconfig.build,
eslint flat config and nodemon config, and update the Dockerfile,
compose and CI workflow for the build step.
2026-09-11 10:53:39 +02:00

287 lines
10 KiB
YAML

name: Main Workflow
on:
push:
branches:
- main
pull_request:
branches:
- "*"
permissions:
contents: read
jobs:
install-dependencies:
uses: ./.github/workflows/dependencies.yml
with:
with-build_mails: true
lint-git:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' # Makes sense only for pull requests
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: show
run: git log
- name: Check absence of fixup commits
if: always()
run: |
! git log | grep 'fixup!'
- name: Install gitlint
if: always()
run: pip install --user requests gitlint
- name: Lint commit messages added to main
if: always()
run: ~/.local/bin/gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD
check-changelog:
runs-on: ubuntu-latest
if: |
contains(github.event.pull_request.labels.*.name, 'noChangeLog') == false &&
github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 50
- name: Check that the CHANGELOG has been modified in the current branch
run: git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.after }} | grep 'CHANGELOG.md'
lint-changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Check CHANGELOG max line length
run: |
max_line_length=$(cat CHANGELOG.md | grep -Ev "^\[.*\]: https://github.com" | wc -L)
if [ $max_line_length -ge 80 ]; then
echo "ERROR: CHANGELOG has lines longer than 80 characters."
exit 1
fi
lint-spell-mistakes:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Install codespell
run: pip install --user codespell
- name: Check for typos
run: |
codespell \
--check-filenames \
--ignore-words-list "Dokument,afterAll,excpt,statics" \
--skip "./git/" \
--skip "**/*.pdf" \
--skip "**/*.po" \
--skip "**/*.pot" \
--skip "**/*.json" \
--skip "**/yarn.lock" \
--skip "./src/backend/uv.lock"
lint-back:
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/backend
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version-file: "src/backend/pyproject.toml"
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Install the project
run: uv sync --locked --all-extras
- name: Check code formatting with ruff
run: uv run ruff format . --diff
- name: Lint code with ruff
run: uv run ruff check .
- name: Lint code with pylint
run: uv run pylint impress demo core
test-back:
runs-on: ubuntu-latest
needs: install-dependencies
defaults:
run:
working-directory: src/backend
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: impress
POSTGRES_USER: dinum
POSTGRES_PASSWORD: pass
ports:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
# message stream for the collaboration server (see the yhub steps below)
valkey:
image: valkey/valkey:alpine
ports:
- 6379:6379
options: --health-cmd "valkey-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
env:
DJANGO_CONFIGURATION: Test
DJANGO_SETTINGS_MODULE: impress.settings
DJANGO_SECRET_KEY: ThisIsAnExampleKeyForTestPurposeOnly
OIDC_OP_JWKS_ENDPOINT: /endpoint-for-test-purpose-only
DB_HOST: localhost
DB_NAME: impress
DB_USER: dinum
DB_PASSWORD: pass
DB_PORT: 5432
STORAGES_STATICFILES_BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage
AWS_S3_ENDPOINT_URL: http://localhost:9000
AWS_S3_ACCESS_KEY_ID: impress
AWS_S3_SECRET_ACCESS_KEY: password
# Collaboration server. The integration tests reach it over this url and
# skip themselves when nothing answers; yhub reads the JWKS back from the
# django server started alongside it, so both sides must share
# JWT_PRIVATE_KEY_FILE.
COLLABORATION_API_URL: http://localhost:3002/collaboration
JWT_PRIVATE_KEY_FILE: ${{ github.workspace }}/data/jwt/private.pem
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Create writable /data
run: |
sudo mkdir -p /data/media && \
sudo mkdir -p /data/static
- name: Restore the mail templates
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
id: mail-templates
with:
path: "src/backend/core/templates/mail"
key: mail-templates-${{ hashFiles('src/mail/mjml') }}
fail-on-cache-miss: true
- name: Start MinIO
run: |
docker pull minio/minio
docker run -d --name minio \
-p 9000:9000 \
-e "MINIO_ACCESS_KEY=impress" \
-e "MINIO_SECRET_KEY=password" \
-v /data/media:/data \
minio/minio server --console-address :9001 /data
# Tool to wait for a service to be ready
- name: Install Dockerize
run: |
curl -sSL https://github.com/jwilder/dockerize/releases/download/v0.8.0/dockerize-linux-amd64-v0.8.0.tar.gz | sudo tar -C /usr/local/bin -xzv
- name: Wait for MinIO to be ready
run: |
dockerize -wait tcp://localhost:9000 -timeout 10s
- name: Configure MinIO
run: |
MINIO=$(docker ps | grep minio/minio | sed -E 's/.*\s+([a-zA-Z0-9_-]+)$/\1/')
docker exec ${MINIO} sh -c \
"mc alias set impress http://localhost:9000 impress password && \
mc alias ls && \
mc mb impress/impress-media-storage && \
mc version enable impress/impress-media-storage"
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version-file: "src/backend/pyproject.toml"
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Install the project
run: uv sync --locked --all-extras
- name: Install gettext (required to compile messages) and MIME support
run: |
sudo apt-get update
sudo apt-get install -y gettext pandoc shared-mime-info
sudo wget https://raw.githubusercontent.com/suitenumerique/django-lasuite/refs/heads/main/assets/conf/mime.types -O /etc/mime.types
# --- collaboration server -------------------------------------------
# The yhub integration tests drive a real collaboration server: it reads
# legacy documents out of MinIO and reads this backend's JWKS back to
# verify the admin token the tests mint, so the two must share the
# signing key. Tests skip themselves when nothing answers on
# COLLABORATION_API_URL.
- name: Generate the JWT signing key
working-directory: .
run: bin/generate-jwt-private-key.sh
- name: Generate a MO file from strings extracted from the project
run: uv run python manage.py compilemessages
- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: "22.x"
- name: Install and build the collaboration server
working-directory: src/yhub-server
# a full install (typescript is a dev dependency) so `yarn build` can
# compile src/ to the dist/ started below
run: |
yarn install --frozen-lockfile
yarn build
# yhub ships its own DDL and creates the database as well, so this needs
# the dependencies installed above — hence its place after them
- name: Create the collaboration server database
working-directory: src/yhub-server
env:
POSTGRES: postgres://dinum:pass@localhost:5432/yhub
run: yarn init-db
- name: Start the backend for the collaboration server to authenticate against
env:
DJANGO_ALLOWED_HOSTS: "*"
run: |
nohup uv run python manage.py runserver 0.0.0.0:8000 --noreload \
> /tmp/backend.log 2>&1 &
dockerize -wait http://localhost:8000/api/v1.0/jwks -timeout 60s
- name: Start the collaboration server
working-directory: src/yhub-server
env:
PORT: 3002
REDIS: redis://localhost:6379
POSTGRES: postgres://dinum:pass@localhost:5432/yhub
REDIS_PREFIX: yhub
COLLABORATION_BACKEND_BASE_URL: http://localhost:8000
COLLABORATION_SERVER_ORIGIN: http://localhost:3000
# the legacy Django bucket it migrates documents out of, named apart
# from the AWS_S3_* the job sets for django itself
SOFT_MIGRATION: "true"
LEGACY_S3_ENDPOINT_URL: http://localhost:9000
LEGACY_S3_ACCESS_KEY_ID: impress
LEGACY_S3_SECRET_ACCESS_KEY: password
LEGACY_S3_BUCKET_NAME: impress-media-storage
run: |
nohup node dist/server.js > /tmp/yhub.log 2>&1 &
dockerize -wait tcp://localhost:3002 -timeout 30s
- name: Run tests
run: uv run pytest -n 2
- name: Collaboration server logs
if: failure()
run: cat /tmp/yhub.log /tmp/backend.log