Skip to content

AB-449 PostgreSQL Operator: Release workflow + PostgreSQL 15 to 18 Test Matrix - #5

Merged
ThoSap merged 21 commits into
mainfrom
ab-449-postgresql-operator-publish-workflow-and-pg-15-to-18-test-matrix
Jan 26, 2026
Merged

AB-449 PostgreSQL Operator: Release workflow + PostgreSQL 15 to 18 Test Matrix#5
ThoSap merged 21 commits into
mainfrom
ab-449-postgresql-operator-publish-workflow-and-pg-15-to-18-test-matrix

Conversation

@ThoSap

@ThoSap ThoSap commented Jan 22, 2026

Copy link
Copy Markdown
Member

No description provided.

@ThoSap ThoSap self-assigned this Jan 22, 2026
@linear

linear Bot commented Jan 22, 2026

Copy link
Copy Markdown
AB-449 PostgreSQL Operator

Based on the research and PoC done in the ticket and PR https://github.com/aboutbits/minio-operator/pull/1

We most likely will use CloudNativePG AB-396 for the DB Setup and this operator to manage the access, e.g. PostgreSQL roles and grants.

The scope of the operator is:

  • Role management
  • Grant management
  • Database management

@ThoSap ThoSap changed the title AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 test matrix AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 Test Matrix Jan 22, 2026
Base automatically changed from ab-449-postgresql-operator-default-priviege to main January 22, 2026 21:19
@ThoSap ThoSap changed the title AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 Test Matrix AB-449 PostgreSQL Operator: Release workflow + PostgreSQL 15 to 18 Test Matrix Jan 23, 2026
@ThoSap
ThoSap requested a review from Copilot January 23, 2026 10:16

Copilot AI left a comment

Copy link
Copy Markdown

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 updates the PostgreSQL operator to support PostgreSQL versions 15-18 by implementing a test matrix and introducing a release workflow. The changes remove the MAINTAIN privilege (available only in PostgreSQL 17+) to ensure backward compatibility with PostgreSQL 15 and 16.

Changes:

  • Updated default PostgreSQL version from 17.7 to 18
  • Added test configuration files for PostgreSQL versions 15, 16, 17, and 18
  • Removed MAINTAIN privilege support to maintain compatibility with PostgreSQL 15+
  • Introduced Axion Release Plugin for version management
  • Replaced single test workflow with matrix testing across PostgreSQL versions 15-18

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
operator/src/main/resources/application.yml Updated default PostgreSQL image from 17.7 to 18
operator/src/main/resources/application-test-pg*.yml Added test profile configurations for PostgreSQL 15, 16, 17, and 18
operator/src/main/java/it/aboutbits/postgresql/crd/grant/GrantSpec.java Removed maintain from privilege documentation
operator/src/main/java/it/aboutbits/postgresql/crd/grant/GrantObjectType.java Commented out MAINTAIN privilege and removed import
operator/src/main/java/it/aboutbits/postgresql/crd/defaultprivilege/DefaultPrivilegeSpec.java Removed maintain from privilege documentation
operator/src/main/java/it/aboutbits/postgresql/crd/defaultprivilege/DefaultPrivilegeObjectType.java Commented out MAINTAIN privilege and removed import
operator/src/main/java/it/aboutbits/postgresql/core/Privilege.java Commented out MAINTAIN enum value
operator/src/main/docker/compose-deviservices-test-pg*.yml Added Docker Compose configurations for each PostgreSQL version
gradle/libs.versions.toml Added Axion Release Plugin dependency
gradle.properties Disabled parallel Gradle builds due to Quarkus issue
Makefile Added test targets for each PostgreSQL version
.github/workflows/test.yml Removed standalone test workflow
.github/workflows/release.yml Added comprehensive release workflow with Docker and Helm chart publishing
.github/workflows/main.yml Replaced test workflow with matrix testing across PostgreSQL 15-18

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread operator/src/main/resources/application-test-pg18.yml Outdated
Comment thread operator/src/main/resources/application-test-pg17.yml Outdated
Comment thread operator/src/main/resources/application-test-pg16.yml Outdated
Comment thread operator/src/main/resources/application-test-pg15.yml Outdated
image: postgres:18
command: "postgres -c checkpoint_timeout=10min -c fsync=off -c full_page_writes=off -c max_wal_size=2GB -c synchronous_commit=off"
tmpfs:
- /var/lib/postgresql/18/docker:rw,async,noatime

Copilot AI Jan 23, 2026

Copy link

Choose a reason for hiding this comment

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

The tmpfs path includes a version-specific directory '/var/lib/postgresql/18/docker' that differs from the standard PostgreSQL data directory path used in other versions. This inconsistency could lead to confusion. Consider using the standard '/var/lib/postgresql/data' path for consistency with pg15, pg16, and pg17 configurations.

Suggested change
- /var/lib/postgresql/18/docker:rw,async,noatime
- /var/lib/postgresql/data:rw,async,noatime

