Skip to content

Commit 4383965

Browse files
authored
Merge pull request #28 from Project-Ro-ASD/codex/release-fedora-multiarch
build: add Fedora multi-arch release pipeline
2 parents 5809e77 + 58691e7 commit 4383965

7 files changed

Lines changed: 211 additions & 61 deletions

File tree

.github/workflows/release.yml

Lines changed: 165 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,114 @@ on:
55
tags:
66
- "v*"
77
workflow_dispatch:
8+
inputs:
9+
version:
10+
description: "Release version without the leading v"
11+
required: true
12+
type: string
13+
14+
permissions:
15+
contents: write
16+
17+
concurrency:
18+
group: release-${{ github.ref }}
19+
cancel-in-progress: false
820

921
jobs:
10-
artifacts:
11-
name: Build Release Artifacts
22+
metadata:
23+
name: Resolve Release Metadata
1224
runs-on: ubuntu-latest
25+
26+
outputs:
27+
version: ${{ steps.meta.outputs.version }}
28+
tag_name: ${{ steps.meta.outputs.tag_name }}
29+
archive_prefix: ${{ steps.meta.outputs.archive_prefix }}
30+
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@v4
34+
35+
- name: Resolve version
36+
id: meta
37+
run: |
38+
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
39+
VERSION="${{ inputs.version }}"
40+
else
41+
VERSION="${GITHUB_REF_NAME#v}"
42+
fi
43+
44+
if [[ -z "${VERSION}" ]]; then
45+
echo "Release version could not be determined." >&2
46+
exit 1
47+
fi
48+
49+
PROJECT_VERSION="$(sed -n 's/^[[:space:]]*VERSION[[:space:]]\([0-9.][0-9.]*\)$/\1/p' CMakeLists.txt | head -n1)"
50+
SPEC_DEFAULT_VERSION="$(sed -n 's/^%global upstream_version %{!?upstream_version:\([0-9.][0-9.]*\)}%{?upstream_version}$/\1/p' packaging/rpm/ro-control.spec | head -n1)"
51+
52+
if [[ "${VERSION}" != "${PROJECT_VERSION}" ]]; then
53+
echo "Tag/workflow version (${VERSION}) does not match CMake project version (${PROJECT_VERSION})." >&2
54+
exit 1
55+
fi
56+
57+
if [[ "${VERSION}" != "${SPEC_DEFAULT_VERSION}" ]]; then
58+
echo "Tag/workflow version (${VERSION}) does not match RPM spec default version (${SPEC_DEFAULT_VERSION})." >&2
59+
exit 1
60+
fi
61+
62+
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
63+
echo "tag_name=v${VERSION}" >> "${GITHUB_OUTPUT}"
64+
echo "archive_prefix=ro-control-${VERSION}" >> "${GITHUB_OUTPUT}"
65+
66+
source-archives:
67+
name: Build Source Archives
68+
runs-on: ubuntu-latest
69+
needs: metadata
70+
71+
steps:
72+
- name: Checkout repository
73+
uses: actions/checkout@v4
74+
75+
- name: Create source archives
76+
env:
77+
ARCHIVE_PREFIX: ${{ needs.metadata.outputs.archive_prefix }}
78+
run: |
79+
git archive --format=tar.gz --prefix="${ARCHIVE_PREFIX}/" --output="${ARCHIVE_PREFIX}.tar.gz" "${GITHUB_SHA}"
80+
git archive --format=zip --prefix="${ARCHIVE_PREFIX}/" --output="${ARCHIVE_PREFIX}.zip" "${GITHUB_SHA}"
81+
82+
- name: Upload source archives
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: ro-control-source-${{ needs.metadata.outputs.version }}
86+
path: |
87+
${{ needs.metadata.outputs.archive_prefix }}.tar.gz
88+
${{ needs.metadata.outputs.archive_prefix }}.zip
89+
90+
rpm:
91+
name: Build Fedora RPM (${{ matrix.arch }})
92+
needs: [metadata, source-archives]
93+
runs-on: ${{ matrix.runs_on }}
94+
timeout-minutes: 60
95+
strategy:
96+
fail-fast: false
97+
matrix:
98+
include:
99+
- arch: x86_64
100+
runs_on: ubuntu-24.04
101+
- arch: aarch64
102+
runs_on: ubuntu-24.04-arm
13103
container:
14104
image: fedora:42
15105

