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 the collaboration server working-directory: src/yhub-server run: npm ci --omit=dev # 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: npm run 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 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