Commit Graph

85 Commits

Author SHA1 Message Date
goodolclint-claude[bot] 25746a94e3 ci: storage VM moves to DHCP and is addressed by FQDN (1/2)
The repo stops holding opinions about CI VLAN addressing: the VM boots
via DHCP with hostname pvetest-storage (deterministic MAC for an
optional reservation), registers in the operator's CI DNS zone, and
everything addresses it by STORAGE_VM_FQDN. Replaces the static-IP +
explicit-DNS variables.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:49:48 +00:00
goodolclint-claude[bot] 932cc0dcf5 ci: retire the PVE 8 integration leg
PVE 8 reached EOL 2026-08-31. The full matrix needs 42GiB free on one
parent node; no node has that after the fleet rebuild, so the headroom
guard blocks every run. Dropping the 8a/8b pair brings the requirement
to 26GiB. The module keeps PVE 8 runtime support and the script still
accepts PVE_VERSIONS='9 8' for local runs; the PVE-8-only Pester
contexts stay for SKIP_PROVISION runs against real PVE 8 hosts. Also
counts the storage VM in the headroom error message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:13:33 +00:00
goodolclint-claude[bot] f48f0ea9ae ci: storage and answer services move to a VM inside the CI sandbox (1/2)
The nested PVE guests live on an isolated VLAN with no route to the
runner network (ADR 0032, homelab repo), and the runner-hosted Docker
services died with each ephemeral ARC pod anyway. A small cloud-image VM
in the ci pool now serves NFS, iSCSI, and the auto-install answer files
from inside the sandbox. Includes fixes from Codex and in-house review:
bpg provider >= 0.79.0, serial console for the resized cloud image,
key-based SSH (cloud images refuse password auth), CIDR validation,
storage VM in the headroom check, docker socket mounts removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 19:52:36 +00:00
goodolclint-claude[bot] 07b95aa4d0 Merge branch 'main' into ci/dynamic-node-selection 2026-08-31 18:44:58 +00:00
goodolclint-claude[bot] 71e12e68a1 ci: allow the goodolclint-claude and goodolclint-codex apps in Claude review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:33:14 +00:00
goodolclint-claude[bot] 6bd1c37343 ci: PVE_TARGET_NODE is optional in the workflow docs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:24:07 +00:00
goodolclint-claude[bot] 60e84712f3 Merge branch 'main' into dependabot/github_actions/main/actions/setup-dotnet-6 2026-08-31 17:15:49 +00:00
dependabot[bot] 9fdd89fd95 chore(deps): bump actions/setup-dotnet from 5 to 6
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 5 to 6.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:08:15 +00:00
dependabot[bot] 93c23d21a4 chore(deps): bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:07:37 +00:00
Clint Branham 5b896b4681 ci: integration jobs run on the psproxmoxve ARC scale set
ARC scale sets match runs-on by scale-set name, not by label list.
2026-08-23 09:08:54 -05:00
Clint Branham d3f05187dd ci: nested PVE guests land in the ci pool with VMIDs 5081-5092
The runner token is pool-scoped (PVEVMAdmin on /pool/ci only), so VM.Allocate
succeeds only with pool_id set; VMIDs move into the 5000-5999 CI range.
2026-08-23 09:06:11 -05:00
Clint Branham c7eff18899 ci: feed disk/iso storage and bridge from repo vars for rebuilt homelab 2026-08-23 02:29:49 -05:00
dependabot[bot] 23ffc3531f chore(deps): Bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 14:12:00 +00:00
Clint Branham 6e2f25a083 fix: rewrite Claude Code Review workflow to match official examples
Previous approach (/code-review:code-review --comment) was based on
incorrect documentation research. Reviewing the actual official
examples at anthropics/claude-code-action/examples/pr-review-*.yml
reveals the correct pattern:

1. Use a custom prompt with explicit review instructions (not a
   plugin slash command)
