[PostgreSQL Flexible Server] Onboard to latest Stable release#29244
[PostgreSQL Flexible Server] Onboard to latest Stable release#29244nasc17 wants to merge 7 commits intoAzure:mainfrom
Conversation
| Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status. |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new AutoRest/TypeSpec-based module scaffolding for Az.PostgreSQLFlexibleServer, intended to onboard PostgreSQL Flexible Server cmdlets separately from the existing PostgreSql cmdlets and target the stable Microsoft.DBforPostgreSQL 2025-08-01 API line.
Changes:
- Added a new
PostgreSQLFlexibleServer.Autorestdirectory with TypeSpec emitter configuration (tspconfig.yaml) and spec pinning (tsp-location.yaml). - Added initial module scaffolding docs (how-to, custom/docs/examples/resources/test READMEs) and test utilities.
- Added common utility scripts (e.g., SecureString unprotect helper, subscription ID helper for tests).
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/utils/Unprotect-SecureString.ps1 | Adds SecureString-to-plaintext helper script |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/utils/Get-SubscriptionIdTestSafe.ps1 | Adds helper to resolve SubscriptionId in test playback vs live |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/tspconfig.yaml | TypeSpec PowerShell emitter options + directives |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/tsp-location.yaml | Pins swagger/spec repo commit + directory |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/test/loadEnv.ps1 | Adds test environment loader for playback/record/live |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/test/README.md | Test folder documentation |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/resources/README.md | Resources folder documentation |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/how-to.md | Module development guide |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/examples/README.md | Examples folder documentation |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/docs/README.md | Docs folder documentation |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/custom/README.md | Custom cmdlets folder documentation |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/custom/Az.PostgreSQLFlexibleServer.custom.psm1 | Custom module loader + exports |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/README.md | Module README |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/Properties/AssemblyInfo.cs | Assembly metadata for generated module |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/.gitignore | Ignores generated/build outputs and root artifacts |
| src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/.gitattributes | Sets default text normalization |
You can also share your feedback on Copilot code review. Take the survey.
| } | ||
| $env = @{} | ||
| if (Test-Path -Path $envFilePath) { | ||
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json |
There was a problem hiding this comment.
loadEnv.ps1 builds $envFilePath but then reads JSON from (Join-Path $PSScriptRoot $envFile) instead of $envFilePath, so when the env file is in the parent folder this will silently read the wrong (non-existent) file and leave $env empty. Update the Get-Content call to use $envFilePath.
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json | |
| $env = Get-Content -Path $envFilePath | ConvertFrom-Json |
| if (Test-Path -Path (Join-Path $PSScriptRoot $envFile)) { | ||
| $envFilePath = Join-Path $PSScriptRoot $envFile | ||
| } else { | ||
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' |
There was a problem hiding this comment.
Join-Path $PSScriptRoot '..\$envFile' uses a literal string (no variable expansion) and hard-codes a Windows path separator. Use Join-Path with separate segments (e.g., '..' and $envFile) to keep this script working cross-platform.
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' | |
| $envFilePath = Join-Path (Join-Path $PSScriptRoot '..') $envFile |
| $null = Import-Module -PassThru -Name (Join-Path $PSScriptRoot '..\bin\Az.PostgreSQLFlexibleServer.private.dll') | ||
|
|
||
| # Load the internal module | ||
| $internalModulePath = Join-Path $PSScriptRoot '..\internal\Az.PostgreSQLFlexibleServer.internal.psm1' |
There was a problem hiding this comment.
The Join-Path child paths use Windows backslashes (e.g., '..\bin\...'), which produces invalid paths on non-Windows PowerShell (backslash is treated as a normal character). Build these paths with Join-Path segments (or forward slashes) so the module can load on Linux/macOS.
| $null = Import-Module -PassThru -Name (Join-Path $PSScriptRoot '..\bin\Az.PostgreSQLFlexibleServer.private.dll') | |
| # Load the internal module | |
| $internalModulePath = Join-Path $PSScriptRoot '..\internal\Az.PostgreSQLFlexibleServer.internal.psm1' | |
| $null = Import-Module -PassThru -Name (Join-Path (Join-Path $PSScriptRoot '..') 'bin/Az.PostgreSQLFlexibleServer.private.dll') | |
| # Load the internal module | |
| $internalModulePath = Join-Path (Join-Path $PSScriptRoot '..') 'internal/Az.PostgreSQLFlexibleServer.internal.psm1' |
| @@ -0,0 +1,3 @@ | |||
| directory: specification\postgresql\DBforPostgreSQL.Management | |||
There was a problem hiding this comment.
directory uses Windows-style backslashes. Other tsp-location.yaml files in the repo use forward slashes, and backslashes can break tooling on Linux/macOS. Switch this to specification/postgresql/DBforPostgreSQL.Management.
| directory: specification\postgresql\DBforPostgreSQL.Management | |
| directory: specification/postgresql/DBforPostgreSQL.Management |
| <!-- region Generated --> | ||
| # Az.PostgreSQLFlexibleServer | ||
| This directory contains the PowerShell module for the PostgreSqlFlexibleServer service. | ||
|
|
There was a problem hiding this comment.
The PR adds only src/PostgreSQLFlexibleServer/PostgreSQLFlexibleServer.Autorest/ without the usual sibling module project folder and .sln (for example, src/EdgeAction/EdgeAction/ + src/EdgeAction/EdgeAction.sln) that the repo build uses. If this is meant to ship as a module, add the missing project/solution (and the required ChangeLog.md) or document how it is built and packaged.
| . ($loadEnvPath) | ||
| return $env.SubscriptionId | ||
| } | ||
| return (Get-AzContext).Subscription.Id No newline at end of file |
There was a problem hiding this comment.
Get-SubscriptionIdTestSafe.ps1 doesn’t appear to be referenced by the TypeSpec configuration (SubscriptionId default is still (Get-AzContext).Subscription.Id) or any other script in this module. Either wire this helper into the SubscriptionId default script (so playback works without an Az context) or remove it to avoid carrying unused utilities.
| return (Get-AzContext).Subscription.Id | |
| # Attempt to get the SubscriptionId from the current Az context if available | |
| $subscriptionId = $null | |
| $getAzContextCommand = Get-Command -Name Get-AzContext -ErrorAction SilentlyContinue | |
| if ($getAzContextCommand) { | |
| try { | |
| $context = Get-AzContext -ErrorAction Stop | |
| if ($context -and $context.Subscription -and $context.Subscription.Id) { | |
| $subscriptionId = $context.Subscription.Id | |
| } | |
| } catch { | |
| # Ignore errors here; we'll fall back to environment variables below | |
| } | |
| } | |
| # Fallback: use SubscriptionId from environment if Az context is not available | |
| if (-not $subscriptionId -and $env:SubscriptionId) { | |
| $subscriptionId = $env:SubscriptionId | |
| } | |
| if (-not $subscriptionId) { | |
| throw "Unable to determine SubscriptionId. Ensure an Az context is available or set the 'SubscriptionId' environment variable." | |
| } | |
| return $subscriptionId |
| default: | ||
| script: "(Get-AzContext).Subscription.Id" | ||
| - where: | ||
| variant: ^(Create|Update|Export)(?!.*?Expanded|ViaJsonString|ViaJsonFilePath) |
There was a problem hiding this comment.
The negative lookahead regex is missing grouping: (?!.+Expanded|ViaJsonString|ViaJsonFilePath) will not reliably exclude ViaJsonString/ViaJsonFilePath unless they appear at the current position. Align with the pattern used elsewhere (e.g., (?!.+?(Expanded|ViaJsonString|ViaJsonFilePath))) to avoid removing the wrong variants.
| variant: ^(Create|Update|Export)(?!.*?Expanded|ViaJsonString|ViaJsonFilePath) | |
| variant: ^(Create|Update|Export)(?!.*?(Expanded|ViaJsonString|ViaJsonFilePath)) |
| @@ -0,0 +1,24 @@ | |||
| <!-- region Generated --> | |||
| # Az.PostgreSQLFlexibleServer | |||
| This directory contains the PowerShell module for the PostgreSqlFlexibleServer service. | |||
There was a problem hiding this comment.
The service name casing in the README is inconsistent with the module/service name (PostgreSqlFlexibleServer vs PostgreSQLFlexibleServer/PostgreSQL Flexible Server). Update the text to use the correct PostgreSQL capitalization to avoid confusion in docs.
| This directory contains the PowerShell module for the PostgreSqlFlexibleServer service. | |
| This directory contains the PowerShell module for the PostgreSQL Flexible Server service. |
| - `-Pack`: After building, packages the module into a `.nupkg`. | ||
| - `-Code`: After building, opens a VSCode window with the module's directory and runs (see `-Run`) the module. | ||
| - `-Release`: Builds the module in `Release` configuration (as opposed to `Debug` configuration). | ||
| - `-NoDocs`: Supresses writing the documentation markdown files as part of the cmdlet exporting process. |
There was a problem hiding this comment.
Typo: "Supresses" should be "Suppresses".
| - `-NoDocs`: Supresses writing the documentation markdown files as part of the cmdlet exporting process. | |
| - `-NoDocs`: Suppresses writing the documentation markdown files as part of the cmdlet exporting process. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 193 out of 248 changed files in this pull request and generated 12 comments.
You can also share your feedback on Copilot code review. Take the survey.
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' | ||
| } | ||
| $env = @{} | ||
| if (Test-Path -Path $envFilePath) { | ||
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json |
There was a problem hiding this comment.
The fallback path construction uses a single-quoted string with a literal $envFile and a Windows-only backslash, so it won’t resolve to the intended file on any platform. Also, $envFilePath is computed but then ignored when reading the JSON (line 27 reads from (Join-Path $PSScriptRoot $envFile) instead). Build the fallback path using Join-Path $PSScriptRoot '..' $envFile (or equivalent) and read from $envFilePath consistently.
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' | |
| } | |
| $env = @{} | |
| if (Test-Path -Path $envFilePath) { | |
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json | |
| $envFilePath = Join-Path $PSScriptRoot '..' $envFile | |
| } | |
| $env = @{} | |
| if (Test-Path -Path $envFilePath) { | |
| $env = Get-Content $envFilePath | ConvertFrom-Json |
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' | ||
| } | ||
| $env = @{} | ||
| if (Test-Path -Path $envFilePath) { | ||
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json |
There was a problem hiding this comment.
The fallback path construction uses a single-quoted string with a literal $envFile and a Windows-only backslash, so it won’t resolve to the intended file on any platform. Also, $envFilePath is computed but then ignored when reading the JSON (line 27 reads from (Join-Path $PSScriptRoot $envFile) instead). Build the fallback path using Join-Path $PSScriptRoot '..' $envFile (or equivalent) and read from $envFilePath consistently.
| $envFilePath = Join-Path $PSScriptRoot '..\$envFile' | |
| } | |
| $env = @{} | |
| if (Test-Path -Path $envFilePath) { | |
| $env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json | |
| $envFilePath = Join-Path $PSScriptRoot '..' $envFile | |
| } | |
| $env = @{} | |
| if (Test-Path -Path $envFilePath) { | |
| $env = Get-Content -Path $envFilePath | ConvertFrom-Json |
| @@ -0,0 +1,16 @@ | |||
| #This script converts securestring to plaintext | |||
There was a problem hiding this comment.
This utility intentionally returns plaintext from a SecureString, which undermines secret-handling guarantees and can lead to accidental logging/telemetry exposure. If this is only needed for test tooling, consider scoping it to test-only usage (and ensuring it is not imported/packaged with the shipping module), or redesign consumers to avoid requiring plaintext at all.
| #This script converts securestring to plaintext | ||
|
|
||
| param( | ||
| [Parameter(Mandatory, ValueFromPipeline)] | ||
| [System.Security.SecureString] | ||
| ${SecureString} | ||
| ) | ||
|
|
||
| $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) | ||
| try { | ||
| $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr) | ||
| } finally { | ||
| [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr) | ||
| } | ||
|
|
||
| return $plaintext No newline at end of file |
There was a problem hiding this comment.
This utility intentionally returns plaintext from a SecureString, which undermines secret-handling guarantees and can lead to accidental logging/telemetry exposure. If this is only needed for test tooling, consider scoping it to test-only usage (and ensuring it is not imported/packaged with the shipping module), or redesign consumers to avoid requiring plaintext at all.
| #This script converts securestring to plaintext | |
| param( | |
| [Parameter(Mandatory, ValueFromPipeline)] | |
| [System.Security.SecureString] | |
| ${SecureString} | |
| ) | |
| $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) | |
| try { | |
| $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr) | |
| } finally { | |
| [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr) | |
| } | |
| return $plaintext | |
| # WARNING: This script converts a SecureString to plaintext. | |
| # Use only in controlled scenarios (for example, tooling or tests) and never log or persist the output. | |
| function Unprotect-SecureString { | |
| [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] | |
| param( | |
| [Parameter(Mandatory, ValueFromPipeline)] | |
| [System.Security.SecureString] | |
| ${SecureString} | |
| ) | |
| if (-not $PSCmdlet.ShouldProcess("SecureString value", "Convert to plaintext string")) { | |
| return | |
| } | |
| $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) | |
| try { | |
| $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr) | |
| } finally { | |
| [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr) | |
| } | |
| return $plaintext | |
| } | |
| if ($MyInvocation.InvocationName -eq '.') { | |
| # Script was dot-sourced; export only the function. | |
| return | |
| } | |
| # When executed directly, behave like a script that returns plaintext (with confirmation). | |
| param( | |
| [Parameter(Mandatory, ValueFromPipeline)] | |
| [System.Security.SecureString] | |
| ${SecureString} | |
| ) | |
| Unprotect-SecureString -SecureString $SecureString |
| Describe 'Get-AzPostgreSqlFlexibleServer' { | ||
| It 'List1' -skip { | ||
| { throw [System.NotImplementedException] } | Should -Not -Throw | ||
| } |
There was a problem hiding this comment.
All generated Pester tests are currently -skip with NotImplementedException placeholders, which means the module has no effective automated validation. For a General Release onboarding, please replace at least the key scenarios with real playback tests (or remove the placeholder throws and implement minimal assertions) so CI can catch regressions.
| using System.Reflection; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| [assembly: AssemblyTitle("Microsoft Azure Powershell - PostgreSQLFlexibleServer")] |
There was a problem hiding this comment.
Correct spelling/capitalization in assembly title: 'Powershell' should be 'PowerShell'.
| [assembly: AssemblyTitle("Microsoft Azure Powershell - PostgreSQLFlexibleServer")] | |
| [assembly: AssemblyTitle("Microsoft Azure PowerShell - PostgreSQLFlexibleServer")] |
| license.txt | ||
| /*.ps1 | ||
| /*.psd1 | ||
| /*.ps1xml | ||
| /*.psm1 | ||
| /*.snk | ||
| /*.csproj | ||
| /*.nuspec No newline at end of file |
There was a problem hiding this comment.
These root-level ignore patterns for the AutoRest module folder will prevent committing key module scaffolding files if they exist at the repo root of PostgreSQLFlexibleServer.Autorest (for example build/test scripts, manifests, or project files). Consider removing or narrowing these patterns so they only ignore generated artifacts (e.g., bin/, obj/, generated/, exports/) rather than broad file-type globs.
| license.txt | |
| /*.ps1 | |
| /*.psd1 | |
| /*.ps1xml | |
| /*.psm1 | |
| /*.snk | |
| /*.csproj | |
| /*.nuspec | |
| license.txt |
| license.txt | ||
| /*.ps1 | ||
| /*.psd1 | ||
| /*.ps1xml | ||
| /*.psm1 | ||
| /*.snk | ||
| /*.csproj | ||
| /*.nuspec No newline at end of file |
There was a problem hiding this comment.
These root-level ignore patterns for the AutoRest module folder will prevent committing key module scaffolding files if they exist at the repo root of PostgreSQLFlexibleServer.Autorest (for example build/test scripts, manifests, or project files). Consider removing or narrowing these patterns so they only ignore generated artifacts (e.g., bin/, obj/, generated/, exports/) rather than broad file-type globs.
| license.txt | |
| /*.ps1 | |
| /*.psd1 | |
| /*.ps1xml | |
| /*.psm1 | |
| /*.snk | |
| /*.csproj | |
| /*.nuspec | |
| license.txt |
| ### Example 1: {{ Add title here }} | ||
| ```powershell | ||
| {{ Add code here }} |
There was a problem hiding this comment.
The generated help markdown currently ships with placeholder examples ({{ Add code here }}, etc.). For a General Release module, these placeholders should be replaced with at least one real, runnable example (or removed if examples are not intended to be included yet) to avoid publishing unusable docs.
| {{ Add output here (remove the output block if the example doesn't have an output) }} | ||
| ``` | ||
|
|
||
| {{ Add description here }} |
There was a problem hiding this comment.
The generated help markdown currently ships with placeholder examples ({{ Add code here }}, etc.). For a General Release module, these placeholders should be replaced with at least one real, runnable example (or removed if examples are not intended to be included yet) to avoid publishing unusable docs.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
Description
Onboard PostgreSQL Flexible Server cmdlets to its own folder separate from single sever cmdlets. This onboarding starts with stable api version of Microsoft.DBforPostgreSQL 2025-08-01
Mandatory Checklist
Please choose the target release of Azure PowerShell. (⚠️ Target release is a different concept from API readiness. Please click below links for details.)
Check this box to confirm: I have read the Submitting Changes section of
CONTRIBUTING.mdand reviewed the following information:ChangeLog.mdfile(s) appropriatelysrc/{{SERVICE}}/{{SERVICE}}/ChangeLog.md.## Upcoming Releaseheader in the past tense.ChangeLog.mdif no new release is required, such as fixing test case only.