## Summary
Adds a Sergii-specific smoke test that validates the **Sergii Review
Batch** project surfaces (Linear project `Sergii Review Batch` — TRU-68,
TRU-72, TRU-75) are still functioning on the deployed truckwash.io
dashboard after a release. The test runs in the existing deploy workflow
alongside the generic smoke test and triggers auto-rollback if it fails.
## Why
TRU-96 ("SENERE 4: Deploy Sergii changes to truckwash.io dashboard (test
that it works first)") calls for deploying Sergii's batch of changes to
production with a test-first gate. The current generic
`scripts/smoke-test.sh` only covers `/login`, `/healthz`, and the public
self-serve vehicle step — it does not probe any of the Sergii-touch
surfaces. This PR closes that gap.
## What ships
| File | Purpose |
|---|---|
| `scripts/smoke-test-sergii.sh` | New release-gate smoke test covering
the Sergii Review Batch surfaces |
| `.github/workflows/deploy.yml` | Runs the Sergii smoke test after the
generic one, triggers auto-rollback if it fails, distinguishes failure
modes in the Slack status message |
| `tests/unit/smoke-test-sergii.spec.js` | 9 vitest assertions that lock
the script content and the deploy.yml wiring (prevents accidental
removal of the Sergii release gate) |
## Surfaces covered
- **TRU-72 — Sergii's pages 6-10 review** (`/admin/customer`,
`/admin/product`, `/admin/order`, `/admin/booking`, `/admin/invoicing`)
— must not 5xx.
- **TRU-68 — Sergii's customer email flow** (`/api/customer`,
`/kundeoprettelse`) — must remain 2xx.
- **TRU-75 — Sergii's UVS option** (`/self-serve/program`,
`/self-serve/vehicle`) — must remain 2xx.
- **Dashboard bootstrap sanity** (`/healthz`, `/api/ping`, `/login`) —
the generic smoke test also covers these, but the Sergii script
re-checks to fail-fast on a totally broken deploy.
## Behaviour
- Defaults to `https://staging.truckwash.io` and respects
`SMOKE_BASE_URL` and `SMOKE_TIMEOUT` env vars.
- Exits 0 on all-pass, 1 on any failure.
- `continue-on-error: true` on the workflow step so a failure does not
mask the actual deploy step outcome — the auto-rollback step separately
keys off the Sergii step outcome.
- No authenticated calls, so the test is safe to run unattended in the
deploy workflow.
## Test
```
npx vitest run tests/unit/smoke-test-sergii.spec.js
```
→ **9/9 passed** in 487ms.
## Linked Linear issues
- TRU-96 — https://linear.app/truck-wash-aps/issue/TRU-96 (this PR)
- TRU-68, TRU-72, TRU-75 — covered by the new smoke test
---------
Co-authored-by: Pleno Bugfix Bot <bugfix-bot@pleno.local>
Co-authored-by: Truck Wash Bugfix <bugfix@truckwash.io>
113 lines
3.4 KiB
YAML
113 lines
3.4 KiB
YAML
name: Deploy pleno-vue to Hetzner (staging)
|
|
|
|
on:
|
|
push:
|
|
branches: [master]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: deploy-pleno-vue
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
|
|
|
jobs:
|
|
test-and-deploy:
|
|
name: Build + Deploy
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: 'npm'
|
|
|
|
- name: Install + Build
|
|
run: |
|
|
npm ci --ignore-scripts
|
|
npm run build
|
|
|
|
- name: Setup SSH
|
|
uses: webfactory/ssh-agent@v0.9.0
|
|
with:
|
|
ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
|
|
- name: Add host key
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
|
|
|
- name: Pre-deploy snapshot
|
|
id: pre
|
|
run: |
|
|
ssh "$DEPLOY_USER@$DEPLOY_HOST" '
|
|
set -e
|
|
cd /opt/pleno-vue
|
|
git rev-parse HEAD > /tmp/last_deploy_sha
|
|
echo "pre_sha=$(cat /tmp/last_deploy_sha)" >> $GITHUB_OUTPUT
|
|
'
|
|
|
|
- name: Deploy
|
|
id: deploy
|
|
run: |
|
|
ssh "$DEPLOY_USER@$DEPLOY_HOST" '
|
|
set -e
|
|
cd /opt/pleno-vue
|
|
git fetch origin master
|
|
git reset --hard origin/master
|
|
npm ci --ignore-scripts
|
|
npm run build
|
|
sudo systemctl reload nginx || true
|
|
sudo systemctl reload pleno-vue || true
|
|
echo "Deploy complete: $(git rev-parse --short HEAD)"
|
|
'
|
|
|
|
- name: Smoke test
|
|
id: smoke
|
|
continue-on-error: true
|
|
env:
|
|
SMOKE_BASE_URL: ${{ secrets.SMOKE_BASE_URL }}
|
|
run: |
|
|
bash scripts/smoke-test.sh "$SMOKE_BASE_URL"
|
|
|
|
- name: Sergii Review Batch smoke test (TRU-96)
|
|
id: smoke_sergii
|
|
continue-on-error: true
|
|
env:
|
|
SMOKE_BASE_URL: ${{ secrets.SMOKE_BASE_URL }}
|
|
run: |
|
|
bash scripts/smoke-test-sergii.sh "$SMOKE_BASE_URL"
|
|
|
|
- name: Auto-rollback on smoke failure
|
|
if: steps.smoke.outcome == 'failure' || steps.smoke_sergii.outcome == 'failure'
|
|
run: |
|
|
reason="$([ "${{ steps.smoke.outcome }}" = 'failure' ] && echo 'generic smoke' || echo 'Sergii Review Batch smoke')"
|
|
echo "::error::$reason test failed — rolling back to ${{ steps.pre.outputs.pre_sha }}"
|
|
ssh "$DEPLOY_USER@$DEPLOY_HOST" '
|
|
set -e
|
|
cd /opt/pleno-vue
|
|
git reset --hard ${{ steps.pre.outputs.pre_sha }}
|
|
npm ci --ignore-scripts
|
|
npm run build
|
|
sudo systemctl reload nginx || true
|
|
'
|
|
|
|
- name: Post Slack status
|
|
if: always()
|
|
uses: slackapi/slack-github-action@v1.27.0
|
|
with:
|
|
channel-id: ${{ secrets.AI_DAILY_CHANNEL }}
|
|
payload: |
|
|
{
|
|
"text": "${{ job.status == 'success' && '✅' || '❌' }} Deploy *pleno-vue@${{ github.sha[0:7] }}* — ${{ job.status }}\n${{ steps.smoke.outcome == 'failure' && '⚠️ Generic smoke FAILED → auto-rolled back' || steps.smoke_sergii.outcome == 'failure' && '⚠️ Sergii Review Batch smoke FAILED → auto-rolled back' || '✓ Smoke (generic + Sergii) passed' }}"
|
|
}
|
|
env:
|
|
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|