2. Use claude_args with --allowedTools to enable the MCP inline
   comment tool and gh pr CLI commands — this is what lets Claude
   actually post to the PR
3. Enable track_progress: true for visual progress tracking

Without --allowedTools, Claude has no way to post anything because
the tools for PR commenting aren't allowed by default.

Also removed the plugins and plugin_marketplaces inputs since
they're not needed — the review runs via prompt instructions and
the allowed tools alone.

The custom prompt is tailored to PSProxmoxVE with focus areas
specific to the module: DECISIONS.md compliance, cmdlet
conventions, API correctness against the PVE OpenAPI spec,
test coverage, and security.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 09:09:54 -05:00
Clint Branham 2aa2d5994e fix: allow dependabot PRs in Claude Code Review action
Dependabot PRs were being rejected with:
  Workflow initiated by non-human actor: dependabot (type: Bot)

Add allowed_bots: 'dependabot[bot]' to permit dependency update reviews.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 08:52:36 -05:00
Clint Branham 1f09ae6e94 fix: publish workflow module path must match module name
Publish-Module -Path requires the directory name to match the module
name. Changed artifact download path from ./publish/netstandard2.0/
to ./publish/PSProxmoxVE/ so Publish-Module can find the manifest.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:19:41 -05:00
Clint Branham 13e0c7bdb1 fix: grant write permissions to Claude Code workflows
- claude-code-review.yml: pull-requests/issues read → write (post reviews)
- claude.yml: contents/pull-requests/issues read → write (respond to @claude)
- Upgrade checkout@v4 → v6, fetch-depth: 1 → 0 for full diff context
- Skip draft PRs in review workflow
- Remove boilerplate comments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:11:54 -05:00
Clint Branham 197e206123 chore: scan-9 review findings + fix publish secret name
- Resolve F039 (bare catch regression), F053 (HA coverage), F060
  (cluster config coverage), F084 (PveSession secret hiding)
- Update findings.json: 11 open → 7 open, 0 regressions
- Update REVIEW_REPORT.md with scan-9 results
- Fix publish.yml to use NUGET_API_KEY secret (matches other projects)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 08:58:35 -05:00
Clint Branham e90fb760f6 fix: use force-cleanup in CI for reliable teardown
CI cleanup should always succeed regardless of Terraform state
(cancelled runs, timeouts, partial failures). force-cleanup uses
direct API calls + docker rm instead of terraform destroy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:06:22 -05:00
Clint Branham 226f9d8a12 fix: store Terraform state on shared mount for CI persistence
Terraform state was stored in the container's working directory
(fresh checkout), so it was lost between CI jobs. The cleanup job
couldn't destroy resources because it had no state.

Now stores state at /opt/pve-integration/work/terraform.tfstate via
-state flag on all terraform commands. This persists across the
provision → test → cleanup job chain in GitHub Actions.

