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
9 changes: 7 additions & 2 deletions .github/workflows/history-hygiene.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: Commit history hygiene

on:
push:
branches:
- main
pull_request:

permissions:
Expand All @@ -16,9 +18,12 @@ jobs:
with:
fetch-depth: 0

- name: Check all reachable commits
- name: Check introduced commits
env:
HISTORY_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
HISTORY_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
shell: bash
run: sh .githooks/check-history
run: sh .githooks/check-history "$HISTORY_BASE_SHA" "$HISTORY_HEAD_SHA"

- name: Verify commit-message gate regression coverage
shell: pwsh
Expand Down
43 changes: 34 additions & 9 deletions build/Test-CommitHistoryGate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ function Invoke-CommitMessageHook([string] $Path, [string] $Message) {
return [int]$status
}

function Invoke-HistoryHook([string] $Head) {
Push-Location $repositoryRoot
function Invoke-HistoryHook([string] $WorkingDirectory, [string] $Start, [string] $End) {
$shellCommand = Get-Command sh -ErrorAction SilentlyContinue
$shellPath = if ($shellCommand) { $shellCommand.Source } else { Join-Path (Split-Path $bashPath) "sh.exe" }
if (-not (Test-Path -LiteralPath $shellPath)) { throw "Could not locate the POSIX shell for the history hook." }
Push-Location $WorkingDirectory
try {
& $bashPath --login -c 'sh "$1" "$2" "$3"' efguard-history-gate .githooks/check-history "0000000000000000000000000000000000000000" $Head | Out-Null
$historyHook = Join-Path $repositoryRoot ".githooks/check-history"
& $shellPath $historyHook $Start $End | Out-Null
$status = $LASTEXITCODE
}
finally {
Expand Down Expand Up @@ -95,15 +99,36 @@ fix: preserve useful metadata diagnostics
throw "The commit-message gate accepted conflict-marker lines (exit $markerStatus)."
}

$head = (& git -C $repositoryRoot rev-parse HEAD).Trim()
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($head)) {
throw "Could not determine the current repository commit."
$historyRepository = Join-Path $temporaryRoot "history-repository"
New-Item -ItemType Directory -Path $historyRepository -Force | Out-Null
& git -C $historyRepository init --quiet
if ($LASTEXITCODE -ne 0) { throw "Could not initialize the synthetic history repository." }
& git -C $historyRepository config user.name "KeelMatrix"
& git -C $historyRepository config user.email "keelmatrix@gmail.com"
"legacy baseline" | Set-Content -LiteralPath (Join-Path $historyRepository "baseline.txt")
& git -C $historyRepository add baseline.txt
& git -C $historyRepository commit --quiet -m "legacy baseline" -m "Signed-off-by: dependabot[bot] <support@github.com>"
if ($LASTEXITCODE -ne 0) { throw "Could not create the synthetic legacy baseline." }
$base = (& git -C $historyRepository rev-parse HEAD).Trim()
"clean change" | Set-Content -LiteralPath (Join-Path $historyRepository "clean.txt")
& git -C $historyRepository add clean.txt
& git -C $historyRepository commit --quiet -m "fix: add clean change"
if ($LASTEXITCODE -ne 0) { throw "Could not create the synthetic clean commit." }
$cleanHead = (& git -C $historyRepository rev-parse HEAD).Trim()
if ((Invoke-HistoryHook $historyRepository $base $cleanHead) -ne 0) {
throw "The history gate rejected clean introduced history after an older baseline commit."
}
if ((Invoke-HistoryHook $head) -ne 0) {
throw "The history gate rejected the current reachable branch history."
"polluted change" | Set-Content -LiteralPath (Join-Path $historyRepository "polluted.txt")
& git -C $historyRepository add polluted.txt
& git -C $historyRepository commit --quiet -m "fix: add polluted change" -m "Co-authored-by: unauthorized identity"
if ($LASTEXITCODE -ne 0) { throw "Could not create the synthetic polluted commit." }
$pollutedHead = (& git -C $historyRepository rev-parse HEAD).Trim()
if ((Invoke-HistoryHook $historyRepository $cleanHead $pollutedHead) -eq 0) {
throw "The history gate accepted an introduced commit with a prohibited identity trailer."
}
$global:LASTEXITCODE = 0

Write-Output "Commit-message and reachable-history gate regression coverage passed."
Write-Output "Commit-message and introduced-history gate regression coverage passed."
}
finally {
if (Test-Path -LiteralPath $temporaryRoot) {
Expand Down
1 change: 1 addition & 0 deletions fixtures/Ef10/Ef10Fixture.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.0" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.21" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion fixtures/Ef10Design/Ef10DesignFixture.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.0" />
<!-- Design 10.0.0 copies Microsoft.Build.Tasks.Core 17.14.28, whose System.Security.Cryptography.Xml 9.0.0 dependency carries known advisories. Pin the patched release so the repository dependency audit stays honest. -->
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.12" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.13" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion fixtures/Ef10DesignPrivate/Ef10DesignPrivateFixture.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.0" />
<!-- Design 10.0.0 copies Microsoft.Build.Tasks.Core 17.14.28, whose System.Security.Cryptography.Xml 9.0.0 dependency carries known advisories. Pin the patched release so the repository dependency audit stays honest. -->
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.12" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.13" />
</ItemGroup>
</Project>
Loading