Commit Graph

274 Commits

Author SHA1 Message Date
Simone 9688e7e2f8 fix(backup): bring act-runner back up on every termination path
If ci-backup-template.service is killed mid-run (SIGTERM), the Python
finally block that restarts act-runner.service is skipped. A subsequent
backup then finds the runner already inactive, _stop_runner returns
False, and the finally restart is gated off — leaving the runner down
indefinitely (incident: 21 mag 2026, runner stayed off ~80 min).

Add ExecStopPost=-/bin/systemctl start act-runner.service so systemd
guarantees the runner is restarted regardless of how the unit exits
(success, failure, signal). The `-` prefix preserves the unit's own
exit status.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:35:43 +02:00
Simone bbd376f057 docs: add B1–B4 closeout docs and rewrite B5-closeout as completed
B1: Linux Mint + VMware Workstation + setup-host-linux.sh (Python 3.12 note)
B2: rsync template transfer, VMX registration, smoke tests; keyrings.alt choice
B3: SSH key perms, BuildVMGuest + GiteaPAT via PlaintextKeyring (D-Bus-free)
B4: act-runner.service, config.yaml labels/envs fix, smoke job PASS
B5: rewritten — Python-only timers (no pwsh), 7z compression, --service-name
    act-runner fix, prerequisite dirs, root service for backup

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:57:19 +02:00
Simone 6db20d66bf docs: introduce Phase C (pwsh removal), rename ESXi to Phase D
- Add plans/idea-3-powershell-removal.md: Phase C goal is to eliminate
  the pwsh dependency from the Linux host by porting the remaining PS
  scripts (bench run, validate host, smoke run) to Python sub-commands.
- Update idea-3-esxi-support.md header: Fase C → Fase D.
- Update ideas-overview.md: new four-phase table (A/B/C/D) with
  prerequisiti and criteri for Phase C.
- Rename all "Hook futuri Fase C" (ESXi) → "Hook futuri Fase D" in
  implementation-plan-A-B.md; add Phase C/D entries to summary and
  references section.
- Update PhaseB-user-checklist.md end note and CLAUDE.md to point
  Phase C → pwsh removal, Phase D → ESXi.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:46:01 +02:00
Simone 43a69b82db feat: B5 — port retention/template-backup to Python, deploy systemd timers
- Add `retention run` command (ports Invoke-RetentionPolicy.ps1): purges
  old artifact/log dirs with aggressive mode when disk space is low.
- Add `template backup` command (ports Backup-CITemplate.ps1): 7z -mx=1
  compressed archives in /var/lib/ci/backups/, prunes to keep-count=3,
  stops/restarts act-runner.service around the copy.
- Update ci-retention-policy.service and ci-backup-template.service to use
  Python; pwsh is no longer required on the Linux host.
- Fix ci-watch-runner-health.service: pass --service-name act-runner
  (Linux service name, not Windows act_runner default).
- Fix _list_orphans in vm.py: wrap is_dir() inside the OSError try block
  so a stat() failure on an entry is silently skipped rather than raised.
- Mark B5 complete in PhaseB-user-checklist.md.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:35:07 +02:00
Simone 536fd688e8 feat: update runner configuration steps and add config.yaml generation instructions 2026-05-21 00:45:43 +02:00
Simone b2803c38ef fix: correct order of arguments for template path in local CI build action 2026-05-21 00:34:19 +02:00
Simone a6aa9260b3 fix: update example for extra environment variables and improve Python interpreter resolution for OS compatibility 2026-05-21 00:30:38 +02:00
Simone 3921758392 feat: update action.yml to use pwsh shell and enhance vm.py with start option; add credential management scripts
Lint / pssa (push) Failing after 7s
Lint / python (push) Failing after 1s
2026-05-21 00:11:20 +02:00
Simone b9d6994c85 feat: add setup-host-linux.sh script for CI host bootstrap and update Phase B checklist 2026-05-20 22:13:37 +02:00
Simone 573d11691d docs: Windows host compat is a categorical constraint (B8 cancelled)
User requirement (non-negotiable): the project must stay
first-class compatible with a Windows host permanently — Phase B
adds Linux *alongside* Windows, never replacing/degrading it.
- implementation-plan-A-B §2: categorical-constraint banner; B8
  decommissioning cancelled (kept only as historical record);
  master checklist B8 row updated.
