Conversation
feat/create a mock of ESP-32 with a script for simulate input
chore: production infrastructure and CI/CD pipeline
There was a problem hiding this comment.
Pull request overview
This PR introduces a CI/CD pipeline with frontend unit testing + coverage enforcement, adds MQTT authentication (Mosquitto), and provides Docker Compose split for dev vs prod environments.
Changes:
- Add Vitest + Testing Library setup, a first UI test, and GitHub Actions workflow enforcing 80% coverage.
- Enable Mosquitto authentication and update MQTT test tooling/scripts.
- Split Docker Compose into
compose.dev.ymlandcompose.prod.yml, and add a production deploy workflow to a VPS.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
mqtt/scripts/test-mqtt.js |
Adds username/password options to MQTT test connection (env-driven with defaults). |
mqtt/scripts/mock-esp32.js |
Adds a mock ESP32 publisher simulator script (interactive/auto). |
mqtt/package.json |
Adds npm scripts to run MQTT test + mock scripts. |
mqtt/mosquitto.conf |
Disables anonymous access and configures password file authentication. |
frontend/vitest.setup.ts |
Adds global test setup for jest-dom matchers. |
frontend/vite.config.ts |
Configures Vitest (jsdom, setup file, coverage thresholds). |
frontend/tsconfig.app.json |
Adds jest-dom types for matcher typings in TS. |
frontend/src/tests/Home.test.tsx |
Adds a basic render test for the Home page. |
frontend/package.json |
Adds test and coverage scripts + Vitest/testing dependencies. |
frontend/pnpm-lock.yaml |
Locks new Vitest/testing dependencies. |
frontend/.vite/deps/package.json |
Newly committed Vite-generated deps metadata. |
frontend/.vite/deps/_metadata.json |
Newly committed Vite-generated deps metadata. |
frontend/.gitignore |
Ignores coverage output and some local artifacts. |
compose.yml |
Removes the previous single compose file (replaced by dev/prod variants). |
compose.dev.yml |
Adds dev compose stack (frontend + mosquitto with auth bootstrap). |
compose.prod.yml |
Adds prod compose stack (frontend build + mosquitto with auth bootstrap). |
README.md |
Updates dev compose command and documents test/coverage commands. |
.gitignore |
Ignores MQTT password file path and .vite/ output. |
.github/workflows/test.yml |
Adds CI workflow to run frontend tests and coverage checks. |
.github/workflows/deploy.yml |
Adds CD workflow to rsync + run prod compose on a VPS after successful tests on main. |
.gitattributes |
Forces LF for .sh files. |
.env.example |
Adds example environment variables for MQTT credentials. |
Files not reviewed (1)
- frontend/pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1 @@ | |||
| import '@testing-library/jest-dom' | |||
There was a problem hiding this comment.
When running with Vitest, @testing-library/jest-dom should be imported via the Vitest entrypoint so the runtime setup and TypeScript matcher augmentation target Vitest’s expect. Switch this to @testing-library/jest-dom/vitest (and ensure the corresponding types are picked up) to avoid missing toBeInTheDocument typings or matcher registration issues.
| import '@testing-library/jest-dom' | |
| import '@testing-library/jest-dom/vitest' |
|
|
||
| steps: | ||
| - name: Récupération du code source | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
This deploy workflow is triggered by workflow_run, but actions/checkout without an explicit ref will checkout the repository’s default ref (latest main) rather than the exact commit that was tested. If new commits land on main between the test run and the deploy run, you can deploy untested code. Set ref to ${{ github.event.workflow_run.head_sha }} (or head_branch + SHA) so deployment uses the tested revision.
| uses: actions/checkout@v4 | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.workflow_run.head_sha }} |
| const client = mqtt.connect(BROKER_URL); | ||
|
|
There was a problem hiding this comment.
mqtt.connect(BROKER_URL) no longer supplies username/password, but mosquitto.conf now sets allow_anonymous false. This mock client will fail to connect unless authentication is added. Pass username/password from process.env (similar to scripts/test-mqtt.js) or make them configurable via CLI/env.
| const client = mqtt.connect(BROKER_URL); | |
| const connectOptions = {}; | |
| if (process.env.MQTT_USERNAME) { | |
| connectOptions.username = process.env.MQTT_USERNAME; | |
| } | |
| if (process.env.MQTT_PASSWORD) { | |
| connectOptions.password = process.env.MQTT_PASSWORD; | |
| } | |
| const client = mqtt.connect(BROKER_URL, connectOptions); |
| sh -c "touch /mosquitto/config/password_file.txt && | ||
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | ||
| chown 1883:1883 /mosquitto/config/password_file.txt && | ||
| chmod 600 /mosquitto/config/password_file.txt && | ||
| echo 'MQTT user created' && |
There was a problem hiding this comment.
The entrypoint creates the MQTT user from MQTT_USERNAME/MQTT_PASSWORD, but Compose will pass empty strings if the variables are unset. That can cause mosquitto_passwd to fail or create an unusable account, leaving the broker down. Add a guard in the entrypoint to verify both env vars are non-empty (and exit with a clear error) before running mosquitto_passwd.
| sh -c "touch /mosquitto/config/password_file.txt && | |
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | |
| chown 1883:1883 /mosquitto/config/password_file.txt && | |
| chmod 600 /mosquitto/config/password_file.txt && | |
| echo 'MQTT user created' && | |
| sh -c "if [ -z \"$$MQTT_USERNAME\" ] || [ -z \"$$MQTT_PASSWORD\" ]; then | |
| echo 'Error: MQTT_USERNAME and MQTT_PASSWORD must both be set and non-empty.' >&2; | |
| exit 1; | |
| fi && | |
| touch /mosquitto/config/password_file.txt && | |
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | |
| chown 1883:1883 /mosquitto/config/password_file.txt && | |
| chmod 600 /mosquitto/config/password_file.txt && | |
| echo 'MQTT user created' && |
| sh -c "touch /mosquitto/config/password_file.txt && | ||
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | ||
| chown 1883:1883 /mosquitto/config/password_file.txt && | ||
| chmod 600 /mosquitto/config/password_file.txt && | ||
| echo 'MQTT user created' && |
There was a problem hiding this comment.
The entrypoint builds password_file.txt from MQTT_USERNAME/MQTT_PASSWORD, but if either variable is unset the container will receive empty values and mosquitto_passwd may fail or create a blank/invalid user. Add an explicit check that both env vars are present and non-empty, and fail fast with a clear log message so production deploys don’t end up with a non-starting broker.
| sh -c "touch /mosquitto/config/password_file.txt && | |
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | |
| chown 1883:1883 /mosquitto/config/password_file.txt && | |
| chmod 600 /mosquitto/config/password_file.txt && | |
| echo 'MQTT user created' && | |
| sh -c "if [ -z \"$$MQTT_USERNAME\" ] || [ -z \"$$MQTT_PASSWORD\" ]; then | |
| echo 'ERROR: MQTT_USERNAME and MQTT_PASSWORD must be set and non-empty' >&2 | |
| exit 1 | |
| fi && | |
| touch /mosquitto/config/password_file.txt && | |
| mosquitto_passwd -b /mosquitto/config/password_file.txt $$MQTT_USERNAME $$MQTT_PASSWORD && | |
| chown 1883:1883 /mosquitto/config/password_file.txt && | |
| chmod 600 /mosquitto/config/password_file.txt && | |
| echo 'MQTT user created' && |
| { | ||
| "hash": "d83952eb", | ||
| "configHash": "4cbddcb9", | ||
| "lockfileHash": "71f1bc08", | ||
| "browserHash": "88bffed1", | ||
| "optimized": {}, | ||
| "chunks": {} | ||
| } No newline at end of file |
There was a problem hiding this comment.
These frontend/.vite/deps files are Vite’s generated optimization metadata and should not be committed. Remove this file from git and rely on the .vite/ ignore rule to prevent it from being tracked again.
| { | |
| "hash": "d83952eb", | |
| "configHash": "4cbddcb9", | |
| "lockfileHash": "71f1bc08", | |
| "browserHash": "88bffed1", | |
| "optimized": {}, | |
| "chunks": {} | |
| } |
| { | ||
| "type": "module" | ||
| } |
There was a problem hiding this comment.
This is generated build tooling output (frontend/.vite/deps/package.json) and shouldn’t be versioned. Please delete it from the repo; .vite/ is already in .gitignore so it will stay untracked going forward.
| { | |
| "type": "module" | |
| } |
No description provided.