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.2.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') 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.2.0-preview1] - 2026-10-03 ### 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. ### Fixed - AzureDevOpsDscNative - 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-AzDevOpsApiRestMethod` retry and rate-limit handling: - A 429 without a `Retry-After` header stored the retry interval (milliseconds) in a field read as seconds, so the next attempt slept for 250 seconds. It now backs off exponentially in milliseconds. - `Retry-After` was read with a string indexer that PowerShell 7''s `HttpResponseHeaders` does not have, so it was never found. It is now read from any header shape, as seconds or an HTTP date. - Non-transient errors (400, 401, 403, 404, 409 and other 4xx except 408 and 429) are no longer retried; they throw on the first failure. Network errors, 408, 429 and 5xx are still retried, and there is no sleep after the final failed attempt. - `X-RateLimit-Remaining`, `X-RateLimit-Reset` and `Retry-After` are now read from successful responses, so the "close to throttled" slow-down acts on what Azure DevOps reports; a `Retry-After` wait is honoured once instead of before every request until the next success. - `APIRateLimit.xRateLimitRemaining` defaults to `-1` (not reported) rather than `0`, which read as an exhausted budget and added an extra wait after every 429. - With `-NoAuthentication`, the caller''s own `Authorization` header was cleared after the first attempt, so every retry was sent unauthenticated. The header is now cleared only when the function added it. The authentication header check also tested a non-existent `Authentication` key; the module token header is now set explicitly before every request. - Fixed `Get-AzDoProject` throwing "Process template '''' not found" instead of naming the process that was actually missing - the "not found" error interpolated an unrelated, always-null variable rather than the `-ProcessTemplate` parameter it was given ([issue #75](https://github.com/ZanattaMichael/AzureDevOpsDsc/issues/75)). - Fixed `AzDoProject` failing with "Process template ''<name>'' not found" when the process was created by an `AzDoProcess` resource earlier in the same configuration. `Get`, `New` and `Set` looked the name up only in the `LiveProcesses` cache, and each resource invocation runs in its own runspace, so a process created by another resource was not in it. They now use `Resolve-DevOpsProcess`, which falls back to a live lookup and caches what it finds ([issue #75](https://github.com/ZanattaMichael/AzureDevOpsDsc/issues/75)). - Fixed `AzDoServiceConnection` refusing to create a connection whose `Data` carries `url`. `New-DevOpsServiceConnection` lifted `Data.url` to the endpoint''s top-level `url` but also left it inside `data`, which accepts only the inputs the connection type declares, so the API answered `400 Following fields in the service connection are not expected: url`. `url` is now sent once, at the top level. ### Added - AzureDevOpsDscNative - `AzDoPipeline` now supports GitHub, GitHub Enterprise and Bitbucket repositories, and pipeline variables ([#81](https://github.com/ZanattaMichael/AzureDevOpsDsc/issues/81)): - Added the `RepositoryType` property (`TfsGit` default, `GitHub`, `GitHubEnterprise`, `Bitbucket`) and the `ServiceConnectionName` property, required for the three non-`TfsGit` types and resolved to a connection id via the new helper `Resolve-AzDoServiceConnection`. Added `Convert-AzDoPipelineRepositoryType`, which translates the resource''s repository type names (the Build Definitions API''s) into the Pipelines API''s for the create call, and `Get-AzDoPipelineRepositoryUrl`, which gives the clone URL the build definition records when the repository changes. - Added the `Variables` property (an array of `@{ Name; Value; IsSecret; AllowOverride }` hashtables) and the private API function `Set-DevOpsPipelineVariables`, which reads the build definition, replaces only the named variables in its `variables` map, and writes the whole definition back. Only the variables listed in the configuration are managed; other variables already on the pipeline are left untouched. - Secret variable values are write-only: Azure DevOps never returns one, so drift detection for a secret variable compares only its presence and its `IsSecret`/`AllowOverride` flags' } # End of PSData hashtable } # End of PrivateData hashtable } |