- PhaseB-user-checklist: Passo 9 (B8) cancelled -> dual-host kept;
  Passo 8 no longer a decommission gate; tracking table + closing
  note updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:45:31 +02:00
Simone 6c4e5c2e0e fix(ci): build-ns7zip workflow_dispatch only (decouple from CI-system tags)
Lint / pssa (push) Successful in 26s
Lint / python (push) Successful in 54s
build-ns7zip builds an EXTERNAL repo (nsis-plugin-ns7zip). The
`push: tags v*` trigger (inherited from when this workflow lived in
the plugin repo) made every CI-system tag — including the Phase A
marker v2.0.0-phaseA — auto-build and publish an ns7zip release on
the CI-system repo. Remove the tag trigger; manual dispatch only.
The release job's tag-gate `if` now never fires (skipped) — release
flow already validated with a throwaway tag.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v2.0.0-phaseA
2026-05-17 23:32:46 +02:00
Simone 0f99549b70 docs: implementation-plan-A-B — Phase A closed, B kept as forward plan
Medium update: exec-summary status (A COMPLETATA, B ready), master
checklist A items [x], Phase A gating satisfied, §1 COMPLETATA banner
with real validation deviations (LocalSystem venv/keyring, github-free
artifacts, transport, shim common-params, deferred §8.1/§8.2), §7
A-side definition-of-done [x]. Fase B (§2/§3/§4) + risk matrix +
cronoprogramma left intact as the Phase B design reference alongside
PhaseB-user-checklist.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:29:19 +02:00
Simone fce85b72b4 docs(phaseA): Phase A closed — Passo 9 done (merge + tag)
feature merged to main (2aa12bb), tag v2.0.0-phaseA pushed
(triggers build-ns7zip as final end-to-end validation of main).
All Passi 1-9 [x]. Residual non-blocking cleanup: delete the test
Gitea releases via UI (tags kept).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:23:12 +02:00
Simone b4ca7f3236 docs(phaseA): Passo 9 merge done; global table 6-8 PASS
Lint / pssa (push) Successful in 30s
Lint / python (push) Successful in 1m2s
Build ns7zip (Local CI) / release (push) Has been cancelled
Build ns7zip (Local CI) / build (linux) (push) Has been cancelled
Build ns7zip (Local CI) / build (windows) (push) Has been cancelled
feature merged to main (2aa12bb, tree == feature). Passi 6/7/8 [x],
Passo 9 in progress (release tag pending).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:20:40 +02:00
Simone 2aa12bb73f Merge Fase A: Python rewrite + Linux migration into main
Lint / pssa (push) Successful in 27s
Lint / python (push) Successful in 54s
Phase A validated end-to-end (PhaseA-user-checklist Passi 1-8):
venv deploy, smoke wait-ready/job (Win+Linux), Gitea workflows
(lint, self-test both transports, build-ns7zip matrix + release),
burn-in 12/12, benchmark. ci_orchestrator Python pipeline + PS shims,
github-free artifacts, in-guest/host-clone transports, perf tuning.

