-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpush-to-github.ps1
More file actions
148 lines (129 loc) · 6.1 KB
/
Copy pathpush-to-github.ps1
File metadata and controls
148 lines (129 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# AI-hint: Automates the MiOS release pipeline by cloning the bootstrap repo, overlaying staged changes, bumping the VERSION, updating CHANGELOG.md, and pushing to the main branch via GitHub.
# AI-doc: usr/share/doc/mios/manual/root.md
[CmdletBinding()]
param(
[string]$Version,
[string]$Message = 'release sync',
[string]$StagedDir,
[string]$Repo = 'github.com/mios-dev/MiOS-bootstrap',
[string]$Branch = 'main',
[switch]$DryRun
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Acknowledgment banner.
$_bannerPath = Join-Path -Path $PSScriptRoot -ChildPath 'automation/lib/agreements-banner.ps1'
if ($_bannerPath -and (Test-Path $_bannerPath)) {
. $_bannerPath; Invoke-MiOSAgreementBanner -Entry 'push-to-github.ps1'
}
Remove-Variable _bannerPath -ErrorAction SilentlyContinue
function Write-Step([string]$msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Write-Ok ([string]$msg) { Write-Host " $msg" -ForegroundColor Green }
function Write-Warn([string]$msg) { Write-Host " $msg" -ForegroundColor Yellow }
$repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
if (-not (Test-Path -LiteralPath (Join-Path $repoRoot 'VERSION'))) {
throw "push-to-github.ps1 must live at the repo root next to VERSION."
}
if (-not $Version) {
$Version = (Get-Content -LiteralPath (Join-Path $repoRoot 'VERSION') -Raw).Trim()
Write-Warn "No -Version given; using local VERSION file: $Version"
}
if ($StagedDir) {
if (-not (Test-Path -LiteralPath $StagedDir -PathType Container)) {
throw "Staged companion directory not found: $StagedDir"
}
$StagedDir = (Resolve-Path -LiteralPath $StagedDir).Path
}
# Token discovery never echoed to stdout.
$token = $env:GH_TOKEN
if (-not $token) { $token = $env:GITHUB_TOKEN }
if (-not $token) {
Write-Warn 'No GH_TOKEN/GITHUB_TOKEN in environment; relying on git credential helper.'
}
$workDir = Join-Path ([System.IO.Path]::GetTempPath()) ("mios-push-" + [guid]::NewGuid().ToString('N').Substring(0,8))
Write-Step "Working directory: $workDir"
New-Item -ItemType Directory -Force -Path $workDir | Out-Null
try {
$cloneUrl = if ($token) { "https://x-access-token:$token@$Repo.git" } else { "https://$Repo.git" }
$safeUrl = "https://$Repo.git"
Write-Step "Cloning $safeUrl ($Branch) full history."
git clone --branch $Branch $cloneUrl $workDir 2>&1 | ForEach-Object { Write-Verbose $_ }
if ($LASTEXITCODE -ne 0) { throw "git clone failed (exit $LASTEXITCODE)." }
if ($StagedDir) {
Write-Step "Overlaying staged files from $StagedDir"
$stagedFiles = Get-ChildItem -LiteralPath $StagedDir -Recurse -File
foreach ($f in $stagedFiles) {
$rel = $f.FullName.Substring($StagedDir.Length).TrimStart('\','/')
$dst = Join-Path $workDir $rel
$dstDir = Split-Path -Parent $dst
if (-not (Test-Path -LiteralPath $dstDir)) {
New-Item -ItemType Directory -Force -Path $dstDir | Out-Null
}
Copy-Item -LiteralPath $f.FullName -Destination $dst -Force
Write-Ok "copied $rel"
}
} else {
Write-Step "No -StagedDir; pushing local working tree state under $repoRoot"
# Mirror the working repo into the clone (excluding .git).
$rsyncSrc = (Resolve-Path -LiteralPath $repoRoot).Path
Get-ChildItem -LiteralPath $rsyncSrc -Force -Recurse -File |
Where-Object { $_.FullName -notlike (Join-Path $rsyncSrc '.git*') } |
ForEach-Object {
$rel = $_.FullName.Substring($rsyncSrc.Length).TrimStart('\','/')
if ($rel -like '.git\*' -or $rel -eq '.git') { return }
$dst = Join-Path $workDir $rel
$dstDir = Split-Path -Parent $dst
if (-not (Test-Path -LiteralPath $dstDir)) {
New-Item -ItemType Directory -Force -Path $dstDir | Out-Null
}
Copy-Item -LiteralPath $_.FullName -Destination $dst -Force
}
}
Write-Step "Bumping VERSION $Version"
Set-Content -LiteralPath (Join-Path $workDir 'VERSION') -Value $Version -NoNewline -Encoding utf8
$changelog = Join-Path $workDir 'CHANGELOG.md'
if (Test-Path -LiteralPath $changelog) {
$today = Get-Date -Format 'yyyy-MM-dd'
$existing = Get-Content -LiteralPath $changelog -Raw
$header = "# Changelog`r`nAll notable changes to this project will be documented in this file.`r`n"
$body = $existing
if ($body.StartsWith($header)) { $body = $body.Substring($header.Length).TrimStart() }
$newBlock = "## [v$Version] - $today`r`n`r`n- $Message`r`n`r`n"
Set-Content -LiteralPath $changelog -Value ($header + "`r`n" + $newBlock + $body) -Encoding utf8
Write-Ok "CHANGELOG.md stamped v$Version ($today)"
} else {
Write-Warn "CHANGELOG.md missing in clone skipping changelog stamp."
}
Push-Location $workDir
try {
git add --all 2>&1 | ForEach-Object { Write-Verbose $_ }
$status = git status --porcelain
if (-not $status) {
Write-Warn 'No changes to commit. Nothing to push.'
return
}
$commitMsg = "release: v$Version $Message"
if ($DryRun) {
Write-Step "DRY RUN skipping commit/push. Pending changes:"
Write-Host $status
return
}
git -c user.name='MiOS bot' -c user.email='mios@users.noreply.github.com' `
commit -m $commitMsg 2>&1 | ForEach-Object { Write-Verbose $_ }
if ($LASTEXITCODE -ne 0) { throw "git commit failed (exit $LASTEXITCODE)." }
$sha = (git rev-parse HEAD).Trim()
Write-Step "Pushing to $Branch"
git push origin $Branch 2>&1 | ForEach-Object { Write-Verbose $_ }
if ($LASTEXITCODE -ne 0) { throw "git push failed (exit $LASTEXITCODE)." }
Write-Ok "Commit: $sha"
Write-Ok "GHCR tag (built by CI): ghcr.io/mios-dev/mios:$Version"
}
finally {
Pop-Location
}
}
finally {
if (Test-Path -LiteralPath $workDir) {
Remove-Item -LiteralPath $workDir -Recurse -Force -ErrorAction SilentlyContinue
}
}