AzureDevOpsDscNative.psd1
|
@{ RootModule = 'AzureDevOpsDscNative.psm1' # Version number of this module. # # This value is a fallback for local and CI builds only. Released versions are # driven by the git tag: the publish workflow sets $env:ModuleVersion from the # tag, and the build stamps that value into the packaged manifest instead of this # one. Do not hand-edit this to cut a release - push a vX.Y.Z tag. moduleVersion = '1.3.0' # ID used to uniquely identify this module GUID = 'e7eb078e-5e97-42be-ae8f-decb140fc38e' # Author of this module Author = 'ZanattaMichael' # Company or vendor of this module CompanyName = 'ZanattaMichael' # Copyright statement for this module Copyright = 'Copyright the DSC Community contributors and ZanattaMichael. All rights reserved.' # Description of the functionality provided by this module Description = 'A fork of the DSC Community AzureDevOpsDsc module with native DSC v3 support: every resource is discoverable and invokable by dsc.exe via the Microsoft.Adapter/PowerShell adapter, using generated adapted resource manifests, without requiring a wrapper resource.' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '7.0' # Minimum version of the common language runtime (CLR) required by this module CLRVersion = '4.0' # Functions to export from this module #FunctionsToExport = @() # Cmdlets to export from this module #CmdletsToExport = @() # Variables to export from this module VariablesToExport = @() # Aliases to export from this module AliasesToExport = @() # Import all the 'DSCClassResource', modules as part of this module NestedModules = @() DscResourcesToExport = @('AzDoGroupPermission','AzDoOrganizationGroup','AzDoProject','AzDoProjectServices','AzDoProjectGroup','AzDoGroupMember','AzDoGitRepository','AzDoGitPermission','AzDoAreaPermission','AzDoIterationPermission','AzDoWIPTags','AzDoAreaNodes','AzDoIterationNodes','AzDoBranchPolicy','AzDoVariableGroup','AzDoServiceConnection','AzDoPipelineEnvironment','AzDoAgentPool','AzDoAgentQueue','AzDoTeam','AzDoTeamMember','AzDoPipeline','AzDoPipelinePermission','AzDoEnvironmentApproval','AzDoVariableGroupPermission','AzDoServiceConnectionPermission','AzDoAgentPoolPermission','AzDoSecurityNamespacePermission','AzDoArtifactFeed','AzDoArtifactFeedPermission','AzDoDeploymentGroup','AzDoTaskGroup','AzDoOrganizationSettings','AzDoExtension','AzDoAuditStream','AzDoProjectPermission','AzDoEnvironmentPermission','AzDoWiki','AzDoNotificationSubscription','AzDoRepositorySettings','AzDoCheckConfiguration','AzDoTeamSettings','AzDoArtifactFeedSettings','AzDoArtifactFeedView','AzDoProcess','AzDoProcessPermission','AzDoUserEntitlement','AzDoServiceHook','AzDoPipelineSettings','AzDoQueryFolder','AzDoWorkItemQuery','AzDoQueryPermission','AzDoWIPTagHygiene','AzDoSecureFile','AzDoSecureFilePermission','AzDoPipelineFolder','AzDoPipelineFolderPermission','AzDoGroupEntitlement','AzDoServicePrincipalEntitlement','AzDoPicklist','AzDoProcessWorkItemType','AzDoProcessField','AzDoProcessState','AzDoProcessRule','AzDoProcessBehavior','AzDoPipelineAuthorization','AzDoEnvironmentKubernetesResource','AzDoEnvironmentVMResource','AzDoDeploymentGroupTarget','AzDoReleaseFolder','AzDoReleaseFolderPermission','AzDoReleaseDefinitionPermission','AzDoTestVariable','AzDoTestConfiguration','AzDoTestPlan','AzDoTestSuite','AzDoBuildRetentionSettings','AzDoWikiPage','AzDoTaggingPermission','AzDoAnalyticsPermission','AzDoAnalyticsViewsPermission','AzDoDashboard','AzDoOrganizationPermission','AzDoTaskGroupPermission') RequiredAssemblies = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Set to a prerelease string value if the release should be a prerelease. Prerelease = 'preview1' # Tags applied to this module. These help with module discovery in online galleries. Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource', 'DSCv3', 'AzureDevOps') # A URL to the license for this module. LicenseUri = 'https://github.com/ZanattaMichael/AzureDevOpsDsc/blob/main/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/ZanattaMichael/AzureDevOpsDsc' # A URL to an icon representing this module. IconUri = 'https://dsccommunity.org/images/DSC_Logo_300p.png' # ReleaseNotes of this module. # Per-release notes are generated from the CHANGELOG's [Unreleased] section # at build time and attached to the GitHub Release. This link is the fallback # shown on the Gallery listing. ReleaseNotes = '## [1.3.0-preview1] - 2026-10-18 ### Changed - Build - `azure-pipelines.yml` brought in line with the GitHub workflows so it runs on current Microsoft-hosted agents: full-history checkout for GitVersion, GitVersion.Tool 5.12.0 run with `DOTNET_ROLL_FORWARD=Major` (hosted images no longer ship .NET 6/7), unit tests run under Pester 5.7.1 as in `unit-tests.yml` instead of the Pester 4 `build.ps1 -tasks test` path, HQRM reported but non-gating, and the retired Codecov bash uploader and `PublishCodeCoverageResults@1` removed. The Deploy stage no longer requires a `dsccommunity` organization; it runs only on a `v*` tag with the pipeline variable `PublishRelease` set to `true`. - The integration workflows now cope with more than one runner carrying the `AZDO-AGENT` label. The v2 and v3 live-organization jobs share one concurrency group, so they no longer run against the organization at the same time and delete each other''s test objects in their pre-run teardown. - The integration workflows no longer move module copies out of, and back into, the runner''s standard module folders around each run - a failed move there stranded copies in `RUNNER_TEMP`, which the runner empties between jobs. They load the module only from their workspace build and now fail, naming each one, if a copy is installed in a standard module folder. `tests/Integration/README.md` lists what an `AZDO-AGENT` machine needs. - `scripts/redeploy-module.ps1` no longer copies the build into `Documents\PowerShell\Modules`. It puts `output\builtModule` at the front of `PSModulePath` for the current session and warns about any copy in a standard module folder. - AzureDevOpsDscNative - `AzDoProject.ProcessTemplate` no longer restricts a project to the four system processes (`Agile`, `Scrum`, `CMMI`, `Basic`) via `ValidateSet` - any process name known to the organization, including an inherited process, is accepted and resolved against the `LiveProcesses` cache, falling back to a live lookup. `Set` can now change a project''s process: `Get-AzDoProject` compares the project''s current process against the desired one and, when they differ, resolves both to their system-process ancestor (`Get-AzDoProcessFamilyRootId`) to decide whether Azure DevOps will permit the migration. A compatible change (moving between a system process and one of its inherited children, or between two inherited children of the same parent) is applied via the new `projectprocessmigration` endpoint (`Move-DevOpsProjectProcess`); an incompatible one - crossing unrelated process families - is refused with a clear error in both `Get` and `Set`, since `Get`''s `Error` status still routes to `Set` and the refusal has to be repeated there to hold. Previously, `ProcessTemplate` was listed in `GetDscResourcePropertyNamesWithNoSetSupport()` and `Update-DevOpsProject` took a `ProcessTemplateId` parameter it never referenced, so a process change on an existing project was always a silent no-op ([issue #75](https://github.com/ZanattaMichael/AzureDevOpsDsc/issues/75)). - Performance - `Set()` now runs the resource''s `Get` function once instead of twice: `SetToDesiredState()` reads the current state and passes it to a new `GetDscRequiredAction([Hashtable])` overload rather than reading it again. - The fixed 2-second sleep after every `Set()` is gone. `GetPostSetWaitTimeMs()` now defaults to `0`; a resource whose API needs time before a write is readable overrides it. - Caches are loaded on first use. `Construct()` no longer initializes every cache type (with `-Debug` forced on) each time a resource is instantiated; `Get-CacheObject` already imports a cache when it is first read. A missing cache file is now reported as verbose output rather than a warning, since it is the normal state for a cache nothing has written yet. - Cache lookups no longer copy or scan the whole cache: - `Get-CacheObject` returns the live cache list instead of letting PowerShell unroll it into a copy on every read. An empty cache comes back as an empty list rather than `$null`, and a cache stored as an array is normalized to a `List[CacheItem]` once. - `Add-CacheItem` and `Get-CacheItem` find a key through a new case-insensitive key index (`Get-CacheKeyIndex`) instead of a `Where-Object` scan, so filling a cache is linear rather than quadratic. The index is rebuilt whenever the cache list is replaced or its count changes, and a cache holding a duplicate key falls back to scanning. - `Add-CacheItem` replaces an existing key in place instead of copying the cache through `Remove-CacheItem`. - `Find-Identity` filters the group, user and service-principal caches with `.Where()` instead of copying each one per ACE. - `CacheItem` stamps its creation time with `[datetime]::Now` rather than a `Get-Date` call. - Documentation - `docs/ResourceRoadmap.md` gains §12, the resources a code review found missing that neither the roadmap nor an open issue tracked: permission resources for the `Collection`, `MetaTask`, `ServiceHooks`, `AuditLog`, `EventSubscription` and `VersionControlItems` namespaces and for deployment groups and project agent queues; `AzDoWorkItemTemplate` and `AzDoTaskboardColumn`; `AzDoAgent`, agent pool maintenance and per-pipeline settings on `AzDoPipeline`; `AzDoTestResultRetentionSettings` and organization-wide feed permissions; and project properties and notification delivery settings. It also records what was checked and found already covered or not buildable, and a suggested order. §2, §8 and §9 point to it. - `docs/ResourceRoadmap.md` gains §13 for open issues #66 (Copilot code review) and #67 (GitHub Advanced Security), which the roadmap did not mention. It lists the proposed resources and the questions each issue must settle first, and gives an order. §8 and §9 point to it. ### Fixed - Integration tests - `AzDoQueryPermission` and `AzDoWorkItemQuery` create their query folder through the new `Invoke-TestQueryFolderSet`. It retries the `TF401256: You do not have Write permissions for query Shared Queries` 403 that a project returns for a few seconds after it reaches `wellFormed`. `Invoke-AzDevOpsApiRestMethod` no longer retries a 403, and that retry used to hide the delay. - `AzDoReleaseDefinitionPermission` calls `Enable-TestClassicPipeline` before creating its classic release definition, and skips when an organization policy forbids classic pipelines, as `AzDoTaskGroup` and `AzDoDeploymentGroup` already do. - `AzDoPicklist` polls for up to 30 seconds for the removed picklist to drop out of the picklist list. The list could still return it for a moment after a successful DELETE. - `Get-MIToken` requests its token with `-NoAuthentication`, which `Invoke-APIRestMethod` now honours. It used to build an Authorization header from `$Global:DSCAZDO_AuthenticationToken`, so after a test whose token request failed had left that global null, the post-run teardown threw before cleaning up or reporting the test results. - AzureDevOpsDscNative - Reloading a cache no longer writes the whole cache to the output stream ([issue #55](https://github.com/ZanattaMichael/AzureDevOpsDsc/issues/55)). `Import-CacheObject` returns the collection it imported, and `Initialize-CacheObject`, `Refresh-CacheObject` and `Refresh-AzDoCache` called it for its side effect without discarding that value. Every `New-` and `Set-` function that ends by refreshing its cache printed the cache as a `Key`/`Value` table during `Invoke-DscResource`. - `Get-AzDoProjectServices` reports `NotFound` for a project that does not exist, rather than failing with `TF200016`. Its live fallback lookup now goes through `Resolve-AzDoProject`, which treats a 404 as no project. - `Invoke-AzDevOpsApiRestMethod -AzureArcAuthentication` retries a 408, 429 or 5xx from the Azure Arc token endpoint like any other request. It used to hand every error straight back to `Get-AzManagedIdentityToken`, which only needs the 401 challenge unchanged, so a throttled token request failed the resource being constructed. It showed up as a 429 failing `[AzDoProject]::Export()` and `[AzDoGitRepository]::Export()`. - `Invoke-AzDevOpsApiRestMethod` no longer throws "Unable to find type [APIRateLimit]" on a 429 or a response carrying rate-limit headers. The class lives in the root module, which the nested `AzureDevOpsDsc.Common` module cannot resolve type names from; it now builds the object through the new `New-APIRateLimit` function, as the token classes already do. - The nested `AzureDevOpsDsc.Common` module now imports the `DscResource.Common` copy shipped beside it. It called `Get-LocalizedData` without importing it, so the command was found through auto-discovery as an export of `AzureDevOpsDscNative`, which was itself still loading. Every process that had not already imported `DscResource.Common` globally failed to load the module with "the module could not be loaded". That included each `dsc resource get/test/set` call through the DSC v3 PowerShell adapter. - The identity cache initializer (`AzDoAPI_7_IdentitySubjectDescriptors`) re-added every group, user and service principal with the whole cache item as its value, so `.value.ACLIdentity` read `$null` for all of them and every descriptor lookup in `Find-Identity` missed the cache and fell through to the API. The resolved identity is now stamped onto the cached item in place. - `Invoke-AzDevOp' } # End of PSData hashtable } # End of PrivateData hashtable } |