Also:
- Force cleanup now removes state from both local and shared paths
- Added -reconfigure to terraform init (avoids backend mismatch errors)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:04:38 -05:00
GoodOlClint ec9fde14bd Merge branch 'main' into refactor/test-orchestration 2026-03-25 16:21:40 -05:00
GoodOlClint 8555d6854e "Claude Code Review workflow" 2026-03-25 16:19:28 -05:00
GoodOlClint 33636027b7 "Claude PR Assistant workflow" 2026-03-25 16:19:27 -05:00
Clint Branham 5cfd33d921 fix: update GitHub workflow for credential auth + pve-integration paths
- Volume mounts: /opt/pve-isos → /opt/pve-integration
- CACHE_DIR env: /opt/pve-isos → /opt/pve-integration
- Test step: PVETEST_APITOKEN → PVETEST_PASSWORD (credential auth)
- Cleanup step: add PVE_PASSWORD (needed by terraform destroy)
- Remove PVETEST_APITOKEN from optional secrets docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:27:48 -05:00
Clint Branham fb5d00aad0 fix(ci): add concurrency group to queue integration test runs
Prevents overlapping integration test runs on the self-hosted runner.
Uses cancel-in-progress: false so each run completes its full
lifecycle (including cleanup) before the next one starts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:53:11 -05:00
copilot-swe-agent[bot] efc3e3a8e0 chore: add .github/copilot-instructions.md
Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/45c5e8bb-c3e5-461c-9064-6cdafab4daa0
2026-03-24 20:38:49 +00:00
copilot-swe-agent[bot] 6a63dea923 fix: apply review feedback on Docker storage and security documentation
- Fix storage_ip derivation to use default route first, not Swarm RemoteManagers
- Make iSCSI container entrypoint idempotent (check before create for target/LUN/bind)
- Pin erichough/nfs-server from 'latest' to '2.2.1' for reproducibility
- Replace curl|sh Docker install with apt repo in Dockerfile.test
- Add docker.sock security warnings in docker-compose.test.yml and CI workflow
- Update stale 'storage VM' references in comments and .env.test.example"

Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/534c0a63-2988-496c-b0ae-e291fcfa050b
2026-03-24 18:53:30 +00:00
Clint Branham 9817d30a11 feat(ci): multi-node PVE provisioning and Docker-based shared storage
Provision two PVE nodes per version (a/b) for future cluster testing,
plus Docker-based iSCSI target and NFS server for shared storage tests.

Multi-node changes:
- Each PVE version gets two nodes: 9a/9b and 8a/8b (4 VMs total)
- Parameterized answer.toml FQDN for unique hostnames per node
- Per-node auto-install ISOs with unique answer files
- Node name discovered from FQDN and included in test config
- API token creation handles pre-existing tokens (delete + recreate)
- New test env vars: PVETEST_HOST_B, PVETEST_APITOKEN_B
- Removed preflight cleanup from provision (use explicit cleanup instead)

Docker storage services:
- New docker-compose.storage.yml with iSCSI (tgt) and NFS containers
- Host networking so PVE nodes can reach storage services
- Docker socket mounted into dev-infra container for host Docker access
- Docker CLI added to dev-infra Dockerfile stage
- New test env vars: PVETEST_STORAGE_VM_IP, PVETEST_ISCSI_IQN, PVETEST_NFS_EXPORT

Other fixes:
- first-boot.sh installs open-iscsi on PVE nodes
- preflight-cleanup.sh handles empty ISO filename gracefully
- TMPDIR set to work dir to avoid /tmp overflow during ISO uploads

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:34:15 -05:00
Clint Branham f21c7f84b7 feat(ci): unify CI and local integration test infrastructure
- Replace tests/infrastructure/Dockerfile with tests/Dockerfile.test
  (single multi-stage Dockerfile for both CI and local dev)
- CI container-image job now builds from Dockerfile.test target dev-infra
- Add ARM support: PowerShell installed via dotnet tool on arm64,
  APT package on amd64
- Replace tests/dev.sh (bash) with tests/dev.ps1 (PowerShell) for
  cross-platform support (Windows, macOS, Linux)
- Add -DockerHost parameter for running x86 containers on a remote
  Docker host from ARM Macs (rsyncs repo, uses SSH Docker transport)
- Add -NoCleanup switch to keep nested PVE VMs after integration tests
- integration command now provisions nested PVE VMs instead of testing
  against a pre-existing PVE directly
- Share /opt/pve-isos host path between CI and local dev (was separate
  Docker named volume)
