Process 1 build 0203261608
This commit is contained in:
@@ -1 +1 @@
|
||||
0203261511
|
||||
0203261608
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
BUILD_NUMBER = "0203261511"
|
||||
BUILD_NUMBER = "0203261608"
|
||||
CHANGELOG = '2026-01-22\\n- Initial commit\\n- Ignore build artifacts\\n- Update README\\n- Update README with Docker-first guide\\n\\n2026-01-23\\n- Fix cache titles via Seerr media lookup\\n- Split search actions and improve download options\\n- Fallback manual grab to qBittorrent\\n- Hide header actions when signed out\\n- Add feedback form and webhook\\n- Fix cache titles and move feedback link\\n- Show available status on landing when in Jellyfin\\n- Add default branding assets when missing\\n- Use bundled branding assets\\n- Remove password fields from users page\\n- Add Docker Hub compose override\\n- Fix backend Dockerfile paths for root context\\n- Copy public assets into frontend image\\n- Use backend branding assets for logo and favicon\\n\\n2026-01-24\\n- Route grabs through Sonarr/Radarr only\\n- Document fix buttons in how-it-works\\n- Clarify how-it-works steps and fixes\\n- Map Prowlarr releases to Arr indexers for manual grab\\n- Improve request handling and qBittorrent categories\\n\\n2026-01-25\\n- Add site banner, build number, and changelog\\n- Automate build number tagging and sync\\n- Improve mobile header layout\\n- Move account actions into avatar menu\\n- Add user stats and activity tracking\\n- Add Jellyfin login cache and admin-only stats\\n- Tidy request sync controls\\n- Seed branding logo from bundled assets\\n- Serve bundled branding assets by default\\n- Harden request cache titles and cache-only reads\\n- Build 2501262041\\n\\n2026-01-26\\n- Fix cache title hydration\\n- Fix sync progress bar animation\\n\\n2026-01-27\\n- Add cache control artwork stats\\n- Improve cache stats performance (build 271261145)\\n- Fix backend cache stats import (build 271261149)\\n- Clarify request sync settings (build 271261159)\\n- Bump build number to 271261202\\n- Fix request titles in snapshots (build 271261219)\\n- Fix snapshot title fallback (build 271261228)\\n- Add cache load spinner (build 271261238)\\n- Bump build number (process 2) 271261322\\n- Add service test buttons (build 271261335)\\n- Fallback to TMDB when artwork cache fails (build 271261524)\\n- Hydrate missing artwork from Seerr (build 271261539)\\n\\n2026-01-29\\n- release: 2901262036\\n- release: 2901262044\\n- release: 2901262102\\n- Hardcode build number in backend\\n- Bake build number and changelog\\n- Update full changelog\\n- Tidy full changelog\\n- Build 2901262240: cache users\n\n2026-01-30\n- Merge backend and frontend into one container'
|
||||
|
||||
|
||||
|
||||
@@ -1613,11 +1613,11 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
>
|
||||
{status && <div className="error-banner">{status}</div>}
|
||||
{settingsSections.length > 0 ? (
|
||||
<div className="admin-form">
|
||||
<div className="admin-form admin-zone-stack">
|
||||
{settingsSections
|
||||
.filter(shouldRenderSection)
|
||||
.map((sectionGroup) => (
|
||||
<section key={sectionGroup.key} className="admin-section">
|
||||
<section key={sectionGroup.key} className="admin-section admin-zone">
|
||||
<div className="section-header">
|
||||
<h2>
|
||||
{sectionGroup.key === 'requests' ? 'Request sync controls' : sectionGroup.title}
|
||||
@@ -2228,6 +2228,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
className="settings-action-button"
|
||||
onClick={() => void saveSettingGroup(sectionGroup)}
|
||||
disabled={sectionSaving[sectionGroup.key] || sectionTesting[sectionGroup.key]}
|
||||
>
|
||||
@@ -2236,7 +2237,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
{getSectionTestLabel(sectionGroup.key) ? (
|
||||
<button
|
||||
type="button"
|
||||
className="ghost-button"
|
||||
className="ghost-button settings-action-button"
|
||||
onClick={() => void testSettingGroup(sectionGroup)}
|
||||
disabled={sectionSaving[sectionGroup.key] || sectionTesting[sectionGroup.key]}
|
||||
>
|
||||
@@ -2257,7 +2258,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
</div>
|
||||
)}
|
||||
{showLogs && (
|
||||
<section className="admin-section" id="logs">
|
||||
<section className="admin-section admin-zone" id="logs">
|
||||
<div className="section-header">
|
||||
<h2>Activity log</h2>
|
||||
<div className="log-actions">
|
||||
@@ -2283,7 +2284,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
</section>
|
||||
)}
|
||||
{showCacheExtras && (
|
||||
<section className="admin-section" id="cache">
|
||||
<section className="admin-section admin-zone" id="cache">
|
||||
<div className="section-header">
|
||||
<h2>Saved requests (cache)</h2>
|
||||
</div>
|
||||
@@ -2312,7 +2313,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
</section>
|
||||
)}
|
||||
{showMaintenance && (
|
||||
<section className="admin-section" id="maintenance">
|
||||
<section className="admin-section admin-zone" id="maintenance">
|
||||
<div className="section-header">
|
||||
<h2>Maintenance</h2>
|
||||
</div>
|
||||
@@ -2379,7 +2380,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
||||
</section>
|
||||
)}
|
||||
{showRequestsExtras && (
|
||||
<section className="admin-section" id="schedules">
|
||||
<section className="admin-section admin-zone" id="schedules">
|
||||
<div className="section-header">
|
||||
<h2>Scheduled tasks</h2>
|
||||
</div>
|
||||
|
||||
@@ -1545,6 +1545,13 @@ button span {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.settings-section-actions .settings-action-button {
|
||||
width: 190px;
|
||||
min-width: 190px;
|
||||
flex: 0 0 190px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.settings-inline-field {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
@@ -6214,6 +6221,12 @@ textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settings-section-actions .settings-action-button {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
.sync-meta,
|
||||
.diagnostic-card-top,
|
||||
.diagnostics-category-header,
|
||||
@@ -6233,3 +6246,166 @@ textarea {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
/* Final admin shell + settings section cleanup */
|
||||
.admin-shell,
|
||||
.admin-shell-nav,
|
||||
.admin-card,
|
||||
.admin-shell-rail,
|
||||
.admin-sidebar,
|
||||
.admin-panel {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.admin-shell {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
|
||||
grid-template-areas: "nav main";
|
||||
gap: 22px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.admin-shell.admin-shell--with-rail {
|
||||
grid-template-columns: minmax(220px, 260px) minmax(0, 1fr) minmax(300px, 380px);
|
||||
grid-template-areas: "nav main rail";
|
||||
}
|
||||
|
||||
.admin-shell-nav {
|
||||
grid-area: nav;
|
||||
}
|
||||
|
||||
.admin-card {
|
||||
grid-area: main;
|
||||
}
|
||||
|
||||
.admin-shell-rail {
|
||||
grid-area: rail;
|
||||
position: sticky;
|
||||
top: 20px;
|
||||
align-self: start;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.admin-zone-stack {
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.admin-zone {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.015)),
|
||||
rgba(255, 255, 255, 0.012);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.025);
|
||||
}
|
||||
|
||||
[data-theme='light'] .admin-zone {
|
||||
border-color: rgba(17, 19, 24, 0.08);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(255, 255, 255, 0.72)),
|
||||
rgba(17, 19, 24, 0.018);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.admin-zone .section-header {
|
||||
align-items: flex-start;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
[data-theme='light'] .admin-zone .section-header {
|
||||
border-bottom-color: rgba(17, 19, 24, 0.08);
|
||||
}
|
||||
|
||||
.admin-zone .section-header h2 {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.admin-zone .section-header h2::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 52px;
|
||||
height: 2px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, var(--accent-2), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
.admin-zone .section-subtitle {
|
||||
margin-top: -4px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.admin-shell {
|
||||
grid-template-columns: minmax(220px, 250px) minmax(0, 1fr);
|
||||
grid-template-areas: "nav main";
|
||||
}
|
||||
|
||||
.admin-shell.admin-shell--with-rail {
|
||||
grid-template-areas:
|
||||
"nav main"
|
||||
"nav rail";
|
||||
}
|
||||
|
||||
.admin-shell-rail {
|
||||
position: static;
|
||||
top: auto;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.admin-shell,
|
||||
.admin-shell.admin-shell--with-rail {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.admin-shell {
|
||||
grid-template-areas:
|
||||
"nav"
|
||||
"main";
|
||||
}
|
||||
|
||||
.admin-shell.admin-shell--with-rail {
|
||||
grid-template-areas:
|
||||
"nav"
|
||||
"main"
|
||||
"rail";
|
||||
}
|
||||
|
||||
.admin-shell-nav,
|
||||
.admin-card,
|
||||
.admin-shell-rail {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.admin-shell-nav {
|
||||
position: static;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
.admin-grid,
|
||||
.users-page-toolbar-grid,
|
||||
.users-summary-grid,
|
||||
.users-page-overview-grid,
|
||||
.maintenance-action-grid,
|
||||
.schedule-grid,
|
||||
.diagnostics-inline-summary,
|
||||
.diagnostics-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.admin-zone {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ type AdminShellProps = {
|
||||
}
|
||||
|
||||
export default function AdminShell({ title, subtitle, actions, rail, children }: AdminShellProps) {
|
||||
const hasRail = Boolean(rail)
|
||||
|
||||
return (
|
||||
<div className="admin-shell">
|
||||
<div className={`admin-shell ${hasRail ? 'admin-shell--with-rail' : 'admin-shell--no-rail'}`}>
|
||||
<aside className="admin-shell-nav">
|
||||
<AdminSidebar />
|
||||
</aside>
|
||||
@@ -27,16 +29,7 @@ export default function AdminShell({ title, subtitle, actions, rail, children }:
|
||||
</div>
|
||||
{children}
|
||||
</main>
|
||||
<aside className="admin-shell-rail">
|
||||
{rail ?? (
|
||||
<div className="admin-rail-card admin-rail-card--placeholder">
|
||||
<span className="admin-rail-eyebrow">Insights</span>
|
||||
<h2>Stats rail</h2>
|
||||
<p>Use this column for counters, live status, and quick metrics for this page.</p>
|
||||
<span className="small-pill">{title}</span>
|
||||
</div>
|
||||
)}
|
||||
</aside>
|
||||
{hasRail ? <aside className="admin-shell-rail">{rail}</aside> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ $repoRoot = Resolve-Path "$PSScriptRoot\\.."
|
||||
Set-Location $repoRoot
|
||||
|
||||
$now = Get-Date
|
||||
$buildNumber = "{0}{1}{2}{3}{4}" -f $now.ToString("dd"), $now.ToString("M"), $now.ToString("yy"), $now.ToString("HH"), $now.ToString("mm")
|
||||
$buildNumber = "{0}{1}{2}{3}{4}" -f $now.ToString("dd"), $now.ToString("MM"), $now.ToString("yy"), $now.ToString("HH"), $now.ToString("mm")
|
||||
|
||||
Write-Host "Build number: $buildNumber"
|
||||
|
||||
|
||||
275
scripts/process1.ps1
Normal file
275
scripts/process1.ps1
Normal file
@@ -0,0 +1,275 @@
|
||||
param(
|
||||
[string]$CommitMessage,
|
||||
[switch]$SkipCommit,
|
||||
[switch]$SkipDiscord
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Resolve-Path "$PSScriptRoot\.."
|
||||
Set-Location $repoRoot
|
||||
|
||||
$Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||||
$script:CurrentStep = "initializing"
|
||||
|
||||
function Write-TextFile {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Path,
|
||||
[Parameter(Mandatory = $true)][string]$Content
|
||||
)
|
||||
|
||||
$fullPath = Join-Path $repoRoot $Path
|
||||
$normalized = $Content -replace "`r`n", "`n"
|
||||
[System.IO.File]::WriteAllText($fullPath, $normalized, $Utf8NoBom)
|
||||
}
|
||||
|
||||
function Read-TextFile {
|
||||
param([Parameter(Mandatory = $true)][string]$Path)
|
||||
|
||||
$fullPath = Join-Path $repoRoot $Path
|
||||
return [System.IO.File]::ReadAllText($fullPath)
|
||||
}
|
||||
|
||||
function Get-EnvFileValue {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Path,
|
||||
[Parameter(Mandatory = $true)][string]$Name
|
||||
)
|
||||
|
||||
if (-not (Test-Path $Path)) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$match = Select-String -Path $Path -Pattern "^$([regex]::Escape($Name))=(.*)$" | Select-Object -First 1
|
||||
if (-not $match) {
|
||||
return $null
|
||||
}
|
||||
|
||||
return $match.Matches[0].Groups[1].Value.Trim()
|
||||
}
|
||||
|
||||
function Get-DiscordWebhookUrl {
|
||||
$candidateNames = @(
|
||||
"PROCESS_DISCORD_WEBHOOK_URL",
|
||||
"MAGENT_NOTIFY_DISCORD_WEBHOOK_URL",
|
||||
"DISCORD_WEBHOOK_URL"
|
||||
)
|
||||
|
||||
foreach ($name in $candidateNames) {
|
||||
$value = [System.Environment]::GetEnvironmentVariable($name)
|
||||
if (-not [string]::IsNullOrWhiteSpace($value)) {
|
||||
return $value.Trim()
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($name in $candidateNames) {
|
||||
$value = Get-EnvFileValue -Path ".env" -Name $name
|
||||
if (-not [string]::IsNullOrWhiteSpace($value)) {
|
||||
return $value.Trim()
|
||||
}
|
||||
}
|
||||
|
||||
$configPath = Join-Path $repoRoot "backend/app/config.py"
|
||||
if (Test-Path $configPath) {
|
||||
$configContent = Read-TextFile -Path "backend/app/config.py"
|
||||
$match = [regex]::Match(
|
||||
$configContent,
|
||||
'discord_webhook_url:\s*Optional\[str\]\s*=\s*Field\(\s*default="([^"]+)"',
|
||||
[System.Text.RegularExpressions.RegexOptions]::Singleline
|
||||
)
|
||||
if ($match.Success) {
|
||||
return $match.Groups[1].Value.Trim()
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function Send-DiscordUpdate {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Title,
|
||||
[Parameter(Mandatory = $true)][string]$Body
|
||||
)
|
||||
|
||||
if ($SkipDiscord) {
|
||||
Write-Host "Skipping Discord notification."
|
||||
return
|
||||
}
|
||||
|
||||
$webhookUrl = Get-DiscordWebhookUrl
|
||||
if ([string]::IsNullOrWhiteSpace($webhookUrl)) {
|
||||
Write-Warning "Discord webhook not configured for Process 1."
|
||||
return
|
||||
}
|
||||
|
||||
$content = "**$Title**`n$Body"
|
||||
Invoke-RestMethod -Method Post -Uri $webhookUrl -ContentType "application/json" -Body (@{ content = $content } | ConvertTo-Json -Compress) | Out-Null
|
||||
}
|
||||
|
||||
function Get-BuildNumber {
|
||||
$current = ""
|
||||
if (Test-Path ".build_number") {
|
||||
$current = (Get-Content ".build_number" -Raw).Trim()
|
||||
}
|
||||
|
||||
$candidate = Get-Date
|
||||
$buildNumber = $candidate.ToString("ddMMyyHHmm")
|
||||
if ($buildNumber -eq $current) {
|
||||
$buildNumber = $candidate.AddMinutes(1).ToString("ddMMyyHHmm")
|
||||
}
|
||||
|
||||
return $buildNumber
|
||||
}
|
||||
|
||||
function Wait-ForHttp {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Url,
|
||||
[int]$Attempts = 30,
|
||||
[int]$DelaySeconds = 2
|
||||
)
|
||||
|
||||
$lastError = $null
|
||||
for ($attempt = 1; $attempt -le $Attempts; $attempt++) {
|
||||
try {
|
||||
return Invoke-RestMethod -Uri $Url -TimeoutSec 10
|
||||
} catch {
|
||||
$lastError = $_
|
||||
Start-Sleep -Seconds $DelaySeconds
|
||||
}
|
||||
}
|
||||
|
||||
throw $lastError
|
||||
}
|
||||
|
||||
function Update-BuildFiles {
|
||||
param([Parameter(Mandatory = $true)][string]$BuildNumber)
|
||||
|
||||
Write-TextFile -Path ".build_number" -Content "$BuildNumber`n"
|
||||
|
||||
$buildInfo = Read-TextFile -Path "backend/app/build_info.py"
|
||||
$updatedBuildInfo = [regex]::Replace(
|
||||
$buildInfo,
|
||||
'^BUILD_NUMBER = "\d+"$',
|
||||
"BUILD_NUMBER = `"$BuildNumber`"",
|
||||
[System.Text.RegularExpressions.RegexOptions]::Multiline
|
||||
)
|
||||
Write-TextFile -Path "backend/app/build_info.py" -Content $updatedBuildInfo
|
||||
|
||||
$envPath = Join-Path $repoRoot ".env"
|
||||
if (Test-Path $envPath) {
|
||||
$envContent = Read-TextFile -Path ".env"
|
||||
if ($envContent -match '^BUILD_NUMBER=.*$') {
|
||||
$updatedEnv = [regex]::Replace(
|
||||
$envContent,
|
||||
'^BUILD_NUMBER=.*$',
|
||||
"BUILD_NUMBER=$BuildNumber",
|
||||
[System.Text.RegularExpressions.RegexOptions]::Multiline
|
||||
)
|
||||
} else {
|
||||
$updatedEnv = "BUILD_NUMBER=$BuildNumber`n$envContent"
|
||||
}
|
||||
Write-TextFile -Path ".env" -Content $updatedEnv
|
||||
}
|
||||
|
||||
Push-Location frontend
|
||||
try {
|
||||
npm version $BuildNumber --no-git-tag-version --allow-same-version | Out-Null
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ChangedFilesSummary {
|
||||
$files = git diff --cached --name-only
|
||||
if (-not $files) {
|
||||
return "No staged files"
|
||||
}
|
||||
|
||||
$count = ($files | Measure-Object).Count
|
||||
$sample = $files | Select-Object -First 8
|
||||
$summary = ($sample -join ", ")
|
||||
if ($count -gt $sample.Count) {
|
||||
$summary = "$summary, +$($count - $sample.Count) more"
|
||||
}
|
||||
|
||||
return "$count files: $summary"
|
||||
}
|
||||
|
||||
$buildNumber = $null
|
||||
$branch = $null
|
||||
$commit = $null
|
||||
$publicInfo = $null
|
||||
$changedFiles = "No staged files"
|
||||
|
||||
try {
|
||||
$branch = (git rev-parse --abbrev-ref HEAD).Trim()
|
||||
$buildNumber = Get-BuildNumber
|
||||
Write-Host "Process 1 build number: $buildNumber"
|
||||
|
||||
$script:CurrentStep = "updating build metadata"
|
||||
Update-BuildFiles -BuildNumber $buildNumber
|
||||
|
||||
$script:CurrentStep = "rebuilding local docker stack"
|
||||
docker compose up -d --build
|
||||
|
||||
$script:CurrentStep = "verifying backend health"
|
||||
$health = Wait-ForHttp -Url "http://127.0.0.1:8000/health"
|
||||
if ($health.status -ne "ok") {
|
||||
throw "Health endpoint returned unexpected payload: $($health | ConvertTo-Json -Compress)"
|
||||
}
|
||||
|
||||
$script:CurrentStep = "verifying public build metadata"
|
||||
$publicInfo = Wait-ForHttp -Url "http://127.0.0.1:8000/site/public"
|
||||
if ($publicInfo.buildNumber -ne $buildNumber) {
|
||||
throw "Public build number mismatch. Expected $buildNumber but got $($publicInfo.buildNumber)."
|
||||
}
|
||||
|
||||
$script:CurrentStep = "committing changes"
|
||||
git add -A
|
||||
$changedFiles = Get-ChangedFilesSummary
|
||||
if ((git status --short).Trim()) {
|
||||
if (-not $SkipCommit) {
|
||||
if ([string]::IsNullOrWhiteSpace($CommitMessage)) {
|
||||
$CommitMessage = "Process 1 build $buildNumber"
|
||||
}
|
||||
git commit -m $CommitMessage
|
||||
}
|
||||
}
|
||||
|
||||
$commit = (git rev-parse --short HEAD).Trim()
|
||||
|
||||
$body = @(
|
||||
"Build: $buildNumber"
|
||||
"Branch: $branch"
|
||||
"Commit: $commit"
|
||||
"Health: ok"
|
||||
"Public build: $($publicInfo.buildNumber)"
|
||||
"Changes: $changedFiles"
|
||||
) -join "`n"
|
||||
Send-DiscordUpdate -Title "Process 1 complete" -Body $body
|
||||
|
||||
Write-Host "Process 1 completed successfully."
|
||||
} catch {
|
||||
$failureCommit = ""
|
||||
try {
|
||||
$failureCommit = (git rev-parse --short HEAD).Trim()
|
||||
} catch {
|
||||
$failureCommit = "unknown"
|
||||
}
|
||||
|
||||
$failureBody = @(
|
||||
"Build: $buildNumber"
|
||||
"Branch: $branch"
|
||||
"Commit: $failureCommit"
|
||||
"Step: $script:CurrentStep"
|
||||
"Error: $($_.Exception.Message)"
|
||||
) -join "`n"
|
||||
|
||||
try {
|
||||
Send-DiscordUpdate -Title "Process 1 failed" -Body $failureBody
|
||||
} catch {
|
||||
Write-Warning "Failed to send Discord failure notification: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
throw
|
||||
}
|
||||
Reference in New Issue
Block a user