From 7f0869fce055be5fc7746e1d319826a5ed21790d Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:14:35 -0700 Subject: [PATCH 01/14] add explicit working dir to intall tools step --- .azure-pipelines/common-templates/install-tools.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index a4c9c40cc8..5773c666e2 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -52,18 +52,21 @@ steps: displayName: Install AutoRest inputs: command: custom + workingDir: $(Build.SourcesDirectory) customCommand: install -g autorest@3.7.2 - + - task: Npm@1 displayName: Install AutorestCore inputs: command: custom + workingDir: $(Build.SourcesDirectory) customCommand: install -g @autorest/core@3.10.4 - task: Npm@1 displayName: Install Rush inputs: command: custom + workingDir: $(Build.SourcesDirectory) customCommand: install -g @microsoft/rush - task: PowerShell@2 From db1e91b5afdc4be98a68ea14901a8cec61ebfa43 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:40:15 -0700 Subject: [PATCH 02/14] add registry flag --- .azure-pipelines/common-templates/install-tools.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index 5773c666e2..1fba74edf8 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -53,21 +53,21 @@ steps: inputs: command: custom workingDir: $(Build.SourcesDirectory) - customCommand: install -g autorest@3.7.2 + customCommand: install -g autorest@3.7.2 --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ - task: Npm@1 displayName: Install AutorestCore inputs: command: custom workingDir: $(Build.SourcesDirectory) - customCommand: install -g @autorest/core@3.10.4 + customCommand: install -g @autorest/core@3.10.4 --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ - task: Npm@1 displayName: Install Rush inputs: command: custom workingDir: $(Build.SourcesDirectory) - customCommand: install -g @microsoft/rush + customCommand: install -g @microsoft/rush --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ - task: PowerShell@2 displayName: Rush Build From c6a96f7656d7c0fef5867c401e3583f35fc5ebd5 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:45:33 -0700 Subject: [PATCH 03/14] derive nuget feed uri in script --- tools/Configure-PrivateNpmFeed.ps1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/Configure-PrivateNpmFeed.ps1 b/tools/Configure-PrivateNpmFeed.ps1 index e8d6f75ada..5689165590 100644 --- a/tools/Configure-PrivateNpmFeed.ps1 +++ b/tools/Configure-PrivateNpmFeed.ps1 @@ -35,3 +35,18 @@ Write-Host "Created $rootNpmrc" $rushNpmrc = Join-Path $SourcesDirectory "autorest.powershell/common/config/rush/.npmrc" Set-Content -Path $rushNpmrc -Value $npmrcContent -NoNewline Write-Host "Updated $rushNpmrc" + +# Create NuGet.config to redirect dotnet restore to the private feed +$nugetFeed = $Registry -replace "/npm/registry/$", "/nuget/v3/index.json" +$nugetConfig = @" + + + + + + + +"@ +$nugetConfigPath = Join-Path $SourcesDirectory "NuGet.config" +Set-Content -Path $nugetConfigPath -Value $nugetConfig -NoNewline +Write-Host "Created $nugetConfigPath" From b4ab14bdd4d6c885ba7f6314a8e44d1b995adcc1 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:48:20 -0700 Subject: [PATCH 04/14] remove use of powershell-yaml --- tools/GenerateModules.ps1 | 4 ---- tools/ReadModuleReadMe.ps1 | 14 +++++++++++++- tools/WriteToModuleReadMe.ps1 | 14 +++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/tools/GenerateModules.ps1 b/tools/GenerateModules.ps1 index ce7f44b411..9c6a586830 100644 --- a/tools/GenerateModules.ps1 +++ b/tools/GenerateModules.ps1 @@ -32,10 +32,6 @@ if (-not $Isolated) { # Module import. Import-Module PowerShellGet -# Install Powershell-yaml -if (!(Get-Module -Name powershell-yaml -ListAvailable)) { - Install-Module powershell-yaml -Repository PSGallery -Scope CurrentUser -Force -} $ScriptRoot = $PSScriptRoot $ModulesSrc = Join-Path $ScriptRoot "..\src\" diff --git a/tools/ReadModuleReadMe.ps1 b/tools/ReadModuleReadMe.ps1 index a6f8c5c196..93b07bfa48 100644 --- a/tools/ReadModuleReadMe.ps1 +++ b/tools/ReadModuleReadMe.ps1 @@ -6,12 +6,24 @@ param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $FieldToRead ) $ErrorActionPreference = "Stop" + +function ConvertFrom-SimpleYaml { + param([string]$Yaml) + $result = @{} + $Yaml -split "`n" | ForEach-Object { + if ($_.Trim() -match '^([^:]+):\s*(.*)$') { + $result[$Matches[1].Trim()] = $Matches[2].Trim() + } + } + return $result +} + $FieldValue = $null # Read readme.md. $ReadMeContent = Get-Content $ReadMePath -Delimiter "### Versioning" if ($ReadMeContent.Length -eq 2) { # Convert versioning section to yaml. - $VersioningSection = $ReadMeContent[1].Replace("``", "").Replace("yaml", "") | ConvertFrom-Yaml + $VersioningSection = $ReadMeContent[1].Replace("``", "").Replace("yaml", "") | ConvertFrom-SimpleYaml $FieldValue = $VersioningSection[$FieldToRead] } return $FieldValue diff --git a/tools/WriteToModuleReadMe.ps1 b/tools/WriteToModuleReadMe.ps1 index 0a921551ee..5ac0234e47 100644 --- a/tools/WriteToModuleReadMe.ps1 +++ b/tools/WriteToModuleReadMe.ps1 @@ -7,12 +7,24 @@ param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $NewFieldValue ) $ErrorActionPreference = "Stop" + +function ConvertFrom-SimpleYaml { + param([string]$Yaml) + $result = @{} + $Yaml -split "`n" | ForEach-Object { + if ($_.Trim() -match '^([^:]+):\s*(.*)$') { + $result[$Matches[1].Trim()] = $Matches[2].Trim() + } + } + return $result +} + # Read readme.md. $ReadMeContent = Get-Content $ReadMePath -Delimiter "### Versioning" if ($ReadMeContent.Length -eq 2) { # Convert versioning section to yaml. $UpdatedVersionSection = "### Versioning" + $ReadMeContent[1] - $VersioningSection = $ReadMeContent[1].Replace("``", "").Replace("yaml", "") | ConvertFrom-Yaml + $VersioningSection = $ReadMeContent[1].Replace("``", "").Replace("yaml", "") | ConvertFrom-SimpleYaml $FieldValue = $VersioningSection[$FieldName] $RegexPattern = "$FieldName`:\s*$FieldValue" $UpdatedVersionSection = $UpdatedVersionSection -replace $RegexPattern, "$FieldName`: $NewFieldValue" From 479bf52fc2b15ab5ae21ab492ec184c84cbdae3e Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:09:10 -0700 Subject: [PATCH 05/14] replace rush update purge --- tools/GenerateModules.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/GenerateModules.ps1 b/tools/GenerateModules.ps1 index 9c6a586830..05a3690562 100644 --- a/tools/GenerateModules.ps1 +++ b/tools/GenerateModules.ps1 @@ -48,7 +48,7 @@ if (-not (Test-Path $ModuleMappingPath)) { # Build AutoREST.PowerShell submodule. Set-Location (Join-Path $ScriptRoot "../autorest.powershell") -rush update --purge +rush install rush build $RequiredGraphModules = @() From cfbf2139aa45b4e3196216ac245d1f2ae4866ac1 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:38:43 -0700 Subject: [PATCH 06/14] set npm userconfig for all npm subprocessess --- .azure-pipelines/common-templates/install-tools.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index 1fba74edf8..e3b565c1f9 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -48,6 +48,14 @@ steps: inputs: workingFile: $(Build.SourcesDirectory)/autorest.powershell/common/config/rush/.npmrc + - task: PowerShell@2 + displayName: Set npm userconfig for all npm subprocesses + inputs: + targetType: inline + pwsh: true + script: | + Write-Host "##vso[task.setvariable variable=NPM_CONFIG_USERCONFIG]$(Build.SourcesDirectory)/.npmrc" + - task: Npm@1 displayName: Install AutoRest inputs: From cf46f0e97cf7a6d5a1e590e9d6fdb3bca1b6889b Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 22 Apr 2026 16:52:00 -0700 Subject: [PATCH 07/14] use npmrc for subsequent npm auth --- .../common-templates/install-tools.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index e3b565c1f9..741b1bffa4 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -49,12 +49,17 @@ steps: workingFile: $(Build.SourcesDirectory)/autorest.powershell/common/config/rush/.npmrc - task: PowerShell@2 - displayName: Set npm userconfig for all npm subprocesses + displayName: Apply npm auth config to user profile inputs: targetType: inline pwsh: true script: | - Write-Host "##vso[task.setvariable variable=NPM_CONFIG_USERCONFIG]$(Build.SourcesDirectory)/.npmrc" + # Copy authenticated .npmrc to the user home dir so ALL npm subprocesses + # (including autorest's internal npm calls) use the private feed + auth tokens. + $src = "$(Build.SourcesDirectory)/.npmrc" + $dst = Join-Path $env:USERPROFILE ".npmrc" + Copy-Item -Path $src -Destination $dst -Force + Write-Host "Copied npm config to $dst" - task: Npm@1 displayName: Install AutoRest @@ -85,5 +90,8 @@ steps: workingDirectory: "autorest.powershell" script: | rush install + if ($LASTEXITCODE -ne 0) { throw "rush install failed with exit code $LASTEXITCODE" } rush link - rush rebuild \ No newline at end of file + if ($LASTEXITCODE -ne 0) { throw "rush link failed with exit code $LASTEXITCODE" } + rush rebuild + if ($LASTEXITCODE -ne 0) { throw "rush rebuild failed with exit code $LASTEXITCODE" } \ No newline at end of file From fb758c36c53420c0c97e898a4412e7024ab43ca0 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:45:15 -0700 Subject: [PATCH 08/14] ensure deps downloaded --- .../common-templates/install-tools.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index 741b1bffa4..de2c207444 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -75,6 +75,22 @@ steps: workingDir: $(Build.SourcesDirectory) customCommand: install -g @autorest/core@3.10.4 --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ + - task: PowerShell@2 + displayName: Pre-populate autorest core cache + inputs: + targetType: inline + pwsh: true + script: | + # Autorest looks for @autorest/core in ~/.autorest/@autorest/core//node_modules/ + # Pre-installing it here with the explicit registry flag means autorest never needs + # to make any npm calls during module generation. + $cacheDir = Join-Path $env:USERPROFILE ".autorest\@autorest\core\3.10.4" + New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null + Write-Host "Pre-installing @autorest/core@3.10.4 into autorest cache: $cacheDir" + npm install @autorest/core@3.10.4 --prefix $cacheDir --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ + if ($LASTEXITCODE -ne 0) { throw "Failed to pre-install @autorest/core@3.10.4 into autorest cache (exit $LASTEXITCODE)" } + Write-Host "Autorest core cache pre-populated successfully" + - task: Npm@1 displayName: Install Rush inputs: From b759e241cb9d132cfc86349ed1a5d63a4accb9e8 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 13:37:05 -0700 Subject: [PATCH 09/14] add logging to determine failure --- tools/GenerateModules.ps1 | 18 ++++++++++++++++++ tools/GenerateServiceModule.ps1 | 13 +++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/tools/GenerateModules.ps1 b/tools/GenerateModules.ps1 index 05a3690562..35b911b8e9 100644 --- a/tools/GenerateModules.ps1 +++ b/tools/GenerateModules.ps1 @@ -51,6 +51,24 @@ Set-Location (Join-Path $ScriptRoot "../autorest.powershell") rush install rush build +# Diagnostic: show autorest cache state and npm registry config before generation. +Write-Host "--- Autorest/npm diagnostics ---" +$autorestHome = if ($env:AUTOREST_HOME) { $env:AUTOREST_HOME } else { Join-Path $env:USERPROFILE ".autorest" } +Write-Host "AUTOREST_HOME: $autorestHome" +$coreCacheDir = Join-Path $autorestHome "@autorest\core" +if (Test-Path $coreCacheDir) { + Write-Host "Autorest core cache versions: $(Get-ChildItem $coreCacheDir -Directory | Select-Object -ExpandProperty Name)" + $nodeModulesDir = Join-Path $coreCacheDir "3.10.4\node_modules\@autorest\core" + Write-Host "Cache 3.10.4 node_modules present: $(Test-Path $nodeModulesDir)" +} else { + Write-Host "WARNING: Autorest core cache directory not found at $coreCacheDir" +} +Write-Host "npm registry: $(npm config get registry 2>&1)" +Write-Host "NPM_CONFIG_USERCONFIG: $env:NPM_CONFIG_USERCONFIG" +$userNpmrc = Join-Path $env:USERPROFILE ".npmrc" +Write-Host "~/.npmrc exists: $(Test-Path $userNpmrc)" +Write-Host "--- End diagnostics ---" + $RequiredGraphModules = @() $AuthModuleManifest = Join-Path $ModulesSrc "Authentication" "Authentication" "artifacts" "Microsoft.Graph.Authentication.psd1" $LoadedAuthModule = Import-Module $AuthModuleManifest -PassThru -ErrorAction SilentlyContinue diff --git a/tools/GenerateServiceModule.ps1 b/tools/GenerateServiceModule.ps1 index d5385173ac..d50ba21184 100644 --- a/tools/GenerateServiceModule.ps1 +++ b/tools/GenerateServiceModule.ps1 @@ -69,10 +69,15 @@ $ApiVersion | ForEach-Object { else { $FullModuleVersion = $ModuleMetadata.versions[$CurrentApiVersion].version } - npx autorest --max-memory-size=$MaxMemorySize --module-version:$FullModuleVersion --module-name:$ModuleFullName --service-name:$Module --input-file:$OpenApiFile $AutoRestModuleConfig --max-cpu=2 --network-calls=2 - if ($LastExitCode -ne 0) { - Write-Host -ForegroundColor Red "AutoREST failed to generate '$ModuleFullName' module." - return $LastExitCode + $autorestLog = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "autorest-$($ModuleFullName -replace '[^a-zA-Z0-9-]', '-').log") + npx autorest --verbose --max-memory-size=$MaxMemorySize --module-version:$FullModuleVersion --module-name:$ModuleFullName --service-name:$Module --input-file:$OpenApiFile $AutoRestModuleConfig --max-cpu=2 --network-calls=2 2>&1 | Out-File -FilePath $autorestLog -Encoding utf8 + $autorestExitCode = $LASTEXITCODE + if ($autorestExitCode -ne 0) { + Write-Host -ForegroundColor Red "AutoREST failed (exit $autorestExitCode) generating '$ModuleFullName'." + Write-Host -ForegroundColor Yellow "=== AutoREST log: $autorestLog ===" + if (Test-Path $autorestLog) { Get-Content $autorestLog | ForEach-Object { Write-Host $_ } } + Write-Host -ForegroundColor Yellow "=== End AutoREST log ===" + return $autorestExitCode } Write-Debug "AutoRest generated '$ModuleFullName' successfully." From a7dce76cd0a6018ed4a9739e8c2548a7a08b0000 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 14:46:53 -0700 Subject: [PATCH 10/14] resolve autorest modelerfour --- .../common-templates/install-tools.yml | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/.azure-pipelines/common-templates/install-tools.yml b/.azure-pipelines/common-templates/install-tools.yml index de2c207444..732696fa77 100644 --- a/.azure-pipelines/common-templates/install-tools.yml +++ b/.azure-pipelines/common-templates/install-tools.yml @@ -76,20 +76,35 @@ steps: customCommand: install -g @autorest/core@3.10.4 --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ - task: PowerShell@2 - displayName: Pre-populate autorest core cache + displayName: Pre-populate autorest extension cache inputs: targetType: inline pwsh: true script: | - # Autorest looks for @autorest/core in ~/.autorest/@autorest/core//node_modules/ - # Pre-installing it here with the explicit registry flag means autorest never needs - # to make any npm calls during module generation. - $cacheDir = Join-Path $env:USERPROFILE ".autorest\@autorest\core\3.10.4" - New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null - Write-Host "Pre-installing @autorest/core@3.10.4 into autorest cache: $cacheDir" - npm install @autorest/core@3.10.4 --prefix $cacheDir --registry https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/ - if ($LASTEXITCODE -ne 0) { throw "Failed to pre-install @autorest/core@3.10.4 into autorest cache (exit $LASTEXITCODE)" } - Write-Host "Autorest core cache pre-populated successfully" + # Autorest resolves extensions from ~/.autorest///node_modules/. + # Pre-install every extension referenced by autorest-configuration.md so autorest + # makes zero npm network calls during module generation. + $registry = "https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/" + $extensions = @( + "@autorest/core@3.10.4", + "@autorest/modelerfour@4.24.3" + ) + foreach ($ext in $extensions) { + $parts = $ext -split '@(?=[^@]+$)' # split on last @ + $pkg = $parts[0] + $ver = $parts[1] + $cacheDir = Join-Path $env:USERPROFILE ".autorest\$($pkg.Replace('/','\'))\$ver" + $nodeModules = Join-Path $cacheDir "node_modules\$($pkg.Replace('/','\'))" + if (Test-Path $nodeModules) { + Write-Host "Cache already present: $ext" + continue + } + New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null + Write-Host "Pre-installing $ext into $cacheDir" + npm install $ext --prefix $cacheDir --registry $registry + if ($LASTEXITCODE -ne 0) { throw "Failed to pre-install $ext (exit $LASTEXITCODE)" } + Write-Host "Done: $ext" + } - task: Npm@1 displayName: Install Rush From 1bb5608f84d0105c2341adfc1900ca246ede5d2e Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:24:54 -0700 Subject: [PATCH 11/14] ensure autorest doesnt reach for npm registry --- tools/GenerateModules.ps1 | 12 ++++++++++++ tools/GenerateServiceModule.ps1 | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/tools/GenerateModules.ps1 b/tools/GenerateModules.ps1 index 35b911b8e9..f169452cac 100644 --- a/tools/GenerateModules.ps1 +++ b/tools/GenerateModules.ps1 @@ -63,10 +63,22 @@ if (Test-Path $coreCacheDir) { } else { Write-Host "WARNING: Autorest core cache directory not found at $coreCacheDir" } +$modelerfourCacheDir = Join-Path $autorestHome "@autorest\modelerfour" +if (Test-Path $modelerfourCacheDir) { + Write-Host "Autorest modelerfour cache versions: $(Get-ChildItem $modelerfourCacheDir -Directory | Select-Object -ExpandProperty Name)" + $modelerfourNodeModules = Join-Path $modelerfourCacheDir "4.24.3\node_modules\@autorest\modelerfour" + Write-Host "Cache modelerfour 4.24.3 node_modules present: $(Test-Path $modelerfourNodeModules)" +} else { + Write-Host "WARNING: Autorest modelerfour cache directory not found at $modelerfourCacheDir" +} Write-Host "npm registry: $(npm config get registry 2>&1)" +Write-Host "npm_config_registry env: $env:npm_config_registry" Write-Host "NPM_CONFIG_USERCONFIG: $env:NPM_CONFIG_USERCONFIG" $userNpmrc = Join-Path $env:USERPROFILE ".npmrc" Write-Host "~/.npmrc exists: $(Test-Path $userNpmrc)" +if (Test-Path $userNpmrc) { + Write-Host "~/.npmrc registry line: $(Select-String -Path $userNpmrc -Pattern '^registry=' | Select-Object -First 1 -ExpandProperty Line)" +} Write-Host "--- End diagnostics ---" $RequiredGraphModules = @() diff --git a/tools/GenerateServiceModule.ps1 b/tools/GenerateServiceModule.ps1 index d50ba21184..7636c74cd2 100644 --- a/tools/GenerateServiceModule.ps1 +++ b/tools/GenerateServiceModule.ps1 @@ -69,6 +69,10 @@ $ApiVersion | ForEach-Object { else { $FullModuleVersion = $ModuleMetadata.versions[$CurrentApiVersion].version } + # Route autorest's internal npm registry calls (fetchPackageMetadata for extension + # resolution) through the private feed. The public npm registry is DNS-blocked by + # 1ES supply-chain security enforcement on release pipelines. + $env:npm_config_registry = "https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/" $autorestLog = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "autorest-$($ModuleFullName -replace '[^a-zA-Z0-9-]', '-').log") npx autorest --verbose --max-memory-size=$MaxMemorySize --module-version:$FullModuleVersion --module-name:$ModuleFullName --service-name:$Module --input-file:$OpenApiFile $AutoRestModuleConfig --max-cpu=2 --network-calls=2 2>&1 | Out-File -FilePath $autorestLog -Encoding utf8 $autorestExitCode = $LASTEXITCODE From 16a892375917a0e0b46699fe29afd916551fa6f6 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:55:55 -0700 Subject: [PATCH 12/14] ensure autorest is electing cached files --- tools/GenerateServiceModule.ps1 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tools/GenerateServiceModule.ps1 b/tools/GenerateServiceModule.ps1 index 7636c74cd2..cad6f64edf 100644 --- a/tools/GenerateServiceModule.ps1 +++ b/tools/GenerateServiceModule.ps1 @@ -69,12 +69,23 @@ $ApiVersion | ForEach-Object { else { $FullModuleVersion = $ModuleMetadata.versions[$CurrentApiVersion].version } - # Route autorest's internal npm registry calls (fetchPackageMetadata for extension - # resolution) through the private feed. The public npm registry is DNS-blocked by - # 1ES supply-chain security enforcement on release pipelines. - $env:npm_config_registry = "https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/npm/registry/" + # Pass @autorest/modelerfour as a local --use: argument so autorest loads it + # directly from the pre-populated cache without calling fetchPackageMetadata. + # fetchPackageMetadata is called unconditionally before the cache check inside + # ExtensionManager.findPackage, and it hits the npm registry which is DNS-blocked + # by 1ES supply-chain security on release pipelines. A local --use path bypasses + # findPackage entirely: the extension goes straight into localExtensions, and when + # use-extension in autorest-configuration.md is processed, resolveExtension finds + # it there without any registry call. + $autorestHome = if ($env:AUTOREST_HOME) { $env:AUTOREST_HOME } else { Join-Path $env:USERPROFILE ".autorest" } + $modelerFourPath = Join-Path $autorestHome "@autorest" "modelerfour" "4.24.3" "node_modules" "@autorest" "modelerfour" + $modelerFourUseFlag = if (Test-Path $modelerFourPath) { @("--use:$modelerFourPath") } else { @() } + if ($modelerFourUseFlag.Count -eq 0) { + Write-Host -ForegroundColor Yellow "WARNING: @autorest/modelerfour local cache not found at $modelerFourPath — autorest will attempt npm registry lookup (may fail in network-isolated environment)" + } + $autorestLog = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "autorest-$($ModuleFullName -replace '[^a-zA-Z0-9-]', '-').log") - npx autorest --verbose --max-memory-size=$MaxMemorySize --module-version:$FullModuleVersion --module-name:$ModuleFullName --service-name:$Module --input-file:$OpenApiFile $AutoRestModuleConfig --max-cpu=2 --network-calls=2 2>&1 | Out-File -FilePath $autorestLog -Encoding utf8 + npx autorest @modelerFourUseFlag --verbose --max-memory-size=$MaxMemorySize --module-version:$FullModuleVersion --module-name:$ModuleFullName --service-name:$Module --input-file:$OpenApiFile $AutoRestModuleConfig --max-cpu=2 --network-calls=2 2>&1 | Out-File -FilePath $autorestLog -Encoding utf8 $autorestExitCode = $LASTEXITCODE if ($autorestExitCode -ne 0) { Write-Host -ForegroundColor Red "AutoREST failed (exit $autorestExitCode) generating '$ModuleFullName'." From 91cc124bfb93c9a5a7da543a69bba71f0d0f49fa Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:14:28 -0700 Subject: [PATCH 13/14] fix args --- tools/GenerateServiceModule.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/GenerateServiceModule.ps1 b/tools/GenerateServiceModule.ps1 index cad6f64edf..b5fb25b05d 100644 --- a/tools/GenerateServiceModule.ps1 +++ b/tools/GenerateServiceModule.ps1 @@ -79,7 +79,10 @@ $ApiVersion | ForEach-Object { # it there without any registry call. $autorestHome = if ($env:AUTOREST_HOME) { $env:AUTOREST_HOME } else { Join-Path $env:USERPROFILE ".autorest" } $modelerFourPath = Join-Path $autorestHome "@autorest" "modelerfour" "4.24.3" "node_modules" "@autorest" "modelerfour" - $modelerFourUseFlag = if (Test-Path $modelerFourPath) { @("--use:$modelerFourPath") } else { @() } + # @(if ...) always produces [object[]], preventing PowerShell from unwrapping the + # single-element array to a [string] scalar. A scalar string splatted with @ + # enumerates IEnumerable, passing each character as a separate argument. + $modelerFourUseFlag = @(if (Test-Path $modelerFourPath) { "--use:$modelerFourPath" }) if ($modelerFourUseFlag.Count -eq 0) { Write-Host -ForegroundColor Yellow "WARNING: @autorest/modelerfour local cache not found at $modelerFourPath — autorest will attempt npm registry lookup (may fail in network-isolated environment)" } From 142e80d18a2a4df5714f0339d9c4fc2910d48fe7 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:47:28 -0700 Subject: [PATCH 14/14] retrieve nuget without blocked call --- tools/ManageGeneratedModule.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ManageGeneratedModule.ps1 b/tools/ManageGeneratedModule.ps1 index 5d0e9ff48a..9ea2761727 100644 --- a/tools/ManageGeneratedModule.ps1 +++ b/tools/ManageGeneratedModule.ps1 @@ -47,7 +47,7 @@ foreach ($Package in $NugetPackagesToRemove) { # Add nuget packages from generate modules. foreach ($Package in $NugetPackagesToAdd) { Write-Debug "Executing: dotnet add $ModuleCsProj package $Package" - dotnet add $ModuleCsProj package $Package -s https://api.nuget.org/v3/index.json | Out-Null + dotnet add $ModuleCsProj package $Package | Out-Null if ($LastExitCode) { Write-Error "Failed to execute: dotnet add $ModuleCsProj package $Package" }