- Delete tools/Invoke-Tests.ps1 (unused, overlapped with run-integration.sh)
- Add .gitignore entries for Terraform state/artifacts
- Update all documentation references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:41:28 -05:00
Clint Branham c1e1442155 fix(ci): move PVE_TARGET_NODE from secret to variable
The node name "pve" was being masked in all CI logs because GitHub
Actions auto-masks secret values. Since the node name is not sensitive,
use vars.PVE_TARGET_NODE instead of secrets.PVE_TARGET_NODE.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:49:21 -05:00
Clint Branham 9752b854e4 refactor(ci): simplify workflow to delegate to run-integration.sh
Provision, test, and cleanup jobs now call run-integration.sh instead
of inlining ~170 lines of shell. Logic changes only need to be made
in one place, shared between CI and local dev.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:21:14 -05:00
Clint Branham 6a1253c37b fix: remove pull_request trigger from integration tests workflow 2026-03-24 08:39:16 -05:00
Clint Branham d5f4e13637 fix(security): move hardcoded test password to GitHub Actions secret
- CI workflow: PVE_PASSWORD now reads from secrets.PVE_TEST_PASSWORD
- variables.tf: removed default password, requires TF_VAR env var
- Integration README: examples use <your-test-password> placeholder
- create-api-token.sh: example IP changed to pve.example.com
- .gitignore: added .env/.env.* exclusion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:40:47 -05:00
Clint Branham 1faaba0a20 perf(ci): run PVE 8 and PVE 9 tests in parallel (max-parallel: 2)
Runner VM now has 2 runner instances registered, so both test matrix
entries can execute simultaneously against their respective pre-
provisioned nested PVE VMs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:41:59 -05:00
Clint Branham 68c528e278 fix(ci): pass test config via shared volume instead of job outputs
GitHub Actions redacts any value that matches a secret or masked string
in job outputs, making them empty in downstream jobs. This affected
host IPs, tokens, and even port 8006 (substring of PVE_ENDPOINT).

The provision job now writes connection details to
/opt/pve-isos/test-config.json on the shared volume. Test jobs read
this file directly with jq — no job outputs needed for sensitive values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:29:18 -05:00
Clint Branham 1dd677a50c fix(ci): stop masking nested PVE IPs so job outputs pass through
::add-mask:: on the VM IP addresses caused GitHub Actions to redact
them in job outputs, making needs.provision.outputs.pve*_host empty
in the test jobs. The IPs are internal lab addresses, not sensitive.
Token masking is retained.

Also removes terraform debug output from prior commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:18:32 -05:00
Clint Branham c8c285e000 fix(ci): use RUNNER_TEMP env var in tfvars heredoc, add debug output
${{ runner.temp }} may resolve differently inside containers. Use
${RUNNER_TEMP} shell variable with unquoted heredoc instead. Added
debug output to diagnose ISO path issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:10:26 -05:00
Clint Branham a424dd18ac refactor(ci): parallel provisioning, file caching, provision/test/cleanup split
Restructures the integration test workflow from a monolithic sequential
job into separate provision → test → cleanup stages:

- provision: creates ALL nested PVE VMs in a single terraform apply
  (parallel), waits for APIs, creates tokens, passes outputs to tests
- test: matrix [pve9, pve8] consumes provision outputs, no provisioning
- cleanup: always runs, API-only teardown for all VMs

Terraform refactored to for_each with pve_instances map variable,
enabling parallel ISO upload and VM creation.

New caching scripts reduce redundant downloads:
- ensure-base-iso.sh: downloads PVE ISOs to /opt/pve-isos if missing
- ensure-cloud-images.sh: caches cloud image + OVA with 7-day TTL
- prepare-auto-iso.sh: --cache-dir flag with hash-based skip

Runner no longer needs manual ISO provisioning (zero-touch setup).
cleanup-images bumped to min-versions-to-keep: 3 to survive overlapping
runs. All jobs gated against dependabot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:05:20 -05:00
Clint Branham 728e8df335 fix(ci): gate all integration jobs against dependabot
The dependabot actor check was only on the build job. The container-image
and cleanup-images jobs still ran — cleanup-images with if: always()
deleted GHCR container images while the main branch integration run was
still using them, causing PVE 8 tests to fail with "image not found".