Copilot uses AI. Check for mistakes.

@ThoSap ThoSap Jan 23, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, this is correct, see docker-library/postgres#1259

@ThoSap
ThoSap requested a review from Copilot January 23, 2026 10:27

Copilot AI left a comment

Copy link
Copy Markdown

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 20 out of 21 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ThoSap
ThoSap marked this pull request as ready for review January 23, 2026 10:30
@ThoSap

ThoSap commented Jan 23, 2026

Copy link
Copy Markdown
Member Author

I will add docs and polish the README.md in a follow-up PR.

I'm using the Gradle Plugin https://github.com/allegro/axion-release-plugin, which is very similar to the way npm version works.
https://axion-release-plugin.readthedocs.io/en/latest/

The first version to be released is v0.1.0 by default (0.1.0 for the Helm chart and container image).
After that, the increment input and prerelases will work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In the frontend packages we called this file like this. In the backend packages we used the name publish.yml. I think the name release.yml is more appropriate. I will make a note for myself to change it at all other backend packages.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I changed it already for all backend repositories.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I like it.

Comment thread .github/workflows/release.yml Outdated
Comment on lines +70 to +77
**Manually installing CRDs:**
```bash
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/clusterconnections.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/databases.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/schemas.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/roles.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/grants.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/defaultprivileges.postgresql.aboutbits.it-v1.yml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When do we need these manual installations? Is this really something that is required? Or will everything be handeled by the Helm chart?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It is required if someone is not using the Helm chart, or we add a flag to the Helm chart to not install the CRDs using a simple boolean switch.

Comment thread .github/workflows/release.yml Outdated
Comment on lines +61 to +62
```bash
docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.nextVersion.outputs.version }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When does a user need this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Only if you want to inspect the container image with tools like https://github.com/wagoodman/dive or https://github.com/reproducible-containers/diffoci

For the other cases, you most likely always use the Helm chart.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would remove this, since this is just for debugging reasons. Or at least this is the least important information here. So first the must be the Helm installation instruction.

