-
Notifications
You must be signed in to change notification settings - Fork 1
Tests coverage feature #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,7 @@ | |
| ] | ||
| ], | ||
| "env": { | ||
| "test": { | ||
| "cypress-coverage": { | ||
| "plugins": ["istanbul"] | ||
| } | ||
| } | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,194 @@ | ||
| name: SonarQube | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
| types: [opened, synchronize, reopened] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: sonar-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| sonarqube-pr: | ||
| name: SonarQube PR analysis | ||
| if: >- | ||
| github.event_name == 'pull_request' && | ||
| github.event.pull_request.head.repo.full_name == github.repository && | ||
| github.actor != 'dependabot[bot]' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
|
|
||
| # Keep PR feedback close to Automatic Analysis: scan new code on every | ||
| # update, but do not install dependencies or run coverage suites. | ||
| - name: SonarQube Scan | ||
| uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1 | ||
| env: | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
|
|
||
| unit-coverage: | ||
| name: Jest coverage | ||
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 | ||
| with: | ||
| node-version: "24" | ||
| cache: npm | ||
| cache-dependency-path: package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Run Jest coverage | ||
| run: npm run test:unit:coverage | ||
|
|
||
| - name: Verify Jest LCOV | ||
| run: test -s coverage/jest/lcov.info | ||
|
|
||
| - name: Upload Jest coverage report | ||
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | ||
| with: | ||
| name: jest-coverage-${{ github.run_id }} | ||
| path: coverage/jest | ||
| if-no-files-found: error | ||
| retention-days: 14 | ||
|
|
||
| component-coverage: | ||
| name: Cypress component coverage | ||
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 | ||
| with: | ||
| node-version: "24" | ||
| cache: npm | ||
| cache-dependency-path: package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Install Cypress binary | ||
| run: npx --no-install cypress install | ||
|
|
||
| - name: Run Cypress component coverage | ||
| run: npm run test:component:coverage | ||
|
|
||
| - name: Render Cypress component report | ||
| run: npm run coverage:component | ||
|
|
||
| - name: Verify Cypress LCOV | ||
| run: test -s coverage/component/lcov.info | ||
|
|
||
| - name: Upload Cypress component coverage report | ||
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | ||
| with: | ||
| name: component-coverage-${{ github.run_id }} | ||
| path: coverage/component | ||
| if-no-files-found: error | ||
| retention-days: 14 | ||
|
|
||
| mobile-coverage: | ||
| name: Mobile Jest coverage | ||
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 | ||
| with: | ||
| node-version: "24" | ||
| cache: npm | ||
| cache-dependency-path: | | ||
| package-lock.json | ||
| ui/mobile/package-lock.json | ||
|
|
||
| - name: Install root dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Install mobile dependencies | ||
| run: npm --prefix ui/mobile ci --ignore-scripts | ||
|
|
||
| - name: Run mobile Jest coverage | ||
| run: npm --prefix ui/mobile run test:coverage -- --ci | ||
|
|
||
| - name: Verify mobile Jest LCOV | ||
| run: test -s ui/mobile/coverage/lcov.info | ||
|
|
||
| - name: Upload mobile Jest coverage report | ||
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | ||
| with: | ||
| name: mobile-coverage-${{ github.run_id }} | ||
| path: ui/mobile/coverage | ||
| if-no-files-found: error | ||
| retention-days: 14 | ||
|
|
||
| sonarqube-main: | ||
| name: SonarQube main analysis | ||
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | ||
| needs: [unit-coverage, component-coverage, mobile-coverage] | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
|
|
||
| - name: Download Jest coverage report | ||
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | ||
| with: | ||
| name: jest-coverage-${{ github.run_id }} | ||
| path: coverage/jest | ||
|
|
||
| - name: Download Cypress component coverage report | ||
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | ||
| with: | ||
| name: component-coverage-${{ github.run_id }} | ||
| path: coverage/component | ||
|
|
||
| - name: Download mobile Jest coverage report | ||
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | ||
| with: | ||
| name: mobile-coverage-${{ github.run_id }} | ||
| path: ui/mobile/coverage | ||
|
|
||
| - name: Verify imported LCOV reports | ||
| run: | | ||
| test -s coverage/jest/lcov.info | ||
| test -s coverage/component/lcov.info | ||
| test -s ui/mobile/coverage/lcov.info | ||
|
|
||
| - name: SonarQube Scan with coverage | ||
| uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1 | ||
| with: | ||
| args: >- | ||
| -Dsonar.javascript.lcov.reportPaths=coverage/jest/lcov.info,coverage/component/lcov.info,ui/mobile/coverage/lcov.info | ||
| env: | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
docs/ai/deployment/2026-07-21-feature-sonar-test-coverage.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| --- | ||
| phase: deployment | ||
| title: Sonar Test Coverage Deployment | ||
| description: One-time migration from Automatic Analysis to GitHub Actions | ||
| --- | ||
|
|
||
| # Sonar Test Coverage Deployment | ||
|
|
||
| ## Infrastructure | ||
|
|
||
| - GitHub Actions runs the scanner and coverage producers. | ||
| - SonarQube Cloud stores static-analysis and main coverage measures. | ||
| - GitHub Actions artifacts store independent root Jest, Cypress, and mobile Jest | ||
| reports for 14 days. | ||
|
|
||
| ## Deployment Pipeline | ||
|
|
||
| ### Build Process | ||
|
|
||
| - PR: checkout full Git history and run only the Sonar scanner. | ||
| - Main: run root Jest, Cypress, and mobile Jest coverage in parallel, transfer | ||
| all reports to a final job, then run the scanner. | ||
|
|
||
| ### CI/CD Pipeline | ||
|
|
||
| The dedicated `.github/workflows/sonar.yml` does not replace the existing | ||
| application `.github/workflows/build.yml`. | ||
|
|
||
| ## Environment Configuration | ||
|
|
||
| ### Development | ||
|
|
||
| Local SonarQube keeps project key `EverFreeNote` through a scanner command-line | ||
| override. Local reports must be generated before a local scan. | ||
|
|
||
| ### Production | ||
|
|
||
| - SonarQube Cloud project: `koreyba_EverFreeNote`. | ||
| - Organization: `koreyba`. | ||
| - GitHub secret: `SONAR_TOKEN`. | ||
|
|
||
| ## Deployment Steps | ||
|
|
||
| 1. Ensure `SONAR_TOKEN` exists in GitHub repository secrets. | ||
| 2. Immediately before pushing/enabling this workflow, open SonarQube Cloud | ||
| `Administration > Analysis Method` and disable Automatic Analysis. Do not | ||
| leave both analysis methods active for the same commit. | ||
| 3. Push the workflow branch or update its PR and confirm the scanner-only PR | ||
| check behaves like the previous automatic check. | ||
| 4. Merge to `main` and confirm the resulting workflow imports all three LCOV | ||
| files before publishing the main analysis. | ||
| 5. Confirm the analyzed revision in SonarQube Cloud matches the merged commit. | ||
| 6. Update branch protection if the required-check identity changed from the | ||
| SonarQube Cloud GitHub App check to the GitHub Actions job. | ||
|
|
||
| ## Database Migrations | ||
|
|
||
| None. | ||
|
|
||
| ## Secrets Management | ||
|
|
||
| `SONAR_TOKEN` is stored only in GitHub Secrets. Rotate it in SonarQube Cloud and | ||
| replace the GitHub secret if it is exposed or its owner changes. | ||
|
|
||
| ## Rollback Plan | ||
|
|
||
| 1. Disable the GitHub Actions Sonar workflow. | ||
| 2. Re-enable Automatic Analysis in SonarQube Cloud. | ||
| 3. Accept that coverage will no longer be imported while Automatic Analysis is | ||
| active. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.