Resolution: result tree == feature (authoritative). Removed 5 obsolete
files superseded by Phase A (old gitea/ action+lint paths now under
.gitea/, Pester tests for the replaced PS New/Remove-BuildVM/
Wait-VMReady scripts).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:19:27 +02:00
Simone 5539eddba2 docs(phaseA): mark baseline comparison skipped (decided)
No reliable pre-Python PS baseline; not blocking Phase A close.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:17:10 +02:00
Simone 36913ab6c6 docs(phaseA): Passo 8 benchmark recorded (destroy fixed)
Measure-CIBenchmark.ps1 x4 clean: clone/start/WinRM negligible,
destroy ~4-6s (shim common-param fix), 0 orphans. IP-acquire phase
(20-85s) is the dominant variable cost (VMware Tools IP detect) —
known, non-blocking. No reliable pre-Python PS baseline; infra
metrics tracked in benchmark.jsonl.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:09:56 +02:00
Simone f0a94b86b3 fix(shims): skip PowerShell common params in CLI forwarders
Lint / pssa (push) Successful in 28s
Lint / python (push) Successful in 59s
The blind -X -> --x shims forwarded PowerShell common parameters
(-ErrorAction, -Verbose, ...) to the Python CLI, e.g.
Measure-CIBenchmark.ps1 -> Remove-BuildVM.ps1 -ErrorAction
SilentlyContinue produced `ci_orchestrator vm remove --error-action`
-> "No such option" -> destroy failed (orphan VM left). Skip
common switches and consume value-taking ones. Applied to all 7
blind-loop shims; param-style shims (New-BuildVM, Invoke-RemoteBuild,
Get-BuildArtifacts) are not affected. PSSA clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:03:24 +02:00
Simone f7cfc74290 docs(phaseA): Passo 7 burn-in PASS (12/12, 0 orphans)
Start-BurnInTest.ps1 (lab wrapper: burnin-dummy + build.ps1) — 4
concurrent x 3 rounds all PASS, clean VM/lock teardown each round.
Note the gotcha: raw Test-CapacityBurnIn.ps1 without -BuildCommand
defaults to dotnet and fails on the non-.NET dummy repo.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:57:55 +02:00
Simone 2aeb390f62 docs(phaseA): drop moot failure-contingency checkbox (Passo 6)
All workflows passed; the "if one fails" item never triggered. Replace
the dangling [ ] with a historical note so Passo 6 has no false-open
task.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:44:32 +02:00
Simone 61d80ae47e docs(phaseA): Passo 6 complete — build-ns7zip matrix + release PASS
lint, self-test, build-ns7zip (Win+Linux) and the release job
(Gitea release + asset upload via REST API, auto token) all green.
Phase A Gitea end-to-end validated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:41:41 +02:00
Simone d424646389 fix(ci): close release foreach loop (was truncated -> parse error)
Lint / pssa (push) Successful in 28s
Lint / python (push) Successful in 55s
Build ns7zip (Local CI) / build (windows) (push) Successful in 2m4s
Build ns7zip (Local CI) / build (linux) (push) Successful in 4m24s
Build ns7zip (Local CI) / release (push) Successful in 6s
build-nsInnoUnp.yml shipped without the closing brace of the
asset-upload foreach (and no EOF newline) since its origin; the
release job had never run (tag-only) so the PS parse error
"MissingEndCurlyBrace" was latent until the test tag triggered it.
Close the loop, add per-asset + final Write-Host. PS parse verified.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:35:08 +02:00
Simone be4396ce83 fix(scripts): satisfy PSScriptAnalyzer (lint gate)
Lint / pssa (push) Successful in 31s
Lint / python (push) Successful in 1m3s
- Remove-Securely: suppress PSUseShouldProcessForStateChangingFunctions
  (internal best-effort shred; ShouldProcess prompts are undesirable)
  + add [CmdletBinding()].
- Replace the two empty catch blocks (Set-CIGuestCredential.ps1,
  Test-CIGuestWinRM.ps1) with Write-Verbose so PSAvoidUsingEmptyCatchBlock
  is satisfied while keeping best-effort behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:31:34 +02:00
