Commit Graph

13 Commits

Author SHA1 Message Date
Simone bc894a8058 feat(sprint2): §2.1/2.2/2.3/2.5 — IP lock/lease, scheduled tasks, retention, versioned snapshot
§2.1 — IP race with capacity>1 (Invoke-CIJob.ps1)
  Phases 2-3b (clone+start+IP) now run inside a file-based exclusive mutex
  (F:\CI\State\vm-start.lock via FileShare.None). Only one job at a time is
  in the VM-start phase, preventing concurrent vmrun starts from racing for
  the same DHCP lease. After IP is confirmed unique it is written to an IP
  lease file (F:\CI\State\ip-leases\<IP>.lease). Lock is released immediately
  so build phases run fully in parallel. Lease released in finally block.
  Collision detection: if a lease file already exists for the detected IP,
  the job fails fast with a clear error rather than silently sharing a WinRM target.

§2.5 — Versioned snapshot (Invoke-CIJob.ps1 + runner/config.yaml)
  $SnapshotName now defaults to GITEA_CI_SNAPSHOT_NAME env var, falling back
  to 'BaseClean'. config.yaml documents the commented-out variable for snapshot
  refresh workflow (BaseClean_<yyyyMMdd> naming convention).

§2.3 — Artifact/log retention (scripts/Invoke-RetentionPolicy.ps1)
  Purges per-job subdirs under F:\CI\Artifacts and F:\CI\Logs older than
  RetentionDays (default 30). Switches to AggressiveRetentionDays (default 7)
  when F: free space drops below MinFreeGB (default 50 GB). Also removes stale
  IP lease files older than 12 hours (defensive cleanup for crashed jobs).
  SupportsShouldProcess (-WhatIf) for dry-run.

§2.2 — Scheduled task registration (scripts/Register-CIScheduledTasks.ps1)
  Registers two tasks under \CI\ task folder as SYSTEM/HighestPrivilege:
    CI-CleanupOrphans  — every 6h + AtStartup, -MaxAgeHours 4
    CI-RetentionPolicy — daily 03:00 (+30min random) + AtStartup (+15min random)
  Idempotent (-Force), SupportsShouldProcess (-WhatIf), validates script paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 18:36:38 +02:00
Simone 34b33c5011 fix(winrm-https): PS 5.1 Test-WSMan has no -SessionOption — remove from all call sites
Test-WSMan in Windows PowerShell 5.1 does not support -SessionOption (WSManSessionOption),
causing "Cannot find a parameter matching the name 'SessionOption'" at runtime.

Prepare-WinBuild2025.ps1:
  - Remove Test-WSMan connectivity check step entirely
  - Open New-PSSession directly (handles -SkipCACheck via PSSessionOption)
  - Wrap New-PSSession in try/catch with the same actionable error message
  - Remove $wsmOpt (WSManSessionOption) — no longer needed
  Wait-GuestWinRMReady: replace Test-WSMan probe with New-PSSession probe + Remove-PSSession

Wait-VMReady.ps1:
  - Remove $wsmOpt entirely
  - Replace Test-WSMan -UseSSL -SessionOption with Test-NetConnection -Port 5986
    (TCP open on 5986 = HTTPS listener up = VM ready; credentials not available here)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:58:57 +02:00
Simone 68cde01c9d security(sprint1): §1.1/1.3/1.4 — WinRM HTTPS/5986, SHA256 pinning infra, IP regex per-octet
§1.4 — Replace loose IP ValidatePattern with per-octet regex in 4 scripts
  (Invoke-CIJob, Invoke-RemoteBuild, Get-BuildArtifacts, Wait-VMReady)

§1.1 — Migrate all WinRM connections from HTTP/5985 to HTTPS/5986
  - Deploy post-install.ps1: remove AllowUnencrypted=true; self-signed cert + HTTPS listener
    already present; firewall rule restricted to 192.168.79.0/24
  - Setup-WinBuild2025.ps1: assert AllowUnencrypted=false
  - Prepare-WinBuild2025.ps1: preflight uses TCP/5986; Test-WSMan -UseSSL -Port 5986;
    New-PSSession -UseSSL -Port 5986; host AllowUnencrypted save/restore removed (not needed for HTTPS)
  - Invoke-RemoteBuild, Get-BuildArtifacts: New-PSSession -UseSSL -Port 5986 -Authentication Basic
  - Wait-VMReady: New-WSManSessionOption + Test-WSMan -Port 5986 -UseSSL
  - Validate-DeployState, Validate-SetupState: Invoke-Command -UseSSL -Port 5986,
    AllowUnencrypted check → false; AllowUnencrypted host-side removed from both
  - Docs: PLAN, README, ARCHITECTURE, BEST-PRACTICES, HOST-SETUP, WINDOWS-TEMPLATE-SETUP,
    LINUX-TEMPLATE-SETUP, TODO updated

§1.3 — SHA256 hash pinning infrastructure
  - Assert-Hash function + $script:Hashes hashtable added to Setup-WinBuild2025.ps1
  - Assert-Hash called after dotnet-install.ps1, python installer, vs_buildtools.exe downloads
  - Hashes initialized to '' (warn-skip); must be filled before next snapshot refresh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 14:46:41 +02:00
