Require git provenance for Android Argus staging

This commit is contained in:
Курнат Андрей
2026-06-12 22:30:58 +03:00
parent 32f7c59bd4
commit 251391b1a9
4 changed files with 87 additions and 4 deletions
+79 -1
View File
@@ -9,8 +9,10 @@ param(
[string]$Notes,
[string]$RepositoryUrl = 'https://git.kusoft.xyz/sevenhill/QSfera.git',
[string]$HomepageUrl = 'https://qsfera.kusoft.xyz',
[string]$GitProvenanceRoot,
[switch]$Unlisted,
[switch]$SkipSigningInitialization
[switch]$SkipSigningInitialization,
[switch]$SkipGitProvenanceCheck
)
$ErrorActionPreference = 'Stop'
@@ -112,8 +114,83 @@ function Find-FirstTool([string]$AndroidHome, [string]$ToolName) {
return $tool.FullName
}
function Invoke-Git([string[]]$Arguments) {
$output = & git @Arguments 2>&1
if ($LASTEXITCODE -ne 0) {
throw "git $($Arguments -join ' ') failed with exit code $LASTEXITCODE. Output: $($output | Out-String)"
}
return @($output)
}
function Assert-GitReleaseProvenance([string]$RepositoryRoot) {
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
throw 'git was not found. Argus publication requires git provenance verification.'
}
$previousLocation = Get-Location
try {
Set-Location $RepositoryRoot
$insideWorkTree = (Invoke-Git @('rev-parse', '--is-inside-work-tree') | Select-Object -First 1).Trim()
if ($insideWorkTree -ne 'true') {
throw 'Argus publication must be prepared from inside a git work tree.'
}
$status = Invoke-Git @('status', '--porcelain')
if ($status.Count -gt 0) {
throw "Git work tree has uncommitted changes. Commit or stash all changes before preparing Argus publication."
}
$branch = (Invoke-Git @('rev-parse', '--abbrev-ref', 'HEAD') | Select-Object -First 1).Trim()
if ($branch -eq 'HEAD') {
throw 'Git HEAD is detached. Check out the release branch before preparing Argus publication.'
}
try {
$upstream = (Invoke-Git @('rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}') | Select-Object -First 1).Trim()
} catch {
throw "Git branch has no upstream. Push $branch and set its upstream before Argus publication."
}
Invoke-Git @('fetch', '--quiet')
$aheadBehind = (Invoke-Git @('rev-list', '--left-right', '--count', 'HEAD...@{u}') | Select-Object -First 1).Trim() -split '\s+'
$ahead = [int]$aheadBehind[0]
$behind = [int]$aheadBehind[1]
if ($ahead -ne 0 -or $behind -ne 0) {
throw "Git HEAD must match upstream before Argus publication. Branch $branch tracks $upstream, ahead=$ahead, behind=$behind."
}
return [ordered]@{
repositoryRoot = (Invoke-Git @('rev-parse', '--show-toplevel') | Select-Object -First 1).Trim()
branch = $branch
upstream = $upstream
commit = (Invoke-Git @('rev-parse', 'HEAD') | Select-Object -First 1).Trim()
verifiedAt = [DateTimeOffset]::UtcNow.ToString('O')
}
} finally {
Set-Location $previousLocation
}
}
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $repoRoot
$gitProvenanceRootPath = if ($GitProvenanceRoot) {
(Resolve-Path -LiteralPath $GitProvenanceRoot).Path
} else {
$repoRoot
}
$gitProvenance = if ($SkipGitProvenanceCheck) {
[ordered]@{
skipped = $true
repositoryRoot = $gitProvenanceRootPath
reason = 'SkipGitProvenanceCheck was set'
verifiedAt = [DateTimeOffset]::UtcNow.ToString('O')
}
} else {
Assert-GitReleaseProvenance $gitProvenanceRootPath
}
$javaHome = Resolve-JavaHome
$androidHome = Resolve-AndroidHome
@@ -251,6 +328,7 @@ $metadata = [ordered]@{
notes = if ($Notes) { $Notes } else { $null }
repositoryUrl = if ($RepositoryUrl) { $RepositoryUrl } else { $null }
homepageUrl = if ($HomepageUrl) { $HomepageUrl } else { $null }
git = $gitProvenance
androidPackageName = $packageName
androidVersionCode = [int]$versionCode
targetSdkVersion = [int]$targetSdk