Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 74 additions & 9 deletions .github/workflows/backend-checks.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
name: Backend Lint & Test

on:
# PR-only: every change touching the backend must pass these checks before
# it lands. Re-running the same suite on the merge commit just burns minutes
# — the PR already proved the tree is green, and branch protection ensures
# nothing reaches `main` without that PR. Use workflow_dispatch for an
# explicit manual rerun against `main` (e.g. after a runner-image rollover
# that might shift behaviour).
# PR-only gate (+ manual dispatch). Coverage is reported self-contained via the
# GitHub Actions job summary — no external service, and no PR comment (fork PRs
# only get a read-only token, so a comment post 403s). Works on any plan.
pull_request:
branches: [main]
paths:
- "src/backend/**"
- ".github/workflows/backend-checks.yml"
workflow_dispatch:

# A new push obsoletes any run still in flight for the same ref — cancel it so a
# rebase/force-push doesn't leave a slow instrumented build burning minutes.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-D warnings"

# Coverage goes to the job summary only (no PR comment), so no write scopes are
# needed — read-only is enough.
permissions:
contents: read

jobs:
check:
name: Lint & Test
Expand All @@ -35,7 +43,8 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.95.0"
components: rustfmt, clippy
# llvm-tools-preview ships the LLVM coverage tooling cargo-llvm-cov drives.
components: rustfmt, clippy, llvm-tools-preview

- uses: Swatinem/rust-cache@v2
with:
Expand All @@ -47,8 +56,36 @@ jobs:
- name: Clippy
run: cargo clippy --all-targets --all-features

- name: Run tests
run: cargo test --all
- uses: taiki-e/install-action@cargo-llvm-cov

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify no non-SHA action refs remain in this workflow.
# Expected: zero matches for third-party `uses:` refs not pinned to 40-char SHA.
rg -nP '^\s*-\s*uses:\s*[^@\s]+@(?!(?:[0-9a-f]{40})$).+$' .github/workflows/backend-checks.yml

Repository: constructorfabric/insight

Length of output: 327


🏁 Script executed:

# Display the workflow file around the mentioned lines with context
sed -n '55,145p' .github/workflows/backend-checks.yml | cat -n

Repository: constructorfabric/insight

Length of output: 4069


🏁 Script executed:

# Display the workflow file around line 139 to verify the third unpinned action
sed -n '135,145p' .github/workflows/backend-checks.yml | cat -n

Repository: constructorfabric/insight

Length of output: 569


Pin third-party GitHub Actions to full commit SHAs.

Lines 59, 73, and 139 use floating refs (@cargo-llvm-cov, @v1.3.0), which violates the current policy and weakens supply-chain integrity.

Suggested changes
-      - uses: taiki-e/install-action@cargo-llvm-cov
+      - uses: taiki-e/install-action@<FULL_40_CHAR_COMMIT_SHA>

-      - name: Coverage summary
-        uses: irongut/CodeCoverageSummary@v1.3.0
+      - name: Coverage summary
+        uses: irongut/CodeCoverageSummary@<FULL_40_CHAR_COMMIT_SHA>

-      - name: Coverage summary
-        uses: irongut/CodeCoverageSummary@v1.3.0
+      - name: Coverage summary
+        uses: irongut/CodeCoverageSummary@<FULL_40_CHAR_COMMIT_SHA>
🧰 Tools
🪛 zizmor (1.25.2)

[error] 59-59: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/backend-checks.yml at line 59, The GitHub Actions in the
workflow file use floating version references instead of full commit SHAs, which
violates supply-chain integrity policy. Replace the floating refs for
taiki-e/install-action@cargo-llvm-cov and any other actions pinned to version
tags like `@v1.3.0` with their corresponding full commit SHA hashes. This applies
to all instances across the workflow file where actions use floating refs to
ensure all third-party actions are pinned to immutable commit SHAs.

Source: Linters/SAST tools


# cargo-llvm-cov runs the suite under coverage instrumentation (this
# replaces the plain `cargo test`, so tests still run) and emits a single
# Cobertura report.
- name: Run tests with coverage
run: |
cargo llvm-cov --no-report --all-features --workspace
cargo llvm-cov report --cobertura --output-path cobertura.xml

# Cobertura -> markdown summary (no HTML, no .NET SDK). This is a Docker
# action that runs at the workspace root, so the path is repo-root-relative
# and code-coverage-results.md is written there.
- name: Coverage summary
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: src/backend/cobertura.xml
format: markdown
output: both
badge: true
hide_complexity: true
fail_below_min: true # gate: fail the job if overall line rate < 60% (lower threshold)
thresholds: "60 80"

- name: Coverage to job summary
if: always()
run: |
f="$GITHUB_WORKSPACE/code-coverage-results.md"
if [ -f "$f" ]; then cat "$f" >> "$GITHUB_STEP_SUMMARY";
else echo "_No coverage summary produced (tests likely failed before coverage ran)._" >> "$GITHUB_STEP_SUMMARY"; fi

dotnet-identity:
name: .NET — Identity Service Build & Test
Expand Down Expand Up @@ -82,8 +119,36 @@ jobs:
run: >
dotnet test tests/Insight.Identity.Tests.Unit/Insight.Identity.Tests.Unit.csproj
--no-build --configuration Release
--collect:"XPlat Code Coverage" --results-directory ./coverage

- name: Integration tests (Testcontainers MariaDB)
run: >
dotnet test tests/Insight.Identity.Tests.Integration/Insight.Identity.Tests.Integration.csproj
--no-build --configuration Release
--collect:"XPlat Code Coverage" --results-directory ./coverage

# The two test runs each emit a Cobertura file for the same assemblies;
# merge them into one report (CodeCoverageSummary takes a single file).
- name: Merge coverage
run: |
dotnet tool install --global dotnet-coverage
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet-coverage merge -f cobertura -o merged.cobertura.xml coverage/*/coverage.cobertura.xml

- name: Coverage summary
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: src/backend/services/identity/merged.cobertura.xml
format: markdown
output: both
badge: true
hide_complexity: true
fail_below_min: true # gate: fail the job if overall line rate < 60% (lower threshold)
thresholds: "60 80"

- name: Coverage to job summary
if: always()
run: |
f="$GITHUB_WORKSPACE/code-coverage-results.md"
if [ -f "$f" ]; then cat "$f" >> "$GITHUB_STEP_SUMMARY";
else echo "_No coverage summary produced (tests likely failed before coverage ran)._" >> "$GITHUB_STEP_SUMMARY"; fi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<!-- Coverlet data collector. Backs the "XPlat Code Coverage" collector that
dotnet test runs to emit Cobertura coverage. Dev-only asset; never shipped. -->
<PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageReference Include="FluentAssertions" Version="6.12.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<!-- Coverlet data collector. Backs the "XPlat Code Coverage" collector that
dotnet test runs to emit Cobertura coverage. Dev-only asset; never shipped. -->
<PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageReference Include="FluentAssertions" Version="6.12.2" />
Expand Down
Loading