Replace the header "Byt lösenord" link with an Inställningar menu for changing email or password. Email changes are two-step: request with password, confirmation link to the new address, then password again on confirm so a wrong inbox cannot take over the account. - Backend: EmailChangeService, V10 email_change_tokens, confirm API - Frontend: ChangeEmailPage, ConfirmEmailChangePage, header dropdown - E2E: account-settings round-trips, Mailpit verification, wrong-password guard - Flyway: V9 restore for dev DBs, CI migration checks, V10 for email tokens Co-authored-by: Cursor <cursoragent@cursor.com>
123 lines
5.1 KiB
YAML
123 lines
5.1 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [master, develop]
|
|
pull_request:
|
|
branches: [master, develop]
|
|
|
|
jobs:
|
|
lint-and-test:
|
|
name: Lint, type check, unit tests, coverage
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout repository
|
|
run: |
|
|
git init
|
|
git remote add origin https://x-access-token:${FORGEJO_TOKEN}@srvr.nu/git/jocke/bilhej.git
|
|
git fetch --depth 1 origin ${GITHUB_SHA}
|
|
git checkout FETCH_HEAD
|
|
git fetch --depth 1 origin master
|
|
|
|
- name: Check Flyway migrations
|
|
run: bash scripts/check-flyway-migrations.sh origin/master
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
- uses: https://github.com/actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: 21
|
|
|
|
- name: Install frontend dependencies
|
|
run: npm ci
|
|
working-directory: frontend
|
|
|
|
- name: Lint
|
|
run: npm run lint
|
|
working-directory: frontend
|
|
|
|
- name: Type check
|
|
run: npx vue-tsc --noEmit
|
|
working-directory: frontend
|
|
|
|
- name: Backend coverage
|
|
run: ./gradlew :backend:jacocoTestCoverageVerification
|
|
|
|
- name: Print coverage summary
|
|
run: |
|
|
node -e "
|
|
const fs = require('fs');
|
|
const xml = fs.readFileSync('backend/build/reports/jacoco/test/jacocoTestReport.xml', 'utf8');
|
|
const lineMatch = xml.match(/<counter type=\"LINE\" missed=\"(\d+)\" covered=\"(\d+)\"\\/>/g);
|
|
const branchMatch = xml.match(/<counter type=\"BRANCH\" missed=\"(\d+)\" covered=\"(\d+)\"\\/>/g);
|
|
if (lineMatch && branchMatch) {
|
|
const lastLine = lineMatch[lineMatch.length - 1].match(/missed=\"(\d+)\" covered=\"(\d+)\"/);
|
|
const lastBranch = branchMatch[branchMatch.length - 1].match(/missed=\"(\d+)\" covered=\"(\d+)\"/);
|
|
const lineMissed = +lastLine[1], lineCovered = +lastLine[2];
|
|
const branchMissed = +lastBranch[1], branchCovered = +lastBranch[2];
|
|
const linePct = (lineCovered / (lineMissed + lineCovered) * 100).toFixed(1);
|
|
const branchPct = (branchCovered / (branchMissed + branchCovered) * 100).toFixed(1);
|
|
const allPass = linePct >= 70 && branchPct >= 60;
|
|
console.log('');
|
|
console.log('╔════════════════╦══════════╦════════════╗');
|
|
console.log('║ Coverage Summary — Bilhej ║');
|
|
console.log('╠════════════════╬══════════╬════════════╣');
|
|
console.log('║ Layer │ Lines │ Branch ║');
|
|
console.log('╠════════════════╬══════════╬════════════╣');
|
|
console.log('║ Backend │ ' + (linePct + '%').padStart(7) + ' │ ' + (branchPct + '%').padStart(7) + ' ║');
|
|
console.log('╠════════════════╬══════════╬════════════╣');
|
|
console.log('║ Thresholds │ ' + '70.0%'.padStart(7) + ' │ ' + '60.0%'.padStart(7) + ' ║');
|
|
console.log('╚════════════════╩══════════╩════════════╝');
|
|
console.log(allPass ? 'All backend thresholds met.' : 'Some backend thresholds missed.');
|
|
console.log('');
|
|
console.log('Frontend coverage printed above by Vitest text reporter.');
|
|
console.log('Download full HTML reports from the Artifacts tab.');
|
|
console.log('');
|
|
}
|
|
"
|
|
|
|
- name: Frontend coverage
|
|
run: npm run test:coverage
|
|
working-directory: frontend
|
|
|
|
- name: Upload backend coverage report
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: backend-coverage
|
|
path: backend/build/reports/jacoco/test/html/
|
|
retention-days: 7
|
|
|
|
- name: Upload frontend coverage report
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: frontend-coverage
|
|
path: frontend/coverage/
|
|
retention-days: 7
|
|
|
|
e2e:
|
|
name: E2E browser tests
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
POSTGRES_DB: bilhej
|
|
POSTGRES_USER: bilhej
|
|
POSTGRES_PASSWORD: test_pw_ci_123
|
|
JWT_SECRET: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
STRIPE_SECRET_KEY: sk_test_fake
|
|
STRIPE_WEBHOOK_SECRET: whsec_fake
|
|
STRIPE_PRICE_ID: price_fake
|
|
steps:
|
|
- name: Checkout repository
|
|
run: |
|
|
git init
|
|
git remote add origin https://x-access-token:${FORGEJO_TOKEN}@srvr.nu/git/jocke/bilhej.git
|
|
git fetch --depth 1 origin ${GITHUB_SHA}
|
|
git checkout FETCH_HEAD
|
|
|
|
- name: Run E2E test stack
|
|
run: |
|
|
docker compose \
|
|
-f docker-compose.e2e.yml \
|
|
up --build --abort-on-container-exit --exit-code-from playwright
|