Skip to content

[PostgreSQL Flexible Server] Onboard to latest Stable release#29244

Open
nasc17 wants to merge 7 commits intoAzure:mainfrom
nasc17:nasc/pgFlexOnboarding35
Open

[PostgreSQL Flexible Server] Onboard to latest Stable release#29244
nasc17 wants to merge 7 commits intoAzure:mainfrom
nasc17:nasc/pgFlexOnboarding35

Conversation

@nasc17
Copy link
Member

@nasc17 nasc17 commented Mar 6, 2026

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

  • SHOULD update ChangeLog.md file(s) appropriately
    • Update src/{{SERVICE}}/{{SERVICE}}/ChangeLog.md.
      • A snippet outlining the change(s) made in the PR should be written under the ## Upcoming Release header in the past tense.
    • Should not change ChangeLog.md if no new release is required, such as fixing test case only.
  • SHOULD regenerate markdown help files if there is cmdlet API change. Instruction
  • SHOULD have proper test coverage for changes in pull request.
  • SHOULD NOT adjust version of module manually in pull request

Copilot AI review requested due to automatic review settings March 6, 2026 21:23
@azure-client-tools-bot-prd
Copy link

Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.Autorest directory 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
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json
$env = Get-Content -Path $envFilePath | ConvertFrom-Json

Copilot uses AI. Check for mistakes.
if (Test-Path -Path (Join-Path $PSScriptRoot $envFile)) {
$envFilePath = Join-Path $PSScriptRoot $envFile
} else {
$envFilePath = Join-Path $PSScriptRoot '..\$envFile'
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$envFilePath = Join-Path $PSScriptRoot '..\$envFile'
$envFilePath = Join-Path (Join-Path $PSScriptRoot '..') $envFile

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +6
$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'
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$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'

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,3 @@
directory: specification\postgresql\DBforPostgreSQL.Management
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
directory: specification\postgresql\DBforPostgreSQL.Management
directory: specification/postgresql/DBforPostgreSQL.Management

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +4
<!-- region Generated -->
# Az.PostgreSQLFlexibleServer
This directory contains the PowerShell module for the PostgreSqlFlexibleServer service.

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
. ($loadEnvPath)
return $env.SubscriptionId
}
return (Get-AzContext).Subscription.Id No newline at end of file
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
default:
script: "(Get-AzContext).Subscription.Id"
- where:
variant: ^(Create|Update|Export)(?!.*?Expanded|ViaJsonString|ViaJsonFilePath)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
variant: ^(Create|Update|Export)(?!.*?Expanded|ViaJsonString|ViaJsonFilePath)
variant: ^(Create|Update|Export)(?!.*?(Expanded|ViaJsonString|ViaJsonFilePath))

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,24 @@
<!-- region Generated -->
# Az.PostgreSQLFlexibleServer
This directory contains the PowerShell module for the PostgreSqlFlexibleServer service.
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
This directory contains the PowerShell module for the PostgreSqlFlexibleServer service.
This directory contains the PowerShell module for the PostgreSQL Flexible Server service.

Copilot uses AI. Check for mistakes.
- `-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.
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "Supresses" should be "Suppresses".

Suggested change
- `-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.

Copilot uses AI. Check for mistakes.
@NoriZC
Copy link
Contributor

NoriZC commented Mar 6, 2026

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 3 pipeline(s).

Copilot AI review requested due to automatic review settings March 9, 2026 22:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +23 to +27
$envFilePath = Join-Path $PSScriptRoot '..\$envFile'
}
$env = @{}
if (Test-Path -Path $envFilePath) {
$env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$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

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +27
$envFilePath = Join-Path $PSScriptRoot '..\$envFile'
}
$env = @{}
if (Test-Path -Path $envFilePath) {
$env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$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

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,16 @@
#This script converts securestring to plaintext
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +16
#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
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
#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

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +20
Describe 'Get-AzPostgreSqlFlexibleServer' {
It 'List1' -skip {
{ throw [System.NotImplementedException] } | Should -Not -Throw
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot generated this review using guidance from repository custom instructions.
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("Microsoft Azure Powershell - PostgreSQLFlexibleServer")]
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct spelling/capitalization in assembly title: 'Powershell' should be 'PowerShell'.

Suggested change
[assembly: AssemblyTitle("Microsoft Azure Powershell - PostgreSQLFlexibleServer")]
[assembly: AssemblyTitle("Microsoft Azure PowerShell - PostgreSQLFlexibleServer")]

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +16
license.txt
/*.ps1
/*.psd1
/*.ps1xml
/*.psm1
/*.snk
/*.csproj
/*.nuspec No newline at end of file
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
license.txt
/*.ps1
/*.psd1
/*.ps1xml
/*.psm1
/*.snk
/*.csproj
/*.nuspec
license.txt

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +16
license.txt
/*.ps1
/*.psd1
/*.ps1xml
/*.psm1
/*.snk
/*.csproj
/*.nuspec No newline at end of file
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
license.txt
/*.ps1
/*.psd1
/*.ps1xml
/*.psm1
/*.snk
/*.csproj
/*.nuspec
license.txt

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +45
### Example 1: {{ Add title here }}
```powershell
{{ Add code here }}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
{{ Add output here (remove the output block if the example doesn't have an output) }}
```

{{ Add description here }}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
@NoriZC
Copy link
Contributor

NoriZC commented Mar 9, 2026

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 3 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants