test(M00): 强化仓库完整性门禁
This commit is contained in:
@@ -1,16 +1,164 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-workspace.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-line-endings.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-large-files.ps1
|
||||
|
||||
$status = & git status --short --untracked-files=all
|
||||
if ($status) {
|
||||
Write-Host "Current git status:"
|
||||
$status | ForEach-Object { Write-Host $_ }
|
||||
$expectedOrigin = "ssh://git@git.txyundm.cn:2222/panda/qipai.git"
|
||||
$requiredPaths = @(
|
||||
"V5.0.md",
|
||||
"V4.8.md",
|
||||
"setup.sh",
|
||||
"deploy/README.md",
|
||||
"deploy/VERSION",
|
||||
"docs/current-baseline.md",
|
||||
"docs/module-status.md",
|
||||
"docs/feature-status.md",
|
||||
"docs/workspace-status.md",
|
||||
"docs/reference-inventory.md",
|
||||
"docs/reference-redaction-log.md",
|
||||
"docs/repository-completeness.md",
|
||||
"scripts/dev/windows/check-workspace.ps1",
|
||||
"scripts/dev/windows/check-reference.ps1",
|
||||
"scripts/dev/windows/check-repo-completeness.ps1",
|
||||
"scripts/dev/windows/check-secrets.ps1",
|
||||
"scripts/dev/windows/check-large-files.ps1",
|
||||
"scripts/dev/windows/check-line-endings.ps1",
|
||||
"scripts/dev/wsl/check-env.sh",
|
||||
"scripts/dev/wsl/check-emqx.sh",
|
||||
"scripts/dev/wsl/start-emqx.sh",
|
||||
"scripts/dev/wsl/stop-emqx.sh",
|
||||
"scripts/dev/wsl/check-workspace.sh",
|
||||
"scripts/dev/wsl/prepare-test-copy.sh",
|
||||
"scripts/dev/wsl/verify-linux.sh",
|
||||
"scripts/dev/wsl/mqtt-smoke.sh",
|
||||
"scripts/dev/wsl/check-gitea-ssh.sh",
|
||||
"scripts/dev/wsl/check-api-domain.sh",
|
||||
"scripts/dev/wsl/cleanup-test-copy.sh"
|
||||
)
|
||||
|
||||
$forbiddenTrackedPatterns = @(
|
||||
'(^|/)\.env$',
|
||||
'(^|/)\.env\.(?!example$)',
|
||||
'\.(pem|key|p12|crt|csr)$',
|
||||
'(^|/)node_modules/',
|
||||
'(^|/)dist/',
|
||||
'(^|/)build/',
|
||||
'(^|/)coverage/',
|
||||
'(^|/)\.cache/',
|
||||
'(^|/)\.vite/',
|
||||
'(^|/)logs/',
|
||||
'\.log$',
|
||||
'(^|/)uploads/',
|
||||
'(^|/)backup/',
|
||||
'(^|/)backups/',
|
||||
'\.bak$',
|
||||
'\.dump$',
|
||||
'\.sql\.gz$',
|
||||
'^scripts/dev/wsl/mqtt-smoke\.env$'
|
||||
)
|
||||
|
||||
$allowedTrackedRegex = @(
|
||||
'^deploy/backup/'
|
||||
)
|
||||
|
||||
function Convert-ToRepoPath {
|
||||
param([string]$Path)
|
||||
return ($Path -replace '\\', '/').TrimStart('./')
|
||||
}
|
||||
|
||||
function Assert-GitTracked {
|
||||
param([string]$Path)
|
||||
& git -c core.quotePath=false ls-files --error-unmatch -- $Path *> $null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Required repository file is missing or untracked: $Path"
|
||||
}
|
||||
}
|
||||
|
||||
$origin = & git remote get-url origin
|
||||
if ($origin -ne $expectedOrigin) {
|
||||
throw "Invalid origin: $origin"
|
||||
}
|
||||
|
||||
$branch = & git branch --show-current
|
||||
if ($branch -ne "main") {
|
||||
throw "Branch must be main, actual: $branch"
|
||||
}
|
||||
|
||||
$aheadBehind = (& git rev-list --left-right --count main...origin/main).Trim()
|
||||
$aheadBehindParts = $aheadBehind -split '\s+'
|
||||
$ahead = [int]$aheadBehindParts[0]
|
||||
$behind = [int]$aheadBehindParts[1]
|
||||
if ($behind -gt 0) {
|
||||
throw "Local main is behind origin/main or diverged: $aheadBehind"
|
||||
}
|
||||
if ($ahead -gt 0) {
|
||||
Write-Host "INFO: local main is ahead of origin/main; push and verify remote after commit."
|
||||
}
|
||||
else {
|
||||
Write-Host "PASS: worktree has no pending changes."
|
||||
Write-Host "PASS: local main matches origin/main."
|
||||
}
|
||||
|
||||
Write-Host "PASS: repository completeness baseline check finished; review pending changes before commit."
|
||||
foreach ($path in $requiredPaths) {
|
||||
if (-not (Test-Path $path)) {
|
||||
throw "Required path does not exist: $path"
|
||||
}
|
||||
Assert-GitTracked $path
|
||||
}
|
||||
|
||||
$untracked = @(& git -c core.quotePath=false status --porcelain=v1 --untracked-files=all | Where-Object { $_.StartsWith("?? ") })
|
||||
if ($untracked.Count -gt 0) {
|
||||
$untracked | ForEach-Object { Write-Host "UNTRACKED: $_" }
|
||||
throw "Untracked files found. Track deliverables or add an explicit ignore rule."
|
||||
}
|
||||
|
||||
$nestedGitDirs = @(Get-ChildItem -Force -Directory -Recurse -Filter ".git" -ErrorAction SilentlyContinue | Where-Object {
|
||||
$_.FullName -ne (Join-Path (Get-Location).Path ".git")
|
||||
})
|
||||
if ($nestedGitDirs.Count -gt 0) {
|
||||
$nestedGitDirs | ForEach-Object { Write-Host "NESTED-GIT: $($_.FullName)" }
|
||||
throw "Nested Git directories found."
|
||||
}
|
||||
|
||||
$gitModules = @(& git -c core.quotePath=false ls-files -- ".gitmodules")
|
||||
if ($gitModules.Count -gt 0) {
|
||||
$gitModules | ForEach-Object { Write-Host "SUBMODULE-METADATA: $_" }
|
||||
throw "Submodule metadata is tracked; V5.0 requires a single repository."
|
||||
}
|
||||
|
||||
$tracked = @(& git -c core.quotePath=false ls-files)
|
||||
$forbiddenTracked = @()
|
||||
foreach ($file in $tracked) {
|
||||
$repoPath = Convert-ToRepoPath $file
|
||||
$isAllowed = $false
|
||||
foreach ($allowed in $allowedTrackedRegex) {
|
||||
if ($repoPath -match $allowed) {
|
||||
$isAllowed = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($isAllowed) {
|
||||
continue
|
||||
}
|
||||
|
||||
foreach ($pattern in $forbiddenTrackedPatterns) {
|
||||
if ($repoPath -match $pattern) {
|
||||
$forbiddenTracked += $repoPath
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($forbiddenTracked.Count -gt 0) {
|
||||
$forbiddenTracked | Sort-Object -Unique | ForEach-Object { Write-Host "FORBIDDEN-TRACKED: $_" }
|
||||
throw "Forbidden runtime, secret, dependency, build, backup, log, or upload files are tracked."
|
||||
}
|
||||
|
||||
& git diff --check
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-secrets.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-line-endings.ps1
|
||||
|
||||
$ignored = @(& git -c core.quotePath=false status --ignored --short --untracked-files=all | Where-Object { $_ -like "!! *" })
|
||||
if ($ignored.Count -gt 0) {
|
||||
Write-Host ("INFO: ignored local-only files present: {0}" -f $ignored.Count)
|
||||
}
|
||||
|
||||
Write-Host "PASS: repository completeness check passed."
|
||||
|
||||
@@ -4,6 +4,7 @@ $ErrorActionPreference = "Stop"
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-reference.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-line-endings.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-large-files.ps1
|
||||
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-repo-completeness.ps1
|
||||
|
||||
if (Test-Path "package.json") {
|
||||
npm run lint --if-present
|
||||
|
||||
Reference in New Issue
Block a user