chore(claude): normalize line endings and refresh the agent-facing docs #440
Workflow file for this run
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
| name: Code Quality | |
| on: | |
| pull_request: | |
| branches: [main] | |
| # Detects whether a PR *adds* new dead code or duplication compared to main. | |
| # - fallow covers VueApp (dead code, unused exports, complexity, duplication) | |
| # - jscpd covers C# (web/Areas/**/*.cs) since fallow is JS/TS-only | |
| # - resharper-pr-gate covers C# inspections (dead-conditional, NRT-contract, and | |
| # redundancy findings the Roslyn build doesn't catch); PR-scoped so pre-existing | |
| # issues are not blocking — only NEW findings at lines this PR added/modified fail. | |
| # Passes if counts are equal to or lower than main. | |
| jobs: | |
| fallow-regression: | |
| name: Fallow regression (VueApp) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| VueApp/package-lock.json | |
| - name: Install dependencies (root) | |
| run: npm ci | |
| - name: Install dependencies (VueApp) | |
| # fallow resolves the tsconfig chain (incl. @tsconfig/node24) and needs | |
| # VueApp's node_modules to produce accurate counts. Without this step, | |
| # CI reports inflated unresolved-imports / unused-types numbers. | |
| run: npm ci --prefix VueApp | |
| - name: Baseline complexity on main | |
| # `fallow audit`'s complexity gate re-attributes pre-existing findings as | |
| # "new" when files are substantially refactored — moves/rewrites defeat | |
| # its base-snapshot matching, so untouched hotspots get re-flagged. | |
| # Baseline complexity against main's tree (same worktree approach as the | |
| # jscpd-regression jobs below) so only genuinely-new complexity fails. | |
| # Duplication is already gated by jscpd-regression; fallow's own | |
| # duplication verdict is warn-only, so it isn't baselined here. | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: | | |
| BASE_TREE="$(mktemp -d)" | |
| git worktree add --detach "$BASE_TREE" "origin/$BASE_REF" | |
| npx fallow health --root "$BASE_TREE/VueApp" --save-baseline "$RUNNER_TEMP/fallow-health-baseline.json" --quiet || true | |
| git worktree remove --force "$BASE_TREE" | |
| - name: Audit fallow on changed files | |
| # `fallow audit` scopes to files changed since --base and returns a | |
| # pass/warn/fail verdict. --health-baseline excludes complexity that | |
| # already existed on main, so a refactor that moves code doesn't fail on | |
| # pre-existing hotspots. | |
| run: npx fallow audit --root VueApp --base origin/${{ github.base_ref }} --health-baseline "$RUNNER_TEMP/fallow-health-baseline.json" | |
| jscpd-regression-csharp: | |
| name: JSCPD regression (C#) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| VueApp/package-lock.json | |
| - name: Install dependencies (root) | |
| run: npm ci | |
| - name: Baseline jscpd on main | |
| # Use a separate worktree at the base ref so the baseline scan sees | |
| # main's full tree — files added by the PR aren't present, files | |
| # changed by the PR carry main's content. Pathspec `git checkout` | |
| # would leave PR-only files in place and pollute the baseline. | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: | | |
| BASE_TREE="$(mktemp -d)" | |
| git worktree add --detach "$BASE_TREE" "origin/$BASE_REF" | |
| node scripts/audit-jscpd-regression.js --save .jscpd-baseline-cs.json "$BASE_TREE/web/Areas" --format csharp --pattern '**/*.cs' --min-lines 15 | |
| git worktree remove --force "$BASE_TREE" | |
| - name: Check jscpd regression on PR | |
| run: node scripts/audit-jscpd-regression.js --check .jscpd-baseline-cs.json web/Areas --format csharp --pattern '**/*.cs' --min-lines 15 | |
| jscpd-regression-vue: | |
| name: JSCPD regression (Vue/TS) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| VueApp/package-lock.json | |
| - name: Install dependencies (root) | |
| run: npm ci | |
| - name: Baseline jscpd on main | |
| # See the C# baseline step above for why we use a worktree here. | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| run: | | |
| BASE_TREE="$(mktemp -d)" | |
| git worktree add --detach "$BASE_TREE" "origin/$BASE_REF" | |
| node scripts/audit-jscpd-regression.js --save .jscpd-baseline-vue.json "$BASE_TREE/VueApp/src" | |
| git worktree remove --force "$BASE_TREE" | |
| - name: Check jscpd regression on PR | |
| run: node scripts/audit-jscpd-regression.js --check .jscpd-baseline-vue.json VueApp/src | |
| resharper-pr-gate: | |
| name: ReSharper PR-scoped gate (C#) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - uses: actions/setup-dotnet@9a946fdbd5fb07b82b2f5a4466058b876ab72bb2 # v5.3.0 | |
| with: | |
| global-json-file: global.json | |
| - name: Install dependencies (root) | |
| run: npm ci | |
| - name: Restore dotnet local tools (jb / dotnet-ef / libman) | |
| run: dotnet tool restore | |
| - name: Restore NuGet | |
| run: dotnet restore Viper.sln | |
| - name: Run inspectcode + PR-diff gate | |
| # The script runs the full inspectcode scan, parses the SARIF, and only | |
| # fails on findings located at lines this PR added/modified vs base ref. | |
| run: node scripts/audit-resharper-regression.js --base origin/${{ github.base_ref }} | |
| - name: Upload SARIF report | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: resharper-sarif | |
| path: inspect-report/inspect.sarif | |
| retention-days: 3 |