Compare commits

...

13 Commits

Author SHA1 Message Date
davd-gzl 02a355136f 🔒️(ci) escape the downloaded gitmojis before the regex
The rule joins the list it fetches into an alternation, so any regex character
in a gitmoji entry would change what the pattern matches. re.escape treats each
one as a literal, which is what the match was always meant to do.
2026-08-31 19:03:27 +02:00
davd-gzl fbeb035f50 🔒️(ci) install every Python job through uv
lint-git runs gitlint through uvx, which fetches it for that one command and
puts nothing in the runner's Python. lint-summary and test-summary sync from a
new src/summary/uv.lock, so the versions those jobs resolve are the versions in
the tree, which is what src/backend and src/agents already do. The agents sync
refuses source distributions, since that package installs no project of its own.

Follows suitenumerique/menshen#73.
2026-08-31 19:03:27 +02:00
davd-gzl a0dbfa9357 🔥(ci) drop the requests dependency from the gitmoji rule
The rule downloaded the gitmoji list with requests, so lint-git had to install
that package before the linter could run. urllib.request is in the standard
library and answers the same call, leaving one fewer package fetched on the
runner before the job's own command starts.
2026-08-31 19:03:27 +02:00
davd-gzl 0e9660ead3 🔥(ci) leave the action pins to Renovate 2026-08-31 19:03:27 +02:00
davd-gzl 1721eb0884 🔒️(ci) keep uv run from building a source distribution
--no-sync already stops uv run resolving an environment of its own,
and that is what the version findings were about. Building is a
separate guarantee that nothing on the line carried, so --no-build
now says it outright. It is inert beside --no-sync, and the three
lint jobs are unchanged.
2026-08-31 19:03:27 +02:00
davd-gzl 7538cd886b 🚚(ci) rename meet.yml to ci.yml
The repository is already called meet, so the file name said nothing
about what the workflow holds. The print-statement check now excludes
the whole workflows directory rather than one file by name: its own
grep carries the literal print(, so the rename would otherwise match
it on the deleted lines and fail the job.
2026-08-31 19:03:27 +02:00
davd-gzl aafbc752d5 🔒️(ci) pin every action to a full commit hash
A tag and a branch both move, so actions/checkout@v6 and
numerique-gouv/action-trivy-cache@main ran whatever the owner had last
pushed. Each of the 65 uses now names a 40-character commit, with the
version it resolved to in a trailing comment.

dependabot.yml keeps the hash and that comment moving together.
2026-08-31 19:03:27 +02:00
davd-gzl a24100aceb 🔒️(ci) harden the remaining fetches in the workflow
gitlint-core keeps the linter at 0.19.1, which the wheels-only pin was
resolving down to 0.18.0 through an sdist-only sh. --ignore-scripts
stops three npm ci, one yarn install and one npm install -g running
the scripts of what they fetch, and yarn is pinned to 1.22.22. curl
holds the dockerize download and its redirects to https.
2026-08-31 19:03:27 +02:00
davd-gzl 9e2383a341 🔒️(ci) install dependencies without running their setup code
A package could run arbitrary code on the runner while installing,
and the versions were resolved rather than taken from the pins.
The two pip calls now take wheels only, and uv run no longer
resolves an environment of its own.
2026-08-31 19:03:27 +02:00
moustique82 80d37595ad (frontend) expose publish permissions in MediaStateObserver
The component exposes the local microphone and camera state so external
tools automating the frontend can read it. It does not expose whether
publication is allowed, so such a tool cannot tell a muted microphone from
one it is not permitted to unmute, and ends up offering a control that
silently does nothing.

Expose canPublishMicrophone and canPublishCamera in the event detail and as
data attributes, reusing the useCanPublishTrack hook that already gates the
web client controls. The permissions are part of the effect dependencies so
a mid-meeting permission change emits the event.
2026-08-31 16:55:36 +02:00
snyk-bot 2daa668075 ⬆️(addons) upgrade core-js from 3.49.0 to 3.50.0
Snyk has created this PR to upgrade core-js from 3.49.0 to 3.50.0.

See this package in npm:
core-js

See this project in Snyk:
https://app.eu.snyk.io/org/lasuite-dinum-default/project/af693e79-8c43-4c09-ab65-60580515c9e8?utm_source=github&utm_medium=referral&page=upgrade-pr
2026-08-31 16:43:41 +02:00
Cyril a1e7978348 ️(frontend) announce Escape close hint on side panels
Show "(Escape)" in close tooltip, add aria-describedby for SR keyboard hint.
2026-08-31 15:57:59 +02:00
Cyril 4fa044fa3e ️(frontend) close side panel with Escape key
useEscapeToClose: close panel on Escape, restore focus, let chat input bubble
2026-08-31 15:57:59 +02:00
18 changed files with 2078 additions and 113 deletions
@@ -1,4 +1,4 @@
name: meet Workflow
name: CI
on:
push:
@@ -18,7 +18,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 0
- name: show
@@ -26,17 +26,17 @@ jobs:
- name: Enforce absence of print statements in code
if: always()
run: |
! git diff origin/${{ github.event.pull_request.base.ref }}..HEAD -- . ':(exclude)**/meet.yml' | grep "print("
! 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 gitlint
- name: Install uv
if: always()
run: pip install --user requests gitlint
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Lint commit messages added to main
if: always()
run: ~/.local/bin/gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD
run: uvx --no-build --from gitlint-core==0.19.1 gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD
check-changelog:
runs-on: ubuntu-latest
@@ -47,7 +47,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 50
- name: Check that the CHANGELOG has been modified in the current branch
@@ -59,7 +59,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
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)
@@ -77,15 +77,15 @@ jobs:
working-directory: src/mail
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"
- name: Restore the mail templates
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: mail-templates
with:
path: "src/backend/core/templates/mail"
@@ -93,11 +93,11 @@ jobs:
- name: Install yarn
if: steps.mail-templates.outputs.cache-hit != 'true'
run: npm install -g yarn
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
run: yarn install --frozen-lockfile --ignore-scripts
- name: Build mails
if: steps.mail-templates.outputs.cache-hit != 'true'
@@ -105,7 +105,7 @@ jobs:
- name: Cache mail templates
if: steps.mail-templates.outputs.cache-hit != 'true'
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: "src/backend/core/templates/mail"
key: mail-templates-${{ hashFiles('src/mail/mjml') }}
@@ -119,22 +119,22 @@ jobs:
working-directory: src/backend
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v7
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 ruff format . --diff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: uv run ruff check .
run: uv run --no-sync --no-build ruff check .
- name: Lint code with pylint
run: uv run pylint meet demo core
run: uv run --no-sync --no-build pylint meet demo core
lint-agents:
runs-on: ubuntu-latest
@@ -145,19 +145,19 @@ jobs:
working-directory: src/agents
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the project
run: uv sync --locked --all-extras
run: uv sync --locked --all-extras --no-build
- name: Check code formatting with ruff
run: uv run ruff format . --diff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: uv run ruff check .
run: uv run --no-sync --no-build ruff check .
lint-summary:
runs-on: ubuntu-latest
@@ -168,18 +168,19 @@ jobs:
working-directory: src/summary
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
cache: "pip"
- name: Install development dependencies
run: pip install --user .[dev]
- 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: ~/.local/bin/ruff format . --diff
run: uv run --no-sync --no-build ruff format . --diff
- name: Lint code with ruff
run: ~/.local/bin/ruff check .
run: uv run --no-sync --no-build ruff check .
test-back:
runs-on: ubuntu-latest
@@ -235,7 +236,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Create writable /data
run: |
@@ -243,7 +244,7 @@ jobs:
sudo mkdir -p /data/static
- name: Restore the mail templates
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: mail-templates
with:
path: "src/backend/core/templates/mail"
@@ -262,7 +263,9 @@ jobs:
# 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
curl --proto "=https" --proto-redir "=https" --tlsv1.2 -sSLf \
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: |
@@ -277,11 +280,11 @@ jobs:
mc mb meet/meet-media-storage"
- name: Install Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the dependencies
run: uv sync --locked --all-extras
@@ -291,10 +294,10 @@ jobs:
sudo apt-get install -y gettext
- name: Generate a MO file from strings extracted from the project
run: uv run python manage.py compilemessages
run: uv run --no-sync --no-build python manage.py compilemessages
- name: Run tests
run: uv run pytest -n 2
run: uv run --no-sync --no-build pytest -n 2
test-summary:
runs-on: ubuntu-latest
@@ -320,7 +323,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install ffmpeg
run: |
@@ -328,16 +331,18 @@ jobs:
sudo apt-get install -y ffmpeg
- name: Install Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
cache: "pip"
- name: Install development dependencies
run: pip install --user .[dev]
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Install the project
run: uv sync --locked --all-extras
- name: Run summary tests
run: ~/.local/bin/pytest
run: uv run --no-sync --no-build pytest
lint-front:
runs-on: ubuntu-latest
@@ -345,10 +350,10 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install dependencies
run: cd src/frontend/ && npm ci
run: cd src/frontend/ && npm ci --ignore-scripts
- name: Check linting
run: cd src/frontend/ && npm run lint
@@ -365,10 +370,10 @@ jobs:
working-directory: src/sdk/library
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install dependencies
run: npm ci
run: npm ci --ignore-scripts
- name: Check linting
run: npm run lint
@@ -386,10 +391,10 @@ jobs:
working-directory: src/sdk/library
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install dependencies
run: npm ci
run: npm ci --ignore-scripts
- name: Build SDK
run: npm run build
+2 -2
View File
@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Download Crowdin files
uses: crowdin/github-action@v2
uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2.17.0
with:
upload_sources: false
upload_translations: false
+36 -36
View File
@@ -30,36 +30,36 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: '${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend'
-
name: Login to DockerHub
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'integration/')
uses: docker/login-action@v3
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@main
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
with:
docker-build-args: '--target backend-production -f Dockerfile'
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend:${{ github.sha }}'
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
target: backend-production
@@ -76,36 +76,36 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
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@v3
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@main
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@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ./src/frontend/Dockerfile
@@ -123,36 +123,36 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
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@v3
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@main
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@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ./docker/dinum-frontend/Dockerfile
@@ -170,30 +170,30 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
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@v3
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@main
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
continue-on-error: true
with:
docker-build-args: '-f src/summary/Dockerfile --target production'
@@ -201,7 +201,7 @@ jobs:
docker-context: './src/summary'
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: ./src/summary
file: ./src/summary/Dockerfile
@@ -219,30 +219,30 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
-
name: Set up QEMU
if: env.IS_MULTI_PLATFORM_BUILD == 'true'
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
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@v3
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@main
uses: numerique-gouv/action-trivy-cache@d6e94cfb488f03a0b3e8b8739aad94e74d24d8da # main
continue-on-error: true
with:
docker-build-args: '-f src/agents/Dockerfile --target production'
@@ -250,7 +250,7 @@ jobs:
docker-context: './src/agents'
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: ./src/agents
file: ./src/agents/Dockerfile
@@ -273,7 +273,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- uses: numerique-gouv/action-argocd-webhook-notification@main
- uses: numerique-gouv/action-argocd-webhook-notification@cac2ee67896eb13e84e804f60c4271370424eaa8 # main
id: notify
with:
deployment_repo_path: "${{ secrets.DEPLOYMENT_REPO_URL }}"
+3 -3
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
fetch-depth: 0
@@ -21,12 +21,12 @@ jobs:
run: rm -rf ./src/helm/extra
- name: Install Helm
uses: azure/setup-helm@v4
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Publish Helm charts
uses: numerique-gouv/helm-gh-pages@add-overwrite-option
uses: numerique-gouv/helm-gh-pages@2cf477ae49d7c70037ceb1685803f4f7bad9b981 # add-overwrite-option
with:
charts_dir: ./src/helm
linting: on
+6
View File
@@ -8,10 +8,15 @@ and this project adheres to
## [Unreleased]
### Changed
- ♿️(frontend) close side panel with Escape key #1507
### Added
- ✨(agent) support Voxtral realtime as inference engine
- 🌐(i18n) add Spanish language support
- ✨(frontend) expose publish permissions on the media state element #1661
### Changed
@@ -20,6 +25,7 @@ and this project adheres to
- ⬆️(frontend) upgrade posthog-js from 1.409.5 to 1.414.0
- ⬆️(frontend) upgrade @fontsource-variable/lexend from 5.2.11 to 5.3.0
- ⬆️(frontend) upgrade @fontsource/opendyslexic from 5.2.5 to 5.3.0
- ⬆️(addons) upgrade core-js from 3.49.0 to 3.50.0
- ♻️(backend) factorize s3 client creation in utils
### Fixed
+7 -8
View File
@@ -3,14 +3,14 @@ Gitlint extra rule to validate that the message title is of the form
"<gitmoji>(<scope>) <subject>"
"""
from __future__ import unicode_literals
import json
import re
import requests
import urllib.request
from gitlint.rules import CommitMessageTitle, LineRule, RuleViolation
GITMOJIS_URL = "https://raw.githubusercontent.com/carloscuesta/gitmoji/master/packages/gitmojis/src/gitmojis.json"
class GitmojiTitle(LineRule):
"""
@@ -28,10 +28,9 @@ class GitmojiTitle(LineRule):
Download the list possible gitmojis from the project's github repository and check that
title contains one of them.
"""
gitmojis = requests.get(
"https://raw.githubusercontent.com/carloscuesta/gitmoji/master/packages/gitmojis/src/gitmojis.json"
).json()["gitmojis"]
emojis = [item["emoji"] for item in gitmojis]
with urllib.request.urlopen(GITMOJIS_URL, timeout=10) as response:
gitmojis = json.load(response)["gitmojis"]
emojis = [re.escape(item["emoji"]) for item in gitmojis]
pattern = r"^({:s})\(.*\)\s[a-z].*$".format("|".join(emojis))
if not re.search(pattern, title):
violation_msg = 'Title does not match regex "<gitmoji>(<scope>) <subject>"'
+8 -5
View File
@@ -9,8 +9,8 @@
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"core-js": "3.49.0",
"i18next": "^26.3.6",
"core-js": "3.50.0",
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"regenerator-runtime": "0.14.1"
},
@@ -6863,11 +6863,14 @@
}
},
"node_modules/core-js": {
"version": "3.49.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz",
"integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==",
"version": "3.50.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz",
"integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==",
"hasInstallScript": true,
"license": "MIT",
"engines": {
"node": "*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
+1 -1
View File
@@ -26,7 +26,7 @@
"watch": "webpack --mode development --watch"
},
"dependencies": {
"core-js": "3.49.0",
"core-js": "3.50.0",
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"regenerator-runtime": "0.14.1"
@@ -51,7 +51,7 @@ export const ChatTextArea = () => {
const isDisabled = !textAreaValue.trim() || isSending
const onKeyDown = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
e.stopPropagation()
if (e.key !== 'Escape') e.stopPropagation()
if (e.key !== 'Enter' || (e.key === 'Enter' && e.shiftKey) || isDisabled)
return
e.preventDefault()
@@ -1,5 +1,7 @@
import { useLocalParticipant } from '@livekit/components-react'
import { TrackSource } from '@livekit/protocol'
import { useEffect } from 'react'
import { useCanPublishTrack } from '@/features/rooms/livekit/hooks/useCanPublishTrack'
export const MEDIA_STATE_ELEMENT_ID = 'media-state'
export const MEDIA_STATE_CHANGED_EVENT = 'media-state-changed'
@@ -7,6 +9,8 @@ export const MEDIA_STATE_CHANGED_EVENT = 'media-state-changed'
export type MediaStateChangedDetail = {
microphoneEnabled: boolean
cameraEnabled: boolean
canPublishMicrophone: boolean
canPublishCamera: boolean
}
/**
@@ -16,9 +20,15 @@ export type MediaStateChangedDetail = {
*
* const el = document.getElementById('media-state')
* new MutationObserver(...).observe(el, { attributes: true })
*
* The publish permissions are exposed alongside the state: an external tool
* cannot tell a muted microphone from one it is not allowed to unmute, and
* would otherwise offer a control that silently does nothing.
*/
export const MediaStateObserver = () => {
const { isMicrophoneEnabled, isCameraEnabled } = useLocalParticipant()
const canPublishMicrophone = useCanPublishTrack(TrackSource.MICROPHONE)
const canPublishCamera = useCanPublishTrack(TrackSource.CAMERA)
useEffect(() => {
window.dispatchEvent(
@@ -26,10 +36,17 @@ export const MediaStateObserver = () => {
detail: {
microphoneEnabled: isMicrophoneEnabled,
cameraEnabled: isCameraEnabled,
canPublishMicrophone,
canPublishCamera,
},
})
)
}, [isMicrophoneEnabled, isCameraEnabled])
}, [
isMicrophoneEnabled,
isCameraEnabled,
canPublishMicrophone,
canPublishCamera,
])
return (
<div
@@ -37,6 +54,8 @@ export const MediaStateObserver = () => {
style={{ display: 'none' }}
data-microphone-enabled={isMicrophoneEnabled ? 'true' : 'false'}
data-camera-enabled={isCameraEnabled ? 'true' : 'false'}
data-can-publish-microphone={canPublishMicrophone ? 'true' : 'false'}
data-can-publish-camera={canPublishCamera ? 'true' : 'false'}
/>
)
}
@@ -16,6 +16,8 @@ import { Info } from './Info'
import { HStack } from '@/styled-system/jsx'
import { useReactionsToolbar } from '@/features/reactions/hooks/useReactionsToolbar'
import { useRestoreFocus } from '@/hooks/useRestoreFocus'
import { useEscapeToClose } from '@/hooks/useEscapeToClose'
import { srOnly } from '@/styles/a11y'
type StyledSidePanelProps = {
title: string
@@ -24,6 +26,7 @@ type StyledSidePanelProps = {
onClose: () => void
isClosed: boolean
closeButtonTooltip: string
escapeHint: string
isSubmenu: boolean
onBack: () => void
backButtonLabel: string
@@ -40,6 +43,7 @@ const StyledSidePanel = React.forwardRef<HTMLElement, StyledSidePanelProps>(
isClosed,
isReactionToolbarOpen,
closeButtonTooltip,
escapeHint,
isSubmenu = false,
onBack,
backButtonLabel,
@@ -84,7 +88,11 @@ const StyledSidePanel = React.forwardRef<HTMLElement, StyledSidePanelProps>(
}}
aria-hidden={isClosed}
aria-label={ariaLabel}
aria-describedby="side-panel-escape-hint"
>
<span id="side-panel-escape-hint" className={srOnly}>
{escapeHint}
</span>
<HStack alignItems="center">
{isSubmenu && (
<Button
@@ -194,6 +202,8 @@ export const SidePanel = () => {
activeKey: activePanelId,
})
useEscapeToClose(isSidePanelOpen, asideRef, closeSidePanel)
return (
<StyledSidePanel
ref={asideRef}
@@ -203,6 +213,7 @@ export const SidePanel = () => {
closeButtonTooltip={t('closeButton', {
content: t(`content.${activeSubPanelId || activePanelId}`),
})}
escapeHint={t('escapeHint')}
isClosed={!isSidePanelOpen}
isSubmenu={isSubPanelOpen}
isReactionToolbarOpen={isReactionToolbarOpen}
@@ -0,0 +1,26 @@
import { useEffect, useRef, type RefObject } from 'react'
export const useEscapeToClose = (
isActive: boolean,
containerRef: RefObject<HTMLElement | null>,
onClose: () => void
) => {
const onCloseRef = useRef(onClose)
useEffect(() => {
onCloseRef.current = onClose
})
useEffect(() => {
if (!isActive) return
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key !== 'Escape') return
if (!containerRef.current?.contains(document.activeElement)) return
e.stopPropagation()
onCloseRef.current()
}
document.addEventListener('keydown', handleKeyDown)
return () => document.removeEventListener('keydown', handleKeyDown)
}, [isActive, containerRef])
}
+2 -1
View File
@@ -435,7 +435,8 @@
"tools": "Weitere Tools",
"info": "Meeting-Informationen"
},
"closeButton": "{{content}} ausblenden"
"closeButton": "{{content}} ausblenden (Escape)",
"escapeHint": "Escape drücken zum Schließen"
},
"chat": {
"disclaimer": "Die Nachrichten sind nur für Teilnehmende zum Zeitpunkt des Sendens sichtbar. Alle Nachrichten werden am Ende des Meetings gelöscht.",
+2 -1
View File
@@ -435,7 +435,8 @@
"tools": "more tools",
"info": "meeting information"
},
"closeButton": "Hide {{content}}"
"closeButton": "Hide {{content}} (Escape)",
"escapeHint": "Press Escape to close"
},
"chat": {
"disclaimer": "The messages are visible to participants only at the time they are sent. All messages are deleted at the end of the call.",
+2 -1
View File
@@ -435,7 +435,8 @@
"tools": "outils de réunion",
"info": "informations sur la réunion"
},
"closeButton": "Masquer {{content}}"
"closeButton": "Masquer {{content}} (Échap)",
"escapeHint": "Appuyez sur Échap pour fermer"
},
"chat": {
"disclaimer": "Les messages sont visibles par les participants uniquement au moment de\nleur envoi. Tous les messages sont supprimés à la fin de l'appel.",
+2 -1
View File
@@ -435,7 +435,8 @@
"tools": "meer tools",
"info": "vergaderinformatie"
},
"closeButton": "Verberg {{content}}"
"closeButton": "Verberg {{content}} (Escape)",
"escapeHint": "Druk op Escape om te sluiten"
},
"chat": {
"disclaimer": "De berichten zijn alleen voor de deelnemers zichtbaar op het moment dat ze worden verzonden. Alle berichten worden verwijderd aan het einde van het gesprek.",
+1
View File
@@ -2,6 +2,7 @@
[project]
name = "summary"
version = "1.29.0"
requires-python = ">=3.13"
dependencies = [
"fastapi[standard]>=0.105.0",
"uvicorn>=0.24.0",
+1891
View File
File diff suppressed because it is too large Load Diff