Skip to content

Conversation

@N6REJ
Copy link
Contributor

@N6REJ N6REJ commented Nov 24, 2025

User description

testing ci/cd


PR Type

Tests, Enhancement


Description

  • Add comprehensive PostgreSQL CI/CD testing workflow for multiple versions

  • Implement intelligent version detection from releases.properties file

  • Support manual workflow dispatch with specific version selection

  • Generate detailed test results with PR comments and artifact uploads


Diagram Walkthrough

flowchart LR
  A["PR/Manual Trigger"] --> B["Detect PostgreSQL Versions"]
  B --> C["Download & Extract"]
  C --> D["Verify Installation"]
  D --> E["Test Functionality"]
  E --> F["Generate Report"]
  F --> G["Comment on PR"]
Loading

File Walkthrough

Relevant files
Tests
postgresql-test.yml
Complete PostgreSQL CI/CD testing workflow implementation

.github/workflows/postgresql-test.yml

  • New comprehensive workflow file with 554 lines implementing PostgreSQL
    testing pipeline
  • Detect-versions job intelligently selects versions from
    releases.properties or manual input
  • Test-postgresql job runs on Windows with multi-version matrix strategy
  • Implements three testing phases: download/extract, verify executables,
    test functionality
  • Report-results job generates PR comments with test summaries and
    uploads artifacts
+554/-0 

@qodo-code-review
Copy link

qodo-code-review bot commented Nov 24, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Token exposure risk

Description: The workflow uses a long-lived GitHub token in curl requests to the GitHub API without
scoping or least-privilege and echoes returned data to logs, which risks leaking sensitive
repository metadata and increases exposure if the token is inadvertently logged or reused;
prefer using the built-in GITHUB_TOKEN via actions/gh-cli or actions/github-script with
minimal permissions and avoid echoing API payloads.
postgresql-test.yml [81-97]

Referred Code
CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
  jq -r '.[].filename')

echo "Changed files in PR:"
echo "$CHANGED_FILES"

# Check if releases.properties was changed
if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
  echo "releases.properties was modified in this PR"

  # Get the diff from GitHub API using curl
  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
    jq -r '.[] | select(.filename == "releases.properties") | .patch')
Information disclosure

Description: The workflow prints the full list of changed file paths from the PR to logs, which may
disclose sensitive repository structure or filenames in public CI logs; consider redacting
or limiting output or gating debug logs behind a verbosity flag.
postgresql-test.yml [86-88]

Referred Code
echo "Changed files in PR:"
echo "$CHANGED_FILES"
Shell injection risk

Description: Lines parsed from the API response and shell-expanded through multiple pipes are later
echoed and used to construct test targets without strict validation, creating a potential
command injection or shell globbing risk if maliciously crafted patch lines are parsed;
mitigate by setting set -o pipefail -euo pipefail, using safe parsing with jq, and
quoting/whitelisting version patterns strictly.
postgresql-test.yml [103-124]

Referred Code
CHANGED_VERSIONS=$(echo "$PATCH" | \
  grep "^+" | \
  grep -v "^+++" | \
  grep -E "^\+[0-9]+\.[0-9]+" | \
  sed 's/^+//' | \
  cut -d'=' -f1 | \
  tr -d ' ')

if [ -z "$CHANGED_VERSIONS" ]; then
  echo "No new versions found in releases.properties changes"
  echo "Testing latest 5 versions as fallback"
  VERSIONS=$(grep -E "^[0-9]+\.[0-9]+" releases.properties | \
    cut -d'=' -f1 | \
    tr -d ' ' | \
    sort -V -r | \
    head -5 | \
    jq -R -s -c 'split("\n") | map(select(length > 0)) | unique')
