diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 95d09b92252..41d2d07e867 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -31,6 +31,9 @@ variables: REGISTRY: 'msgraphprodregistry.azurecr.io' REGISTRY_NAME: 'msgraphprodregistry' IMAGE_NAME: 'public/microsoftgraph/powershell' + # Expose the build identity's token as a process-wide env var so generation scripts (including + # ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) trigger: branches: diff --git a/.azure-pipelines/command-metadata-refresh.yml b/.azure-pipelines/command-metadata-refresh.yml index cfa6f32361c..2312fb284e8 100644 --- a/.azure-pipelines/command-metadata-refresh.yml +++ b/.azure-pipelines/command-metadata-refresh.yml @@ -31,6 +31,9 @@ variables: BuildAgent: ${{ parameters.BuildAgent }} Branch: "ModuleCommandMetadataRefresh" BaseBranch: ${{ parameters.BaseBranch }} + # Expose the build identity's token as a process-wide env var so generation scripts (including + # ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) trigger: branches: diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index c1f65040840..e8c44f83890 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -64,6 +64,48 @@ steps: Copy-Item -Path $src -Destination $dst -Force Write-Host "Copied npm config to $dst" + - task: PowerShell@2 + displayName: Register private module feed (CFSClean) + inputs: + targetType: inline + pwsh: true + errorActionPreference: continue + script: | + # Register the private Azure Artifacts feed (PowerShell Gallery upstream) as a Trusted + # PSRepository so generation-time Install-Module/Find-Module resolve through it instead of + # the public PowerShell Gallery. Persisted for the job (visible to later steps + runspaces). + # errorActionPreference is 'continue' because PackageManagement emits benign non-terminating + # errors (e.g. source-already-registered) that would otherwise fail the task; Register-CfsFeed + # throws on genuine failure, which still fails the step. + . "$(Build.SourcesDirectory)/tools/Get-CfsFeedCredential.ps1" + Unregister-PublicPSGallery + Register-CfsFeed + Get-PSRepository | Format-List Name, SourceLocation, InstallationPolicy, Trusted + # PowerShellGet bootstraps the NuGet provider via a native tool during registration, which can + # leave a stray non-zero $LASTEXITCODE that fails the task even though registration succeeded. + # Register-CfsFeed throws on genuine failure (halting before this line), so reset it here. + $global:LASTEXITCODE = 0 + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - task: PowerShell@2 + displayName: Pre-install generation tooling modules (CFSClean) + inputs: + targetType: inline + pwsh: true + errorActionPreference: continue + script: | + # Install PlatyPS / Pester / powershell-yaml / PowerHTML from the private feed up-front, in this + # controlled credential context, so the lazy Install-Module calls during generation are skipped + # by their Get-Module -ListAvailable guards (authenticated private-feed installs are fragile in + # the parallel generation runspaces). + . "$(Build.SourcesDirectory)/tools/Get-CfsFeedCredential.ps1" + Install-CfsToolingModules + Get-Module -ListAvailable -Name PlatyPS, Pester, powershell-yaml, PowerHTML | Format-Table Name, Version, Path -AutoSize + $global:LASTEXITCODE = 0 + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - task: Npm@1 displayName: Install AutoRest retryCountOnTaskFailure: 2 diff --git a/.azure-pipelines/generation-templates/authentication-module.yml b/.azure-pipelines/generation-templates/authentication-module.yml index 4dc2d7148d1..df35650f367 100644 --- a/.azure-pipelines/generation-templates/authentication-module.yml +++ b/.azure-pipelines/generation-templates/authentication-module.yml @@ -20,6 +20,8 @@ steps: pwsh: true script: | . $(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1 -EnableSigning:$${{ parameters.Sign }} -Build + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ${{ if eq(parameters.Test, true) }}: - task: PowerShell@2 diff --git a/.azure-pipelines/generation-templates/meta-module.yml b/.azure-pipelines/generation-templates/meta-module.yml index f4310d987d2..fcf9a876652 100644 --- a/.azure-pipelines/generation-templates/meta-module.yml +++ b/.azure-pipelines/generation-templates/meta-module.yml @@ -1,4 +1,4 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. +# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. parameters: @@ -50,3 +50,5 @@ steps: pwsh: true script: | . $(System.DefaultWorkingDirectory)/tools/GenerateMetaModule.ps1 -Pack -ArtifactsLocation $(Build.ArtifactStagingDirectory) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/.azure-pipelines/generation-templates/workload-modules.yml b/.azure-pipelines/generation-templates/workload-modules.yml index 47cbc030be1..4a5f5443764 100644 --- a/.azure-pipelines/generation-templates/workload-modules.yml +++ b/.azure-pipelines/generation-templates/workload-modules.yml @@ -1,4 +1,4 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. +# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. parameters: @@ -20,6 +20,8 @@ steps: pwsh: true script: | . $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -EnableSigning:$${{ parameters.Sign }} -Build -ExcludeExampleTemplates -ExcludeNotesSection + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - template: ../common-templates/guardian-analyzer.yml @@ -94,3 +96,5 @@ steps: pwsh: true script: | . $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -SkipGeneration -Pack -ArtifactsLocation $(Build.ArtifactStagingDirectory) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/.azure-pipelines/weekly-generation.yml b/.azure-pipelines/weekly-generation.yml index e859bc415c8..3583c5e6db0 100644 --- a/.azure-pipelines/weekly-generation.yml +++ b/.azure-pipelines/weekly-generation.yml @@ -42,6 +42,9 @@ parameters: variables: BaseBranch: ${{ parameters.BaseBranch }} BuildAgent: ${{ parameters.BuildAgent }} + # Expose the build identity's token as a process-wide env var so generation scripts (including + # ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) trigger: none pr: none schedules: diff --git a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 index de52fcaef5a..1e257e1d5b8 100644 --- a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 +++ b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 @@ -7,7 +7,11 @@ BeforeAll { $ModulePath = Join-Path $PSScriptRoot "..\artifacts\$ModuleName.psd1" Import-Module $ModulePath -Force $RandomClientId = (New-Guid).Guid - Install-Module Az.Accounts -Repository PSGallery -Scope CurrentUser -Force -AllowClobber + # CFSClean: Az.Accounts is pre-installed from the private feed in install-tools (public PSGallery is + # unregistered under network isolation), so only install here if it is somehow not already present. + if (-not (Get-Module -Name Az.Accounts -ListAvailable)) { + Install-Module Az.Accounts -Scope CurrentUser -Force -AllowClobber + } } Describe 'Connect-MgGraph ParameterSets' { BeforeAll { diff --git a/tools/BuildModule.ps1 b/tools/BuildModule.ps1 index e6485f5dfd4..7aa82f20b81 100644 --- a/tools/BuildModule.ps1 +++ b/tools/BuildModule.ps1 @@ -66,8 +66,12 @@ if ($ModuleFullName -ne "Microsoft.Graph.Authentication") { } # Lock module GUID. See https://github.com/Azure/autorest.powershell/issues/981. -$ExistingModule = Find-Module $ModuleFullName -Repository PSGallery -ErrorAction SilentlyContinue -$ModuleGuid = ($null -eq $ExistingModule) ? (New-Guid).Guid : $ExistingModule.AdditionalMetadata.GUID +# CFSClean: the private feed does not surface the module GUID via Find-Module's AdditionalMetadata, +# so read it from the package published on the feed. Mint a new GUID only when unpublished (matches +# the original "first publish" behaviour) without ever querying the public PowerShell Gallery. +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$ModuleGuid = Get-CfsModuleGuid -Name $ModuleFullName +if ([string]::IsNullOrWhiteSpace($ModuleGuid)) { $ModuleGuid = (New-Guid).Guid } [HashTable]$ModuleManifestSettings = @{ Guid = $ModuleGuid diff --git a/tools/GenerateAuthenticationModule.ps1 b/tools/GenerateAuthenticationModule.ps1 index 6d71c22f35d..18939a6ff0c 100644 --- a/tools/GenerateAuthenticationModule.ps1 +++ b/tools/GenerateAuthenticationModule.ps1 @@ -2,7 +2,7 @@ # Licensed under the MIT License. [CmdletBinding()] Param( - [string] $RepositoryName = "PSGallery", + [string] $RepositoryName = "PowerShell_V2_Build", [string] $RepositoryApiKey, [string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"), [switch] $Build, diff --git a/tools/GenerateHelp.ps1 b/tools/GenerateHelp.ps1 index 24750d984f1..1138a96912d 100644 --- a/tools/GenerateHelp.ps1 +++ b/tools/GenerateHelp.ps1 @@ -7,8 +7,12 @@ Param( [string] $ModuleMappingConfigPath = (Join-Path $PSScriptRoot "..\config\ModulesMapping.jsonc") ) # Install PlatyPS +# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream). +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred } if (!(Get-Module -Name PlatyPS -ListAvailable)) { - Install-Module PlatyPS -Force + Install-Module PlatyPS -Repository (Get-CfsFeedName) -Force } Import-Module PlatyPS -Force -Scope Global diff --git a/tools/GenerateMetaModule.ps1 b/tools/GenerateMetaModule.ps1 index a921fb8cb25..1419db24f47 100644 --- a/tools/GenerateMetaModule.ps1 +++ b/tools/GenerateMetaModule.ps1 @@ -6,7 +6,7 @@ Param( [ValidateSet("v1.0", "beta")] $ApiVersion = @("v1.0", "beta"), [string] $RepositoryApiKey, - [string] $RepositoryName = "PSGallery", + [string] $RepositoryName = "PowerShell_V2_Build", [string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"), [switch] $Pack, [switch] $Publish, diff --git a/tools/GenerateRollUpModule.ps1 b/tools/GenerateRollUpModule.ps1 index 25e779bdf6b..7a76433b230 100644 --- a/tools/GenerateRollUpModule.ps1 +++ b/tools/GenerateRollUpModule.ps1 @@ -4,7 +4,7 @@ [CmdletBinding()] Param( [string] $RepositoryApiKey, - [string] $RepositoryName = "PSGallery", + [string] $RepositoryName = "PowerShell_V2_Build", [string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"), [string] $ModuleMappingConfigPath = (Join-Path $PSScriptRoot "..\config\ModulesMapping.jsonc"), [int] $ModulePreviewNumber = -1, @@ -19,6 +19,14 @@ enum VersionState { } $ErrorActionPreference = 'Stop' $LASTEXITCODE = $null +# CFSClean: authenticate module installs/queries to the private feed (credential from the build token). +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { + $PSDefaultParameterValues['Find-Module:Credential'] = $__cfsCred + $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred + $PSDefaultParameterValues['Save-Module:Credential'] = $__cfsCred +} if ($PSEdition -ne 'Core') { Write-Error 'This script requires PowerShell Core to execute. [Note] Generated cmdlets will work in both PowerShell Core or Windows PowerShell.' } diff --git a/tools/Get-CfsFeedCredential.ps1 b/tools/Get-CfsFeedCredential.ps1 new file mode 100644 index 00000000000..b6f62ae54ae --- /dev/null +++ b/tools/Get-CfsFeedCredential.ps1 @@ -0,0 +1,138 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.SYNOPSIS + Shared helpers to route PowerShell module installs/queries through the private Azure Artifacts + feed (CFSClean network isolation) instead of the public PowerShell Gallery. + +.DESCRIPTION + The private feed `PowerShell_V2_Build` has a PowerShell Gallery upstream, so it can serve both + the internally published Graph modules and public tooling modules (Pester, PlatyPS, + powershell-yaml, PowerHTML). Reads the credential from the process-wide $env:SYSTEM_ACCESSTOKEN + (mapped from $(System.AccessToken) at the pipeline `variables:` level), so it works inside + ForEach-Object -Parallel runspaces where session state is not inherited. +#> + +$script:CfsFeedName = 'PowerShell_V2_Build' +$script:CfsFeedUrl = 'https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/nuget/v2' + +function Get-CfsFeedName { + return $script:CfsFeedName +} + +function Get-CfsFeedCredential { + # Returns a PSCredential built from the build identity's access token, or $null when the token is + # unavailable (e.g. local dev), in which case callers fall back to their default behaviour. + if ([string]::IsNullOrWhiteSpace($env:SYSTEM_ACCESSTOKEN)) { + return $null + } + $token = ConvertTo-SecureString $env:SYSTEM_ACCESSTOKEN -AsPlainText -Force + return [System.Management.Automation.PSCredential]::new('azure', $token) +} + +function Register-CfsFeed { + # Registers the private feed as a Trusted PSRepository (idempotent). Persisted under the user's + # PowerShellGet config, so a single registration per job is visible to later steps and runspaces. + $cred = Get-CfsFeedCredential + # Get-PSRepository can lazily return nothing in a fresh session even when the source is already + # persisted (registered by an earlier step/runspace). Get-PackageSource surfaces that collision, + # so check both before attempting to register. + if ((Get-PSRepository -Name $script:CfsFeedName -ErrorAction SilentlyContinue) -or + (Get-PackageSource -Name $script:CfsFeedName -ErrorAction SilentlyContinue)) { + Write-Host "Package source '$($script:CfsFeedName)' is already registered; skipping." + return + } + # The "already added" collision is a non-terminating error emitted by an internal PackageManagement + # cmdlet that bypasses -ErrorAction Stop (and would otherwise fail the task under its default Stop + # preference), so redirect every stream to null and verify the outcome instead of trusting the call. + Register-PSRepository -Name $script:CfsFeedName -SourceLocation $script:CfsFeedUrl -InstallationPolicy Trusted -Credential $cred -ErrorAction SilentlyContinue *> $null + if (-not (Get-PSRepository -Name $script:CfsFeedName -ErrorAction SilentlyContinue)) { + throw "Failed to register PSRepository '$($script:CfsFeedName)'." + } + Write-Host "Registered PSRepository '$($script:CfsFeedName)'." +} + +function Unregister-PublicPSGallery { + # Remove the public PowerShell Gallery. Call this FIRST, before any other PowerShellGet operation, + # so PSGallery is gone before an enumeration resolves its source location (which egresses to + # www.powershellgallery.com - a CFSClean2 violation). Unregister-PackageSource removes the source + # entry without resolving its location; the PSRepository fallback covers the PowerShellGet view. + Unregister-PackageSource -Name 'PSGallery' -Force -ErrorAction SilentlyContinue *> $null + if (Get-PSRepository -Name 'PSGallery' -ErrorAction SilentlyContinue) { + Unregister-PSRepository -Name 'PSGallery' -ErrorAction SilentlyContinue *> $null + } + Write-Host "Removed public 'PSGallery'; module installs now resolve only through '$($script:CfsFeedName)'." + $global:LASTEXITCODE = 0 +} + +function Install-CfsToolingModules { + # Pre-installs the generation-time tooling modules from the private feed once, in this controlled + # credential context, so the lazy Install-Module calls during generation are skipped by their + # Get-Module -ListAvailable guards. This avoids repeating authenticated private-feed installs across + # many generation steps and parallel runspaces (where credential/source resolution is fragile). + $cred = Get-CfsFeedCredential + $tooling = @( + @{ Name = 'PlatyPS' }, + @{ Name = 'Pester'; SkipPublisherCheck = $true }, + @{ Name = 'powershell-yaml'; AcceptLicense = $true }, + @{ Name = 'PowerHTML' }, + @{ Name = 'Az.Accounts' } + ) + foreach ($t in $tooling) { + if (Get-Module -Name $t.Name -ListAvailable) { + Write-Host "Tooling module '$($t.Name)' already available; skipping." + continue + } + $params = @{ Name = $t.Name; Repository = $script:CfsFeedName; Scope = 'AllUsers'; Force = $true; AllowClobber = $true } + if ($null -ne $cred) { $params.Credential = $cred } + if ($t.SkipPublisherCheck) { $params.SkipPublisherCheck = $true } + if ($t.AcceptLicense) { $params.AcceptLicense = $true } + Install-Module @params + Write-Host "Installed tooling module '$($t.Name)' from '$($script:CfsFeedName)'." + } + $global:LASTEXITCODE = 0 +} + +function Get-CfsModuleGuid { + # Returns the GUID of the module already published to the private feed, or $null when it is not + # published there or the GUID cannot be determined (callers then mint a fresh GUID, preserving the + # original "first publish" behaviour). The Azure Artifacts feed does not surface the GUID via + # Find-Module's AdditionalMetadata (public PS Gallery does), so this downloads the published package + # directly over HTTP from the feed's NuGet v2 OData endpoint and reads the GUID from its manifest. + # Using raw HTTP (not Find-Module/Save-Package) avoids PowerShellGet/PackageManagement source + # resolution, which is unreliable in the generation runspaces, and never touches public PS Gallery. + # The module GUID is version-independent (locked), so any published version's manifest is fine. + param( + [Parameter(Mandatory)][string] $Name + ) + if ([string]::IsNullOrWhiteSpace($env:SYSTEM_ACCESSTOKEN)) { return $null } + $headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("azure:$($env:SYSTEM_ACCESSTOKEN)")) } + $tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("cfsguid_" + [System.Guid]::NewGuid().ToString('N')) + try { + New-Item -ItemType Directory -Path $tmp -Force | Out-Null + $findUri = "$($script:CfsFeedUrl)/FindPackagesById()?id='$Name'" + $resp = Invoke-WebRequest -Uri $findUri -Headers $headers -UseBasicParsing -ErrorAction Stop + [xml]$xml = $resp.Content + $entry = @($xml.feed.entry) | Where-Object { $_.content.src } | Select-Object -Last 1 + if ($null -eq $entry) { return $null } + $nupkgPath = Join-Path $tmp "$Name.nupkg" + Invoke-WebRequest -Uri $entry.content.src -Headers $headers -OutFile $nupkgPath -UseBasicParsing -ErrorAction Stop + Add-Type -AssemblyName System.IO.Compression.FileSystem + $zip = [System.IO.Compression.ZipFile]::OpenRead($nupkgPath) + try { + $psd1 = $zip.Entries | Where-Object { $_.Name -eq "$Name.psd1" } | Select-Object -First 1 + if ($null -eq $psd1) { return $null } + $reader = [System.IO.StreamReader]::new($psd1.Open()) + try { $content = $reader.ReadToEnd() } finally { $reader.Dispose() } + } + finally { $zip.Dispose() } + $match = [regex]::Match($content, "(?im)^\s*GUID\s*=\s*['`"]([0-9a-fA-F-]{36})['`"]") + if ($match.Success) { return $match.Groups[1].Value } + return $null + } + catch { return $null } + finally { + Remove-Item -Path $tmp -Recurse -Force -ErrorAction SilentlyContinue + } +} diff --git a/tools/ImportExamples.ps1 b/tools/ImportExamples.ps1 index 030b224e757..3212d68e1f8 100644 --- a/tools/ImportExamples.ps1 +++ b/tools/ImportExamples.ps1 @@ -575,13 +575,17 @@ function Get-ExistingCorrectExamples { } $RetainedExamples = New-Object Collections.Generic.List[string] +# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream). +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred } if (!(Get-Module "powershell-yaml" -ListAvailable -ErrorAction SilentlyContinue)) { - Install-Module "powershell-yaml" -AcceptLicense -Scope CurrentUser -Force + Install-Module "powershell-yaml" -Repository (Get-CfsFeedName) -AcceptLicense -Scope CurrentUser -Force } If (-not (Get-Module -ErrorAction Ignore -ListAvailable PowerHTML)) { Write-Verbose "Installing PowerHTML module for the current user..." - Install-Module PowerHTML -ErrorAction Stop -Scope CurrentUser -Force + Install-Module PowerHTML -Repository (Get-CfsFeedName) -ErrorAction Stop -Scope CurrentUser -Force } Import-Module -ErrorAction Stop PowerHTML diff --git a/tools/TestModule.ps1 b/tools/TestModule.ps1 index adfb15d7576..081f9ca81d8 100644 --- a/tools/TestModule.ps1 +++ b/tools/TestModule.ps1 @@ -5,8 +5,12 @@ param([string] $ModulePath, [string] $ModuleName, [string] $ModuleTestsPath, [sw $ErrorActionPreference = 'Stop' # Install Pester +# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream). +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred } if (!(Get-Module -Name Pester -ListAvailable)) { - Install-Module -Name Pester -Force -SkipPublisherCheck + Install-Module -Name Pester -Repository (Get-CfsFeedName) -Force -SkipPublisherCheck } if(-not $Isolated) { diff --git a/tools/UpdateOpenApi.ps1 b/tools/UpdateOpenApi.ps1 index 64d4e4f154c..1b98f04ca41 100644 --- a/tools/UpdateOpenApi.ps1 +++ b/tools/UpdateOpenApi.ps1 @@ -15,8 +15,11 @@ if ($PSEdition -ne 'Core') { } if (!(Get-Module powershell-yaml -ListAvailable)) { - # Install Powershell-yaml - Install-Module powershell-yaml -Force + # Install Powershell-yaml from the private feed (PowerShell Gallery upstream). (CFSClean) + . (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') + $__cfsCred = Get-CfsFeedCredential + if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred } + Install-Module powershell-yaml -Repository (Get-CfsFeedName) -Force } $GraphVersion = "v1.0" diff --git a/tools/ValidateUpdatedModuleVersion.ps1 b/tools/ValidateUpdatedModuleVersion.ps1 index b916f78f5b6..69d925b1725 100644 --- a/tools/ValidateUpdatedModuleVersion.ps1 +++ b/tools/ValidateUpdatedModuleVersion.ps1 @@ -4,7 +4,7 @@ param( [Parameter()][ValidateNotNullOrEmpty()][string] $ModuleName, [Parameter()][ValidateNotNullOrEmpty()][string] $NextVersion, - [Parameter()][string] $PSRepository = "PSGallery", + [Parameter()][string] $PSRepository = "PowerShell_V2_Build", [int] $ModulePreviewNumber = -1 ) enum VersionState { @@ -18,6 +18,15 @@ enum VersionState { Import-Module PackageManagement Import-Module PowerShellGet +# CFSClean: authenticate module queries to the private feed (credential from the build token). +. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { + $PSDefaultParameterValues['Find-Module:Credential'] = $__cfsCred + $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred + $PSDefaultParameterValues['Save-Module:Credential'] = $__cfsCred +} + $AllowPreRelease = $true if($ModulePreviewNumber -eq -1) { $AllowPreRelease = $false diff --git a/tools/Versions/BumpModuleVersion.ps1 b/tools/Versions/BumpModuleVersion.ps1 index 6325b5ddc0b..411fe80b426 100644 --- a/tools/Versions/BumpModuleVersion.ps1 +++ b/tools/Versions/BumpModuleVersion.ps1 @@ -7,12 +7,17 @@ Param( [switch] $BumpBetaModule, [switch] $BumpAuthModule, [string] $PreReleaseTag, - [string] $Repository = "PSGallery" + [string] $Repository = "PowerShell_V2_Build" ) $ErrorActionPreference = "Stop" . $PSScriptRoot\SetModuleVersion.ps1 +# CFSClean: authenticate module queries to the private feed (credential from the build token). +. (Join-Path $PSScriptRoot '..\Get-CfsFeedCredential.ps1') +$__cfsCred = Get-CfsFeedCredential +if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Find-Module:Credential'] = $__cfsCred } + # Calculate and bump v1.0 module version if ($BumpV1Module.IsPresent) { $v1Module = Find-Module "Microsoft.Graph" -Repository $Repository -AllowPrerelease