diff --git a/.gitea/workflows/dependency-scan.yml b/.gitea/workflows/dependency-scan.yml new file mode 100644 index 000000000..c2c68ab29 --- /dev/null +++ b/.gitea/workflows/dependency-scan.yml @@ -0,0 +1,58 @@ +name: Dependency vulnerability scan + +# Scheduled NuGet advisory scan — a Gitea-native stand-in for Dependabot (ersatztv#14). +# Surfaces vulnerable direct/transitive packages on a schedule instead of only when a +# `dotnet restore` happens to break. This is DETECTION ONLY; automated update PRs are +# tracked separately (self-hosted Renovate — server-management#484). +# +# Scans the FULL solution (including the Scanner project, which the image build strips) +# so coverage isn't narrower than the code we ship. +# +# NOTE: Gitea runs `schedule` triggers only from the default branch (main); the workflow +# must be merged to main before the cron registers. Use `workflow_dispatch` to run on demand. + +on: + workflow_dispatch: + schedule: + # Mondays 06:00 UTC + - cron: '0 6 * * 1' + +# Independent of the build pipeline's concurrency group; a stale scan can be cancelled. +concurrency: + group: ersatztv-depscan + cancel-in-progress: true + +jobs: + scan: + name: NuGet vulnerable packages + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Restore + run: dotnet restore ErsatzTV.sln + + - name: Scan for vulnerable packages (direct + transitive) + # bash + `set -euo pipefail` so a failing `dotnet list` (e.g. the audit source + # is unreachable while restore served from cache) fails the job instead of + # falling through to a false "no vulnerable packages" green. + shell: bash + run: | + set -euo pipefail + echo "Running: dotnet list package --vulnerable --include-transitive" + dotnet list ErsatzTV.sln package --vulnerable --include-transitive 2>&1 | tee depscan.txt + # `dotnet list package --vulnerable` exits 0 even when advisories exist, so detect + # findings by the report marker and fail the run if any are present. Expect this to + # be RED until ersatztv#8 clears the current NCalcSync / SQLitePCLRaw advisories; + # after that, a red run means a NEW advisory has appeared. + if grep -q "has the following vulnerable packages" depscan.txt; then + echo "::error::Vulnerable NuGet packages detected — see report above (tracked: ersatztv#8)." + exit 1 + fi + echo "No vulnerable packages found." diff --git a/Directory.Build.targets b/Directory.Build.targets index 2e906ed8e..bb539cbf2 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -6,7 +6,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..a3750c7fd --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,104 @@ + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ErsatzTV.Application/ErsatzTV.Application.csproj b/ErsatzTV.Application/ErsatzTV.Application.csproj index df10c6035..8d4a2baeb 100644 --- a/ErsatzTV.Application/ErsatzTV.Application.csproj +++ b/ErsatzTV.Application/ErsatzTV.Application.csproj @@ -10,15 +10,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj index 87a7309a0..ac3a24095 100644 --- a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj +++ b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj @@ -7,22 +7,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/ErsatzTV.Core/ErsatzTV.Core.csproj b/ErsatzTV.Core/ErsatzTV.Core.csproj index 342e03ab3..d89b45f03 100644 --- a/ErsatzTV.Core/ErsatzTV.Core.csproj +++ b/ErsatzTV.Core/ErsatzTV.Core.csproj @@ -10,27 +10,27 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj index edb5e6a38..b0481bd77 100644 --- a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj +++ b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj @@ -8,14 +8,14 @@ - - - - - - - - + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj index 068391dc3..ae249a3d3 100644 --- a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj +++ b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj @@ -11,12 +11,12 @@ - - - - - - + + + + + + diff --git a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj index 723beea5d..352dcf8c0 100644 --- a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj +++ b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj index 37a4476e2..d1cabae48 100644 --- a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj +++ b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj @@ -12,10 +12,10 @@ - - - - + + + + diff --git a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj index 6e9575e54..a7d6125c7 100644 --- a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj +++ b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj @@ -9,20 +9,20 @@ - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj index eead7978f..1613bf6fd 100644 --- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj +++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj @@ -12,33 +12,33 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - + + + + + + + + + + + diff --git a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj index 2ceee7724..ceb7fe688 100644 --- a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj +++ b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj @@ -9,21 +9,21 @@ - - - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + diff --git a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj index 626120a71..677e3e8d8 100644 --- a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj +++ b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj @@ -21,21 +21,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/ErsatzTV.Tests/ErsatzTV.Tests.csproj b/ErsatzTV.Tests/ErsatzTV.Tests.csproj index abe870896..5581d1eaf 100644 --- a/ErsatzTV.Tests/ErsatzTV.Tests.csproj +++ b/ErsatzTV.Tests/ErsatzTV.Tests.csproj @@ -11,13 +11,13 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index 68c9683da..853503151 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -29,38 +29,38 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + + + + diff --git a/docker/Dockerfile b/docker/Dockerfile index a311ed4a3..f468b1703 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,9 +25,11 @@ COPY scripts/scripted-schedules/. /app/scripted-schedules/ # copy csproj and restore as distinct layers COPY *.sln . # repo-wide build config (MSBuild props/targets incl. NuGet-audit warning -# exemptions, SDK pin, analyzer severities) must be present before restore so the -# image build matches local/CI builds -COPY Directory.Build.props Directory.Build.targets global.json .editorconfig ./ +# exemptions, SDK pin, analyzer severities, and the Central Package Management +# version manifest) must be present before restore so the image build matches +# local/CI builds. Directory.Packages.props is REQUIRED here: with CPM the csproj +# carry no versions, so restore fails without the central manifest. +COPY Directory.Build.props Directory.Build.targets Directory.Packages.props global.json .editorconfig ./ COPY artwork/* ./artwork/ COPY ErsatzTV/*.csproj ./ErsatzTV/ COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/