else
  echo "Versions detected in PR:"
  echo "$CHANGED_VERSIONS"
  VERSIONS=$(echo "$CHANGED_VERSIONS" | jq -R -s -c 'split("\n") | map(select(length > 0)) | unique')


 ... (clipped 1 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Limited Auditing: The workflow echoes some operational messages but does not produce structured audit logs
with user identity context for critical actions like version detection and test-skipping
decisions.

Referred Code
# Check if releases.properties was changed
if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
  echo "releases.properties was modified in this PR"

  # Get the diff from GitHub API using curl
  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
    jq -r '.[] | select(.filename == "releases.properties") | .patch')

  echo "Analyzing diff for added/modified versions..."

  # Extract ALL added lines (lines starting with +) that contain version numbers
  # Test ALL versions added in the PR (including RC/beta/alpha)
  CHANGED_VERSIONS=$(echo "$PATCH" | \
    grep "^+" | \
    grep -v "^+++" | \
    grep -E "^\+[0-9]+\.[0-9]+" | \
    sed 's/^+//' | \
    cut -d'=' -f1 | \
    tr -d ' ')


 ... (clipped 33 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing Failure Paths: Network/API failures from curl or empty responses are not handled explicitly, which could
lead to silent skips or empty version lists without actionable error context.

Referred Code
CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
  jq -r '.[].filename')

echo "Changed files in PR:"
echo "$CHANGED_FILES"

# Check if releases.properties was changed
if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
  echo "releases.properties was modified in this PR"

  # Get the diff from GitHub API using curl
  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
    jq -r '.[] | select(.filename == "releases.properties") | .patch')

  echo "Analyzing diff for added/modified versions..."

  # Extract ALL added lines (lines starting with +) that contain version numbers

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unvalidated Input: Data from GitHub API responses (filenames and patches) is used without validation or error
checks, which may cause unintended behavior if the payload is unexpected or empty.

Referred Code
CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
  jq -r '.[].filename')

echo "Changed files in PR:"
echo "$CHANGED_FILES"

# Check if releases.properties was changed
if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
  echo "releases.properties was modified in this PR"

  # Get the diff from GitHub API using curl
  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
    jq -r '.[] | select(.filename == "releases.properties") | .patch')

  echo "Analyzing diff for added/modified versions..."

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Nov 24, 2025

PR Code Suggestions ✨

Latest suggestions up to 604ad29

CategorySuggestion                                                                                                                                    Impact
Possible issue
Null-safe error reporting on download

Add a null check before accessing StatusCode in the Invoke-WebRequest error
handling to prevent script crashes on certain network errors and improve error
reporting.