Simone 1fbe2c87cc perf(ci): 8 vCPU for ns7zip build VM (4 was starving parallel build)
Lint / pssa (push) Failing after 30s
Lint / python (push) Successful in 1m1s
Build ns7zip (Local CI) / build (windows) (push) Successful in 1m26s
Build ns7zip (Local CI) / build (linux) (push) Successful in 4m8s
Build ns7zip (Local CI) / release (push) Failing after 0s
WSL on the host builds the 3 configs in parallel in ~103s (= one
config) — the parallel design is correct. The 4-vCPU CI VM ran 3x
make -j on 4 cores -> oversubscription thrash -> ~3x slower. Not
structural / not RAM. Bump guest-cpu to 8 (job.py patches the clone
VMX numvcpus); host is 10c/20t, this matrix is 2 VMs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:12:03 +02:00
Simone 956681c419 feat(ci): guest-cpu/guest-memory-mb action inputs on main
Runner fetches the composite action from @main. Propagates the VMX
override inputs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 21:42:48 +02:00
Simone 7b4051412b feat(ci): expose guest-cpu/guest-memory-mb; ns7zip Linux 8GB
job.py already patches the clone VMX (numvcpus/memsize) via
--guest-cpu/--guest-memory-mb; expose them as action inputs
(default '0' = keep template). build-ns7zip.yml sets
guest-memory-mb: 8192 — the parallel MinGW cross-compile thrashes at
the 4 GB Linux template default (Windows template is 6 GB).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 21:42:47 +02:00
Simone 9b42823984 fix(winrm): retry transient WSMan host-process faults (1018)
Lint / pssa (push) Failing after 25s
Lint / python (push) Successful in 57s
After a memory-heavy parallel build the guest can momentarily fail to
launch wsmprovhost (WSManFault 1018), which broke artifact collect
(now does Compress-Archive + fetch over WinRM). run() retries up to 4x
with exponential backoff on transient WSMan markers, dropping the
cached shell so a fresh one is opened once the guest recovers.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 21:30:56 +02:00
Simone 3d3b00c71b fix(ci): harden release job condition (avoid stuck 'blocked')
A bare `if: github.ref_type == 'tag'` on a needs-dependent job can
leave `release` stuck in "blocked" instead of skipped for
workflow_dispatch runs on Gitea. Use the explicit
${{ github.event_name == 'push' && github.ref_type == 'tag' }} form.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 21:08:49 +02:00
Simone 4f22d11a84 feat(build): live-stream Linux build output; ns7zip via in-guest clone
Lint / pssa (push) Failing after 26s
Lint / python (push) Successful in 52s
- SshTransport.run_streaming: incremental channel recv, forwards
  stdout/stderr live (no more one-block-at-end). _linux_build uses it
  with PYTHONUNBUFFERED so the guest python flushes promptly.
- _tail_lines split out for failure messages (no double print).
- Windows live streaming deferred (TODO 8.2) — pypsrp execute_ps
  returns only at completion.
- build-ns7zip.yml: use-git-clone:'true' (in-guest), repo-url ->
  https://gitea.emulab.it/... (guest-reachable; host SSH alias was
  host-only). Requires GiteaPAT in the LocalSystem keyring or a public
  nsis-plugin-ns7zip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:51:48 +02:00
Simone 29c4ef09bc ci: ns7zip build uses --dist; collect dist/
ns7zip now supports --dist (commit 57133b7 on nsis-plugin-ns7zip):
DLLs land in <repo>/dist/<config>. Build with `python build_plugin.py
--dist` and collect artifact-source 'dist'.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:33:56 +02:00
Simone eec3f42fe0 ci: single build-command for ns7zip (Linux has python)
Linux template provides `python`, so the OS-aware split is
unnecessary. Use `python build_plugin.py` for both matrix legs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:28:39 +02:00
Simone b2cfe85f88 fix(ci): correct ns7zip build-command and artifact-source
build_plugin.py is a dispatcher: it auto-detects host/toolset and
forwards extra args to the per-version script, which rejected
--final/--dist-dir. Both the Windows (legacy 2601_vs2026) and Linux
build scripts copy nsis7z.dll into <repo>/plugins/{x86-ansi,
x86-unicode,amd64-unicode}, not dist.

- build-command: just `python build_plugin.py` (python3 on Linux —
  Ubuntu 24.04 has no `python`).
