diff --git a/.github/workflows/postgresql-test.yml b/.github/workflows/postgresql-test.yml
new file mode 100644
index 0000000..515453e
--- /dev/null
+++ b/.github/workflows/postgresql-test.yml
@@ -0,0 +1,717 @@
+name: PostgreSQL Module Tests
+
+on:
+ pull_request:
+ branches:
+ - main
+ - develop
+ types: [opened, synchronize, reopened, edited]
+
+jobs:
+ detect-versions:
+ name: Detect PostgreSQL Versions
+ runs-on: ubuntu-latest
+ outputs:
+ versions: ${{ steps.get-versions.outputs.versions }}
+ has-changes: ${{ steps.check-changes.outputs.has-changes }}
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Check for Changes
+ id: check-changes
+ run: |
+ if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
+ echo "has-changes=true" >> $GITHUB_OUTPUT
+ echo "Manual workflow trigger - will run tests"
+ elif [ "${{ github.event_name }}" == "pull_request" ]; then
+ echo "has-changes=true" >> $GITHUB_OUTPUT
+ echo "Pull request - will run tests"
+ else
+ CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
+ if echo "$CHANGED_FILES" | grep -qE "releases\.properties|\.github/workflows/postgresql-test\.yml"; then
+ echo "has-changes=true" >> $GITHUB_OUTPUT
+ echo "Relevant files changed - will run tests"
+ else
+ echo "has-changes=false" >> $GITHUB_OUTPUT
+ echo "No relevant changes - skipping tests"
+ fi
+ fi
+
+ - name: Get PostgreSQL Versions
+ id: get-versions
+ run: |
+ if [ "${{ github.event.inputs.version }}" != "" ]; then
+ # Manual workflow with specific version
+ VERSION="${{ github.event.inputs.version }}"
+ echo "Testing specific version: $VERSION"
+ VERSIONS="[\"$VERSION\"]"
+ else
+ # Get all versions from releases.properties
+ VERSIONS=$(grep -E "^[0-9]+\.[0-9]+" releases.properties | cut -d'=' -f1 | tr -d ' ' | jq -R -s -c 'split("\n") | map(select(length > 0)) | unique | sort_by(split(".") | map(tonumber)) | reverse | .[0:5]')
+ echo "Testing latest 5 versions"
+ 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'
+ runs-on: windows-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ version: ${{ fromJson(needs.detect-versions.outputs.versions) }}
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Create Test Directories
+ run: |
+ New-Item -ItemType Directory -Force -Path "test-postgresql" | Out-Null
+ New-Item -ItemType Directory -Force -Path "test-results" | Out-Null
+ New-Item -ItemType Directory -Force -Path "test-data" | Out-Null
+ Write-Host "✅ Test directories created"
+
+ - name: Phase 1.1 - Download PostgreSQL
+ id: download-postgresql
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $version = "${{ matrix.version }}"
+
+ Write-Host "=== Phase 1.1: Download PostgreSQL $version ==="
+
+ # Read releases.properties to get download URL
+ $releasesFile = "releases.properties"
+ $downloadUrl = ""
+
+ if (Test-Path $releasesFile) {
+ $content = Get-Content $releasesFile
+ foreach ($line in $content) {
+ if ($line -match "^$version\s*=\s*(.+)$") {
+ $downloadUrl = $matches[1].Trim()
+ break
+ }
+ }
+ } else {
+ Write-Host "❌ ERROR: releases.properties file not found!"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=releases.properties file not found" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ if (-not $downloadUrl) {
+ Write-Host "❌ ERROR: Version $version not found in releases.properties"
+ Write-Host "Available versions in releases.properties:"
+ Get-Content $releasesFile | Select-String "^[0-9]" | ForEach-Object { Write-Host " - $($_.Line.Split('=')[0].Trim())" }
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=Version $version not found in releases.properties" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ Write-Host "Download URL: $downloadUrl"
+
+ try {
+ $fileName = [System.IO.Path]::GetFileName($downloadUrl)
+ $downloadPath = Join-Path "test-postgresql" $fileName
+
+ Write-Host "Downloading PostgreSQL $version..."
+ Write-Host "Target file: $downloadPath"
+
+ 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__)"
+ Write-Host "URL attempted: $downloadUrl"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=Download failed: $($_.Exception.Message)" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ if (Test-Path $downloadPath) {
+ $fileSize = (Get-Item $downloadPath).Length / 1MB
+ Write-Host "✅ Downloaded: $fileName ($([math]::Round($fileSize, 2)) MB)"
+
+ # Verify file is not empty or too small
+ if ($fileSize -lt 0.1) {
+ Write-Host "❌ ERROR: Downloaded file is too small ($([math]::Round($fileSize, 2)) MB), likely corrupted"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=Downloaded file is too small or corrupted" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ # Extract the archive
+ Write-Host "Extracting archive..."
+ $extractOutput = & 7z x $downloadPath -o"test-postgresql" -y 2>&1
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Extraction successful"
+
+ # List extracted contents
+ Write-Host "Extracted contents:"
+ Get-ChildItem -Path "test-postgresql" -Directory | ForEach-Object { Write-Host " - $($_.Name)" }
+
+ # Find the postgresql directory
+ $pgDir = Get-ChildItem -Path "test-postgresql" -Directory | Where-Object { $_.Name -match "^postgresql" } | Select-Object -First 1
+
+ if ($pgDir) {
+ $pgPath = $pgDir.FullName
+ Write-Host "✅ PostgreSQL directory found: $pgPath"
+
+ # Verify bin directory exists
+ $binPath = Join-Path $pgPath "bin"
+ if (Test-Path $binPath) {
+ Write-Host "✅ bin directory exists"
+ echo "pg-path=$pgPath" >> $env:GITHUB_OUTPUT
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ ERROR: bin directory not found in $pgPath"
+ Write-Host "Directory structure:"
+ Get-ChildItem -Path $pgPath | ForEach-Object { Write-Host " - $($_.Name)" }
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=bin directory not found in extracted archive" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } else {
+ Write-Host "❌ ERROR: PostgreSQL directory not found after extraction"
+ Write-Host "Expected directory pattern: postgresql*"
+ Write-Host "Found directories:"
+ Get-ChildItem -Path "test-postgresql" -Directory | ForEach-Object { Write-Host " - $($_.Name)" }
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=PostgreSQL directory not found after extraction" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } else {
+ Write-Host "❌ ERROR: Extraction failed with exit code: $LASTEXITCODE"
+ Write-Host "7z output:"
+ Write-Host $extractOutput
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=Extraction failed with exit code $LASTEXITCODE" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } else {
+ Write-Host "❌ ERROR: Download file not found at expected path: $downloadPath"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=Download file not found after download attempt" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ ERROR: Unexpected error occurred"
+ Write-Host "Error message: $($_.Exception.Message)"
+ Write-Host "Stack trace: $($_.ScriptStackTrace)"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ echo "error=$($_.Exception.Message)" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 1.2 - Verify PostgreSQL Installation
+ id: verify-postgresql
+ if: steps.download-postgresql.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $pgPath = "${{ steps.download-postgresql.outputs.pg-path }}"
+
+ Write-Host "=== Phase 1.2: Verify PostgreSQL Installation ==="
+
+ # Check for required executables
+ $binPath = Join-Path $pgPath "bin"
+ $requiredExes = @("postgres.exe", "psql.exe", "pg_ctl.exe", "initdb.exe", "createdb.exe", "dropdb.exe")
+
+ $allFound = $true
+ $verifyResults = @{}
+
+ foreach ($exe in $requiredExes) {
+ $exePath = Join-Path $binPath $exe
+ if (Test-Path $exePath) {
+ Write-Host "✅ Found: $exe"
+ $verifyResults[$exe] = @{ found = $true; path = $exePath }
+ } else {
+ Write-Host "❌ Missing: $exe"
+ $verifyResults[$exe] = @{ found = $false }
+ $allFound = $false
+ }
+ }
+
+ # Test postgres version
+ if ($allFound) {
+ try {
+ $postgresExe = Join-Path $binPath "postgres.exe"
+ $versionOutput = & $postgresExe --version 2>&1 | Out-String
+ Write-Host "Version: $versionOutput"
+ $verifyResults["version"] = $versionOutput.Trim()
+ } catch {
+ Write-Host "⚠️ Could not get version: $_"
+ }
+ }
+
+ $verifyResults | ConvertTo-Json -Depth 10 | Out-File "test-results/verify.json"
+
+ if ($allFound) {
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ echo "bin-path=$binPath" >> $env:GITHUB_OUTPUT
+ } else {
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 2.1 - Initialize Database Cluster
+ id: init-database
+ if: steps.verify-postgresql.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+ $dataDir = Join-Path (Get-Location) "test-data\pgdata"
+
+ Write-Host "=== Phase 2.1: Initialize Database Cluster ==="
+ Write-Host "Data directory: $dataDir"
+
+ try {
+ $initdbExe = Join-Path $binPath "initdb.exe"
+
+ # Initialize the database cluster
+ Write-Host "Initializing database cluster..."
+ $output = & $initdbExe -D $dataDir -U postgres -A trust --locale=C --encoding=UTF8 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Database cluster initialized successfully"
+ Write-Host $output
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ echo "data-dir=$dataDir" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ Database initialization failed"
+ Write-Host $output
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ Error initializing database: $_"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 2.2 - Start PostgreSQL Server
+ id: start-server
+ if: steps.init-database.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+ $dataDir = "${{ steps.init-database.outputs.data-dir }}"
+ $logFile = Join-Path (Get-Location) "test-results\postgresql.log"
+
+ Write-Host "=== Phase 2.2: Start PostgreSQL Server ==="
+
+ try {
+ $pgCtlExe = Join-Path $binPath "pg_ctl.exe"
+
+ # Start the server
+ Write-Host "Starting PostgreSQL server..."
+ $output = & $pgCtlExe -D $dataDir -l $logFile start 2>&1 | Out-String
+ Write-Host $output
+
+ # Wait for server to be ready
+ Write-Host "Waiting for server to be ready..."
+ Start-Sleep -Seconds 5
+
+ # Check server status
+ $statusOutput = & $pgCtlExe -D $dataDir status 2>&1 | Out-String
+ Write-Host $statusOutput
+
+ if ($statusOutput -match "server is running") {
+ Write-Host "✅ PostgreSQL server is running"
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ echo "log-file=$logFile" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ Server is not running"
+ if (Test-Path $logFile) {
+ Write-Host "Server log:"
+ Get-Content $logFile | Write-Host
+ }
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ Error starting server: $_"
+ if (Test-Path $logFile) {
+ Write-Host "Server log:"
+ Get-Content $logFile | Write-Host
+ }
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 3.1 - Test Database Connection
+ id: test-connection
+ if: steps.start-server.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+
+ Write-Host "=== Phase 3.1: Test Database Connection ==="
+
+ try {
+ $psqlExe = Join-Path $binPath "psql.exe"
+
+ # Test connection to default postgres database
+ Write-Host "Testing connection to postgres database..."
+ $output = & $psqlExe -U postgres -d postgres -c "SELECT version();" 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Connection successful"
+ Write-Host $output
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ Connection failed"
+ Write-Host $output
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ Error testing connection: $_"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 3.2 - Test Database Creation
+ id: test-create-db
+ if: steps.test-connection.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+ $testDbName = "bearsampp_test_db"
+
+ Write-Host "=== Phase 3.2: Test Database Creation ==="
+
+ try {
+ $createdbExe = Join-Path $binPath "createdb.exe"
+ $psqlExe = Join-Path $binPath "psql.exe"
+
+ # Create test database
+ Write-Host "Creating test database: $testDbName"
+ $output = & $createdbExe -U postgres $testDbName 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Database created successfully"
+
+ # Verify database exists
+ Write-Host "Verifying database exists..."
+ $verifyOutput = & $psqlExe -U postgres -d postgres -c "\l" 2>&1 | Out-String
+
+ if ($verifyOutput -match $testDbName) {
+ Write-Host "✅ Database verified in database list"
+
+ # Create a test table
+ Write-Host "Creating test table..."
+ $tableOutput = & $psqlExe -U postgres -d $testDbName -c "CREATE TABLE test_table (id SERIAL PRIMARY KEY, name VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);" 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Test table created"
+
+ # Insert test data
+ Write-Host "Inserting test data..."
+ $insertOutput = & $psqlExe -U postgres -d $testDbName -c "INSERT INTO test_table (name) VALUES ('Bearsampp Test 1'), ('Bearsampp Test 2');" 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Test data inserted"
+
+ # Query test data
+ Write-Host "Querying test data..."
+ $queryOutput = & $psqlExe -U postgres -d $testDbName -c "SELECT * FROM test_table;" 2>&1 | Out-String
+ Write-Host $queryOutput
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Test data queried successfully"
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ echo "test-db=$testDbName" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ Failed to query test data"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ }
+ } else {
+ Write-Host "❌ Failed to insert test data"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ }
+ } else {
+ Write-Host "❌ Failed to create test table"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ }
+ } else {
+ Write-Host "❌ Database not found in list"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ }
+ } else {
+ Write-Host "❌ Database creation failed"
+ Write-Host $output
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ Error creating database: $_"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 3.3 - Test Database Deletion
+ id: test-delete-db
+ if: steps.test-create-db.outputs.success == 'true'
+ continue-on-error: true
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+ $testDbName = "${{ steps.test-create-db.outputs.test-db }}"
+
+ Write-Host "=== Phase 3.3: Test Database Deletion ==="
+
+ try {
+ $dropdbExe = Join-Path $binPath "dropdb.exe"
+ $psqlExe = Join-Path $binPath "psql.exe"
+
+ # Drop test database
+ Write-Host "Dropping test database: $testDbName"
+ $output = & $dropdbExe -U postgres $testDbName 2>&1 | Out-String
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ Database dropped successfully"
+
+ # Verify database no longer exists
+ Write-Host "Verifying database was deleted..."
+ $verifyOutput = & $psqlExe -U postgres -d postgres -c "\l" 2>&1 | Out-String
+
+ if ($verifyOutput -notmatch $testDbName) {
+ Write-Host "✅ Database successfully removed from database list"
+ echo "success=true" >> $env:GITHUB_OUTPUT
+ } else {
+ Write-Host "❌ Database still exists in list"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ }
+ } else {
+ Write-Host "❌ Database deletion failed"
+ Write-Host $output
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+ } catch {
+ Write-Host "❌ Error deleting database: $_"
+ echo "success=false" >> $env:GITHUB_OUTPUT
+ exit 1
+ }
+
+ - name: Phase 4 - Cleanup and Stop Server
+ if: always() && steps.start-server.outputs.success == 'true'
+ run: |
+ $ErrorActionPreference = "Continue"
+ $binPath = "${{ steps.verify-postgresql.outputs.bin-path }}"
+ $dataDir = "${{ steps.init-database.outputs.data-dir }}"
+
+ Write-Host "=== Phase 4: Cleanup and Stop Server ==="
+
+ try {
+ $pgCtlExe = Join-Path $binPath "pg_ctl.exe"
+
+ # Stop the server
+ Write-Host "Stopping PostgreSQL server..."
+ $output = & $pgCtlExe -D $dataDir stop -m fast 2>&1 | Out-String
+ Write-Host $output
+
+ # Wait for server to stop
+ Start-Sleep -Seconds 3
+
+ # Verify server stopped
+ $statusOutput = & $pgCtlExe -D $dataDir status 2>&1 | Out-String
+
+ if ($statusOutput -match "no server running") {
+ Write-Host "✅ PostgreSQL server stopped successfully"
+ } else {
+ Write-Host "⚠️ Server may still be running"
+ }
+ } catch {
+ Write-Host "⚠️ Error during cleanup: $_"
+ }
+
+ - name: Generate Test Summary
+ if: always()
+ run: |
+ $version = "${{ matrix.version }}"
+
+ Write-Host "`n=== Test Summary for PostgreSQL $version ==="
+
+ $phase1_1 = "${{ steps.download-postgresql.outputs.success }}" -eq "true"
+ $phase1_2 = "${{ steps.verify-postgresql.outputs.success }}" -eq "true"
+ $phase2_1 = "${{ steps.init-database.outputs.success }}" -eq "true"
+ $phase2_2 = "${{ steps.start-server.outputs.success }}" -eq "true"
+ $phase3_1 = "${{ steps.test-connection.outputs.success }}" -eq "true"
+ $phase3_2 = "${{ steps.test-create-db.outputs.success }}" -eq "true"
+ $phase3_3 = "${{ steps.test-delete-db.outputs.success }}" -eq "true"
+
+ # Get error messages if any
+ $error1_1 = "${{ steps.download-postgresql.outputs.error }}"
+
+ $summary = "### PostgreSQL $version`n`n"
+
+ $summary += "**Phase 1: Installation Validation**`n"
+ $summary += "- Download & Extract: $(if ($phase1_1) { '✅ PASS' } else { '❌ FAIL' })`n"
+ if (-not $phase1_1 -and $error1_1) {
+ $summary += " - Error: $error1_1`n"
+ }
+ $summary += "- Verify Executables: $(if ($phase1_2) { '✅ PASS' } else { '❌ FAIL' })`n`n"
+
+ if ($phase1_2) {
+ $summary += "**Phase 2: Server Initialization**`n"
+ $summary += "- Initialize Cluster: $(if ($phase2_1) { '✅ PASS' } else { '❌ FAIL' })`n"
+ if ($phase2_1) {
+ $summary += "- Start Server: $(if ($phase2_2) { '✅ PASS' } else { '❌ FAIL' })`n"
+ }
+ $summary += "`n"
+ }
+
+ if ($phase2_2) {
+ $summary += "**Phase 3: Database Operations**`n"
+ $summary += "- Test Connection: $(if ($phase3_1) { '✅ PASS' } else { '❌ FAIL' })`n"
+ if ($phase3_1) {
+ $summary += "- Create Database: $(if ($phase3_2) { '✅ PASS' } else { '❌ FAIL' })`n"
+ if ($phase3_2) {
+ $summary += "- Delete Database: $(if ($phase3_3) { '✅ PASS' } else { '❌ FAIL' })`n"
+ }
+ }
+ $summary += "`n"
+ }
+
+ # Overall status
+ $allPassed = $phase1_1 -and $phase1_2 -and $phase2_1 -and $phase2_2 -and $phase3_1 -and $phase3_2 -and $phase3_3
+
+ if ($allPassed) {
+ $summary += "**Overall Status:** ✅ ALL TESTS PASSED`n"
+ } else {
+ $summary += "**Overall Status:** ❌ SOME TESTS FAILED`n"
+ $summary += "`n"
+ $summary += "`n"
+ $summary += "💡 Click here for troubleshooting tips
`n`n"
+ $summary += "- Check the workflow logs for detailed error messages`n"
+ $summary += "- Download the test artifacts for complete logs`n"
+ $summary += "- Review the server logs if server startup failed`n"
+ $summary += "- Verify the .7z archive structure matches expected format`n"
+ $summary += " `n"
+ }
+
+ Write-Host $summary
+ $summary | Out-File "test-results/summary.md"
+
+ - name: Upload Test Results
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-results-postgresql-${{ matrix.version }}
+ path: test-results/
+ retention-days: 30
+
+ - name: Upload Server Logs
+ if: always() && steps.start-server.outputs.success == 'true'
+ uses: actions/upload-artifact@v4
+ with:
+ name: server-logs-postgresql-${{ matrix.version }}
+ path: test-results/postgresql.log
+ retention-days: 7
+
+ report-results:
+ name: Report Test Results
+ needs: [detect-versions, test-postgresql]
+ if: always() && needs.detect-versions.outputs.has-changes == 'true' && needs.test-postgresql.result != 'cancelled'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download all test results
+ uses: actions/download-artifact@v4
+ with:
+ path: all-results
+ continue-on-error: true
+
+ - name: Generate PR Comment
+ run: |
+ echo "## 🐘 PostgreSQL Module Tests - Complete Results" > comment.md
+ echo "" >> comment.md
+ echo "**Test Date:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> comment.md
+ echo "" >> comment.md
+
+ # Check if artifacts exist
+ if [ -d "all-results" ]; then
+ for version_dir in all-results/test-results-postgresql-*; do
+ if [ -d "$version_dir" ]; then
+ for summary_file in "$version_dir"/summary.md; do
+ if [ -f "$summary_file" ]; then
+ cat "$summary_file" >> comment.md
+ echo "" >> comment.md
+ fi
+ done
+ fi
+ done
+ else
+ echo "⚠️ No test results available" >> comment.md
+ echo "" >> comment.md
+ fi
+
+ echo "---" >> comment.md
+ echo "" >> comment.md
+ echo "### 📋 Test Phases" >> comment.md
+ echo "" >> comment.md
+ echo "✅ **Completed:**" >> comment.md
+ echo "- Phase 1: Installation Validation (Download, Extract, Verify)" >> comment.md
+ echo "- Phase 2: Server Initialization (Init Cluster, Start Server)" >> comment.md
+ echo "- Phase 3: Database Operations (Connect, Create DB, Delete DB)" >> comment.md
+ echo "- Phase 4: Cleanup (Stop Server)" >> comment.md
+ echo "" >> comment.md
+ echo "_All phases of PostgreSQL testing are complete! Check artifacts for detailed logs._" >> comment.md
+
+ cat comment.md
+
+ - name: Comment on PR
+ if: github.event_name == 'pull_request'
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const comment = fs.readFileSync('comment.md', 'utf8');
+
+ const { data: comments } = await github.rest.issues.listComments({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ });
+
+ const botComment = comments.find(comment =>
+ comment.user.type === 'Bot' &&
+ comment.body.includes('🐘 PostgreSQL Module Tests')
+ );
+
+ if (botComment) {
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: botComment.id,
+ body: comment
+ });
+ } else {
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: comment
+ });
+ }
+
+ - name: Display Results Summary (Manual Run)
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "## 🐘 PostgreSQL Module Tests - Manual Run Results"
+ echo ""
+ cat comment.md
diff --git a/.gradle/9.2.0/checksums/checksums.lock b/.gradle/9.2.0/checksums/checksums.lock
new file mode 100644
index 0000000..df77bc8
Binary files /dev/null and b/.gradle/9.2.0/checksums/checksums.lock differ
diff --git a/.gradle/9.2.0/executionHistory/executionHistory.lock b/.gradle/9.2.0/executionHistory/executionHistory.lock
new file mode 100644
index 0000000..adeee5b
Binary files /dev/null and b/.gradle/9.2.0/executionHistory/executionHistory.lock differ
diff --git a/.gradle/9.2.0/fileChanges/last-build.bin b/.gradle/9.2.0/fileChanges/last-build.bin
new file mode 100644
index 0000000..f76dd23
Binary files /dev/null and b/.gradle/9.2.0/fileChanges/last-build.bin differ
diff --git a/.gradle/9.2.0/fileHashes/fileHashes.lock b/.gradle/9.2.0/fileHashes/fileHashes.lock
new file mode 100644
index 0000000..6b25e65
Binary files /dev/null and b/.gradle/9.2.0/fileHashes/fileHashes.lock differ
diff --git a/.gradle/9.2.0/gc.properties b/.gradle/9.2.0/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/.gradle/build-cache/gc.properties b/.gradle/build-cache/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000..0d05db1
Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000..0f27397
--- /dev/null
+++ b/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Sun Nov 16 08:54:49 CST 2025
+gradle.version=9.2.0
diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/bin/postgresql13.23/bearsampp.conf b/bin/postgresql13.23/bearsampp.conf
new file mode 100644
index 0000000..e40daee
--- /dev/null
+++ b/bin/postgresql13.23/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "13.23"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql13.23/init.bat b/bin/postgresql13.23/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql13.23/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql13.23/pg_hba.conf.ber b/bin/postgresql13.23/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql13.23/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql13.23/postgresql.conf.ber b/bin/postgresql13.23/postgresql.conf.ber
new file mode 100644
index 0000000..295a564
--- /dev/null
+++ b/bin/postgresql13.23/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql13.23/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql13.23/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql13.23/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/bin/postgresql14.20/bearsampp.conf b/bin/postgresql14.20/bearsampp.conf
new file mode 100644
index 0000000..6135c44
--- /dev/null
+++ b/bin/postgresql14.20/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "14.20"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql14.20/init.bat b/bin/postgresql14.20/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql14.20/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql14.20/pg_hba.conf.ber b/bin/postgresql14.20/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql14.20/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql14.20/postgresql.conf.ber b/bin/postgresql14.20/postgresql.conf.ber
new file mode 100644
index 0000000..9de4e91
--- /dev/null
+++ b/bin/postgresql14.20/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql14.20/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql14.20/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql14.20/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/bin/postgresql15.15/bearsampp.conf b/bin/postgresql15.15/bearsampp.conf
new file mode 100644
index 0000000..9114d52
--- /dev/null
+++ b/bin/postgresql15.15/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "15.15"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql15.15/init.bat b/bin/postgresql15.15/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql15.15/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql15.15/pg_hba.conf.ber b/bin/postgresql15.15/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql15.15/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql15.15/postgresql.conf.ber b/bin/postgresql15.15/postgresql.conf.ber
new file mode 100644
index 0000000..d96be5b
--- /dev/null
+++ b/bin/postgresql15.15/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql15.15/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql15.15/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql15.15/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/bin/postgresql16.11/bearsampp.conf b/bin/postgresql16.11/bearsampp.conf
new file mode 100644
index 0000000..640002d
--- /dev/null
+++ b/bin/postgresql16.11/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "16.11"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql16.11/init.bat b/bin/postgresql16.11/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql16.11/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql16.11/pg_hba.conf.ber b/bin/postgresql16.11/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql16.11/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql16.11/postgresql.conf.ber b/bin/postgresql16.11/postgresql.conf.ber
new file mode 100644
index 0000000..3f85190
--- /dev/null
+++ b/bin/postgresql16.11/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql16.11/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql16.11/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql16.11/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/bin/postgresql17.7/bearsampp.conf b/bin/postgresql17.7/bearsampp.conf
new file mode 100644
index 0000000..2c398bf
--- /dev/null
+++ b/bin/postgresql17.7/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "17.7"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql17.7/init.bat b/bin/postgresql17.7/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql17.7/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql17.7/pg_hba.conf.ber b/bin/postgresql17.7/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql17.7/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql17.7/postgresql.conf.ber b/bin/postgresql17.7/postgresql.conf.ber
new file mode 100644
index 0000000..94be22d
--- /dev/null
+++ b/bin/postgresql17.7/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql17.7/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql17.7/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql17.7/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/bin/postgresql18.1/bearsampp.conf b/bin/postgresql18.1/bearsampp.conf
new file mode 100644
index 0000000..93ef67d
--- /dev/null
+++ b/bin/postgresql18.1/bearsampp.conf
@@ -0,0 +1,14 @@
+postgresqlVersion = "18.1"
+postgresqlCtlExe = "bin/pg_ctl.exe"
+postgresqlCliExe = "bin/psql.exe"
+postgresqlDumpExe = "bin/pg_dump.exe"
+postgresqlDumpAllExe = "bin/pg_dumpall.exe"
+postgresqlConf = "data/postgresql.conf"
+postgresqlUserConf = "data/pg_hba.conf"
+postgresqlAltConf = "postgresql.conf.ber"
+postgresqlAltUserConf = "pg_hba.conf.ber"
+postgresqlPort = "5432"
+postgresqlRootUser = "postgres"
+postgresqlRootPwd = ""
+
+bundleRelease = "@RELEASE_VERSION@"
diff --git a/bin/postgresql18.1/init.bat b/bin/postgresql18.1/init.bat
new file mode 100644
index 0000000..f0acb2d
--- /dev/null
+++ b/bin/postgresql18.1/init.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+
+%~dp0bin\initdb.exe -U postgres -A trust -E utf8 -D "%~dp0data" > "~BEARSAMPP_WIN_PATH~\logs\postgresql-install.log" 2>&1
+copy /y "%~dp0postgresql.conf.ber" "%~dp0data\postgresql.conf"
+copy /y "%~dp0pg_hba.conf.ber" "%~dp0data\pg_hba.conf"
diff --git a/bin/postgresql18.1/pg_hba.conf.ber b/bin/postgresql18.1/pg_hba.conf.ber
new file mode 100644
index 0000000..29b8f8b
--- /dev/null
+++ b/bin/postgresql18.1/pg_hba.conf.ber
@@ -0,0 +1,3 @@
+# TYPE DATABASE USER ADDRESS METHOD
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
diff --git a/bin/postgresql18.1/postgresql.conf.ber b/bin/postgresql18.1/postgresql.conf.ber
new file mode 100644
index 0000000..f449d31
--- /dev/null
+++ b/bin/postgresql18.1/postgresql.conf.ber
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# FILE LOCATIONS
+#------------------------------------------------------------------------------
+data_directory = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql18.1/data'
+hba_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql18.1/data/pg_hba.conf'
+ident_file = '~BEARSAMPP_LIN_PATH~/bin/postgresql/postgresql18.1/data/pg_ident.conf'
+
+#------------------------------------------------------------------------------
+# CONNECTIONS AND AUTHENTICATION
+#------------------------------------------------------------------------------
+listen_addresses = '*'
+port = 5432
+max_connections = 100
+
+#------------------------------------------------------------------------------
+# RESOURCE USAGE (except WAL)
+#------------------------------------------------------------------------------
+shared_buffers = 32MB
+
+#------------------------------------------------------------------------------
+# ERROR REPORTING AND LOGGING
+#------------------------------------------------------------------------------
+log_destination = 'stderr'
+logging_collector = on
+log_directory = '~BEARSAMPP_LIN_PATH~/logs'
+log_filename = 'postgresql.log'
+log_file_mode = 0777
+log_truncate_on_rotation = off
+log_rotation_age = 0
+log_rotation_size = 0
+
+client_min_messages = notice
+log_min_messages = warning
+log_min_error_statement = error
+log_min_duration_statement = -1
diff --git a/build/reports/problems/problems-report.html b/build/reports/problems/problems-report.html
new file mode 100644
index 0000000..1dd6e08
--- /dev/null
+++ b/build/reports/problems/problems-report.html
@@ -0,0 +1,659 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Gradle Configuration Cache
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
diff --git a/docs/CI-CD-TESTING.md b/docs/CI-CD-TESTING.md
new file mode 100644
index 0000000..454b55b
--- /dev/null
+++ b/docs/CI-CD-TESTING.md
@@ -0,0 +1,255 @@
+# PostgreSQL Module CI/CD Testing
+
+## Overview
+
+This document describes the automated testing workflow for the Bearsampp PostgreSQL module. The CI/CD pipeline ensures that PostgreSQL builds are properly packaged, can be extracted, started, and perform basic database operations.
+
+## Workflow Triggers
+
+The PostgreSQL testing workflow is triggered automatically on:
+
+- **Pull Request Events**: When a PR is opened, synchronized (new commits pushed), reopened, or edited
+ - Target branches: `main` or `develop`
+
+## Test Scope
+
+The workflow tests the **latest 5 PostgreSQL versions** from `releases.properties` by default. This ensures recent versions are validated while keeping CI runtime reasonable.
+
+## Test Phases
+
+### Phase 1: Installation Validation
+
+**Purpose**: Verify the PostgreSQL package can be downloaded and extracted correctly.
+
+**Steps**:
+1. **Download PostgreSQL** (Phase 1.1)
+ - Reads the download URL from `releases.properties`
+ - Downloads the `.7z` archive from GitHub releases
+ - Reports download size and success status
+
+2. **Extract Archive** (Phase 1.1)
+ - Extracts the `.7z` file using 7-Zip
+ - Locates the `postgresqlVERSION` subfolder
+ - Validates the directory structure
+
+3. **Verify Executables** (Phase 1.2)
+ - Checks for required PostgreSQL executables:
+ - `postgres.exe` - Main database server
+ - `psql.exe` - Command-line client
+ - `pg_ctl.exe` - Server control utility
+ - `initdb.exe` - Database cluster initialization
+ - `createdb.exe` - Database creation utility
+ - `dropdb.exe` - Database deletion utility
+ - Retrieves and displays PostgreSQL version
+
+### Phase 2: Server Initialization
+
+**Purpose**: Verify PostgreSQL can initialize a database cluster and start successfully.
+
+**Steps**:
+1. **Initialize Database Cluster** (Phase 2.1)
+ - Creates a new PostgreSQL data directory
+ - Initializes the cluster with:
+ - User: `postgres`
+ - Authentication: `trust` (for testing)
+ - Locale: `C`
+ - Encoding: `UTF8`
+ - Validates initialization success
+
+2. **Start PostgreSQL Server** (Phase 2.2)
+ - Starts the PostgreSQL server using `pg_ctl`
+ - Waits for server to be ready (5 seconds)
+ - Verifies server is running
+ - Captures server logs for debugging
+
+### Phase 3: Database Operations
+
+**Purpose**: Verify basic database operations work correctly.
+
+**Steps**:
+1. **Test Connection** (Phase 3.1)
+ - Connects to the default `postgres` database
+ - Executes `SELECT version();` query
+ - Validates connection and query execution
+
+2. **Test Database Creation** (Phase 3.2)
+ - Creates a test database: `bearsampp_test_db`
+ - Verifies database appears in database list
+ - Creates a test table with columns:
+ - `id` (SERIAL PRIMARY KEY)
+ - `name` (VARCHAR(100))
+ - `created_at` (TIMESTAMP)
+ - Inserts sample data (2 test records)
+ - Queries and displays the test data
+ - Validates all operations succeed
+
+3. **Test Database Deletion** (Phase 3.3)
+ - Drops the test database using `dropdb`
+ - Verifies database no longer exists in database list
+ - Validates cleanup was successful
+
+### Phase 4: Cleanup
+
+**Purpose**: Properly shut down the PostgreSQL server.
+
+**Steps**:
+- Stops the PostgreSQL server using `pg_ctl stop -m fast`
+- Waits for graceful shutdown (3 seconds)
+- Verifies server has stopped
+- Runs even if previous phases failed (using `if: always()`)
+
+## Test Results
+
+### Artifacts
+
+The workflow generates and uploads the following artifacts:
+
+1. **Test Results** (`test-results-postgresql-VERSION`)
+ - `verify.json` - Executable verification results
+ - `summary.md` - Human-readable test summary
+ - Retention: 30 days
+
+2. **Server Logs** (`server-logs-postgresql-VERSION`)
+ - `postgresql.log` - Complete server log output
+ - Retention: 7 days
+
+### PR Comments
+
+For pull requests, the workflow automatically posts a comment with:
+- Test date and time (UTC)
+- Summary for each tested version
+- Pass/fail status for each phase
+- Overall test status
+- Links to detailed artifacts
+
+The comment is updated if it already exists (no duplicate comments).
+
+### Test Summary Format
+
+Each version's summary includes:
+
+```
+### PostgreSQL X.Y
+
+**Phase 1: Installation Validation**
+- Download & Extract: ✅ PASS / ❌ FAIL
+- Verify Executables: ✅ PASS / ❌ FAIL
+
+**Phase 2: Server Initialization**
+- Initialize Cluster: ✅ PASS / ❌ FAIL
+- Start Server: ✅ PASS / ❌ FAIL
+
+**Phase 3: Database Operations**
+- Test Connection: ✅ PASS / ❌ FAIL
+- Create Database: ✅ PASS / ❌ FAIL
+- Delete Database: ✅ PASS / ❌ FAIL
+
+**Overall Status:** ✅ ALL TESTS PASSED / ❌ SOME TESTS FAILED
+```
+
+## Error Handling
+
+- Each phase uses `continue-on-error: true` to allow subsequent phases to run
+- Failed phases are clearly marked in the summary
+- Server logs are always uploaded for debugging
+- Cleanup phase always runs to prevent resource leaks
+
+## Platform
+
+- **Runner**: `windows-latest`
+- **Reason**: PostgreSQL builds are Windows executables (.exe)
+- **Tools**: Native Windows PowerShell, 7-Zip
+
+## Matrix Strategy
+
+- **Parallel Execution**: Tests run in parallel for different versions
+- **Fail-Fast**: Disabled (`fail-fast: false`) to test all versions even if one fails
+- **Version Selection**: Latest 5 versions from `releases.properties`
+
+## Workflow File Location
+
+`.github/workflows/postgresql-test.yml`
+
+## Maintenance
+
+### Adding New Test Cases
+
+To add new database operation tests:
+
+1. Add a new step after Phase 3.3
+2. Use `continue-on-error: true`
+3. Check previous phase success with `if: steps.PREVIOUS_STEP.outputs.success == 'true'`
+4. Set output variable: `echo "success=true/false" >> $env:GITHUB_OUTPUT`
+5. Update the test summary generation to include the new phase
+
+### Modifying Version Selection
+
+To change which versions are tested, edit the `Get PostgreSQL Versions` step:
+
+```bash
+# Current: Latest 5 versions
+VERSIONS=$(... | .[0:5]')
+
+# Example: Latest 3 versions
+VERSIONS=$(... | .[0:3]')
+
+# Example: All versions
+VERSIONS=$(... | .')
+```
+
+### Adjusting Timeouts
+
+Key timing parameters:
+
+- Server startup wait: `Start-Sleep -Seconds 5` (Phase 2.2)
+- Server shutdown wait: `Start-Sleep -Seconds 3` (Phase 4)
+
+Increase these values if tests fail due to slow server startup/shutdown.
+
+## Troubleshooting
+
+### Common Issues
+
+1. **Download Failures**
+ - Check if the release URL in `releases.properties` is valid
+ - Verify GitHub releases are accessible
+ - Check network connectivity
+
+2. **Extraction Failures**
+ - Ensure `.7z` file is not corrupted
+ - Verify 7-Zip is available on the runner
+ - Check archive structure matches expected format
+
+3. **Server Start Failures**
+ - Review `postgresql.log` artifact
+ - Check for port conflicts (default: 5432)
+ - Verify data directory permissions
+
+4. **Connection Failures**
+ - Ensure server had enough time to start
+ - Check authentication settings (trust mode)
+ - Review server logs for errors
+
+### Debugging
+
+To debug a specific version:
+
+1. Check the workflow run in GitHub Actions
+2. Expand the failed step to see detailed output
+3. Download the test results artifact
+4. Review `postgresql.log` for server-side errors
+5. Check `verify.json` for executable validation details
+
+## Best Practices
+
+1. **Always test before merging**: The workflow runs on PRs to catch issues early
+2. **Review test summaries**: Check PR comments for test results
+3. **Investigate failures**: Don't merge if tests fail without understanding why
+4. **Keep versions updated**: Regularly update `releases.properties` with new PostgreSQL versions
+5. **Monitor artifact storage**: Old artifacts are automatically cleaned up after retention period
+
+## Related Documentation
+
+- [PostgreSQL Official Documentation](https://www.postgresql.org/docs/)
+- [GitHub Actions Documentation](https://docs.github.com/en/actions)
+- [Bearsampp Project](https://github.com/Bearsampp)
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..964e864
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,36 @@
+# PostgreSQL Module Documentation
+
+This directory contains documentation for the Bearsampp PostgreSQL module.
+
+## Available Documentation
+
+### [CI/CD Testing](CI-CD-TESTING.md)
+
+Comprehensive guide to the automated testing workflow for PostgreSQL builds:
+- Workflow triggers and configuration
+- Detailed test phase descriptions
+- Test results and artifacts
+- Troubleshooting guide
+- Maintenance instructions
+
+## Quick Links
+
+- **Workflow File**: [`.github/workflows/postgresql-test.yml`](../.github/workflows/postgresql-test.yml)
+- **Releases**: [`releases.properties`](../releases.properties)
+- **Main Repository**: [Bearsampp PostgreSQL Module](https://github.com/Bearsampp/module-postgresql)
+
+## Contributing
+
+When adding new features or making changes to the PostgreSQL module:
+
+1. Update relevant documentation in this folder
+2. Ensure CI/CD tests pass on your pull request
+3. Review test results in the automated PR comment
+4. Update this README if adding new documentation files
+
+## Support
+
+For issues or questions:
+- Open an issue on [GitHub](https://github.com/Bearsampp/module-postgresql/issues)
+- Check existing documentation for troubleshooting steps
+- Review CI/CD test logs for build-related issues