Compare commits

..

2 Commits

Author SHA1 Message Date
lebaudantoine 4a6b44f562 🔒️(agents) upgrade libpcre2-8-0 to fix CVE-2026-103111
The python:3.14.7-slim base image ships libpcre2-8-0
10.46-1~deb13u2, which is affected by CVE-2026-103111 (HIGH):
an out-of-bounds write triggered by a crafted regular expression.

Explicitly install libpcre2-8-0 in the base stage so apt pulls
the patched 10.46-1~deb13u3 from trixie-security. All stages
(builder, development, production) inherit the fix.

This line can be dropped once an upstream python slim image
ships the patched package.
2026-10-01 16:23:01 +02:00
lebaudantoine 4a94e0316f 🔒️(backend) fix HIGH CVEs in Django and urllib3
Address the following HIGH severity CVEs reported by Trivy on the
backend image:

* Django 5.2.16 → 5.2.17
  - CVE-2026-15307 — remote code execution via GeoDjango spatial
    lookups.

* urllib3 2.7.0 → 2.8.0
  - CVE-2026-97687 — traffic interception via HTTPS proxy TLS
    configuration override.
  - CVE-2026-97689 — denial of service via unbounded memory
    allocation in the chunk parser.
2026-10-01 15:59:25 +02:00
35 changed files with 528 additions and 208 deletions
-9
View File
@@ -1,9 +0,0 @@
[codespell]
# Files that are not English, or generated
skip = ./.git,*.pdf,*.po,*.pot,*.json,*.lock,package-lock.json,
./LICENSES,
./src/summary/summary/core/locales,
./src/summary/summary/core/prompt.py
# Valid words in French (connexion) or in the code (statics)
ignore-words-list = connexion,statics
check-filenames = true
-20
View File
@@ -1,20 +0,0 @@
# Debian 13 base image (python:3.14-slim): no fixed version available yet.
# Review regularly and remove entries once Debian ships a fix.
# util-linux
CVE-2026-76642
CVE-2026-78408
CVE-2026-78409
CVE-2026-78410
# acl
CVE-2026-54369
# ncurses
CVE-2025-69720
# systemd
CVE-2026-16742
# perl-base (fix deferred by Debian)
CVE-2026-9538
-19
View File
@@ -1,19 +0,0 @@
name: Changelog Workflow
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
changelog:
uses: suitenumerique/ci/.github/workflows/_changelog.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1
+176 -22
View File
@@ -11,30 +11,180 @@ permissions:
contents: read contents: read
jobs: jobs:
lint-git:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' # Makes sense only for pull requests
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 0
- name: show
run: git log
- name: Enforce absence of print statements in code
if: always()
run: |
! git diff origin/${{ github.event.pull_request.base.ref }}..HEAD -- . ':(exclude).github/workflows/**' | grep "print("
- name: Check absence of fixup commits
if: always()
run: |
! git log | grep 'fixup!'
- name: Install uv
if: always()
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Lint commit messages added to main
if: always()
run: uvx --no-build --from gitlint-core==0.19.1 gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD
lint-python: check-changelog:
name: lint ${{ matrix.service }} runs-on: ubuntu-latest
strategy: if: |
fail-fast: false contains(github.event.pull_request.labels.*.name, 'noChangeLog') == false &&
matrix: github.event_name == 'pull_request'
include: permissions:
- service: backend contents: read
working_directory: src/backend steps:
pylint_targets: meet demo core - name: Checkout repository
- service: agents uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
working_directory: src/agents with:
pylint_targets: "" fetch-depth: 50
- service: summary - name: Check that the CHANGELOG has been modified in the current branch
working_directory: src/summary run: git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.after }} | grep 'CHANGELOG.md'
pylint_targets: ""
uses: suitenumerique/ci/.github/workflows/_python-lint.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1 lint-changelog:
with: runs-on: ubuntu-latest
working_directory: ${{ matrix.working_directory }} permissions:
python_version: "3.13" contents: read
pylint_targets: ${{ matrix.pylint_targets }} steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- 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
build-mails:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: src/mail
steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Node.js
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"
- name: Restore the mail templates
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: mail-templates
with:
path: "src/backend/core/templates/mail"
key: mail-templates-${{ hashFiles('src/mail/mjml') }}
- name: Install yarn
if: steps.mail-templates.outputs.cache-hit != 'true'
run: npm install -g --ignore-scripts yarn@1.22.22
- name: Install node dependencies
if: steps.mail-templates.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- name: Build mails
if: steps.mail-templates.outputs.cache-hit != 'true'
run: yarn build
- name: Cache mail templates
if: steps.mail-templates.outputs.cache-hit != 'true'
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: "src/backend/core/templates/mail"
key: mail-templates-${{ hashFiles('src/mail/mjml') }}
lint-back:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: src/backend
steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the project
run: uv sync --locked --all-extras
- name: Check code formatting with ruff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: uv run --no-sync --no-build ruff check .
- name: Lint code with pylint
run: uv run --no-sync --no-build pylint meet demo core
lint-agents:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: src/agents
steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the project
run: uv sync --locked --all-extras --no-build
- name: Check code formatting with ruff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: uv run --no-sync --no-build ruff check .
lint-summary:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: src/summary
steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the project
run: uv sync --locked --all-extras
- name: Check code formatting with ruff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: uv run --no-sync --no-build ruff check .
test-back: test-back:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build-mails
permissions: permissions:
contents: read contents: read
defaults: defaults:
@@ -94,8 +244,12 @@ jobs:
sudo mkdir -p /data/media && \ sudo mkdir -p /data/media && \
sudo mkdir -p /data/static sudo mkdir -p /data/static
- name: Build or restore the mail templates - name: Restore the mail templates
uses: suitenumerique/ci/actions/mail-templates@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1 uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: mail-templates
with:
path: "src/backend/core/templates/mail"
key: mail-templates-${{ hashFiles('src/mail/mjml') }}
# Creates the access key and the bucket on startup # Creates the access key and the bucket on startup
- name: Start Garage - name: Start Garage
-14
View File
@@ -1,14 +0,0 @@
name: Project quality Workflow
on:
pull_request:
permissions:
contents: read
jobs:
quality:
uses: suitenumerique/ci/.github/workflows/_project-quality.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1
with:
print_check_paths: src/backend src/summary src/agents
codespell_ignore_words: "unsecure"
+33
View File
@@ -0,0 +1,33 @@
name: Download Crowdin translations
on:
workflow_dispatch:
types: [file-fully-translated]
permissions:
contents: write
pull-requests: write
jobs:
crowdin:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Download Crowdin files
uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2.17.0
with:
upload_sources: false
upload_translations: false
download_translations: true
localization_branch_name: l10n_crowdin_translations
create_pull_request: true
pull_request_title: "New Crowdin translations"
pull_request_body: "New Crowdin pull request with translations"
pull_request_base_branch_name: "main"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
CROWDIN_BASE_PATH: ${{ github.workspace }}
+252 -49
View File
@@ -1,5 +1,5 @@
name: Docker images name: Docker Hub Workflow
run-name: Docker images run-name: Docker Hub Workflow
on: on:
workflow_dispatch: workflow_dispatch:
@@ -15,62 +15,265 @@ on:
permissions: permissions:
contents: read contents: read
env:
DOCKER_USER: 1001:127
DOCKER_CONTAINER_REGISTRY_HOSTNAME: docker.io
DOCKER_CONTAINER_REGISTRY_NAMESPACE: lasuite
IS_MULTI_PLATFORM_BUILD: ${{ startsWith(github.ref, 'refs/tags/v') }}
BUILD_PLATFORMS: ${{ startsWith(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
jobs: jobs:
build-and-push: build-and-push-backend:
name: ${{ matrix.service }} runs-on: ubuntu-latest
strategy: permissions:
fail-fast: false contents: read
matrix: steps:
include: -
- service: backend name: Checkout repository
image_name: lasuite/meet-backend uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
context: . -
file: ./Dockerfile name: Set up QEMU
target: backend-production if: env.IS_MULTI_PLATFORM_BUILD == 'true'
- service: frontend uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
image_name: lasuite/meet-frontend -
context: . name: Set up Docker Buildx
file: ./src/frontend/Dockerfile uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
target: frontend-production -
- service: frontend-dinum name: Docker meta
image_name: lasuite/meet-frontend-dinum id: meta
context: . uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
file: ./docker/dinum-frontend/Dockerfile with:
target: frontend-production images: '${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend'
- service: summary -
image_name: lasuite/meet-summary name: Login to DockerHub
context: ./src/summary if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
file: ./src/summary/Dockerfile uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
target: production with:
- service: agents username: ${{ secrets.DOCKER_HUB_USER }}
image_name: lasuite/meet-agents password: ${{ secrets.DOCKER_HUB_PASSWORD }}
context: ./src/agents -
file: ./src/agents/Dockerfile name: Run trivy scan
target: production uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
uses: suitenumerique/ci/.github/workflows/_docker-publish.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1 with:
with: docker-build-args: '--target backend-production -f Dockerfile'
image_name: ${{ matrix.image_name }} docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend:${{ github.sha }}'
context: ${{ matrix.context }} -
file: ${{ matrix.file }} name: Build and push
target: ${{ matrix.target }} uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
docker_user: "1001:127" with:
is_multi_platform: ${{ startsWith(github.ref, 'refs/tags/v') }} context: .
should_push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }} target: backend-production
trivy_scan: true platforms: ${{ env.BUILD_PLATFORMS }}
trivy_ignore_files: ./.github/.trivyignore build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
secrets: push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }}
DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }} tags: ${{ steps.meta.outputs.tags }}
DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} labels: ${{ steps.meta.outputs.labels }}
build-and-push-frontend-generic:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
-
name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: '${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend'
-
name: Login to DockerHub
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
-
name: Run trivy scan
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
with:
docker-build-args: '-f src/frontend/Dockerfile --target frontend-production'
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend:${{ github.sha }}'
-
name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ./src/frontend/Dockerfile
target: frontend-production
platforms: ${{ env.BUILD_PLATFORMS }}
build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-and-push-frontend-dinum:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
-
name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: '${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend-dinum'
-
name: Login to DockerHub
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
-
name: Run trivy scan
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
with:
docker-build-args: '-f docker/dinum-frontend/Dockerfile --target frontend-production'
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend-dinum:${{ github.sha }}'
-
name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ./docker/dinum-frontend/Dockerfile
target: frontend-production
platforms: ${{ env.BUILD_PLATFORMS }}
build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-and-push-summary:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
-
name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: '${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-summary'
-
name: Login to DockerHub
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
-
name: Run trivy scan
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
continue-on-error: true
with:
docker-build-args: '-f src/summary/Dockerfile --target production'
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-summary:${{ github.sha }}'
docker-context: './src/summary'
-
name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: ./src/summary
file: ./src/summary/Dockerfile
target: production
platforms: ${{ env.BUILD_PLATFORMS }}
build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-and-push-agents:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
-
name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: lasuite/meet-agents
-
name: Login to DockerHub
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
-
name: Run trivy scan
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
continue-on-error: true
with:
docker-build-args: '-f src/agents/Dockerfile --target production'
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-agents:${{ github.sha }}'
docker-context: './src/agents'
-
name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: ./src/agents
file: ./src/agents/Dockerfile
target: production
platforms: ${{ env.BUILD_PLATFORMS }}
build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
push: ${{ github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
notify-argocd: notify-argocd:
permissions: permissions:
contents: read contents: read
needs: needs:
- build-and-push - build-and-push-frontend-generic
- build-and-push-frontend-dinum
- build-and-push-backend
- build-and-push-summary
- build-and-push-agents
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
steps: steps:
- uses: suitenumerique/ci/actions/argocd-webhook-notification@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1 - uses: numerique-gouv/action-argocd-webhook-notification@cac2ee67896eb13e84e804f60c4271370424eaa8 # main
id: notify id: notify
with: with:
deployment_repo_path: "${{ secrets.DEPLOYMENT_REPO_URL }}" deployment_repo_path: "${{ secrets.DEPLOYMENT_REPO_URL }}"
+23 -7
View File
@@ -1,17 +1,33 @@
name: Release Helm chart name: Release Chart
run-name: Release Chart
on: on:
push: push:
branches:
- main
paths: paths:
- src/helm/meet/** - src/helm/meet/**
permissions:
contents: read
jobs: jobs:
release: release:
permissions: permissions:
contents: write contents: write
uses: suitenumerique/ci/.github/workflows/_release-helm-chart.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1 runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 0
- name: Cleanup
run: rm -rf ./src/helm/extra
- name: Install Helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Publish Helm charts
uses: numerique-gouv/helm-gh-pages@2cf477ae49d7c70037ceb1685803f4f7bad9b981 # add-overwrite-option
with:
charts_dir: ./src/helm
linting: on
token: ${{ secrets.GITHUB_TOKEN }}
-21
View File
@@ -1,21 +0,0 @@
name: Security analysis
on:
push:
branches:
- main
pull_request:
branches:
- "**"
permissions: {}
jobs:
zizmor:
permissions:
contents: read
actions: read
security-events: write
uses: suitenumerique/ci/.github/workflows/_zizmor.yml@ca6401ac83e981e5b0a94f06f68baaa6e6d0a436 # v0.0.1
with:
config: .github/zizmor.yml
-5
View File
@@ -1,5 +0,0 @@
rules:
unpinned-uses:
config:
policies:
"suitenumerique/*": ref-pin
+1 -1
View File
@@ -407,7 +407,7 @@ and this project adheres to
### Fixed ### Fixed
- ♿️(frontend) improve accessibility of the Effects panel #1401 - ♿️(frontend) improve accessibilty of the Effects panel #1401
## [1.20.0] - 2026-06-12 ## [1.20.0] - 2026-06-12
+3 -2
View File
@@ -37,13 +37,14 @@ RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev uv sync --locked --no-dev
# ---- mails ---- # ---- mails ----
FROM node:22-alpine AS mail-builder FROM node:22 AS mail-builder
COPY ./src/mail /mail/app COPY ./src/mail /mail/app
WORKDIR /mail/app WORKDIR /mail/app
RUN npm ci --ignore-scripts && npm run build RUN yarn install --frozen-lockfile && \
yarn build
# ---- static link collector ---- # ---- static link collector ----
+8 -8
View File
@@ -55,12 +55,12 @@ function _docker_compose() {
function _dc_run() { function _dc_run() {
_set_user _set_user
user_args=() user_args="--user=$USER_ID"
if [ -n "$USER_ID" ]; then if [ -z $USER_ID ]; then
user_args=("--user=$USER_ID") user_args=""
fi fi
_docker_compose run --rm "${user_args[@]}" "$@" _docker_compose run --rm $user_args "$@"
} }
# _dc_exec: wrap docker compose exec command # _dc_exec: wrap docker compose exec command
@@ -74,12 +74,12 @@ function _dc_exec() {
echo "🐳(compose) exec command: '\$@'" echo "🐳(compose) exec command: '\$@'"
user_args=() user_args="--user=$USER_ID"
if [ -n "$USER_ID" ]; then if [ -z $USER_ID ]; then
user_args=("--user=$USER_ID") user_args=""
fi fi
_docker_compose exec "${user_args[@]}" "$@" _docker_compose exec $user_args "$@"
} }
# _django_manage: wrap django's manage.py command with docker compose # _django_manage: wrap django's manage.py command with docker compose
+1 -1
View File
@@ -40,7 +40,7 @@ if [ -n "$CUSTOM_LOGO_URL" ]; then
[[ "$IS_SVG" == false ]] && echo "[custom-logo] ERROR: not a valid SVG file" >&2 && exit 1 [[ "$IS_SVG" == false ]] && echo "[custom-logo] ERROR: not a valid SVG file" >&2 && exit 1
mv -f "$TMP_FILE" "$LOGO_FILE" mv -f "$TMP_FILE" "$LOGO_FILE"
echo "[custom-logo] INFO: Custom logo downloaded successfully" echo "[custom-logo] INFO: Custom logo downloaded successfuly"
fi fi
mv src/backend/* ./ mv src/backend/* ./
+1 -1
View File
@@ -7,7 +7,7 @@ gunicorn -b 0.0.0.0:8000 meet.wsgi:application --log-file - &
bin/run & bin/run &
# if the current shell is killed, also terminate all its children # if the current shell is killed, also terminate all its children
trap 'pkill -TERM -P $$' SIGTERM trap "pkill SIGTERM -P $$" SIGTERM
# wait for a single child to finish, # wait for a single child to finish,
wait -n wait -n
+5 -4
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -o errexit set -o errexit
CURRENT_DIR=$(pwd)
NAMESPACE=${1:-meet} NAMESPACE=${1:-meet}
SECRET_NAME=${2:-bitwarden-cli-meet} SECRET_NAME=${2:-bitwarden-cli-meet}
TEMP_SECRET_FILE=$(mktemp) TEMP_SECRET_FILE=$(mktemp)
@@ -29,10 +30,10 @@ check_secret_exists() {
# Collect user input securely # Collect user input securely
get_user_input() { get_user_input() {
echo "Please provide the following information:" echo "Please provide the following information:"
read -r -p "Enter your Vaultwarden email login: " LOGIN read -p "Enter your Vaultwarden email login: " LOGIN
read -r -s -p "Enter your Vaultwarden password: " PASSWORD read -s -p "Enter your Vaultwarden password: " PASSWORD
echo echo
read -r -p "Enter your Vaultwarden server url: " URL read -p "Enter your Vaultwarden server url: " URL
} }
# Create and apply the secret # Create and apply the secret
@@ -76,7 +77,7 @@ main() {
exit 0 exit 0
fi fi
echo -e "${TEMP_SECRET_FILE}" echo -e ${TEMP_SECRET_FILE}
get_user_input get_user_input
echo -e "\nCreating Vaultwarden secret…" echo -e "\nCreating Vaultwarden secret…"
+2 -2
View File
@@ -3,7 +3,7 @@
mkdir -p "$(dirname -- "${BASH_SOURCE[0]}")/../.git/hooks/" mkdir -p "$(dirname -- "${BASH_SOURCE[0]}")/../.git/hooks/"
PRE_COMMIT_FILE="$(dirname -- "${BASH_SOURCE[0]}")/../.git/hooks/pre-commit" PRE_COMMIT_FILE="$(dirname -- "${BASH_SOURCE[0]}")/../.git/hooks/pre-commit"
cat <<'EOF' >"$PRE_COMMIT_FILE" cat <<'EOF' >$PRE_COMMIT_FILE
#!/bin/bash #!/bin/bash
# directories containing potential secrets # directories containing potential secrets
@@ -27,4 +27,4 @@ for d in $DIRS; do
done done
EOF EOF
chmod +x "$PRE_COMMIT_FILE" chmod +x $PRE_COMMIT_FILE
+1 -1
View File
@@ -68,7 +68,7 @@ fi
# Ask user for release version number # Ask user for release version number
echo "" echo ""
read -r -p "Enter release version number (e.g., 1.2.3): " VERSION read -p "Enter release version number (e.g., 1.2.3): " VERSION
# Validate version format (basic semver check) # Validate version format (basic semver check)
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
-1
View File
@@ -1,5 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
git submodule update --init --recursive git submodule update --init --recursive
# shellcheck disable=SC2016
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx' git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
+1 -1
View File
@@ -8,6 +8,6 @@ environments=$(awk '/environments:/ {flag=1; next} flag && NF {print} !NF {flag=
for env in $environments; do for env in $environments; do
echo "################### $env lint ###################" echo "################### $env lint ###################"
helmfile -e "$env" -f src/helm/helmfile.yaml lint || exit 1 helmfile -e $env -f src/helm/helmfile.yaml lint || exit 1
echo -e "\n" echo -e "\n"
done done
+2 -2
View File
@@ -172,7 +172,7 @@ services:
working_dir: /app working_dir: /app
node: node:
image: node:22-alpine image: node:22
user: "${DOCKER_USER:-1000}" user: "${DOCKER_USER:-1000}"
environment: environment:
HOME: /tmp HOME: /tmp
@@ -271,7 +271,7 @@ services:
- /app/.venv - /app/.venv
redis-summary: redis-summary:
image: redis:5 image: redis
ports: ports:
- "6379:6379" - "6379:6379"
+1 -1
View File
@@ -1,7 +1,7 @@
# Bureautix proxy overrides # Bureautix proxy overrides
# #
# Builds submitted through the Docker API of the Podman service get none of # Builds submitted through the Docker API of the Podman service get none of
# the proxy variables in their RUN steps. We need to pass the http_proxy explicitly # the proxy variables in their RUN steps. We need to pass the http_proxy explicitely
# otherwise all connections fail during the build. # otherwise all connections fail during the build.
x-proxy-vars: &proxy-vars x-proxy-vars: &proxy-vars
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"extends": ["github>suitenumerique/ci//renovate/default"], "extends": ["github>numerique-gouv/renovate-configuration"],
"dependencyDashboard": true, "dependencyDashboard": true,
"labels": ["dependencies", "noChangeLog"], "labels": ["dependencies", "noChangeLog"],
"packageRules": [ "packageRules": [
+1 -1
View File
@@ -21,7 +21,7 @@ const { initI18n, translateUI } = require("../common/i18n");
document.querySelector("#close-msg").style.display = "block"; document.querySelector("#close-msg").style.display = "block";
}) })
.catch((e) => { .catch((e) => {
console.error(`Error occurred: ${e}`); console.error(`Error occured: ${e}`);
}) })
.finally(() => { .finally(() => {
// NOTE: doesn't work with the desktop client — the browser considers // NOTE: doesn't work with the desktop client — the browser considers
@@ -24,7 +24,7 @@ class BaseEgressService:
def _get_filepath(self, filename: str, extension: str) -> str: def _get_filepath(self, filename: str, extension: str) -> str:
"""Construct the file path for a given filename and extension. """Construct the file path for a given filename and extension.
Insecure method, doesn't handle paths robustly and securely. Unsecure method, doesn't handle paths robustly and securely.
""" """
return f"{self._config.output_folder}/{filename}.{extension}" return f"{self._config.output_folder}/{filename}.{extension}"
@@ -27,7 +27,7 @@ def test_api_files_list_anonymous_not_allowed():
def test_api_files_list_authentificated_user_allowed(): def test_api_files_list_authentificated_user_allowed():
""" """
Authenticated users should be allowed to list files Authentificated users should be allowed to list files
""" """
user = factories.UserFactory() user = factories.UserFactory()
client = APIClient() client = APIClient()
@@ -458,7 +458,7 @@ def test_mute_participant_livekit_token_presence_check_twirp_error_forbidden(
room = RoomFactory() room = RoomFactory()
mock_livekit_client.room.get_participant.side_effect = TwirpError( mock_livekit_client.room.get_participant.side_effect = TwirpError(
msg="an error occurred", code="not_found", status=500 msg="an error occured", code="not_found", status=500
) )
user = AnonymousUser() user = AnonymousUser()
@@ -1,5 +1,5 @@
""" """
Test SIP management service. Test SIP mamagement service.
""" """
# pylint: disable=W0212 # pylint: disable=W0212
+1 -1
View File
@@ -121,7 +121,7 @@ const config: Config = {
}, },
tokens: defineTokens({ tokens: defineTokens({
/* we take a few things from the panda preset but for now we clear out some stuff. /* we take a few things from the panda preset but for now we clear out some stuff.
* This way we'll only add the things we need step by step and prevent using lots of different things. * This way we'll only add the things we need step by step and prevent using lots of differents things.
*/ */
...pandaPreset.theme.tokens, ...pandaPreset.theme.tokens,
colors: defineTokens.colors({ colors: defineTokens.colors({
@@ -158,7 +158,7 @@ export const Conference = ({
* *
* Issue: On Firefox behind proxy configurations, WebSocket signaling fails to establish. * Issue: On Firefox behind proxy configurations, WebSocket signaling fails to establish.
* Symptom: Client receives HTTP 200 instead of expected 101 (Switching Protocols). * Symptom: Client receives HTTP 200 instead of expected 101 (Switching Protocols).
* Root Cause: Certificate/security issue where the initial request is considered insecure. * Root Cause: Certificate/security issue where the initial request is considered unsecure.
* *
* Solution: Pre-establish a WebSocket connection to the signaling server, which fails. * Solution: Pre-establish a WebSocket connection to the signaling server, which fails.
* This "primes" the connection, allowing subsequent WebSocket establishments to work correctly. * This "primes" the connection, allowing subsequent WebSocket establishments to work correctly.
+4 -3
View File
@@ -1,9 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if ! docker image ls | grep readme-generator-for-helm; then docker image ls | grep readme-generator-for-helm
if [ "$?" -ne "0" ]; then
git clone https://github.com/bitnami/readme-generator-for-helm.git /tmp/readme-generator-for-helm git clone https://github.com/bitnami/readme-generator-for-helm.git /tmp/readme-generator-for-helm
cd /tmp/readme-generator-for-helm || exit 1 cd /tmp/readme-generator-for-helm
docker build -t readme-generator-for-helm:latest . docker build -t readme-generator-for-helm:latest .
cd "$(dirname -- "${BASH_SOURCE[0]}")" || exit 1 cd $(dirname -- "${BASH_SOURCE[0]}")
fi fi
docker run --rm -it -v .:/source -w /source readme-generator-for-helm:latest readme-generator -v values.yaml -r README.md docker run --rm -it -v .:/source -w /source readme-generator-for-helm:latest readme-generator -v values.yaml -r README.md
+1 -1
View File
@@ -51,7 +51,7 @@ app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }} {{- end }}
{{/* {{/*
transform dictionary of environment variables transform dictionnary of environment variables
Usage : {{ include "meet.env.transformDict" .Values.envVars }} Usage : {{ include "meet.env.transformDict" .Values.envVars }}
Example: Example:
+2 -2
View File
@@ -1,5 +1,5 @@
#!/bin/sh #!/usr/bin/env bash
set -e set -eo pipefail
# Run html-to-text to convert all html files to text files # Run html-to-text to convert all html files to text files
DIR_MAILS="../backend/core/templates/mail/" DIR_MAILS="../backend/core/templates/mail/"
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh #!/usr/bin/env bash
# Run mjml command to convert all mjml templates to html files # Run mjml command to convert all mjml templates to html files
DIR_MAILS="../backend/core/templates/mail/html/" DIR_MAILS="../backend/core/templates/mail/html/"
+2 -2
View File
@@ -9,8 +9,8 @@
}, },
"private": true, "private": true,
"scripts": { "scripts": {
"build-mjml-to-html": "sh ./bin/mjml-to-html", "build-mjml-to-html": "bash ./bin/mjml-to-html",
"build-html-to-plain-text": "sh ./bin/html-to-plain-text", "build-html-to-plain-text": "bash ./bin/html-to-plain-text",
"build": "npm run build-mjml-to-html && npm run build-html-to-plain-text" "build": "npm run build-mjml-to-html && npm run build-html-to-plain-text"
}, },
"volta": { "volta": {