The label id was hardcoded (failedLabel = 1), so deleting/recreating the
label in x9/xetup-runs (new id) would make issue creation drop the label or
fail. Look the id up by name at runtime; on any lookup failure (network,
auth, decode, or label absent) file the issue unlabeled rather than not at
all. Verified end-to-end: label resolved and attached via lookup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
buildHTML ran before zipLog, so the email footer always claimed
"log v priloze (<host>-Deploy.log.zip)" even when the log was unreadable
and no attachment was added. Zip the log first and pass the attachment
name into buildHTML; footer now names the zip only when present, otherwise
points solely to the local copy. Covered by TestBuildHTMLFooterMatchesAttachment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On any ERROR step, xetup now files an issue in the private x9/xetup-runs
tracker (title "FAILED <host> - <version> - <date>", label "failed", body =
step table + tail-capped Deploy.log) via the xetup-bot write:issue token,
baked in through -ldflags. Best-effort and non-blocking; successful runs stay
silent and the email is the fallback.
The deployment email now attaches the zipped Deploy.log and links to this
run's issue plus the run history filtered to this machine.
- internal/buildinfo: ldflags-injected Version + RunsToken
- internal/runreport: issue filing, retries, tail-capped log
- internal/report: multipart/mixed with zip attachment, tracker links;
buildMessage split out and covered by report_test.go
- release.yml: inject Version (tag/SHA) + FORGEJO_RUNS_TOKEN via ldflags
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add three GUI feature toggles to the bloatware step:
- standardBloatware (default on) - the bulk AppX/capability/feature list
- removeNewOutlook (default on) - new Outlook for Windows (Microsoft.OutlookForWindows)
- removeSnippingTool (default OFF) - Snipping Tool across all three lists
Each toggle is independent via Test-RemovalAllowed in 01-bloatware.ps1.
Snipping Tool (ScreenSketch + legacy capability/feature) is now kept by
default as a common productivity tool, like Calculator. Classic Outlook from
M365 is a Win32 app and was never touched; only the bundled new Outlook is.
Also fix a latent bug: the Go Config struct had no Bloatware field, so the
GUI's runtime-config regeneration silently dropped bloatware.keepPackages.
Added the field so the keep-list survives to the script.
Docs: SPEC.md, CHANGELOG.md, web/data/descriptions.json, web/spec/index.html.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Critical fixes:
- Fix resume mode: StepsByIDs returned Enabled=false, all resume steps
would be SKIPPED (deployment could never resume after reboot)
- Add reboot loop protection: per-step retry counter (max 5) prevents
infinite reboot cycles when a step always exits with code 9
- Block reboot when state.Save() fails in resumePhase (prevents state
loss leading to full restart from scratch)
- Atomic state file write (write-to-tmp + rename) prevents JSON
corruption on BSOD/power loss mid-write
- Script watchdog: kills scripts after 30 min of no output (resets on
each line, so active long-running scripts are never killed)
- Fix copyFile: check Close() error explicitly instead of deferred
close that silently drops flush errors (e.g. disk full)
High severity:
- Cleanup() now logs errors instead of silently ignoring them
- Email report: 3 retries with backoff + always saves C:\X9\report.html
- Winget parallel jobs: 10 min timeout, kill hung jobs
- UCPD stop verification: 2s wait + state check before PDF association
- Atera installer: /qn -> /qb so MFA window can appear
- GVLK activation: match by EditionID (registry, not localized) instead
of fragile OS caption string matching
Medium severity:
- Default profile hive unload: retry loop (5 attempts, increasing delay)
- LayoutModification.xml: UTF-8 without BOM (PS 5.1 Set-Content adds BOM)
- Set-Reg SYSTEM task: try/finally ensures temp file + task cleanup
- Windows Update: @($available).Count for PS 5.1 single-result edge case
- config.json: add missing kmsServer field in activation section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Atera agent: download URL requires MFA in browser session, so
Invoke-WebRequest gets HTML instead of MSI. Changed to bundled
MSI from assets/Atera/ - download once from dashboard, no network
dependency. Graceful skip with log message when MSI not present.
Removed unused --resume argument from X9-Resume scheduled task
registration. Resume is detected via state file, not CLI flag.
CI pipeline: added mingw-w64-gcc and CGO_ENABLED=1 for Walk
cross-compilation (required since Walk migration from Fyne).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Email report: HTML summary sent via SMTP2Go (mail-eu.smtp2go.com)
at the end of every deployment. Subject "xetup report HOSTNAME",
body contains per-step status table with timestamps. Non-blocking
(goroutine) so it doesn't delay the summary screen.
Pre-flight checks: admin rights, winget availability, network
connectivity (DNS resolve), and disk space verified before the
config form. Results shown as colored status lines at the top
of the GUI - red warnings tell the technician what's wrong
before starting a 30-minute deployment.
Parallel winget: 02-software.ps1 now launches all winget installs
as background jobs (Start-Job) and waits for all to complete.
7-Zip, Acrobat, OpenVPN run simultaneously instead of sequentially,
saving 3-5 minutes per deployment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause fix: runner.go passed config as unevaluated PS expression
via -File mode - scripts received a literal string instead of parsed
object. Changed to -ConfigPath; scripts load JSON themselves via
shared common.ps1 (Write-Log, Get-Feature, Load-Config).
GUI now regenerates runtime config before run so user selections
actually reach the scripts.
Merged 04-default-profile + 05-personalization into single script
(one hive load/unload, no Explorer restart, no hive contention).
Deleted Deploy-Windows.ps1 (xetup.exe is sole entry point),
06-scheduled-tasks.ps1 (tasks caused more harm than good),
07-desktop-info.ps1 (replaced by BackInfo long ago).
Step ordering: activation moved early, pcIdentity before WU
(exit 9 on rename only when rename actually happened).
Edge policies split into mandatory (telemetry, first-run) vs
recommended (UI preferences user can override).
Atera install uses Start-Process -Wait instead of fragile sleep.
Updated config.json, tests, DefaultConfig to match current state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
xetup.exe now acts as an orchestrator across system reboots:
- PS scripts exit 9 to signal "reboot needed, re-run me" (WU) or
"done but reboot needed to finalize" (Dell BIOS)
- On exit 9: xetup saves state.json, ensures adminx9 account,
copies itself to stable path, enables autologon, registers
X9-Resume scheduled task (AtLogOn adminx9, RunLevel Highest)
- On resume: loads pending steps from state, continues seamlessly
with "Pokracuji po restartu..." label in the run window
- On completion: disables autologon, removes X9-Resume task,
deletes state file, shows summary with accumulated results
across all reboot rounds
New packages: internal/state, internal/prereboot
Script 12: simplified to exit 0 (done) or exit 9 (reboot needed)
Script 11: exit 9 when DCU exit code 1 (BIOS staged, reboot needed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Steps pcIdentity and network had swapped Num+ScriptName values
and were listed after 11/12 instead of before them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 04-default-profile: default profile now pins Explorer+Edge (was empty),
preventing MS Store and other defaults from appearing in taskbar
- 03-system-registry: disable Edge new tab page quick links, background,
content feed (NewTabPageQuickLinksEnabled/BackgroundEnabled/AllowedBackgroundTypes)
- 05-personalization: set Wallpaper="" in default hive so new user accounts
get solid-color background instead of black fallback
- runner: add onStepStart callback, fires before each script launch
- gui: step progress strip in run phase — color-coded labels per step
(pending gray · / running blue ► / ok green ✓ / error red ✗ / skipped gray –)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Walk uses Win32 controls directly — works on VMware ESXi, Hyper-V and any VM
without GPU. No CGo, no MinGW needed.
- internal/gui/gui.go: 3-phase Walk declarative GUI (form → live run → summary)
- cmd/xetup/app.manifest: UAC requireAdministrator + ComCtl32 v6 + DPI awareness
- CI: remove MinGW, add rsrc generation step, simplified build