- artifact-source: 'plugins' (fixes the "dist missing" failure too).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:27:14 +02:00
Simone 383490b769 ci: rename build workflow to build-ns7zip.yml on main
Propagates the renamed cross-repo build workflow (targets
nsis-plugin-ns7zip) to main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:12:26 +02:00
Simone 97ec820ebb ci: rename build-nsInnoUnp.yml -> build-ns7zip.yml; update doc refs
Workflow now targets Simone/nsis-plugin-ns7zip. Renamed the file and
the workflow `name:`, and updated all references in active docs
(plans/archived and docs/archived left as frozen history).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:12:25 +02:00
Simone facf3670b2 ci: build-nsInnoUnp targets nsis-plugin-ns7zip
Switch the cross-repo build target to Simone/nsis-plugin-ns7zip
(repo-url, artifact-name, release asset name).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:09:15 +02:00
Simone 67c90f10eb fix(build): flush guest build output + put tail in failure message
Lint / pssa (push) Failing after 23s
Lint / python (push) Successful in 52s
On a non-zero build the guest stdout/stderr was written unflushed
then a ClickException raised, so the cause was lost (only
"build command failed (exit 1)" surfaced). _report_build_output now
emits the output with markers, flushes both streams, and returns the
last lines which are appended to the failure message — diagnosable
even if act_runner buffering drops the body. Applied to Linux + Windows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:47:17 +02:00
Simone 02ea7e61ec fix(ci): conditional --commit splat on main
Propagates the PS5.1 empty-arg-drop fix (runner fetches action @main).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:39:37 +02:00
Simone 2b8011c35d fix(ci): don't splat empty --commit (PS5.1 drops zero-length args)
PowerShell 5.1 drops a zero-length string when splatting to a native
exe, so an empty $repoCommit shifted flag/value pairing and click saw
the build command as an unexpected positional. Append --commit only
when a commit is set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:39:36 +02:00
Simone 61cb6cdb40 feat(ci): repo-branch/repo-commit inputs on main
Runner fetches the composite action from @main. Propagates the
cross-repo branch/commit inputs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:37:20 +02:00
Simone ed4dc793f5 feat(ci): repo-branch/repo-commit inputs for cross-repo builds
github.ref_name/github.sha refer to the workflow's own repo. When
repo-url points elsewhere (build-nsInnoUnp builds
nsis-plugin-nsinnounp) the workflow's branch does not exist there
("Remote branch ... not found in upstream origin"). New inputs:
- repo-branch: target branch (default: github.ref_name)
- repo-commit: target commit (default: github.sha only if repo-url
  not overridden; cross-repo => empty = branch tip, no pin)
build-nsInnoUnp.yml sets repo-branch: main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:37:18 +02:00
Simone 0df592504f fix(job): surface redacted git stderr from host-side clone
Lint / pssa (push) Failing after 24s
Lint / python (push) Successful in 49s
_host_clone hid all stderr ("exit 128" with no cause). Surface the
last stderr lines with scheme://user:pass@ credentials masked, so
failures (e.g. unresolved SSH alias under LocalSystem) are diagnosable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:28:35 +02:00
Simone 8be5fa8220 fix(ci): build-nsInnoUnp uses host-side clone (SSH alias is host-only)
repo-url is ssh://gitea-ci/... — an SSH alias defined only in the
host ~/.ssh/config. With the new in-guest-clone default the guest
tried to resolve `gitea-ci` and failed (name resolution). Set
use-git-clone:'false' so the host (which has the alias + SSH key)
performs the clone.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:24:00 +02:00
Simone 0d51ba29b6 fix(ci): build-nsInnoUnp uses full Gitea action URL
Short-form `Simone/local-ci-cd-system/...@main` resolved to
github.com (DEFAULT_ACTIONS_URL=github) -> "authentication required:
Repository not found". Use the full gitea.emulab.it URL like
self-test.yml.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:14:23 +02:00
Simone 2201d0ace6 docs(phaseA): record self-test smoke matrix (both transports PASS)
Passo 6: self-test.yml validated — in-guest clone (default) and
host-side clone+zip, Windows + Linux, all SUCCESS. Artifact handling
github-free.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:11:40 +02:00
Simone ecfe0f3006 feat(ci): use-git-clone/submodules default-on in action (main)
Runner fetches the composite action from @main. Propagates the
default-on transport/submodules inputs and explicit flag forwarding.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:00:53 +02:00
Simone 29dfbf1cae feat(job): wire use-git-clone + submodules; default in-guest clone
Lint / pssa (push) Failing after 26s
Lint / python (push) Successful in 54s
The job command previously discarded --use-git-clone and --submodules
(`del`) and always in-guest cloned with submodules off — making both
action inputs dead no-ops (submodule repos silently broken).

