Skip to content
Open
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ jobs:
- name: Check for vulnerable dependencies
run: dotnet list KeelMatrix.QueryWatch.sln package --vulnerable
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: csharp
- name: Build for CodeQL
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
- name: Analyze with CodeQL
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
perf-bench:
if: (github.event_name == 'pull_request' || github.ref == 'refs/heads/main') && github.actor != 'dependabot[bot]'
needs: build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
Expand Down Expand Up @@ -109,6 +109,6 @@ jobs:
exit 1

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ This repo ships three tiny sample apps (EF Core, ADO.NET, Dapper) that **consume
```bash
dotnet pack ./src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj -c Release --include-symbols --p:SymbolPackageFormat=snupkg --output ./artifacts/packages
dotnet pack ./src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj -c Release --include-symbols --p:SymbolPackageFormat=snupkg --output ./artifacts/packages
dotnet pack ./src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj -c Release --include-symbols --p:SymbolPackageFormat=snupkg --output ./artifacts/packages
```
2. **Install local packages to samples** (pins to `./artifacts/packages` via `samples/NuGet.config`):
- Windows (PowerShell): `./samples/init.ps1`
- Linux/macOS (bash): `./samples/init.sh`
2. **Install local packages to samples** (pins to `../artifacts/packages` via `samples/NuGet.config`):
- Windows (PowerShell): `pwsh -NoProfile -File build/Dev-PackInstallSamples.ps1`
- Linux/macOS (bash): `bash build/Dev-PackInstallSamples.sh`
3. **Run a sample** (EF example shown):
```bash
dotnet run --project ./samples/EFCore.Sqlite/EFCore.Sqlite.csproj -c Release
Expand Down Expand Up @@ -77,7 +78,7 @@ var options = new DbContextOptionsBuilder<MyDbContext>()
```csharp
using Dapper;
using Microsoft.Data.Sqlite;
using KeelMatrix.QueryWatch.Dapper;
using KeelMatrix.QueryWatch;
using KeelMatrix.QueryWatch.Testing;

using var q = QueryWatchScope.Start(exportJsonPath: "artifacts/dapper.json", sampleTop: 200);
Expand All @@ -99,7 +100,7 @@ var rows = await conn.QueryAsync("SELECT 1");

