Skip to content

Commit 2a6ad4a

Browse files
authored
Build rpm packages (#92)
CI fails because workflow runs on base of PR but `defineversion` runs on target. Closes FerretDB/FerretDB#5379.
2 parents 61e3e55 + 720bcbb commit 2a6ad4a

File tree

7 files changed

+70
-48
lines changed

7 files changed

+70
-48
lines changed

.github/workflows/ferretdb_packages.yml

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,27 @@ concurrency:
5252
cancel-in-progress: false
5353

5454
jobs:
55-
deb:
55+
packages:
5656
strategy:
5757
fail-fast: false
5858
matrix:
59-
os: [deb11, deb12, ubuntu22.04, ubuntu24.04]
59+
os: [deb11, deb12, ubuntu22.04, ubuntu24.04, rhel8, rhel9]
6060
arch: [amd64, arm64]
6161
pg: [15, 16, 17]
6262
include:
6363
- arch: amd64
6464
runner: ubuntu-24.04
6565
- arch: arm64
6666
runner: ubuntu-24.04-arm
67-
68-
name: .debs (${{ matrix.os }}, ${{ matrix.arch }}, Pg${{ matrix.pg }})
67+
exclude:
68+
# pg 15 is not supported for rpm packages
69+
# https://github.com/FerretDB/documentdb/blob/ferretdb/packaging/README.md
70+
- os: rhel8
71+
pg: 15
72+
- os: rhel9
73+
pg: 15
74+
75+
name: packages (${{ matrix.os }}, ${{ matrix.arch }}, Pg${{ matrix.pg }})
6976
runs-on: ${{ matrix.runner }}
7077
timeout-minutes: 40
7178

@@ -115,17 +122,17 @@ jobs:
115122
cd packaging/defineversion
116123
go mod tidy
117124
go mod verify
118-
go run . -control-file ../../pg_documentdb/documentdb.control -pg-version ${{ matrix.pg }} -debian-only
125+
go run . -control-file ../../pg_documentdb/documentdb.control -pg-version ${{ matrix.pg }} -package-version-only
119126
120-
- name: Build ${{ steps.version.outputs.debian_version }}
121-
if: steps.version.outputs.debian_version != ''
122-
run: ./packaging/build_packages.sh --os ${{ matrix.os }} --pg ${{ matrix.pg }} --version ${{ steps.version.outputs.debian_version }} --test-clean-install
127+
- name: Build ${{ steps.version.outputs.package_version }}
128+
if: steps.version.outputs.package_version != ''
129+
run: ./packaging/build_packages.sh --os ${{ matrix.os }} --pg ${{ matrix.pg }} --version ${{ steps.version.outputs.package_version }} --test-clean-install
123130

124-
- name: Upload .deb packages
131+
- name: Upload packages
125132
uses: actions/upload-artifact@v4
126133
with:
127-
name: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.pg }}-${{ steps.version.outputs.debian_version }}
128-
path: packaging/*.deb
134+
name: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.pg }}-${{ steps.version.outputs.package_version }}
135+
path: packaging/*(.deb|.rpm)
129136
retention-days: 1
130137
if-no-files-found: error
131138
compression-level: 0
@@ -141,7 +148,7 @@ jobs:
141148
runs-on: ubuntu-24.04
142149
timeout-minutes: 40
143150

144-
needs: deb
151+
needs: packages
145152

146153
if: >
147154
github.event_name != 'pull_request_target' ||

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ build/
7070
# temp schedules
7171
*.tmp
7272

73-
# deb packages
73+
# packages
7474
*.deb
75+
*.rpm
7576

7677
site/

packaging/build_packages.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ if [[ $TEST_CLEAN_INSTALL == true ]]; then
192192
docker run --rm documentdb-test-packages:latest
193193

194194
elif [[ "$PACKAGE_TYPE" == "rpm" ]]; then
195-
rpm_package_name=$(ls "$abs_output_dir" | grep -E "${OS}-postgresql${PG}-documentdb-${DOCUMENTDB_VERSION}.*\.x86_64\.rpm" | head -n 1)
195+
rpm_package_name=$(ls "$abs_output_dir" | grep -E "${OS}-postgresql${PG}-documentdb-${DOCUMENTDB_VERSION}.*\.rpm" | head -n 1)
196196
if [[ -z "$rpm_package_name" ]]; then
197197
echo "Error: Could not find the built RPM package in $abs_output_dir for testing."
198198
exit 1

packaging/defineversion/main.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import (
1818
// but with a leading `v`.
1919
var semVerTag = regexp.MustCompile(`^v(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`)
2020

21-
// versions represents Docker image names and tags, and Debian package version.
21+
// versions represents Docker image names and tags, and package versions used by Debian and RPM.
2222
type versions struct {
2323
dockerDevelopmentImages []string
2424
dockerProductionImages []string
25-
debian string
25+
packageVersion string
2626
}
2727

2828
// parseGitTag parses git tag in specific format and returns SemVer components.
@@ -82,11 +82,13 @@ func debugEnv(action *githubactions.Action) {
8282
}
8383
}
8484

85-
// defineVersion extracts Docker image names and tags, and Debian package version using the environment variables defined by GitHub Actions.
85+
// defineVersion extracts Docker image names and tags, and package versions used by Debian and RPM
86+
// using the environment variables defined by GitHub Actions.
8687
//
87-
// The Debian package version is based on `default_version` in the control file.
88-
// See https://www.debian.org/doc/debian-policy/ch-controlfields.html#version.
89-
// We use `upstream_version` only.
88+
// The Debian and RPM package versions are based on `default_version` in the control file.
89+
// See https://www.debian.org/doc/debian-policy/ch-controlfields.html#version,
90+
// and https://fedoraproject.org/wiki/PackagingDrafts/TildeVersioning#Basic_versioning_rules.
91+
// The Debian uses `upstream_version` only.
9092
// For that reason, we can't use `-`, so we replace it with `~`.
9193
func defineVersion(controlDefaultVersion, pgVersion string, getenv githubactions.GetenvFunc) (*versions, error) {
9294
repo := getenv("GITHUB_REPOSITORY")
@@ -139,29 +141,33 @@ func defineVersion(controlDefaultVersion, pgVersion string, getenv githubactions
139141
return res, nil
140142
}
141143

142-
// defineVersionForPR defines Docker image names and tags, and Debian package version for PR.
144+
// defineVersionForPR defines Docker image names and tags, and package version for PR.
143145
// See [defineVersion].
144146
func defineVersionForPR(controlDefaultVersion, pgVersion, owner, repo, branch string) *versions {
145147
// for branches like "dependabot/submodules/XXX"
146148
parts := strings.Split(branch, "/")
147149
branch = parts[len(parts)-1]
148150

151+
packageVersion := fmt.Sprintf("%s-pr-%s", controlDefaultVersion, branch)
152+
packageVersion = disallowedDebian.ReplaceAllString(packageVersion, "~")
153+
packageVersion = disallowedRPM.ReplaceAllString(packageVersion, "~")
154+
149155
res := &versions{
150156
dockerDevelopmentImages: []string{
151157
fmt.Sprintf("ghcr.io/%s/postgres-%s-dev:%s-pr-%s", owner, repo, pgVersion, branch),
152158
},
153159
dockerProductionImages: []string{
154160
fmt.Sprintf("ghcr.io/%s/postgres-%s-dev:%s-pr-%s-prod", owner, repo, pgVersion, branch),
155161
},
156-
debian: disallowedDebian.ReplaceAllString(fmt.Sprintf("%s-pr-%s", controlDefaultVersion, branch), "~"),
162+
packageVersion: packageVersion,
157163
}
158164

159165
// PRs are only for testing; no Quay.io and Docker Hub repos
160166

161167
return res
162168
}
163169

164-
// defineVersionForBranch defines Docker image names and tags, and Debian package version for branch.
170+
// defineVersionForBranch defines Docker image names and tags, and package version for branch.
165171
// See [defineVersion].
166172
func defineVersionForBranch(controlDefaultVersion, pgVersion, owner, repo, branch string) (*versions, error) {
167173
if branch != "ferretdb" {
@@ -175,7 +181,7 @@ func defineVersionForBranch(controlDefaultVersion, pgVersion, owner, repo, branc
175181
dockerProductionImages: []string{
176182
fmt.Sprintf("ghcr.io/%s/postgres-%s-dev:%s-ferretdb-prod", owner, repo, pgVersion),
177183
},
178-
debian: fmt.Sprintf("%s~ferretdb", controlDefaultVersion),
184+
packageVersion: fmt.Sprintf("%s~ferretdb", controlDefaultVersion),
179185
}
180186

181187
// forks don't have Quay.io and Docker Hub orgs
@@ -196,7 +202,7 @@ func defineVersionForBranch(controlDefaultVersion, pgVersion, owner, repo, branc
196202
return res, nil
197203
}
198204

199-
// defineVersionForTag defines Docker image names and tags, and Debian package version for tag.
205+
// defineVersionForTag defines Docker image names and tags, and package version for tag.
200206
// See [defineVersion].
201207
func defineVersionForTag(controlDefaultVersion, pgVersion, owner, repo, tag string) (*versions, error) {
202208
major, minor, patch, prerelease, err := parseGitTag(tag)
@@ -219,8 +225,12 @@ func defineVersionForTag(controlDefaultVersion, pgVersion, owner, repo, tag stri
219225
tags = append(tags, "latest")
220226
}
221227

228+
packageVersion := fmt.Sprintf("%s-%s", tagVersion, prerelease)
229+
packageVersion = disallowedDebian.ReplaceAllString(packageVersion, "~")
230+
packageVersion = disallowedRPM.ReplaceAllString(packageVersion, "~")
231+
222232
res := versions{
223-
debian: disallowedDebian.ReplaceAllString(fmt.Sprintf("%s-%s", tagVersion, prerelease), "~"),
233+
packageVersion: packageVersion,
224234
}
225235

226236
for _, t := range tags {
@@ -253,7 +263,7 @@ func defineVersionForTag(controlDefaultVersion, pgVersion, owner, repo, tag stri
253263
func setSummary(action *githubactions.Action, version *versions) {
254264
var buf strings.Builder
255265

256-
fmt.Fprintf(&buf, "Debian package version (`upstream_version` only): `%s`\n\n", version.debian)
266+
fmt.Fprintf(&buf, "Package version (Debian with `upstream_version` only, or RPM): `%s`\n\n", version.packageVersion)
257267

258268
w := tabwriter.NewWriter(&buf, 1, 1, 1, ' ', tabwriter.Debug)
259269
fmt.Fprintf(w, "\tType\tDocker image\t\n")
@@ -278,7 +288,7 @@ func setSummary(action *githubactions.Action, version *versions) {
278288
func main() {
279289
controlFileF := flag.String("control-file", "../pg_documentdb/documentdb.control", "pg_documentdb/documentdb.control file path")
280290
pgVersionF := flag.String("pg-version", "17", "Major PostgreSQL version")
281-
debianOnlyF := flag.Bool("debian-only", false, "Only set output for Debian package version")
291+
packageVersionOnlyF := flag.Bool("package-version-only", false, "Only set output for package version")
282292

283293
flag.Parse()
284294

@@ -307,13 +317,13 @@ func main() {
307317
action.Fatalf("%s", err)
308318
}
309319

310-
action.SetOutput("debian_version", res.debian)
320+
action.SetOutput("package_version", res.packageVersion)
311321

312-
if *debianOnlyF {
322+
if *packageVersionOnlyF {
313323
// Only 3 summaries are shown in the GitHub Actions UI by default,
314-
// and Docker summaries are more important (and include Debian version anyway).
315-
output := fmt.Sprintf("Debian package version (`upstream_version` only): `%s`", res.debian)
316-
action.Infof("%s", output)
324+
// and Docker summaries are more important (and include package version anyway).
325+
action.Infof("package version (Debian with `upstream_version` only, or RPM): `%s`", res.packageVersion)
326+
317327
return
318328
}
319329

packaging/defineversion/main_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func TestDefineVersion(t *testing.T) {
9494
dockerProductionImages: []string{
9595
"ghcr.io/ferretdb/postgres-documentdb-dev:17-pr-define-version-prod",
9696
},
97-
debian: "0.103.0~pr~define~version",
97+
packageVersion: "0.103.0~pr~define~version",
9898
},
9999
},
100100
"pull_request-other": {
@@ -114,7 +114,7 @@ func TestDefineVersion(t *testing.T) {
114114
dockerProductionImages: []string{
115115
"ghcr.io/otherorg/postgres-otherrepo-dev:17-pr-define-version-prod",
116116
},
117-
debian: "0.103.0~pr~define~version",
117+
packageVersion: "0.103.0~pr~define~version",
118118
},
119119
},
120120

@@ -135,7 +135,7 @@ func TestDefineVersion(t *testing.T) {
135135
dockerProductionImages: []string{
136136
"ghcr.io/ferretdb/postgres-documentdb-dev:17-pr-define-version-prod",
137137
},
138-
debian: "0.103.0~pr~define~version",
138+
packageVersion: "0.103.0~pr~define~version",
139139
},
140140
},
141141
"pull_request_target-other": {
@@ -155,7 +155,7 @@ func TestDefineVersion(t *testing.T) {
155155
dockerProductionImages: []string{
156156
"ghcr.io/otherorg/postgres-otherrepo-dev:17-pr-define-version-prod",
157157
},
158-
debian: "0.103.0~pr~define~version",
158+
packageVersion: "0.103.0~pr~define~version",
159159
},
160160
},
161161

@@ -180,7 +180,7 @@ func TestDefineVersion(t *testing.T) {
180180
"ghcr.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
181181
"quay.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
182182
},
183-
debian: "0.103.0~ferretdb",
183+
packageVersion: "0.103.0~ferretdb",
184184
},
185185
},
186186
"push/ferretdb-other": {
@@ -200,7 +200,7 @@ func TestDefineVersion(t *testing.T) {
200200
dockerProductionImages: []string{
201201
"ghcr.io/otherorg/postgres-otherrepo-dev:17-ferretdb-prod",
202202
},
203-
debian: "0.103.0~ferretdb",
203+
packageVersion: "0.103.0~ferretdb",
204204
},
205205
},
206206

@@ -268,7 +268,7 @@ func TestDefineVersion(t *testing.T) {
268268
"quay.io/ferretdb/postgres-documentdb:17-0.103.0-ferretdb-2.2.0-beta.1",
269269
"quay.io/ferretdb/postgres-documentdb:latest",
270270
},
271-
debian: "0.103.0~ferretdb~2.2.0~beta.1",
271+
packageVersion: "0.103.0~ferretdb~2.2.0~beta.1",
272272
},
273273
},
274274
"push/tag/release-other": {
@@ -294,7 +294,7 @@ func TestDefineVersion(t *testing.T) {
294294
"ghcr.io/otherorg/postgres-otherrepo:17-0.103.0-ferretdb-2.2.0-beta.1",
295295
"ghcr.io/otherorg/postgres-otherrepo:latest",
296296
},
297-
debian: "0.103.0~ferretdb~2.2.0~beta.1",
297+
packageVersion: "0.103.0~ferretdb~2.2.0~beta.1",
298298
},
299299
},
300300

@@ -332,7 +332,7 @@ func TestDefineVersion(t *testing.T) {
332332
"ghcr.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
333333
"quay.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
334334
},
335-
debian: "0.103.0~ferretdb",
335+
packageVersion: "0.103.0~ferretdb",
336336
},
337337
},
338338
"schedule-other": {
@@ -352,7 +352,7 @@ func TestDefineVersion(t *testing.T) {
352352
dockerProductionImages: []string{
353353
"ghcr.io/otherorg/postgres-otherrepo-dev:17-ferretdb-prod",
354354
},
355-
debian: "0.103.0~ferretdb",
355+
packageVersion: "0.103.0~ferretdb",
356356
},
357357
},
358358

@@ -377,7 +377,7 @@ func TestDefineVersion(t *testing.T) {
377377
"ghcr.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
378378
"quay.io/ferretdb/postgres-documentdb-dev:17-ferretdb-prod",
379379
},
380-
debian: "0.103.0~ferretdb",
380+
packageVersion: "0.103.0~ferretdb",
381381
},
382382
},
383383
"workflow_run-other": {
@@ -397,7 +397,7 @@ func TestDefineVersion(t *testing.T) {
397397
dockerProductionImages: []string{
398398
"ghcr.io/otherorg/postgres-otherrepo-dev:17-ferretdb-prod",
399399
},
400-
debian: "0.103.0~ferretdb",
400+
packageVersion: "0.103.0~ferretdb",
401401
},
402402
},
403403
} {
@@ -443,13 +443,13 @@ func TestSummary(t *testing.T) {
443443
dockerProductionImages: []string{
444444
"quay.io/ferretdb/postgres-documentdb:latest",
445445
},
446-
debian: "0.103.0~ferretdb",
446+
packageVersion: "0.103.0~ferretdb",
447447
}
448448

449449
setSummary(action, result)
450450

451451
expectedStdout := strings.ReplaceAll(`
452-
Debian package version ('upstream_version' only): '0.103.0~ferretdb'
452+
Package version (Debian with 'upstream_version' only, or RPM): '0.103.0~ferretdb'
453453
454454
|Type |Docker image |
455455
|---- |------------ |
@@ -462,7 +462,7 @@ Debian package version ('upstream_version' only): '0.103.0~ferretdb'
462462
assert.Equal(t, expectedStdout, stdout.String(), "stdout does not match")
463463

464464
expectedSummary := strings.ReplaceAll(`
465-
Debian package version ('upstream_version' only): '0.103.0~ferretdb'
465+
Package version (Debian with 'upstream_version' only, or RPM): '0.103.0~ferretdb'
466466
467467
|Type |Docker image |
468468
|---- |------------ |

packaging/defineversion/debian.go renamed to packaging/defineversion/package_version.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ var controlDefaultVer = regexp.MustCompile(`(?m)^default_version = '(?P<major>[0
1414
// See https://www.debian.org/doc/debian-policy/ch-controlfields.html#version.
1515
var disallowedDebian = regexp.MustCompile(`[^A-Za-z0-9\.+~]`)
1616

17+
// disallowedRPM matches disallowed characters of pre-release string.
18+
// See https://fedoraproject.org/wiki/PackagingDrafts/TildeVersioning#Basic_versioning_rules.
19+
var disallowedRPM = regexp.MustCompile(`[^A-Za-z0-9\._+~]`)
20+
1721
// getControlDefaultVersion returns the default_version field from the control file
1822
// in SemVer format (0.103-0 -> 0.103.0).
1923
func getControlDefaultVersion(f string) (string, error) {

0 commit comments

Comments
 (0)