Skip to content

Commit 0483a90

Browse files
GabriFedi97NiccoloFeigbartolini
authored
feat: support sql version in metadata files (#149)
Adds support for tracking PostgreSQL extension SQL versions separately from Debian package versions, enabling accurate version verification in E2E tests. Closes #145 Signed-off-by: Gabriele Fedi <gabriele.fedi@enterprisedb.com> Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com> Signed-off-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com> Co-authored-by: Niccolò Fei <niccolo.fei@enterprisedb.com> Co-authored-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com>
1 parent 0505da2 commit 0483a90

File tree

17 files changed

+142
-57
lines changed

17 files changed

+142
-57
lines changed

CONTRIBUTING_NEW_EXTENSION.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,26 @@ The scaffolding generates `metadata.hcl`, `Dockerfile`, and `README.md`.
152152
Follow the specific instructions and "TODO" comments found within each
153153
generated file to finalize your extension.
154154

155+
#### Package Version vs. SQL Version
156+
157+
Your `metadata.hcl` file requires two version fields:
158+
159+
- **`package`**: The full Debian package version (e.g., `0.8.2-1.pgdg13+1`).
160+
This includes packaging metadata and is used to install the correct package.
161+
162+
- **`sql`**: The PostgreSQL extension version as it appears in the catalog
163+
(e.g., `0.8.2`). This is the version of the extension that will be verified
164+
as part of the automatic testing of the resulting containers. It should
165+
match what is defined by the `default_version` field in the control file.
166+
167+
168+
> [!WARNING]
169+
> The `sql` version is optional and only needed if your extension uses
170+
> `CREATE EXTENSION` (when `create_extension = true` in metadata).
171+
155172
> [!TIP]
156-
> Pay close attention to the `// renovate:` comments in the metadata; these are
157-
> required for automated version tracking.
173+
> Pay close attention to the `// renovate:` comments in the metadata and
174+
> `README.md` files; these are required for automated version tracking.
158175
159176
---
160177

README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -138,26 +138,27 @@ other tools to identify the base PostgreSQL version and OS distribution.
138138

139139
### CloudNativePG-Specific Labels
140140

141-
| Label | Description | Example |
142-
| :--- | :--- | :--- |
143-
| `io.cloudnativepg.image.base.name` | Base PostgreSQL container image | `ghcr.io/cloudnative-pg/postgresql:18-minimal-bookworm` |
144-
| `io.cloudnativepg.image.base.pgmajor` | PostgreSQL major version | `18` |
145-
| `io.cloudnativepg.image.base.os` | Operating system distribution | `bookworm` |
141+
| Label | Description | Example |
142+
|:--------------------------------------|:---------------------------------|:--------------------------------------------------------|
143+
| `io.cloudnativepg.image.base.name` | Base PostgreSQL container image | `ghcr.io/cloudnative-pg/postgresql:18-minimal-bookworm` |
144+
| `io.cloudnativepg.image.base.pgmajor` | PostgreSQL major version | `18` |
145+
| `io.cloudnativepg.image.base.os` | Operating system distribution | `bookworm` |
146+
| `io.cloudnativepg.image.sql.version` | PostgreSQL extension SQL version | `0.8.2` |
146147

147148
### Standard OCI Labels
148149

149150
In addition to CloudNativePG-specific labels, all images include standard OCI
150151
annotations as defined by the [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/main/annotations.md):
151152

152-
| Label | Description |
153-
| :--- | :--- |
154-
| `org.opencontainers.image.created` | Image creation timestamp |
155-
| `org.opencontainers.image.version` | Extension version |
156-
| `org.opencontainers.image.revision` | Git commit SHA |
157-
| `org.opencontainers.image.title` | Human-readable image title |
158-
| `org.opencontainers.image.description` | Image description |
159-
| `org.opencontainers.image.source` | Source repository URL |
160-
| `org.opencontainers.image.licenses` | License identifier |
153+
| Label | Description |
154+
|:---------------------------------------|:----------------------------|
155+
| `org.opencontainers.image.created` | Image creation timestamp |
156+
| `org.opencontainers.image.version` | Extension's package version |
157+
| `org.opencontainers.image.revision` | Git commit SHA |
158+
| `org.opencontainers.image.title` | Human-readable image title |
159+
| `org.opencontainers.image.description` | Image description |
160+
| `org.opencontainers.image.source` | Source repository URL |
161+
| `org.opencontainers.image.licenses` | License identifier |
161162

162163
You can inspect these labels using container tools:
163164

dagger/maintenance/image.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ const (
2222
DefaultDistribution = "trixie"
2323
)
2424

25+
const (
26+
AnnotationImageSQLVersion = "io.cloudnativepg.image.sql.version"
27+
AnnotationImageBaseName = "io.cloudnativepg.image.base.name"
28+
)
29+
2530
var SupportedDistributions = []string{
2631
"bookworm",
2732
"trixie",
@@ -147,16 +152,16 @@ func getExtensionImageWithTimestamp(metadata *extensionMetadata, distribution st
147152
// extractExtensionVersion returns the extension version for a given distribution and pgMajor,
148153
// extracted from the extension's metadata.
149154
func extractExtensionVersion(versions versionMap, distribution string, pgMajor int) (string, error) {
150-
packageVersion := versions[distribution][strconv.Itoa(pgMajor)]
151-
if packageVersion == "" {
155+
extVersion, ok := versions[distribution][strconv.Itoa(pgMajor)]
156+
if !ok {
152157
return "", fmt.Errorf("no package version found for distribution %q and version %d",
153158
distribution, pgMajor)
154159
}
155160

156161
re := regexp.MustCompile(`^(\d+(?:\.\d+)+)`)
157-
matches := re.FindStringSubmatch(packageVersion)
162+
matches := re.FindStringSubmatch(extVersion.Package)
158163
if len(matches) < 2 {
159-
return "", fmt.Errorf("cannot extract extension version from %q", packageVersion)
164+
return "", fmt.Errorf("cannot extract extension version from %q", extVersion.Package)
160165
}
161166

162167
return matches[1], nil

dagger/maintenance/main.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,18 @@ func (m *Maintenance) GenerateTestingValues(
172172
return nil, err
173173
}
174174

175-
pgImage := annotations["io.cloudnativepg.image.base.name"]
175+
pgImage := annotations[AnnotationImageBaseName]
176176
if pgImage == "" {
177177
return nil, fmt.Errorf(
178-
"extension image %s doesn't have an 'io.cloudnativepg.image.base.name' annotation",
179-
targetExtensionImage)
178+
"extension image %s doesn't have an %q annotation or its value is empty",
179+
targetExtensionImage, AnnotationImageBaseName)
180180
}
181181

182-
version := annotations["org.opencontainers.image.version"]
183-
if version == "" {
182+
version := annotations[AnnotationImageSQLVersion]
183+
if version == "" && metadata.CreateExtension {
184184
return nil, fmt.Errorf(
185-
"extension image %s doesn't have an 'org.opencontainers.image.version' annotation",
186-
targetExtensionImage)
185+
"extension image %s doesn't have an %q annotation or its value is empty",
186+
targetExtensionImage, AnnotationImageSQLVersion)
187187
}
188188

189189
extensionInfos, err := generateTestingValuesExtensions(ctx, source, metadata, targetExtensionImage, version, registryUsername, registryPassword)

dagger/maintenance/parse.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ type buildMatrix struct {
1818
MajorVersions []string
1919
}
2020

21-
type versionMap map[string]map[string]string
21+
type extensionVersion struct {
22+
Package string `hcl:"package" cty:"package"`
23+
}
24+
25+
type versionMap map[string]map[string]extensionVersion
2226

2327
type extensionMetadata struct {
2428
Name string `hcl:"name" cty:"name"`

dagger/maintenance/testingvalues.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ func generateTestingValuesExtensions(ctx context.Context, source *dagger.Directo
7272
if err != nil {
7373
return nil, err
7474
}
75-
depVersion := depAnnotations["org.opencontainers.image.version"]
75+
depVersion := depAnnotations[AnnotationImageSQLVersion]
7676
if depVersion == "" {
7777
return nil, fmt.Errorf(
78-
"extension image %s doesn't have an 'org.opencontainers.image.version' annotation",
79-
depConfiguration.ImageVolumeSource.Reference)
78+
"extension image %s doesn't have an %q annotation or its value is empty",
79+
depConfiguration.ImageVolumeSource.Reference, AnnotationImageSQLVersion)
8080
}
8181

8282
out = append(out, &testingExtensionInfo{

docker-bake.hcl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ target "default" {
7979
"index,manifest:io.cloudnativepg.image.base.name=${getBaseImage(distro, pgVersion)}",
8080
"index,manifest:io.cloudnativepg.image.base.pgmajor=${pgVersion}",
8181
"index,manifest:io.cloudnativepg.image.base.os=${distro}",
82+
"index,manifest:io.cloudnativepg.image.sql.version=${getExtensionSqlVersion(distro, pgVersion)}",
8283
]
8384
labels = {
8485
"org.opencontainers.image.created" = "${now}",
@@ -96,6 +97,7 @@ target "default" {
9697
"io.cloudnativepg.image.base.name" = "${getBaseImage(distro, pgVersion)}",
9798
"io.cloudnativepg.image.base.pgmajor" = "${pgVersion}",
9899
"io.cloudnativepg.image.base.os" = "${distro}",
100+
"io.cloudnativepg.image.sql.version" = "${getExtensionSqlVersion(distro, pgVersion)}",
99101
}
100102
}
101103

@@ -106,7 +108,12 @@ function getImageName {
106108

107109
function getExtensionPackage {
108110
params = [ distro, pgVersion ]
109-
result = metadata.versions[distro][pgVersion]
111+
result = metadata.versions[distro][pgVersion]["package"]
112+
}
113+
114+
function getExtensionSqlVersion {
115+
params = [ distro, pgVersion ]
116+
result = lookup(metadata.versions[distro][pgVersion], "sql", "")
110117
}
111118

112119
// Parse the packageVersion to extract the MM.mm.pp extension version.

pg-crash/metadata.hcl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ metadata = {
1616

1717
versions = {
1818
bookworm = {
19-
// renovate: suite=bookworm-pgdg depName=postgresql-18-pg-crash
20-
"18" = "0.3-2.pgdg12+1"
19+
"18" = {
20+
// renovate: suite=bookworm-pgdg depName=postgresql-18-pg-crash
21+
package = "0.3-2.pgdg12+1"
22+
}
2123
}
2224
trixie = {
23-
// renovate: suite=trixie-pgdg depName=postgresql-18-pg-crash
24-
"18" = "0.3-2.pgdg13+1"
25+
"18" = {
26+
// renovate: suite=trixie-pgdg depName=postgresql-18-pg-crash
27+
package = "0.3-2.pgdg13+1"
28+
}
2529
}
2630
}
2731
}

pgaudit/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ spec:
5555
name: cluster-pgaudit
5656
extensions:
5757
- name: pgaudit
58-
# renovate: suite=trixie-pgdg depName=postgresql-18-pgaudit
58+
# renovate: suite=trixie-pgdg depName=postgresql-18-pgaudit extractVersion=^(?<version>\d+\.\d+)
5959
version: '18.0'
6060
```
6161

pgaudit/metadata.hcl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@ metadata = {
1414

1515
versions = {
1616
bookworm = {
17-
// renovate: suite=bookworm-pgdg depName=postgresql-18-pgaudit
18-
"18" = "18.0-2.pgdg12+1"
17+
"18" = {
18+
// renovate: suite=bookworm-pgdg depName=postgresql-18-pgaudit
19+
package = "18.0-2.pgdg12+1"
20+
// renovate: suite=bookworm-pgdg depName=postgresql-18-pgaudit extractVersion=^(?<version>\d+\.\d+)
21+
sql = "18.0"
22+
}
1923
}
2024
trixie = {
21-
// renovate: suite=trixie-pgdg depName=postgresql-18-pgaudit
22-
"18" = "18.0-2.pgdg13+1"
25+
"18" = {
26+
// renovate: suite=trixie-pgdg depName=postgresql-18-pgaudit
27+
package = "18.0-2.pgdg13+1"
28+
// renovate: suite=trixie-pgdg depName=postgresql-18-pgaudit extractVersion=^(?<version>\d+\.\d+)
29+
sql = "18.0"
30+
}
2331
}
2432
}
2533
}

0 commit comments

Comments
 (0)