```csharp
using Microsoft.Data.Sqlite;
using KeelMatrix.QueryWatch.Ado;
using KeelMatrix.QueryWatch;
using KeelMatrix.QueryWatch.Testing;

using var q = QueryWatchScope.Start(exportJsonPath: "artifacts/ado.json", sampleTop: 200);
Expand Down
55 changes: 55 additions & 0 deletions build/Dev-CleanPackInstallSamples.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Param()
$ErrorActionPreference = 'Stop'

function Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Run {
param([Parameter(Mandatory=$true)][string]$exe, [Parameter(ValueFromRemainingArguments=$true)][string[]]$args)
Write-Host (" " + $exe + " " + ($args -join " ")) -ForegroundColor DarkGray
& $exe @args
if ($LASTEXITCODE -ne 0) { throw "Command failed: $exe $($args -join ' ')" }
}

$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $repoRoot

try {
Step ".NET SDK info"
Run dotnet --info | Out-Null

$artifacts = Join-Path $repoRoot "artifacts"
$pkgDir = Join-Path $artifacts "packages"
if (-not (Test-Path $pkgDir)) { New-Item -ItemType Directory -Path $pkgDir | Out-Null }

# 0) Clean local KeelMatrix.* packages only (leave other artifacts intact)
Step "Clean ./artifacts/packages (KeelMatrix.QueryWatch*)"
Get-ChildItem -Path $pkgDir -Filter "KeelMatrix.QueryWatch*.nupkg" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
Get-ChildItem -Path $pkgDir -Filter "KeelMatrix.QueryWatch*.snupkg" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue

# 1) Restore solution
Step "Restore solution"
Run dotnet restore "KeelMatrix.QueryWatch.sln"

# 2) Build in dependency-friendly order
Step "Build libraries (Release)"
Run dotnet build "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" -c Release --no-restore
Run dotnet build "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" -c Release --no-restore
Run dotnet build "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" -c Release --no-restore

# 3) Pack all
Step "Pack libraries -> ./artifacts/packages"
$packArgs = @('--configuration','Release','--no-build','--include-symbols','--p:SymbolPackageFormat=snupkg','--output',$pkgDir)
Run dotnet pack "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" @packArgs
Run dotnet pack "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" @packArgs
Run dotnet pack "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" @packArgs

# 4) Restore samples against local feed
Step "Restore samples with samples/NuGet.config"
Run dotnet restore "samples/QueryWatch.Samples.sln" --configfile "samples/NuGet.config"

Step "Done"
Write-Host "Cleaned, packed, and restored samples successfully." -ForegroundColor Green
}
catch {
Write-Error $_
exit 1
}
39 changes: 39 additions & 0 deletions build/Dev-CleanPackInstallSamples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail

step() { printf "\n==> %s\n" "$1"; }
run() { printf " %s\n" "$*" >&2; "$@"; }

SCRIPT_DIR="$( cd -- "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$REPO_ROOT"

step ".NET SDK info"
run dotnet --info >/dev/null

ARTIFACTS="$REPO_ROOT/artifacts"
PKG_DIR="$ARTIFACTS/packages"
mkdir -p "$PKG_DIR"

step "Clean ./artifacts/packages (KeelMatrix.QueryWatch*)"
find "$PKG_DIR" -maxdepth 1 -type f \( -name 'KeelMatrix.QueryWatch*.nupkg' -o -name 'KeelMatrix.QueryWatch*.snupkg' \) -print -delete || true

step "Restore solution"
run dotnet restore "KeelMatrix.QueryWatch.sln"

step "Build libraries (Release)"
run dotnet build "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" -c Release --no-restore
run dotnet build "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" -c Release --no-restore
run dotnet build "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" -c Release --no-restore

step "Pack libraries -> ./artifacts/packages"
COMMON_PACK_ARGS=('--configuration' 'Release' '--no-build' '--include-symbols' '--p:SymbolPackageFormat=snupkg' '--output' "$PKG_DIR")
run dotnet pack "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" "${COMMON_PACK_ARGS[@]}"
run dotnet pack "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" "${COMMON_PACK_ARGS[@]}"
run dotnet pack "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" "${COMMON_PACK_ARGS[@]}"

step "Restore samples with samples/NuGet.config"
run dotnet restore "samples/QueryWatch.Samples.sln" --configfile "samples/NuGet.config"

step "Done"
echo "Cleaned, packed, and restored samples successfully."
51 changes: 51 additions & 0 deletions build/Dev-PackInstallSamples.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Param()
$ErrorActionPreference = 'Stop'

function Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Run {
param([Parameter(Mandatory=$true)][string]$exe, [Parameter(ValueFromRemainingArguments=$true)][string[]]$args)
Write-Host (" " + $exe + " " + ($args -join " ")) -ForegroundColor DarkGray
& $exe @args
if ($LASTEXITCODE -ne 0) { throw "Command failed: $exe $($args -join ' ')" }
}

$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $repoRoot

try {
Step ".NET SDK info"
Run dotnet --info | Out-Null

$artifacts = Join-Path $repoRoot "artifacts"
$pkgDir = Join-Path $artifacts "packages"
if (-not (Test-Path $pkgDir)) { New-Item -ItemType Directory -Path $pkgDir | Out-Null }

# 1) Restore solution (ensures props/targets are resolved)
Step "Restore solution"
Run dotnet restore "KeelMatrix.QueryWatch.sln"

# 2) Build packable libraries (Release)
Step "Build libraries (Release)"
Run dotnet build "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" -c Release --no-restore
Run dotnet build "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" -c Release --no-restore
Run dotnet build "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" -c Release --no-restore

# 3) Pack to ./artifacts/packages (symbols included)
Step "Pack libraries -> ./artifacts/packages"
$packArgs = @('--configuration','Release','--no-build','--include-symbols','--p:SymbolPackageFormat=snupkg','--output',$pkgDir)
Run dotnet pack "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" @packArgs
Run dotnet pack "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" @packArgs
Run dotnet pack "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" @packArgs

# 4) Restore samples using their NuGet.config (pins KeelMatrix.QueryWatch* to ../artifacts/packages)
Step "Restore samples with samples/NuGet.config"
Run dotnet restore "samples/QueryWatch.Samples.sln" --configfile "samples/NuGet.config"

Step "Done"
Write-Host "Packages are in: $pkgDir" -ForegroundColor Green
Write-Host "Samples restored against local packages." -ForegroundColor Green
}
catch {
Write-Error $_
exit 1
}
37 changes: 37 additions & 0 deletions build/Dev-PackInstallSamples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail

step() { printf "\n==> %s\n" "$1"; }
run() { printf " %s\n" "$*" >&2; "$@"; }

SCRIPT_DIR="$( cd -- "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$REPO_ROOT"

step ".NET SDK info"
run dotnet --info >/dev/null

ARTIFACTS="$REPO_ROOT/artifacts"
PKG_DIR="$ARTIFACTS/packages"
mkdir -p "$PKG_DIR"

step "Restore solution"
run dotnet restore "KeelMatrix.QueryWatch.sln"

step "Build libraries (Release)"
run dotnet build "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" -c Release --no-restore
run dotnet build "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" -c Release --no-restore
run dotnet build "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" -c Release --no-restore

step "Pack libraries -> ./artifacts/packages"
COMMON_PACK_ARGS=('--configuration' 'Release' '--no-build' '--include-symbols' '--p:SymbolPackageFormat=snupkg' '--output' "$PKG_DIR")
run dotnet pack "src/KeelMatrix.QueryWatch.Redaction/KeelMatrix.QueryWatch.Redaction.csproj" "${COMMON_PACK_ARGS[@]}"
run dotnet pack "src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj" "${COMMON_PACK_ARGS[@]}"
run dotnet pack "src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj" "${COMMON_PACK_ARGS[@]}"

step "Restore samples with samples/NuGet.config"
run dotnet restore "samples/QueryWatch.Samples.sln" --configfile "samples/NuGet.config"

step "Done"
echo "Packages are in: $PKG_DIR"
echo "Samples restored against local packages."
94 changes: 94 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# 🧰 Build Scripts

Helper scripts for local development and CI.
Run from the **repo root** unless otherwise noted.

---

## 📦 What’s Here

- **`Dev-PackInstallSamples.ps1` / `.sh`** — Restore, build, and **pack** `KeelMatrix.QueryWatch*` libraries, then restore **samples** against the locally packed feed (`./artifacts/packages`).
→ `build/Dev-PackInstallSamples.ps1` • `build/Dev-PackInstallSamples.sh`

- **`Dev-CleanPackInstallSamples.ps1` / `.sh`** — Same as above, but first **cleans** local `KeelMatrix.QueryWatch*.nupkg` / `.snupkg` before rebuilding & packing. Ideal when iterating locally.
→ `build/Dev-CleanPackInstallSamples.ps1` • `build/Dev-CleanPackInstallSamples.sh`

- **`Update-ReadmeFlags.ps1`** — Builds the CLI and updates the README block between
`<!-- BEGIN:CLI_FLAGS -->` and `<!-- END:CLI_FLAGS -->` using `--print-flags-md`.
Writes fallback output to `docs/CLI_FLAGS.generated.md` if markers are missing.
→ `build/Update-ReadmeFlags.ps1`

- **`Pack-Sign-Push.ps1`** — End-to-end **pack → (optional) sign → push** workflow.
Stubs for signing/publishing (customize for your environment).
→ `build/Pack-Sign-Push.ps1`

- **`New-DevSecrets.ps1`** — Stub that documents how to configure your **NuGet API key** and import a **code-signing certificate** locally. Safe to customize for your organization.
→ `build/New-DevSecrets.ps1`

> PowerShell (`.ps1`) and Bash (`.sh`) variants are provided to support cross-platform workflows.

---

## ⚡ Quick Tasks

### Pack libs and restore samples (fast path)

#### Windows / PowerShell
```powershell
pwsh -NoProfile -File build/Dev-PackInstallSamples.ps1
```

#### Linux / macOS
```bash
bash build/Dev-PackInstallSamples.sh
```

---

### Clean old local packages, repack, restore samples

```powershell
pwsh -NoProfile -File build/Dev-CleanPackInstallSamples.ps1
```

```bash
bash build/Dev-CleanPackInstallSamples.sh
```

---

### Refresh CLI flags in README

```powershell
./build/Update-ReadmeFlags.ps1
```

---

### End-to-end pack → (optional) sign → push

Customize first, then run:
```powershell
./build/Pack-Sign-Push.ps1
```

---

## 🧩 Prerequisites

- **.NET SDK 8.x+** → check via:
```bash
dotnet --info
```
See: `docs/DEV.md`
- For signing/publish flows: configure your **NuGet API key** and (optional) **code-signing certificate** locally.
See: `build/New-DevSecrets.ps1`

---

## 📁 Conventions

- Artifacts are written to `./artifacts` (subfolders: `packages/`, `benchmarks/`, etc).
See: `build/Dev-PackInstallSamples.ps1` or `bench/README.md`.

---
4 changes: 2 additions & 2 deletions docs/DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ Read more in `bench/BENCHMARKS.md`.
dotnet pack ./src/KeelMatrix.QueryWatch/KeelMatrix.QueryWatch.csproj -c Release --no-build --include-symbols --p:SymbolPackageFormat=snupkg -o ./artifacts/packages
dotnet pack ./src/KeelMatrix.QueryWatch.EfCore/KeelMatrix.QueryWatch.EfCore.csproj -c Release --no-build --include-symbols --p:SymbolPackageFormat=snupkg -o ./artifacts/packages

# Then run the sample helper
pwsh -NoProfile -File samples/init.ps1
# Then run the sample setup
pwsh -NoProfile -File build/Dev-PackInstallSamples.ps1
dotnet run --project samples/EFCore.Sqlite/EFCore.Sqlite.csproj -c Release
```