- job.py: --use-git-clone/--host-clone and --submodules/--no-submodules
  are real booleans defaulting to ON. Default = in-guest clone with
  submodules. --host-clone clones on the host into a temp dir
  (_host_clone) and transfers a zip; temp dir cleaned in finally.
  clone_submodules now honoured (was hardcoded False).
- action.yml: use-git-clone / submodules default 'true'; forward the
  explicit positive/negative flag so the Python default is overridden
  deterministically.
- self-test.yml: add smoke-{windows,linux}-hostclone jobs covering the
  host-side transport (default jobs already cover in-guest).
- tests: default-transport, host-clone, and --no-submodules coverage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:00:46 +02:00
Simone a26a7e784e docs(todo): defer GitHub Actions mirror (fix 1) — checkout still github.com
Artifact github.com dependency removed (fix 2 applied). Remaining:
actions/checkout@v4 in lint.yml. Recorded as deferred §8.1 with
revisit conditions (air-gapped host / total github.com independence).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:44:49 +02:00
Simone 5c6fb778ad refactor(ci): drop upload-artifact from action on main
Runner fetches the composite action from @main. Propagates the
github.com-free artifact handling (host-side collect dir).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:42:38 +02:00
Simone d6031a5e32 refactor(ci): drop upload/download-artifact (remove github.com dependency)
actions/upload-artifact and download-artifact run code fetched from
github.com (and v4 is GHES-incompatible, v3 deprecated). The runner
host is single with a shared filesystem, so the orchestrator's
host-side collect dir is the artifact handoff:

- action.yml: replace the two upload-artifact steps with
  host-path report steps; artifacts stay under F:\CI\Artifacts and
  are aged by Invoke-RetentionPolicy.ps1.
- build-nsInnoUnp.yml: release job reads
  F:\CI\Artifacts\{run_id}-{run_attempt}-{target} directly instead of
  download-artifact; existing Gitea REST release-asset upload unchanged.

Tradeoff (accepted): artifacts are no longer downloadable from the
Gitea Actions run page for non-tag builds — only on host disk, and as
release assets for tagged builds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:42:36 +02:00
Simone 456db0a3e2 refactor(artifacts): harmonize Windows to Linux raw-file collection
Lint / pssa (push) Failing after 23s
Lint / python (push) Successful in 50s
Windows produced an intermediate C:\CI\output\artifacts.zip that
upload-artifact then re-zipped (zip-in-zip), while Linux deposited raw
files. Make both paths consistent: the build stages raw outputs into a
collect dir; collect zips it only as a transport archive, fetches, and
extracts into the host artifact dir; actions/upload-artifact produces
the single final archive.

- _windows_build: param artifact_zip -> output_dir; stage raw files
  (in-place when source IS the collect dir, else wipe+copy), no
  Compress-Archive; absolute artifact-source resolved.
- _windows_collect: zip guest dir as transport, fetch, extract (mirror
  _linux_collect); guest_path is now the collect directory.
- job.py / build_run CLI: pass output_dir; rename --guest-artifact-zip
  -> --guest-output-dir.
- Tests updated for the raw-file contract.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:30:34 +02:00