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
42 changes: 22 additions & 20 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,36 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: csharp
# build-mode: none analyses the C# source directly, without a build.
# It is load-bearing, not a convenience, for two reasons:
#
# 1. paths-ignore (below) only takes effect in this mode. When CodeQL
# builds a compiled language, GitHub applies no path filter — every
# file the compiler sees is analysed, obj/ included — so under the
# explicit build this workflow used to run, paths-ignore was
# silently inert and the xUnit auto-generated entry point in obj/
# was analysed and flagged in every repo. Buildless extraction
# honours the filter, so the exclusion the standard mandates
# actually happens.
#
# 2. It reads the source across every target framework at once. These
# repos multi-target, and autobuild has picked a single TFM in the
# past, silently analysing half the code; the explicit build existed
# to guard against that. Buildless extraction reads the source
# itself, not one TFM's build output, so it covers all of it with no
# build step to get wrong.
build-mode: none
# security-and-quality is broader than the default security-extended;
# these are small libraries, so the extra findings are affordable.
queries: security-and-quality
# Analyse source only. obj/ and bin/ hold generated and compiled
# output — e.g. the xUnit auto-generated entry point — so findings
# there are noise against code no human maintains.
# there are noise against code no human maintains. Effective only
# under build-mode: none (above).
#
# query-filters excludes the two audit queries that fire on every
# P/Invoke declaration and call site (cs/unmanaged-code,
Expand All @@ -57,9 +70,7 @@ jobs:
# noise there and non-native repos have no P/Invoke for them to hit.
# This excludes ONLY those two queries — every other
# security-and-quality query still runs on the interop files, so no
# real finding is lost (STANDARD.md 4.4). This repo has no P/Invoke,
# so the block matches nothing here; it is carried to keep the
# workflow identical to the template (STANDARD.md 3.0.1).
# real finding is lost (STANDARD.md 4.4).
config: |
paths-ignore:
- "**/obj/**"
Expand All @@ -70,15 +81,6 @@ jobs:
- exclude:
id: cs/call-to-unmanaged-code

# Explicit build rather than autobuild: these repos multi-target, and
# autobuild has picked a single TFM in the past, silently analysing half
# the code. Restore is separate so a restore failure is legible.
- name: Restore
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore

- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v4
with:
Expand Down
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Aligned `codeql.yml` with the updated canonical template (`STANDARD.md` 4.4,
3.0.1): the C# analysis now runs `build-mode: none` (buildless extraction), so
the `Setup .NET` / `Restore` / `Build` steps are gone. This is load-bearing,
not cosmetic — GitHub applies the `paths-ignore` for `**/obj/**` and
`**/bin/**` *only* under buildless extraction; under the previous explicit
build every file the compiler saw was analysed, `obj/` included, so the
exclusion was silently inert and the xUnit auto-generated entry point in
`obj/` was scanned and flagged. Buildless extraction honours the filter (and
reads the source across both target frameworks at once, with no build step to
get wrong).

### Fixed

- Genuinely excluded the two `cs/missed-ternary-operator` alerts CodeQL raised
against the generated `obj/**/XunitAutoGeneratedEntryPoint.cs` — the
`paths-ignore` now takes effect (see the `build-mode: none` change above)
rather than the alerts sitting open against code no human maintains.
- Resolved every open CodeQL code-scanning alert from the `security-and-quality`
pack with a genuine code change rather than a suppression (no consumer-visible
behaviour changes):
Expand All @@ -31,7 +48,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `cs/missed-using-statement`: the debounce task now scopes its
`CancellationTokenSource` with a `using` block instead of a manual
`finally`-dispose, preserving the existing (idempotent) disposal semantics.
- `cs/local-not-disposed`: the test CLI harness now disposes its `TestConsole`.
- `cs/local-not-disposed`: the test CLI harness binds its `using` directly to
the `new TestConsole()` allocation and calls `.Interactive()` as a separate
statement, so the disposal is visible to dataflow — the earlier fluent
`new TestConsole().Interactive()` left CodeQL unable to connect the
allocation to the disposed variable.

## [1.0.0] — 2026-08-21

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public static async Task<CliResult> RunAsync(
var app = new CommandApp(new TypeRegistrar(services));
app.Configure(config => config.AddSettingsBranch());

using var console = new TestConsole().Interactive();
using var console = new TestConsole();
console.Interactive();
foreach (var line in consoleInput)
{
console.Input.PushTextWithEnter(line);
Expand Down