From 79c97ec21174953a6ce33896c4b74b4b1ce06230 Mon Sep 17 00:00:00 2001 From: Clint Branham Date: Wed, 20 May 2026 19:23:29 -0500 Subject: [PATCH] docs: cut CHANGELOG into versioned entries, refresh ReleaseNotes Doc hygiene catch-up surfaced by the PR #62 review: - CHANGELOG.md: the [Unreleased] section had accumulated all post-preview work without ever being cut into release entries. Promote it into: - [0.1.3] - new fixes from #58 (DiskSize normalization) and #59 (HttpClient -TimeoutSeconds + RequestTimeout surfacing) - [0.1.2] - #43/#44/#45 fixes from PR #46 - [0.1.1] - the cmdlet expansion + OpenAPI validation that actually shipped to PSGallery as 0.1.1 Reset [Unreleased] to empty. - src/PSProxmoxVE/PSProxmoxVE.psd1: replace the stale "Initial preview release" ReleaseNotes (carried over since 0.1.0-preview) with actual 0.1.3 notes. PSGallery shows this on the version page. - CLAUDE.md: document the release process so future bumps update the psd1 version, psd1 ReleaseNotes, and CHANGELOG together before the tag is cut. Prevents this hygiene gap from recurring. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 63 +++++++++++++++++++++++--------- CLAUDE.md | 18 +++++++++ src/PSProxmoxVE/PSProxmoxVE.psd1 | 16 +++++++- 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e198dc5..30d0ce0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,28 +7,52 @@ and this project adheres to [Conventional Commits](https://www.conventionalcommi ## [Unreleased] +## [0.1.3] - 2026-05-20 + +### Added + +- `Connect-PveServer -TimeoutSeconds` to set the session-default `HttpClient` timeout (default 100s; `0` = infinite). (#59) +- `Send-PveFile -TimeoutSeconds` and `Invoke-PveStorageDownload -TimeoutSeconds` for per-call override with a 30-minute implicit default so large uploads/downloads no longer trip the 100s default. (#59) + +### Fixed + +- `New-PveVm -DiskSize` and `New-PveContainer -RootFsSize` now normalize unit suffixes (`32G`, `1T`, `32GB`, etc.) to bare GiB before constructing the disk spec. Previously the suffix was passed verbatim, which LVM/LVM-thin storages rejected with `unable to parse lvm volume name '32G'`. Sub-GB units (`M`, `MB`, `K`, `KB`) are now rejected client-side with a clear error. (#58) +- `PveHttpClient.SendAsync` surfaces `HttpClient.Timeout` firings as `PveApiException(RequestTimeout)` with the resource path and configured timeout, instead of leaking a raw `TaskCanceledException`. Works across `net48`, `net10.0`, and `netstandard2.0`. (#59) +- Disk-size validation runs before `ShouldProcess` so typos like `512M` are caught with `-WhatIf`, regardless of whether `-DiskStorage`/`-RootFsStorage` is also supplied. (#58) + +## [0.1.2] - 2026-03-27 + +### Fixed + +- `Get-PveApiToken`: `FullTokenId` is now computed from `UserId!TokenId` (was always empty). (#44) +- `Set-PvePermission`: added `token` ACL type with auto-detection from `!` in `-UgId`, enabling permission assignment for API tokens. (#43) +- `Connect-PveServer`: always emits the session to the pipeline. Use `-Quiet` to suppress; `-PassThru` is kept hidden for backwards compatibility. (#45) + +## [0.1.1] - 2026-03-26 + ### Added - Firewall management cmdlets (21): rules, security groups, aliases, IP sets, options at cluster/node/VM/container levels - Backup/vzdump cmdlets (5): ad-hoc backup creation and scheduled backup job CRUD -- SDN IPAM cmdlets (3): Get/New/Remove-PveSdnIpam for IPAM plugin management -- SDN DNS cmdlets (3): Get/New/Remove-PveSdnDns for DNS plugin management -- SDN Controller cmdlets (3): Get/New/Remove-PveSdnController for controller management -- PSGallery version badge in README -- Integration tests for firewall rules, aliases, IP sets, backup jobs, and OVA import -- SDN Update cmdlets (7): Set-PveSdnZone/Vnet/Subnet/Controller/Ipam/Dns + Invoke-PveSdnApply -- Set-PveRole, Set-PveStorage, Set-PveApiToken for missing update operations -- Get-PveClusterResource: single-call cluster-wide inventory of all VMs, containers, nodes, storage -- Task management: Get-PveTaskList (list tasks on node), Stop-PveTask (cancel running tasks) -- Pool management cmdlets (4): Get/New/Set/Remove-PvePool -- Get-PveBackupInfo: find VMs/containers not covered by backup jobs -- VM disk operations: Move-PveVmDisk (storage migration), Remove-PveVmDisk (detach/delete) -- Guest agent extensions (6): Get-PveVmGuestOsInfo, Get-PveVmGuestFsInfo, Read/Write-PveVmGuestFile, Set-PveVmGuestPassword, Invoke-PveVmGuestFsTrim -- Container gaps (6): Suspend/Resume-PveContainer, Resize-PveContainerDisk, New-PveContainerTemplate, Move-PveContainerVolume, Get-PveContainerInterface -- Storage content management (4): Get-PveStorageStatus, Remove/Set-PveStorageContent, New-PveStorageDisk -- Node operations (6): Get/Set-PveNodeConfig, Get/Set-PveNodeDns, Start/Stop-PveNodeVms -- Access management (9): Get/New/Set/Remove-PveGroup, Get/New/Set/Remove-PveDomain, Set-PvePassword +- SDN IPAM cmdlets (3): `Get`/`New`/`Remove-PveSdnIpam` for IPAM plugin management +- SDN DNS cmdlets (3): `Get`/`New`/`Remove-PveSdnDns` for DNS plugin management +- SDN Controller cmdlets (3): `Get`/`New`/`Remove-PveSdnController` for controller management +- SDN Update cmdlets (7): `Set-PveSdnZone`/`Vnet`/`Subnet`/`Controller`/`Ipam`/`Dns` + `Invoke-PveSdnApply` +- `Set-PveRole`, `Set-PveStorage`, `Set-PveApiToken` for missing update operations +- `Get-PveClusterResource`: single-call cluster-wide inventory of all VMs, containers, nodes, storage +- Task management: `Get-PveTaskList` (list tasks on node), `Stop-PveTask` (cancel running tasks) +- Pool management cmdlets (4): `Get`/`New`/`Set`/`Remove-PvePool` +- `Get-PveBackupInfo`: find VMs/containers not covered by backup jobs +- VM disk operations: `Move-PveVmDisk` (storage migration), `Remove-PveVmDisk` (detach/delete) +- Guest agent extensions (6): `Get-PveVmGuestOsInfo`, `Get-PveVmGuestFsInfo`, `Read`/`Write-PveVmGuestFile`, `Set-PveVmGuestPassword`, `Invoke-PveVmGuestFsTrim` +- Container gaps (6): `Suspend`/`Resume-PveContainer`, `Resize-PveContainerDisk`, `New-PveContainerTemplate`, `Move-PveContainerVolume`, `Get-PveContainerInterface` +- Storage content management (4): `Get-PveStorageStatus`, `Remove`/`Set-PveStorageContent`, `New-PveStorageDisk` +- Node operations (6): `Get`/`Set-PveNodeConfig`, `Get`/`Set-PveNodeDns`, `Start`/`Stop-PveNodeVms` +- Access management (9): `Get`/`New`/`Set`/`Remove-PveGroup`, `Get`/`New`/`Set`/`Remove-PveDomain`, `Set-PvePassword` - Two-tier version gating: introduced vs default version with clear user messaging +- 70 xUnit tests validating every `ValidateSet` against the PVE OpenAPI spec, with `pve-api-enums.json` fixture extracted from the full spec +- Integration tests for firewall rules, aliases, IP sets, backup jobs, and OVA import +- PSGallery version badge in README ### Changed @@ -41,7 +65,7 @@ and this project adheres to [Conventional Commits](https://www.conventionalcommi - `ValidateRange(100, 999999999)` added to all `VmId` parameters - `Uri.EscapeDataString()` applied to all dynamic URL path segments - Hardcoded verb strings replaced with verb class constants (`VerbsCommon.Get`, etc.) -- Auth header magic strings extracted to named constants in PveHttpClient +- Auth header magic strings extracted to named constants in `PveHttpClient` - Bare `catch` blocks replaced with specific or filtered exception handling - MAML help (dll-Help.xml) and 170 markdown cmdlet docs generated - PSGallery publish workflow with PS 5.1 smoke testing @@ -49,6 +73,9 @@ and this project adheres to [Conventional Commits](https://www.conventionalcommi ### Fixed - `ConfirmImpact.High` added to all destructive cmdlets (Stop, Reset, Restart, Suspend, Remove, Restore, New-PveTemplate) +- Storage `ValidateSet`: removed `glusterfs` (dropped in PVE 9), added `btrfs` and `esxi` +- Backup compression: `none` → `0` (PVE expects the string `"0"`, not `"none"`) +- Cluster resource filter: removed `lxc` (PVE uses `vm` for both QEMU and LXC) - Hardcoded test password moved from CI workflow to GitHub Actions secret - Terraform variable default password removed (requires env var) diff --git a/CLAUDE.md b/CLAUDE.md index 29beff9..d217a8a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,3 +93,21 @@ This repo uses a structured review system to track findings and prevent regressi Finding IDs (F001, F002...) are permanent. A resolved finding is never deleted from findings.json — it is marked `resolved` with evidence of the fix. If a finding reappears, it is marked `regressed` and retains its original ID. + +## Releasing to PSGallery + +Tag-driven: pushing a `v*` tag to `main` triggers `.github/workflows/publish.yml` (build → +PS 5.1 smoke test → publish to PSGallery → create GitHub Release with auto-generated notes). + +Each release PR must update **three** things in lockstep before the tag is cut: + +1. `ModuleVersion` in `src/PSProxmoxVE/PSProxmoxVE.psd1` (semver patch for bug-fix-only; + minor for new features; major for breaking changes). +2. `ReleaseNotes` in the same psd1 — this is what PSGallery surfaces on the version page. + Replace the previous version's notes; do not append. +3. `CHANGELOG.md` — cut the `[Unreleased]` section into a new `[X.Y.Z] - YYYY-MM-DD` + block and reset `[Unreleased]` to empty. + +After merge, tag `main` with `vX.Y.Z` and push the tag. The publish workflow rewrites +the psd1 `ModuleVersion` in the build artifact from the tag, so the tag and the source +version must match. diff --git a/src/PSProxmoxVE/PSProxmoxVE.psd1 b/src/PSProxmoxVE/PSProxmoxVE.psd1 index efeed3c..e8d9720 100644 --- a/src/PSProxmoxVE/PSProxmoxVE.psd1 +++ b/src/PSProxmoxVE/PSProxmoxVE.psd1 @@ -371,7 +371,21 @@ ProjectUri = 'https://github.com/goodolclint/PSProxmoxVE' # Release notes for this version - ReleaseNotes = 'Initial preview release. Supports PVE 8.x and 9.x with VM, container, storage, network, SDN, user/role/permission, template, cloud-init, snapshot, and task management.' + ReleaseNotes = @' +## 0.1.3 + +Fixed: +- New-PveVm -DiskSize / New-PveContainer -RootFsSize normalize unit suffixes + (32G, 1T, etc.) to bare GiB before sending to PVE so the documented call + shape works on LVM/LVM-thin storages (#58). +- HttpClient timeouts are now configurable via -TimeoutSeconds on + Connect-PveServer (session default), Send-PveFile, and + Invoke-PveStorageDownload (per-call, 30-minute implicit default). + Timeouts surface as PveApiException(RequestTimeout) instead of a raw + TaskCanceledException (#59). + +Full changelog: https://github.com/goodolclint/PSProxmoxVE/blob/main/CHANGELOG.md +'@ }