Simone ea882c99d7 fix(scripts): update TemplatePath to correct directory for WinBuild2025.vmx 2026-05-10 01:07:31 +02:00
Simone 3c4dd68282 fix(scripts): update default VMX path to WinBuild2025.vmx in Test-NsinnounpBuild.ps1 2026-05-10 01:02:20 +02:00
Simone d2b20284d1 fix: wait for vmware-vmx.exe release before deleteVM
After hard stop, vmware-vmx.exe briefly holds file locks causing
deleteVM to fail with "Insufficient permissions". Replace the fixed
3s sleep with a vmrun-list poll loop (up to 20s) that waits until
the VMX is no longer registered as running, then retry deleteVM up
to 3x with 0/3/6s backoff before falling back to directory removal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 00:53:32 +02:00
Simone e6d44dad06 test: enable -VerifyArtifact by default in Test-NsinnounpBuild.ps1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:47:30 +02:00
Simone 2f2aa2bd9c test: add Test-NsinnounpBuild.ps1 e2e smoke test script
Wraps Invoke-CIJob.ps1 with nsinnounp params, verifies artifact exists.
Optional -VerifyArtifact flag expands zip and checks for expected
DLL/EXE names. Supports -Commit for pinned SHA testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:46:27 +02:00
Simone cc9e5f3969 fix: shallow clone + unshallow fallback for specific commit checkout
Previous fix removed --depth 1 entirely when $Commit was set, causing
full clones on every workflow run (github.sha is always non-empty).

Better approach: keep --depth 1 (fast path), detect checkout failure,
then fetch --unshallow and retry. Only pays full-clone cost when the
requested commit is actually older than HEAD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:45:27 +02:00
Simone f373c0c24b fix: apply all FIX-TODO items (P0/P1/P2)
P0 bugs:
- Invoke-CIJob.ps1: skip --depth 1 when $Commit specified (shallow clone
  + checkout specific commit was silently failing)
- Get-BuildArtifacts.ps1: check .Length -eq 0 not rounded sizeKB (false
  fail on artifacts smaller than 50 bytes)
- build-nsis.yml: upgrade upload-artifact v3 -> v4 (v3 deprecated)

P0 security:
- Remove hardcoded default password CIBuild!ChangeMe2026 from all scripts,
  README, TODO; prompt Read-Host -AsSecureString at runtime instead
- Setup-TemplateVM.ps1: replace `net user $u $p /add` (password in argv /
  audit log 4688) with New-LocalUser + local ConvertTo-SecureString
- Prepare-TemplateSetup.ps1: save and restore WSMan AllowUnencrypted +
  TrustedHosts in finally block (was permanently mutating host WinRM config)
- Setup-TemplateVM.ps1: remove duplicate MaxMemoryPerShellMB (winrm set
  + Set-Item both setting same value)

P1 doc (stale Host-Only / VMnet11 era):
- Setup-TemplateVM.ps1: rewrite NETWORK REQUIREMENT block + final steps
  (system uses VMnet8 NAT permanently, not VMnet11 Host-Only)
- Invoke-CIJob.ps1 Phase 1 comment: correct network model
- ARCHITECTURE.md: remove Git from toolchain list (not installed); clarify
  zip-transfer rationale (no PAT in VM, not network isolation)
- BEST-PRACTICES.md: rewrite Step 8 as NAT topology verification

P1 minor:
- Invoke-RemoteBuild.ps1: remove wasted first New-Item (created then
  immediately removed and recreated)
- Wait-VMReady.ps1: remove unused $elapsed; simplify try/catch around
  native command (exit codes don't throw)
- Install-Runner.ps1: add deprecation notice pointing to Setup-Host.ps1

P2 operational:
- Add scripts/Cleanup-OrphanedBuildVMs.ps1 with -WhatIf support
- Get-BuildArtifacts.ps1 -IncludeLogs: add -Recurse (msbuild logs in subdir)
- Add gitea/workflows/lint.yml (PSScriptAnalyzer on .ps1 push/PR)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:39:52 +02:00
Simone 97a852c9f3 fix: use Start-Transcript -Append to allow nested transcript in VS Code session 2026-05-08 23:59:51 +02:00
Simone b64d6c2c5d feat: stream build output in real-time + log capture and retention
Invoke-RemoteBuild.ps1:
- Custom build command: replace buffered collect-then-print with
  Write-Host streaming inside Invoke-Command (WinRM forwards Write-Host
  in real-time to the host console)
- Set PYTHONUNBUFFERED=1 in the remote session to prevent Python from
  holding lines in its internal buffer
- Same streaming approach for dotnet restore and dotnet build paths
- Return value is now just int exit code instead of hashtable

Invoke-CIJob.ps1:
- Add -LogDir parameter (default F:\CI\Logs)
- Add -LogRetentionDays parameter (default 30)
- Start-Transcript at job start -> F:\CI\Logs\<JobId>\invoke-ci.log
- Stop-Transcript in finally block (guaranteed execution)
- Auto-purge log directories older than LogRetentionDays after each job
2026-05-08 23:56:10 +02:00
Simone dd238121b3 chore: initial commit local CI/CD system (e2e verified, production-ready)
Sistema CI locale basato su VMware Workstation + Gitea Actions + act_runner.
Testato e2e con nsis-plugin-nsinnounp (MSBuild + Python, 4 configurazioni parallele).

- scripts/: Invoke-CIJob, Invoke-RemoteBuild, New/Remove-BuildVM, Wait-VMReady, Get-BuildArtifacts
- runner/: act_runner config (windows-build label, capacity 4)
- gitea/workflows/: build-nsis.yml (template per progetti MSBuild/Python)
- template/: script di provisioning template VM (VS BuildTools 2026, .NET SDK 10, Python 3.13)
- docs/: ARCHITECTURE, CI-FLOW, OPTIMIZATION, BEST-PRACTICES, Setup-GiteaSSH

Verificato: e2e-009 SUCCESS in 02:09, cleanup automatico VM confermato.
2026-05-08 23:25:50 +02:00