Now all four integration jobs (build, container-image, integration,
cleanup-images) are gated with github.actor != 'dependabot[bot]'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 15:28:19 -05:00
dependabot[bot] 26a43fc52b chore(deps): Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 20:21:00 +00:00
Clint Branham 339ffaf0bd fix(ci): remove net48 build target from unit-tests, skip integration for dependabot
unit-tests.yml: The publishable project targets netstandard2.0 only
(D009/F047), so the net48 build matrix entry fails. PS 5.1 loads
netstandard2.0 assemblies on .NET Framework 4.8, so the PS 5.1 Pester
tests now use the netstandard2.0 artifact.

integration-tests.yml: Skip entire workflow for dependabot PRs since
integration tests on the self-hosted runner are expensive and dependency
bumps don't warrant full end-to-end testing. Also updates dotnet SDK
from 9.0.x to 10.0.x for consistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 15:02:04 -05:00
Clint Branham 68dadbfdc0 fix: remediate findings F045, F047, F048, F064, F070, F071, F076-F079
Phase 1 — Trivial fixes:
- F071: Add Uri.EscapeDataString to GetPveTemplateCmdlet node path
- F077: Add ValidateRange(100, 999999999) to GetPveTaskListCmdlet.VmId
- F076: Create .github/dependabot.yml (nuget + github-actions, weekly)
- F079: Fix unit-tests.yml dotnet SDK from 9.0.x to 10.0.x
- F048: Mark wont_fix — sync-over-async accepted for PS 5.1 compat

Phase 2 — Framework targeting (D009 compliance):
- F047: Reduce publishable csproj to netstandard2.0 only, remove all
  #if NET48/NETSTANDARD2_0 conditionals from PveHttpClient.cs,
  restructure build.yml for netstandard2.0 publish + net10.0/net48 tests
- F064: Resolved by F047 — SMA 7.5.0 ItemGroup removed with net10.0 TFM
- F070: Add PS 5.1 smoke-test job to publish.yml (windows-latest)

Phase 3 — IPveHttpClient interface extraction (F045):
- Extract IPveHttpClient interface from PveHttpClient
- Add constructor injection to all 14 service classes
- Services use injected client when available, create+dispose when not

Phase 4 — Service unit tests (F078):
- 196 new xUnit tests across 10 service test files
- All services tested via Moq-mocked IPveHttpClient
- Total test count: 382 (was 186)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:51:37 -05:00
Clint Branham 94424367bf fix: remediate scan-4 findings F058, F062, F063, F071, F072, F073, F074, F075
F058 (critical): Replace while(true) infinite-loop task polling with
TaskService.WaitForTask in 5 container snapshot and storage cmdlets.

F073+F047 (high): Migrate net9.0 → net10.0 across both source .csproj
files, build.yml, publish.yml, and test helper.

F071 (medium): Add Uri.EscapeDataString() to all inline URL path
segments in ~16 cmdlets that bypass service classes (D003).

F062+F063 (medium): Add ConfirmImpact.High to Restart-PveContainer
and Suspend-PveContainer (D006).

F075 (medium): Generate markdown help docs for 89 cmdlets that were
missing documentation (170 total, up from 81).

F072 (low): Remove unused System.Text.Json dependency from Core.csproj.
F074 (low): Raise publish smoke-test threshold from 60 to 150.
F065 (low): Add .github/ISSUE_TEMPLATE/config.yml.
F066 (low): Add CODEOWNERS.

Also fix _TestHelper.ps1 net9.0 → net10.0 framework reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:54:28 -05:00
Clint Branham 1c4c112565 test: expand integration and unit test coverage to 84 test cases
Integration tests (27 contexts, 84 test cases, up from 48 cmdlets to 76):
- VM: Suspend/Resume/Resize
- Containers: full lifecycle (create, config, start, stop, restart, clone)
- Container Snapshots: create, list, restore, remove
- SDN: zone/vnet/subnet CRUD (PVE 8+ version-gated)
- Storage: create/remove directory storage, Invoke-PveStorageDownload
- OVA Import: Import-PveOva with generated test OVA
- Cloud-Init: Invoke-PveCloudInitRegenerate
- Templates: Remove-PveTemplate
- Disconnect-PveServer: verify disconnect + post-disconnect failure