16-
permissions:
17-
contents: read
18-
19106
steps:
20107
- name: Checkout repository
21108
uses: actions/checkout@v4
22109

110+
- name: Download source archives
111+
uses: actions/download-artifact@v4
112+
with:
113+
name: ro-control-source-${{ needs.metadata.outputs.version }}
114+
path: dist
115+
23116
- name: Install packaging dependencies
24117
run: |
25118
dnf install -y \
@@ -37,73 +130,97 @@ jobs:
37130
kf6-qqc2-desktop-style \
38131
polkit-devel
39132
40-
- name: Derive release version
133+
- name: Build RPM artifacts
134+
env:
135+
VERSION: ${{ needs.metadata.outputs.version }}
136+
ARCHIVE_PREFIX: ${{ needs.metadata.outputs.archive_prefix }}
137+
RPM_ARCH: ${{ matrix.arch }}
41138
run: |
42-
VERSION="${GITHUB_REF_NAME#v}"
43-
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
139+
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS dist/rpm
140+
cp "dist/${ARCHIVE_PREFIX}.tar.gz" "${HOME}/rpmbuild/SOURCES/"
141+
cp packaging/rpm/ro-control.spec "${HOME}/rpmbuild/SPECS/ro-control.spec"
44142
45-
- name: Create source archives
143+
rpmbuild -ba "${HOME}/rpmbuild/SPECS/ro-control.spec" \
144+
--define "_topdir ${HOME}/rpmbuild" \
145+
--define "upstream_version ${VERSION}" \
146+
--define "dist .fc42"
147+
148+
cp ~/rpmbuild/RPMS/*/*.rpm dist/rpm/
149+
150+
if [[ "${RPM_ARCH}" == "x86_64" ]]; then
151+
cp ~/rpmbuild/SRPMS/*.src.rpm dist/rpm/
152+
fi
153+
154+
- name: Verify package metadata
155+
env:
156+
VERSION: ${{ needs.metadata.outputs.version }}
157+
RPM_ARCH: ${{ matrix.arch }}
46158
run: |
47-
PREFIX="ro-control-${VERSION}"
48-
git archive --format=tar.gz --prefix="${PREFIX}/" --output="${PREFIX}.tar.gz" "${GITHUB_SHA}"
49-
git archive --format=zip --prefix="${PREFIX}/" --output="${PREFIX}.zip" "${GITHUB_SHA}"
159+
RPM_FILE="$(find dist/rpm -maxdepth 1 -type f -name "*.${RPM_ARCH}.rpm" | head -n1)"
160+
if [[ -z "${RPM_FILE}" ]]; then
161+
echo "Failed to locate built ${RPM_ARCH} RPM." >&2
162+
exit 1
163+
fi
50164
51-
- name: Build RPM artifacts
165+
rpm -qp --info "${RPM_FILE}" > "dist/rpm/ro-control-${VERSION}-${RPM_ARCH}-info.txt"
166+
rpm -qp --requires "${RPM_FILE}" | sort > "dist/rpm/ro-control-${VERSION}-${RPM_ARCH}-requires.txt"
167+
168+
- name: Install and smoke-test RPM
169+
env:
170+
VERSION: ${{ needs.metadata.outputs.version }}
171+
RPM_ARCH: ${{ matrix.arch }}
52172
run: |
53-
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS
54-
cp "ro-control-${VERSION}.tar.gz" "${HOME}/rpmbuild/SOURCES/"
55-
cp packaging/rpm/ro-control.spec "${HOME}/rpmbuild/SPECS/ro-control.spec"
56-
rpmbuild -ba "${HOME}/rpmbuild/SPECS/ro-control.spec" \
57-
--define "_topdir ${HOME}/rpmbuild"
58-
cp ~/rpmbuild/SRPMS/*.src.rpm .
59-
cp ~/rpmbuild/RPMS/*/*.rpm .
173+
RPM_FILE="$(find dist/rpm -maxdepth 1 -type f -name "*.${RPM_ARCH}.rpm" | head -n1)"
174+
dnf install -y --nogpgcheck "${RPM_FILE}"
60175
61-
- name: Generate checksums
176+
INSTALLED_VERSION="$(ro-control --version | tr -d '\n')"
177+
if [[ "${INSTALLED_VERSION}" != "${VERSION}" ]]; then
178+
echo "Installed CLI version (${INSTALLED_VERSION}) does not match release version (${VERSION})." >&2
179+
exit 1
180+
fi
181+
182+
ro-control --help > /dev/null
183+
184+
- name: Generate per-arch checksums
185+
env:
186+
VERSION: ${{ needs.metadata.outputs.version }}
187+
RPM_ARCH: ${{ matrix.arch }}
62188
run: |
63-
sha256sum \
64-
"ro-control-${VERSION}.tar.gz" \
65-
"ro-control-${VERSION}.zip" \
66-
*.rpm \
67-
*.src.rpm > "ro-control-${VERSION}-SHA256SUMS.txt"
189+
(
190+
cd dist/rpm
191+
sha256sum * > "ro-control-${VERSION}-${RPM_ARCH}-SHA256SUMS.txt"
192+
)
68193
69-
- name: Upload release artifacts
194+
- name: Upload RPM artifacts
70195
uses: actions/upload-artifact@v4
71196
with:
72-
name: ro-control-release-${{ env.VERSION }}
73-
path: |
74-
ro-control-${{ env.VERSION }}.tar.gz
75-
ro-control-${{ env.VERSION }}.zip
76-
*.rpm
77-
*.src.rpm
78-
ro-control-${{ env.VERSION }}-SHA256SUMS.txt
197+
name: ro-control-rpm-${{ matrix.arch }}-${{ needs.metadata.outputs.version }}
198+
path: dist/rpm/*
79199

80200
release:
81201
name: Create GitHub Release
82202
runs-on: ubuntu-latest
83-
needs: artifacts
84-
85-
permissions:
86-
contents: write
203+
needs: [metadata, source-archives, rpm]
87204

88205
steps:
89-
- name: Derive release version
90-
run: |
91-
VERSION="${GITHUB_REF_NAME#v}"
92-
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
93-
94-
- name: Download release artifacts
206+
- name: Download all release artifacts
95207
uses: actions/download-artifact@v4
96208
with:
97-
name: ro-control-release-${{ env.VERSION }}
209+
pattern: ro-control-*
98210
path: dist
211+
merge-multiple: true
99212

100213
- name: Publish release
101214
uses: softprops/action-gh-release@v2
102215
with:
216+
tag_name: ${{ needs.metadata.outputs.tag_name }}
217+
target_commitish: ${{ github.sha }}
103218
generate_release_notes: true
104219
files: |
105-
dist/ro-control-${{ env.VERSION }}.tar.gz
106-
dist/ro-control-${{ env.VERSION }}.zip
220+
dist/ro-control-${{ needs.metadata.outputs.version }}.tar.gz
221+
dist/ro-control-${{ needs.metadata.outputs.version }}.zip
107222
dist/*.rpm
108223
dist/*.src.rpm
109-
dist/ro-control-${{ env.VERSION }}-SHA256SUMS.txt
224+
dist/*SHA256SUMS.txt
225+
dist/*-requires.txt
226+
dist/*-info.txt

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- Test suite expanded to cover monitor metric ranges and detector reporting
2525
- Repository metadata and packaging references aligned with the active GitHub organization
2626
- Privileged command flow now uses a dedicated allowlisted helper instead of raw `pkexec` command dispatch
27+
- GitHub release automation now targets Fedora `x86_64` and `aarch64` RPM publication from tagged builds
2728

2829
### Fixed
2930
- Command execution path preserves stdout reliably
3031
- RPM repository URL resolution and repository failure handling improved
3132
- Updater API/header alignment and monitor test compatibility issues resolved
3233
- Repository cleanup for stray macOS metadata files
3334
- PolicyKit metadata, helper install path, and packaged action identifiers are now consistent
35+
- Release packaging now validates tag/CMake/spec version alignment before publishing assets
3436

3537
---
3638

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Additional PNG screenshots should be added before wider store distribution.
114114

115115
### RPM Package
116116

117-
Download the latest `.rpm` from [Releases](https://github.com/Project-Ro-ASD/ro-Control/releases):
117+
Download the latest Fedora `.rpm` from [Releases](https://github.com/Project-Ro-ASD/ro-Control/releases) and choose the package that matches your machine architecture (`x86_64` or `aarch64`):
118118

119119
```bash
120120
sudo dnf install ./ro-control-*.rpm

README.tr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Daha geniş mağaza / distro dağıtımı öncesinde PNG ekran görüntüleri ek
101101

102102
### RPM Paketi
103103

104-
[Releases](https://github.com/Project-Ro-ASD/ro-Control/releases) sayfasından en son `.rpm` dosyasını indirin:
104+
[Releases](https://github.com/Project-Ro-ASD/ro-Control/releases) sayfasından sistem mimarinize (`x86_64` veya `aarch64`) uygun en güncel Fedora `.rpm` paketini indirin:
105105

106106
```bash
107107
sudo dnf install ./ro-control-*.rpm

docs/RELEASE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,17 @@ Use this checklist for every production release.
2727
## 4. Packaging
2828

2929
- [ ] `packaging/rpm/ro-control.spec` release/version fields are correct.
30-
- [ ] Build RPM artifacts successfully.
30+
- [ ] Build Fedora RPM artifacts successfully for both `x86_64` and `aarch64`.
3131
- [ ] Verify installation and launch on the target desktop environment.
3232
- [ ] Verify `man ro-control` and shell completions install correctly.
33+
- [ ] Confirm release tag version matches `CMakeLists.txt` and `packaging/rpm/ro-control.spec`.
3334

3435
## 5. Tag and Publish
3536

3637
- [ ] Create annotated tag: `vX.Y.Z`.
3738
- [ ] Push tag to trigger release workflow.
38-
- [ ] Verify GitHub Release includes source archives.
39+
- [ ] Verify GitHub Release includes source archives, one `x86_64` RPM, one `aarch64` RPM, and one source RPM.
40+
- [ ] Verify the attached checksum and RPM metadata files are present.
3941

4042
## 6. Post-release
4143

packaging/rpm/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This directory contains the RPM recipe for ro-Control.
77
- Produce a reproducible RPM from a release tarball
88
- Require translation tooling so localized builds are never emitted partially
99
- Run the upstream Qt test suite during `%check`
10+
- Publish GitHub Release RPMs for both `x86_64` and `aarch64`
1011

1112
## Source archive expectations
1213

@@ -34,6 +35,14 @@ spectool -g -R packaging/rpm/ro-control.spec
3435
rpmbuild -ba packaging/rpm/ro-control.spec
3536
```
3637

38+
To build a different release version from the same spec, override the version
39+
macro explicitly:
40+
41+
```bash
42+
rpmbuild -ba packaging/rpm/ro-control.spec \
43+
--define "upstream_version 0.1.0"
44+
```
45+
3746
If you build from a Git checkout instead of a published source archive, create
3847
the tarball first so `%Source0` matches the spec contract.
3948

@@ -43,3 +52,16 @@ The RPM installs the PolicyKit helper policy as
4352

4453
It also installs the CLI manual page and shell completions for Bash, Zsh, and
4554
Fish so command discovery works out of the box on release systems.
55+
56+
## Release automation
57+
58+
The GitHub release workflow builds:
59+
60+
- source archives (`.tar.gz`, `.zip`)
61+
- one Fedora binary RPM for `x86_64`
62+
- one Fedora binary RPM for `aarch64`
63+
- one source RPM
64+
65+
Each architecture job also performs a smoke install with `dnf install` and
66+
verifies that `ro-control --version` matches the tagged release version before
67+
publishing assets.

0 commit comments

Comments
 (0)