.github/workflows/postgresql-test.yml [211-221]

 try {
   Invoke-WebRequest -Uri $downloadUrl -OutFile $downloadPath -UseBasicParsing -TimeoutSec 300
 } catch {
   Write-Host "❌ ERROR: Download failed!"
-  Write-Host "Error details: $($_.Exception.Message)"
-  Write-Host "Status Code: $($_.Exception.Response.StatusCode.value__)"
+  $msg = $_.Exception.Message
+  $statusCode = $null
+  if ($_.Exception.Response -and $_.Exception.Response.StatusCode) {
+    $statusCode = $_.Exception.Response.StatusCode.value__
+  }
+  Write-Host "Error details: $msg"
+  if ($statusCode) { Write-Host "Status Code: $statusCode" }
   Write-Host "URL attempted: $downloadUrl"
   echo "success=false" >> $env:GITHUB_OUTPUT
-  echo "error=Download failed: $($_.Exception.Message)" >> $env:GITHUB_OUTPUT
+  echo "error=Download failed: $msg" >> $env:GITHUB_OUTPUT
   exit 1
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a potential null reference exception that would crash the script and obscure the root cause of a download failure, making the error handling more robust.

Medium
Validate each command's exit code

Check the $LASTEXITCODE after each executable version check instead of only once
at the end, to ensure all command failures are correctly detected.

.github/workflows/postgresql-test.yml [375-385]

-$initdbVersion = & $initdbExe --version 2>&1 | Out-String
-Write-Host $initdbVersion
+$errors = @()
 
-if ($LASTEXITCODE -eq 0) {
+& $postgresExe --version 2>&1 | Out-String | Write-Host
+if ($LASTEXITCODE -ne 0) { $errors += "postgres.exe --version failed with exit code $LASTEXITCODE" }
+
+& $psqlExe --version 2>&1 | Out-String | Write-Host
+if ($LASTEXITCODE -ne 0) { $errors += "psql.exe --version failed with exit code $LASTEXITCODE" }
+
+& $initdbExe --version 2>&1 | Out-String | Write-Host
+if ($LASTEXITCODE -ne 0) { $errors += "initdb.exe --version failed with exit code $LASTEXITCODE" }
+
+if ($errors.Count -eq 0) {
   Write-Host "`n✅ All executables are functional"
   echo "success=true" >> $env:GITHUB_OUTPUT
 } else {
   Write-Host "`n❌ Some executables failed"
+  $errors | ForEach-Object { Write-Host " - $_" }
   echo "success=false" >> $env:GITHUB_OUTPUT
   exit 1
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that only the exit code of the last command is being checked, which could cause a failure in a previous command to be missed.

Medium
Fix GitHub API auth header

Update the curl command to use the recommended Authorization: Bearer header and
add a User-Agent header for GitHub API calls to improve reliability.

.github/workflows/postgresql-test.yml [81-84]

-CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
+CHANGED_FILES=$(curl -s \
+  -H "Authorization: Bearer ${{ github.token }}" \
   -H "Accept: application/vnd.github.v3+json" \
+  -H "User-Agent: gha-postgresql-tests" \
   "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
   jq -r '.[].filename')
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies the use of a deprecated GitHub API authentication header and a missing User-Agent header, improving the reliability and adherence to best practices for API calls.

Low
Use proper auth for patch fetch

Update the curl command to use the recommended Authorization: Bearer header and
add a User-Agent header for GitHub API calls to improve reliability.

.github/workflows/postgresql-test.yml [94-97]

-PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
+PATCH=$(curl -s \
+  -H "Authorization: Bearer ${{ github.token }}" \
   -H "Accept: application/vnd.github.v3+json" \
+  -H "User-Agent: gha-postgresql-tests" \
   "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
   jq -r '.[] | select(.filename == "releases.properties") | .patch')
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies the use of a deprecated GitHub API authentication header and a missing User-Agent header, improving the reliability and adherence to best practices for API calls.

Low
  • More

Previous suggestions

Suggestions up to commit 47c3411
CategorySuggestion                                                                                                                                    Impact
General
Optimize by using a single API call

Refactor the code to use a single GitHub API call instead of two to fetch file
changes. Store the API response in a variable and process it to extract the
required information, improving efficiency.

.github/workflows/postgresql-test.yml [79-99]

-# Get the list of changed files first
+# Get changed files info from the PR in a single API call
 echo "Fetching changed files from PR..."
-CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
+CHANGED_FILES_INFO=$(curl -s -H "Authorization: token ${{ github.token }}" \
   -H "Accept: application/vnd.github.v3+json" \
-  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
-  jq -r '.[].filename')
+  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files")
 
-echo "Changed files in PR:"
-echo "$CHANGED_FILES"
+# Extract the patch for releases.properties, if it was changed
+PATCH=$(echo "$CHANGED_FILES_INFO" | jq -r '.[] | select(.filename == "releases.properties") | .patch')
 
-# Check if releases.properties was changed
-if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
+# Check if a patch was found
+if [ -n "$PATCH" ]; then
   echo "releases.properties was modified in this PR"
-  
-  # Get the diff from GitHub API using curl
-  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
-    -H "Accept: application/vnd.github.v3+json" \
-    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
-    jq -r '.[] | select(.filename == "releases.properties") | .patch')
-  
   echo "Analyzing diff for added/modified versions..."
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies an inefficiency where the same API endpoint is called twice and proposes a more efficient single-call approach, which improves performance and robustness.

Low

@qodo-code-review
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 Security concerns

Token exposure risk:
Raw curl with an authorization header is echoed/handled in logs around API calls. Ensure the token is sourced from secrets (secrets.GITHUB_TOKEN) and avoid echoing request details that might include headers.

⚡ Recommended focus areas for review

Possible API Auth Bug

Using '${{ github.token }}' in curl headers may result in an empty token in some contexts; prefer '${{ secrets.GITHUB_TOKEN }}' or the GH CLI to reliably authenticate to the PR files API.

CHANGED_FILES=$(curl -s -H "Authorization: token ${{ github.token }}" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
  jq -r '.[].filename')

echo "Changed files in PR:"
echo "$CHANGED_FILES"

# Check if releases.properties was changed
if echo "$CHANGED_FILES" | grep -q "^releases.properties$"; then
  echo "releases.properties was modified in this PR"

  # Get the diff from GitHub API using curl
  PATCH=$(curl -s -H "Authorization: token ${{ github.token }}" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
    jq -r '.[] | select(.filename == "releases.properties") | .patch')
Windows Exit Code Handling

In Phase 2, success is inferred from '$LASTEXITCODE' after multiple commands; if an earlier command fails but a later one succeeds, '$LASTEXITCODE' may be zero, masking failures. Capture and check each command's exit status explicitly.

# Test that executables can run and show version
try {
  $postgresExe = Join-Path $binPath "postgres.exe"
  $psqlExe = Join-Path $binPath "psql.exe"
  $initdbExe = Join-Path $binPath "initdb.exe"

  Write-Host "`nTesting postgres.exe --version..."
  $pgVersion = & $postgresExe --version 2>&1 | Out-String
  Write-Host $pgVersion

  Write-Host "`nTesting psql.exe --version..."
  $psqlVersion = & $psqlExe --version 2>&1 | Out-String
  Write-Host $psqlVersion

  Write-Host "`nTesting initdb.exe --version..."
  $initdbVersion = & $initdbExe --version 2>&1 | Out-String
  Write-Host $initdbVersion

  if ($LASTEXITCODE -eq 0) {
    Write-Host "`n✅ All executables are functional"
    echo "success=true" >> $env:GITHUB_OUTPUT
  } else {
    Write-Host "`n❌ Some executables failed"
    echo "success=false" >> $env:GITHUB_OUTPUT
    exit 1
  }
} catch {
Matrix Skip Logic

When 'releases.properties' isn't modified in a PR, versions are set to '[]' and tests are skipped; this may miss regressions when workflow or test logic changes. Consider defaulting to a minimal sanity set instead of skipping entirely.

            fi
          else
            echo "releases.properties was NOT modified in this PR"
            echo "Skipping tests - no versions to test"
            VERSIONS="[]"
          fi
        else
          # For other events, test latest 5 versions
          echo "Testing latest 5 versions"
          VERSIONS=$(grep -E "^[0-9]+\.[0-9]+" releases.properties | \
            cut -d'=' -f1 | \
            tr -d ' ' | \
            sort -V -r | \
            head -5 | \
            jq -R -s -c 'split("\n") | map(select(length > 0)) | unique')
        fi

        echo "versions=$VERSIONS" >> $GITHUB_OUTPUT
        echo "Versions to test: $VERSIONS"

test-postgresql:
  name: Test PostgreSQL ${{ matrix.version }}
  needs: detect-versions
  if: needs.detect-versions.outputs.has-changes == 'true' && needs.detect-versions.outputs.versions != '[]'
  runs-on: windows-latest
  strategy:
    fail-fast: false
    matrix:
      version: ${{ fromJson(needs.detect-versions.outputs.versions) }}

@github-actions
Copy link

github-actions bot commented Nov 24, 2025

🐘 PostgreSQL Module Tests - Results

Test Date: 2025-11-24 00:49:35 UTC
Status: ⚠️ Tests completed with issues

⚠️ No test results available


📋 Test Phases

Each version is tested through the following phases:

  • Phase 1: Installation Validation (Download, Extract, Verify Executables)
  • Phase 2: Basic Functionality (Test Executable Versions)

Check artifacts for detailed logs.

@N6REJ N6REJ merged commit 4cfc3e5 into main Nov 24, 2025
7 checks passed
@N6REJ N6REJ deleted the ci branch November 24, 2025 00:50
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.

2 participants