@ThoSap
ThoSap requested a review from alexlanz January 23, 2026 12:36
Comment thread .github/workflows/release.yml Outdated
Comment on lines +61 to +62
```bash
docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.nextVersion.outputs.version }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would remove this, since this is just for debugging reasons. Or at least this is the least important information here. So first the must be the Helm installation instruction.

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/main.yml Outdated
strategy:
fail-fast: false
matrix:
postgres-version: [ 15, 16, 17, 18 ]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is sick! 💯

TRIGGER,
MAINTAIN
TRIGGER
//MAINTAIN // PostgreSQL 17+

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

General question: Would this break the integration with 15 and 16 if it is not used?

@ThoSap ThoSap Jan 26, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, it would not break the integration if it is not used or tested against.

It currently fails as I added a grant all Grant/DefaultPrivileges step for the respective ObjectType in the tests, which then fails as follows in the code block below.

What I could do is retrieve the PostgreSQL major version from the jOOQ DSLContext and add a minimum optional/nullable PG major version to the Privilege enum constants, and then filter out privileges from the List/Set that do not satisfy the minimum database version.

// Returns the major version number (e.g., 17)
int majorVersion = dsl.connectionResult(connection -> 
    connection.getMetaData().getDatabaseMajorVersion()
);

// OR

// Returns an integer, e.g., 170000
Integer versionNum = dsl.fetchValue("show server_version_num", Integer.class);

// OR

// Returns short string, e.g., "17.0"
String version = dsl.fetchValue("show server_version", String.class);

    2026-01-26 08:40:30,201 DEBUG [org.jooq.tools.LoggerListener] (ReconcilerExecutor-defaultprivilegereconciler-196) Executing query          : alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"
    2026-01-26 08:40:30,206 DEBUG [org.jooq.tools.LoggerListener] (ReconcilerExecutor-defaultprivilegereconciler-196) Exception                : org.jooq.exception.DataAccessException: SQL [alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"]; ERROR: unrecognized privilege type "maintain"
    	at org.jooq_3.20.10.POSTGRES.debug(Unknown Source)
    	at org.jooq.impl.Tools.translate(Tools.java:3709)
    	at org.jooq.impl.Tools.translate(Tools.java:3685)
    	at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:869)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:363)
    	at org.jooq.impl.Tools.attach(Tools.java:1735)
    	at org.jooq.impl.DefaultDSLContext.execute(DefaultDSLContext.java:5338)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeService.grant(DefaultPrivilegeService.java:110)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcileInTransaction(DefaultPrivilegeReconciler.java:232)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.lambda$reconcile$0(DefaultPrivilegeReconciler.java:99)
    	at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:533)
    	at org.jooq.impl.Tools$3$1.block(Tools.java:6402)
    	at java.base/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:4364)
    	at java.base/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:4310)
    	at org.jooq.impl.Tools$3.get(Tools.java:6399)
    	at org.jooq.impl.DefaultDSLContext.transactionResult0(DefaultDSLContext.java:581)
    	at org.jooq.impl.DefaultDSLContext.transactionResult(DefaultDSLContext.java:504)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcile(DefaultPrivilegeReconciler.java:98)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcile(DefaultPrivilegeReconciler.java:22)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler_ClientProxy.reconcile(Unknown Source)
    	at io.javaoperatorsdk.operator.processing.Controller$1.execute(Controller.java:161)
    	at io.javaoperatorsdk.operator.processing.Controller$1.execute(Controller.java:117)
    	at io.javaoperatorsdk.operator.monitoring.micrometer.MicrometerMetrics.lambda$timeControllerExecution$0(MicrometerMetrics.java:151)
    	at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:69)
    	at io.javaoperatorsdk.operator.monitoring.micrometer.MicrometerMetrics.timeControllerExecution(MicrometerMetrics.java:148)
    	at io.javaoperatorsdk.operator.processing.Controller.reconcile(Controller.java:116)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.reconcileExecution(ReconciliationDispatcher.java:154)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleReconcile(ReconciliationDispatcher.java:131)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleDispatch(ReconciliationDispatcher.java:98)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleExecution(ReconciliationDispatcher.java:69)
    	at io.javaoperatorsdk.operator.processing.event.EventProcessor$ReconcilerExecutor.run(EventProcessor.java:483)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
    	at java.base/java.lang.Thread.run(Thread.java:1474)
    Caused by: org.postgresql.util.PSQLException: ERROR: unrecognized privilege type "maintain"
    	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2736)
    	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2421)
    	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372)
    	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:525)
    	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:435)
    	at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:357)
    	at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:342)
    	at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:318)
    	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:313)
    	at org.jooq.tools.jdbc.DefaultStatement.execute(DefaultStatement.java:102)
    	at org.jooq.impl.SettingsEnabledPreparedStatement.execute(SettingsEnabledPreparedStatement.java:227)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:459)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)
    	... 29 more
    2026-01-26 08:40:30,206 DEBUG [org.jooq.impl.DefaultConnectionProvider] (ReconcilerExecutor-defaultprivilegereconciler-196) rollback                 
    2026-01-26 08:40:30,207 DEBUG [org.jooq.impl.DefaultConnectionProvider] (ReconcilerExecutor-defaultprivilegereconciler-196) setting auto commit      : true
    2026-01-26 08:40:30,208 ERROR [it.aboutbits.postgresql.core.BaseReconciler] (ReconcilerExecutor-defaultprivilegereconciler-196) Failed to reconcile resource [resource=test-default-privilege-rc5qtair1jkf9ur5tkulnz5k60tb2cke5io6deom]: org.jooq.exception.DataAccessException: SQL [alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"]; ERROR: unrecognized privilege type "maintain"
    	at org.jooq_3.20.10.POSTGRES.debug(Unknown Source)
    	...

@ThoSap ThoSap Jan 26, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I now check for unsupported privileges and conditionally test these.

@ThoSap
ThoSap requested a review from Copilot January 26, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown

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 25 out of 26 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

… not hardcode PostgreSQL 16 in the assertion
@ThoSap
ThoSap requested a review from Copilot January 26, 2026 10:15

Copilot AI left a comment

Copy link
Copy Markdown

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 24 out of 25 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

operator/src/test/java/it/aboutbits/postgresql/_support/testdata/persisted/creator/GrantCreate.java:137

  • This line was removed, but the withObjects field is still used later in the method (line 129+). If objects should not be set at this location, ensure that withObjects is properly handled in the conditional logic below. Verify that tests relying on object specification still function correctly.
            spec.setObjects(withObjects);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ThoSap

ThoSap commented Jan 26, 2026

Copy link
Copy Markdown
Member Author

I changed the GitHub workflow structure slightly again, since in the release workflow, we only ran the PostgreSQL 18 tests on build, not across the whole test matrix.

Now I'm using the shared workflow_dispatch trigger workflow test.yml again in both main.yml and release.yml.

@ThoSap
ThoSap requested a review from Copilot January 26, 2026 11:12

Copilot AI left a comment

Copy link
Copy Markdown

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 22 out of 23 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread operator/src/test/java/it/aboutbits/postgresql/crd/grant/GrantReconcilerTest.java Outdated
@ThoSap
ThoSap requested a review from Copilot January 26, 2026 11:21

Copilot AI left a comment

Copy link
Copy Markdown

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 22 out of 23 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexlanz alexlanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice job!

@ThoSap
ThoSap merged commit 0d6bc52 into main Jan 26, 2026
8 of 12 checks passed
@ThoSap
ThoSap deleted the ab-449-postgresql-operator-publish-workflow-and-pg-15-to-18-test-matrix branch January 26, 2026 13:05
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.

4 participants