Expand Down
2 changes: 1 addition & 1 deletion samples/Ado.Sqlite/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
// Query back
using (var select = conn.CreateCommand()) {
select.CommandText = Redaction.Apply("SELECT COUNT(*) FROM Users WHERE Name LIKE 'User_%';");
var count = Convert.ToInt32(await select.ExecuteScalarAsync());
var count = Convert.ToInt32(await select.ExecuteScalarAsync(), System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine($"Users in DB: {count}");
}

Expand Down
6 changes: 3 additions & 3 deletions samples/Dapper.Sqlite/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Dapper;
using DapperSample;
using KeelMatrix.QueryWatch.Dapper;
using KeelMatrix.QueryWatch;
using KeelMatrix.QueryWatch.Testing;
using Microsoft.Data.Sqlite;

Expand All @@ -26,15 +26,15 @@
await conn.ExecuteAsync(Redaction.Apply("/* contact: [email protected] */ CREATE TABLE Users(Id INTEGER PRIMARY KEY, Name TEXT NOT NULL);"));

// Insert in a transaction (exercise Transaction wrapper + async APIs)
using (var tx = conn.BeginTransaction()) {
using (var tx = await conn.BeginTransactionAsync()) {
for (int i = 0; i < 3; i++) {
var email = $"user{i}@example.com"; // will be redacted in CommandText
await conn.ExecuteAsync(
Redaction.Apply($"/* email: {email} */ INSERT INTO Users(Name) VALUES (@name);"),
new { name = Redaction.Param("User_" + i) },
transaction: tx);
}
tx.Commit();
await tx.CommitAsync();
}

// Query back (async)
Expand Down
Loading