AzLocal.UpdateManagement v0.8.6: Step.3 cycle-calendar enrichment + 6 v0.8.5 pipeline regression fixes#75
Merged
Conversation
… v0.8.5 pipeline regression fixes + 11 regression-guard tests
NEW (Step.3 cycle calendar)
- Get-AzLocalApplyUpdatesScheduleCycleCalendar: opt-in -CronFiringsByDate (per-day UTC CRON firing times) and -WindowMatchByRingAndDate (per-ring window-coverage >=95% indicator).
- Export-AzLocalApplyUpdatesScheduleAudit auto-wires both via Read-AzLocalApplyUpdatesYamlCrons + ConvertFrom-AzLocalUpdateWindow. Pure render-time contract preserved.
FIX (v0.8.5 thin-YAML port regressions)
- Step.0 Export-AzLocalAuthValidationReport: @() wrap on unary-comma Invoke-AzResourceGraphQuery collapsed cluster count to 1 - switched to direct assignment + variable-level @() coerce.
- Step.3 Test-AzLocalApplyUpdatesScheduleCoverage: array-level .MatchingCrons enumeration crashed under strict mode on empty $segmentStatuses - guarded with Count check.
- Step.4 Get-AzLocalFleetConnectivityStatus: single-cluster RG crashed because if-as-expression silently unwrapped @() to scalar - now $matchedList -> $matched = @($matchedList) at variable level.
- Step.6 Get-AzLocalClusterUpdateReadiness: $cluster.NotFound strict-mode error - 3 builder paths missing the key, all now set NotFound=$false.
- Step.9 Export-AzLocalFleetHealthStatusReport: @() wrap on both Get-AzLocalFleetHealthFailures and Get-AzLocalFleetHealthOverview collapsed row sets - switched to direct assignment.
- Step.2 Set-AzLocalClusterUpdateRingTag: Format-Table without | Out-Host leaked formatter wrapper objects into -PassThru pipeline (Total clusters processed = 44 vs 20 on a 20-row CSV). Added | Out-Host + defence-in-depth ClusterName -is [string] filter in Set-AzLocalClusterUpdateRingTagFromCsv.
- Step.2 per-cluster Message now names the changed tags ("Tags updated: UpdateExcluded: 'False' -> 'True'") instead of always "UpdateRing tag updated successfully".
- Step.2 summary table split into three independent collapsible buckets (Tag Updates Applied / Skipped or Failed / No Tag Updates).
- Node.js 20 deprecation: bumped actions/upload-artifact@v4 -> @v6 in Step.0 GHA YAML (other steps already on v6).
TESTS (11 new regression-guard It blocks across 7 Describe blocks)
- @() wrap on unary-comma return helpers (Invoke-AzResourceGraphQuery, Get-AzLocalFleetHealth{Failures,Overview}, Read-AzLocalApplyUpdatesYamlCrons).
- Step.3 .MatchingCrons strict-mode crash; Step.4 $matched if/else { @() } branch; Step.6 NotFound key on every $clustersToProcess builder; Step.0 $clusterRows variable-level @() coerce; Step.2 Format-Table | Out-Host.
- GitHub Actions Node.js 20 deprecation (artifact action versions across every bundled GHA YAML).
- 12 new cycle-calendar It blocks for backwards compat / both-params header / (+N) suffix / 95% boundary / case-insensitivity / -ClusterRingCounts coexistence.
DRIFT
- 20 bundled Step.{0..9}.yml templates bump GENERATED_AGAINST_MODULE_VERSION 0.8.5 -> 0.8.6.
- Pester $expectedVersion bumped to 0.8.6.
- Same 55 public exports; no parameter changes on existing cmdlets.
CI Pester 'Should have ReleaseNotes within the PSGallery character limit' caught this: previous block measured 10087 chars (over by 87). Collapsed the 7 verbose 'NEW Pester regression guards' sub-bullets into a single dense line listing the guard topics. Functionally identical disclosure; no source / test / behaviour changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AzLocal.UpdateManagement v0.8.6
Step.3 cycle-calendar enrichment + six v0.8.5 thin-YAML pipeline regression fixes + 11 new Pester regression-guard tests. Same 55 public exports; no parameter changes on existing cmdlets.
NEW (Step.3 cycle calendar)
Get-AzLocalApplyUpdatesScheduleCycleCalendargains two opt-in render-time columns:-CronFiringsByDate([hashtable], keys =yyyy-MM-ddUTC, values =[string[]]ofHH:mmUTC firing times) → centered Ring CRON Start Time (UTC) (Step 6 pipeline) column betweenDate (UTC)andDay. 0 firings →_(none)_; 1-2 → comma-joined; 3+ → first 2 +" (+N)"; dead day →_(none - dead day)_.-WindowMatchByRingAndDate([hashtable[string,hashtable]]) → Tag Start Window Match (>=95%) column afterEligible rings. Per-ring line:`Ring`: True/False mat/tot (pct%).Export-AzLocalApplyUpdatesScheduleAuditauto-wires both viaRead-AzLocalApplyUpdatesYamlCrons+ConvertFrom-AzLocalUpdateWindow. Pure render-time contract preserved; failure mode is non-fatal (degrades to v0.8.5 calendar withWrite-Warning).FIX (v0.8.5 thin-YAML port regressions)
Export-AzLocalAuthValidationReport:@()wrap on unary-commaInvoke-AzResourceGraphQuerycollapsed visible-cluster count to 1. Switched to direct assignment +$clusterRows = @($clusterRows)variable-level coerce.Test-AzLocalApplyUpdatesScheduleCoverage: array-level.MatchingCronsenumeration crashed under strict mode on empty$segmentStatuses. Guarded withCountcheck.Get-AzLocalFleetConnectivityStatus: single-cluster RG crashed because if-as-expression silently unwrapped@()to scalar. Now$matchedList→$matched = @($matchedList)at variable level.Get-AzLocalClusterUpdateReadiness:$cluster.NotFoundstrict-mode error — three builder paths missing the key, all now setNotFound=$false.Export-AzLocalFleetHealthStatusReport:@()wrap on bothGet-AzLocalFleetHealthFailuresandGet-AzLocalFleetHealthOverviewcollapsed row sets. Switched to direct assignment.Set-AzLocalClusterUpdateRingTag:Format-Tablewithout| Out-Hostleaked formatter wrapper objects into-PassThrupipeline (Total clusters processed = 44on a 20-row CSV). Added| Out-Host+ defence-in-depthClusterName -is [string]filter inSet-AzLocalClusterUpdateRingTagFromCsv.Messagenow names changed tags (Tags updated: UpdateExcluded: 'False' -> 'True') instead of always"UpdateRing tag updated successfully". Summary split into 3 collapsible buckets (Tag Updates Applied / Skipped or Failed / No Tag Updates).actions/upload-artifact@v4→@v6inStep.0_authentication-test.yml(every other Step YAML already on v6).TESTS (11 new regression-guard It blocks across 7 Describe blocks)
@()wrap on unary-comma return helpers (Invoke-AzResourceGraphQuery,Get-AzLocalFleetHealth{Failures,Overview},Read-AzLocalApplyUpdatesYamlCrons)..MatchingCronsstrict-mode crash; Step.4$matched if/else { @() }branch; Step.6NotFoundkey on every$clustersToProcessbuilder; Step.0$clusterRowsvariable-level@()coerce; Step.2Format-Table | Out-Host.(+N)suffix / 95% boundary / case-insensitivity /-ClusterRingCountscoexistence.DRIFT
Step.{0..9}.ymltemplates bumpGENERATED_AGAINST_MODULE_VERSION0.8.5→0.8.6.$expectedVersionbumped to0.8.6.Local verification
Live): 1102 passed / 0 failed / 1 skipped, ~8m45s.Live-tagged Step.0 / Step.3 / Step.4 integration tests skipped here (env-onlynebird@microsoft.comnot visible to Azure AD Graph from workstation); CI also excludes theLivetag.