Unit tests:
- Guest agent cmdlets (Test-PveVmGuestAgent, Get-PveVmGuestNetwork,
  Invoke-PveVmGuestExec) — parameter metadata, ShouldProcess, session

Test infrastructure:
- prepare-test-environment.sh generates minimal test OVA (OVF + 1MB VMDK)
- CI workflow passes PVETEST_OVA_PATH to integration tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:20:52 -05:00
Clint Branham f2280c1c88 refactor: rename Send-PveIso to Send-PveFile and move VM provisioning into integration tests
Send-PveFile replaces Send-PveIso with a -ContentType parameter
(iso, vztmpl, import). This is a breaking rename — the module has
not been released yet.

Test infrastructure refactored:
- prepare-test-vm.sh replaced with prepare-test-environment.sh
  (only SSH ops: enable content types, upload cloud-init snippet,
  curl download cloud image)
- VM provisioning moved into integration tests as "Linux VM —
  Provisioning" context: Send-PveFile, New-PveVm, Import-PveVmDisk,
  Set-PveVmConfig, Set-PveCloudInitConfig, Start-PveVm,
  Test-PveVmGuestAgent — all tested as part of the test suite
- PVETEST_LINUX_VMID env var removed (VM created by tests)
- PVETEST_CLOUD_IMAGE_PATH + PVETEST_PASSWORD added

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:39:06 -05:00
Clint Branham a8a9cc28b1 chore: add community files and PSGallery publish workflow
- Add CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md
- Add .gitattributes for line ending normalization
- Add GitHub issue templates (bug report, feature request)
- Add pull request template
- Add publish.yml workflow for PSGallery publication on tag push

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:22:13 -05:00
Clint Branham 33962da887 fix(ci): install module before prepare-test-vm.sh runs
The script uses PSProxmoxVE cmdlets but the module was only copied to
the module path after it ran. Move the install step before the test VM
deployment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:20:34 -05:00
Clint Branham 518e5c838a feat(test): use new cmdlets in test VM setup and add guest agent tests
prepare-test-vm.sh now uses module cmdlets for 7 of 8 steps:
- Set-PveVmConfig -AdditionalConfig replaces SSH qm set (8 config keys)
- Test-PveVmGuestAgent replaces SSH qm agent ping
- Only SSH remaining: pvesm set, SCP snippet, qm importdisk

New integration tests for guest agent cmdlets:
- Test-PveVmGuestAgent: verify agent responds
- Get-PveVmGuestNetwork: verify interfaces with IPv4 addresses
- Invoke-PveVmGuestExec: run hostname command, verify exit code + output

Also force Node.js 24 for delete-package-versions (no v6 available yet).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:08:52 -05:00
Clint Branham c6da302742 chore(ci): add GHCR cleanup job to delete old container image versions
Each push creates a ~770MB container image tagged with the commit SHA.
Add a cleanup job that runs after integration tests complete, keeping
only the most recent version and deleting all others.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:49:21 -05:00
Clint Branham d98bd40476 refactor(ci): use PSProxmoxVE cmdlets in test VM preparation
Replace raw qm/SSH commands with module cmdlets where possible:
- Invoke-PveStorageDownload for cloud image download
- New-PveVm for VM creation
- Set-PveCloudInitConfig for cloud-init user/password/IP
- Invoke-PveCloudInitRegenerate to apply config
- Start-PveVm to boot the VM

SSH/SCP retained only for operations without API support:
- Snippet upload (no snippet API)
- pvesm set for snippets content type
- qm importdisk (no importdisk cmdlet)
- qm set for --scsi0, --cicustom, --agent, --boot (not in Set-PveVmConfig)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:52:44 -05:00