From d7eb54b153560c52e8463f65747b0371e5502fbc Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 12:10:37 +0530 Subject: [PATCH 1/5] ci: upgrade the PostgreSQL server test workflow (kept opt-in via 'postgres' label) Bring the Server (Postgres) workflow in line with Server (MariaDB) internals while keeping it opt-in for now: pull_request runs still require the 'postgres' label, but the job now uses the full 4-container matrix (was 1), adds the nightly schedule / workflow_dispatch / repository_dispatch triggers (which always run), and uploads coverage. Builds ERPNext against frappe `develop` (PostgreSQL query-builder/ORM support is merged there), so no fork override is needed. The ERPNext server suite now passes on PostgreSQL and MariaDB from a single codebase; flipping this to run on every PR / become a required check is a later, separate step. --- .github/workflows/server-tests-postgres.yml | 99 ++++++++++++++++++--- 1 file changed, 87 insertions(+), 12 deletions(-) diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml index da5a4b60c3c..ddbaccc1abf 100644 --- a/.github/workflows/server-tests-postgres.yml +++ b/.github/workflows/server-tests-postgres.yml @@ -1,33 +1,61 @@ name: Server (Postgres) on: + repository_dispatch: + types: [frappe-framework-change] pull_request: + # 'labeled' is required so adding the 'postgres' label to an open PR triggers this run + # (the job itself is gated on that label below) + types: [opened, reopened, synchronize, labeled] paths-ignore: - '**.js' + - '**.css' + - '**.svg' - '**.md' - '**.html' - 'crowdin.yml' - '.coderabbit.yml' - '.mergify.yml' - types: [opened, labelled, synchronize, reopened] + schedule: + # Run everday at midnight UTC / 5:30 IST + - cron: "0 0 * * *" + workflow_dispatch: + inputs: + user: + description: 'Frappe Framework repository user (add your username for forks)' + required: true + default: 'frappe' + type: string + branch: + description: 'Frappe Framework branch' + default: 'develop' + required: false + type: string + +permissions: + contents: read concurrency: group: server-postgres-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }} cancel-in-progress: true -permissions: - contents: read - jobs: test: - if: ${{ contains(github.event.pull_request.labels.*.name, 'postgres') }} + # Opt-in on PRs: only runs when the PR carries the 'postgres' label. Scheduled / manual / + # framework-dispatch runs always execute (no PR labels to gate on). + if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'postgres') }} runs-on: ubuntu-latest timeout-minutes: 60 + env: + TZ: 'Asia/Kolkata' + NODE_ENV: "production" + WITH_COVERAGE: ${{ github.event_name != 'pull_request' }} strategy: fail-fast: false + matrix: - container: [1] + container: [1, 2, 3, 4] name: Python Unit Tests @@ -36,16 +64,15 @@ jobs: image: postgres:13.3 env: POSTGRES_PASSWORD: travis + ports: + - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - ports: - - 5432:5432 steps: - - name: Clone uses: actions/checkout@v6 @@ -104,15 +131,63 @@ jobs: restore-keys: | ${{ runner.os }}-yarn- + - name: Cache wkhtmltopdf + uses: actions/cache@v4 + with: + path: /tmp/wkhtmltox.deb + key: wkhtmltox-0.12.6.1-2-jammy-amd64 + - name: Install run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh env: DB: postgres TYPE: server + FRAPPE_USER: ${{ github.event.inputs.user }} + FRAPPE_BRANCH: ${{ github.event.client_payload.sha || github.event.inputs.branch }} - name: Run Tests - run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --use-orchestrator + run: | + cd ~/frappe-bench/ + coverage_flag="" + if [ "$WITH_COVERAGE" = "true" ]; then coverage_flag="--with-coverage"; fi + bench --site test_site run-parallel-tests --lightmode --app erpnext \ + --total-builds ${{ strategy.job-total }} \ + --build-number ${{ matrix.container }} \ + $coverage_flag env: TYPE: server - CI_BUILD_ID: ${{ github.run_id }} - ORCHESTRATOR_URL: http://test-orchestrator.frappe.io + + + - name: Show bench output + if: ${{ always() }} + run: cat ~/frappe-bench/bench_start.log || true + + - name: Upload coverage data + if: ${{ env.WITH_COVERAGE == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: coverage-postgres-${{ matrix.container }} + path: /home/runner/frappe-bench/sites/coverage.xml + + coverage: + name: Coverage Wrap Up + needs: test + if: ${{ github.event_name != 'pull_request' }} + runs-on: ubuntu-latest + steps: + - name: Clone + uses: actions/checkout@v6 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + pattern: coverage-postgres-* + + - name: Upload coverage data + uses: codecov/codecov-action@v4 + with: + name: Postgres + flags: postgres + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + verbose: true From 57d0cebfb827137a3ed68194b527716ddaaca6fd Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 12:29:24 +0530 Subject: [PATCH 2/5] ci: make Postgres coverage upload glob explicit (codecov files) --- .github/workflows/server-tests-postgres.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml index ddbaccc1abf..9e204dbe423 100644 --- a/.github/workflows/server-tests-postgres.yml +++ b/.github/workflows/server-tests-postgres.yml @@ -188,6 +188,8 @@ jobs: with: name: Postgres flags: postgres + # explicit glob: download-artifact extracts each shard into its own coverage-postgres-N/ dir + files: coverage-postgres-*/coverage.xml token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true verbose: true From c820591089d59dbc04e915e92f5fd63efe8bb43c Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 12:35:04 +0530 Subject: [PATCH 3/5] ci: name the Postgres job distinctly so it is not a required check The MariaDB job is named 'Python Unit Tests', and 'Python Unit Tests (1..4)' are the required status checks on develop. Naming the Postgres matrix job the same made its checks report under those required contexts, effectively gating every (labelled) PR on Postgres. Rename it to 'Postgres Unit Tests' so its contexts are distinct and the workflow stays non-required until we deliberately add it to branch protection. --- .github/workflows/server-tests-postgres.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml index 9e204dbe423..3a668133a5f 100644 --- a/.github/workflows/server-tests-postgres.yml +++ b/.github/workflows/server-tests-postgres.yml @@ -57,7 +57,9 @@ jobs: matrix: container: [1, 2, 3, 4] - name: Python Unit Tests + # Distinct from the MariaDB job's "Python Unit Tests" so its check contexts do NOT collide with + # the required "Python Unit Tests (1..4)" status checks -- this keeps Postgres non-required for now. + name: Postgres Unit Tests services: postgres: From a46a6bf921528ee6e99fb14d1cfa4ebefbe7d174 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 12:35:05 +0530 Subject: [PATCH 4/5] ci: speed up Postgres CI by disabling DB durability for the disposable test DB Postgres fsyncs on every commit by default, which dominates a commit-heavy test suite. Turn off synchronous_commit/fsync/full_page_writes on the throwaway CI database (reload- time settings, no restart). MariaDB CI is unaffected (DB != postgres). --- .github/helper/install.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/helper/install.sh b/.github/helper/install.sh index e14e62b92b0..b5f9b9e364b 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -74,6 +74,14 @@ fi if [ "$DB" == "postgres" ];then echo "travis" | psql -h 127.0.0.1 -p 5432 -c "CREATE DATABASE test_frappe" -U postgres; echo "travis" | psql -h 127.0.0.1 -p 5432 -c "CREATE USER test_frappe WITH PASSWORD 'test_frappe'" -U postgres; + # CI databases are disposable, so trade durability for speed: postgres fsyncs on every commit + # by default, which dominates a commit-heavy test suite. These are all reload-time settings + # (no restart needed). MariaDB CI is unaffected (DB != postgres). + echo "travis" | psql -h 127.0.0.1 -p 5432 -U postgres \ + -c "ALTER SYSTEM SET synchronous_commit = 'off'" \ + -c "ALTER SYSTEM SET fsync = 'off'" \ + -c "ALTER SYSTEM SET full_page_writes = 'off'" \ + -c "SELECT pg_reload_conf()"; fi From f95e91323ea7295c7eb90662983c9fe0c373d7e0 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 15:05:11 +0530 Subject: [PATCH 5/5] ci(postgres): install payments app on the test site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Postgres CI site only listed erpnext in install_apps, so the payments app (fetched and built by install.sh via 'bench get-app payments') was never installed on the site — leaving 'tabPayment Gateway' absent. test_payment_request (and other payment-gateway-dependent tests) then errored on Postgres with 'relation "tabPayment Gateway" does not exist', while MariaDB passed because its site_config already lists ["payments", "erpnext"]. Match that ordering for parity. --- .github/helper/site_config_postgres.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/helper/site_config_postgres.json b/.github/helper/site_config_postgres.json index c82905fea02..b01d0438940 100644 --- a/.github/helper/site_config_postgres.json +++ b/.github/helper/site_config_postgres.json @@ -13,6 +13,6 @@ "root_login": "postgres", "root_password": "travis", "host_name": "http://test_site:8000", - "install_apps": ["erpnext"], + "install_apps": ["payments", "erpnext"], "throttle_user_limit": 100 }