Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 165 additions & 48 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,114 @@ on:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Release version without the leading v"
required: true
type: string

permissions:
contents: write

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

jobs:
artifacts:
name: Build Release Artifacts
metadata:
name: Resolve Release Metadata
runs-on: ubuntu-latest

outputs:
version: ${{ steps.meta.outputs.version }}
tag_name: ${{ steps.meta.outputs.tag_name }}
archive_prefix: ${{ steps.meta.outputs.archive_prefix }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Resolve version
id: meta
run: |
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
VERSION="${{ inputs.version }}"
else
VERSION="${GITHUB_REF_NAME#v}"
fi

if [[ -z "${VERSION}" ]]; then
echo "Release version could not be determined." >&2
exit 1
fi

PROJECT_VERSION="$(sed -n 's/^[[:space:]]*VERSION[[:space:]]\([0-9.][0-9.]*\)$/\1/p' CMakeLists.txt | head -n1)"
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)"

if [[ "${VERSION}" != "${PROJECT_VERSION}" ]]; then
echo "Tag/workflow version (${VERSION}) does not match CMake project version (${PROJECT_VERSION})." >&2
exit 1
fi

if [[ "${VERSION}" != "${SPEC_DEFAULT_VERSION}" ]]; then
echo "Tag/workflow version (${VERSION}) does not match RPM spec default version (${SPEC_DEFAULT_VERSION})." >&2
exit 1
fi

echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
echo "tag_name=v${VERSION}" >> "${GITHUB_OUTPUT}"
echo "archive_prefix=ro-control-${VERSION}" >> "${GITHUB_OUTPUT}"

source-archives:
name: Build Source Archives
runs-on: ubuntu-latest
needs: metadata

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Create source archives
env:
ARCHIVE_PREFIX: ${{ needs.metadata.outputs.archive_prefix }}
run: |
git archive --format=tar.gz --prefix="${ARCHIVE_PREFIX}/" --output="${ARCHIVE_PREFIX}.tar.gz" "${GITHUB_SHA}"
git archive --format=zip --prefix="${ARCHIVE_PREFIX}/" --output="${ARCHIVE_PREFIX}.zip" "${GITHUB_SHA}"

- name: Upload source archives
uses: actions/upload-artifact@v4
with:
name: ro-control-source-${{ needs.metadata.outputs.version }}
path: |
${{ needs.metadata.outputs.archive_prefix }}.tar.gz
${{ needs.metadata.outputs.archive_prefix }}.zip

rpm:
name: Build Fedora RPM (${{ matrix.arch }})
needs: [metadata, source-archives]
runs-on: ${{ matrix.runs_on }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
runs_on: ubuntu-24.04
- arch: aarch64
runs_on: ubuntu-24.04-arm
container:
image: fedora:42

permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Download source archives
uses: actions/download-artifact@v4
with:
name: ro-control-source-${{ needs.metadata.outputs.version }}
path: dist

- name: Install packaging dependencies
run: |
dnf install -y \
Expand All @@ -37,73 +130,97 @@ jobs:
kf6-qqc2-desktop-style \
polkit-devel

- name: Derive release version
- name: Build RPM artifacts
env:
VERSION: ${{ needs.metadata.outputs.version }}
ARCHIVE_PREFIX: ${{ needs.metadata.outputs.archive_prefix }}
RPM_ARCH: ${{ matrix.arch }}
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS dist/rpm
cp "dist/${ARCHIVE_PREFIX}.tar.gz" "${HOME}/rpmbuild/SOURCES/"
cp packaging/rpm/ro-control.spec "${HOME}/rpmbuild/SPECS/ro-control.spec"

- name: Create source archives
rpmbuild -ba "${HOME}/rpmbuild/SPECS/ro-control.spec" \
--define "_topdir ${HOME}/rpmbuild" \
--define "upstream_version ${VERSION}" \
--define "dist .fc42"

cp ~/rpmbuild/RPMS/*/*.rpm dist/rpm/

if [[ "${RPM_ARCH}" == "x86_64" ]]; then
cp ~/rpmbuild/SRPMS/*.src.rpm dist/rpm/
fi

- name: Verify package metadata
env:
VERSION: ${{ needs.metadata.outputs.version }}
RPM_ARCH: ${{ matrix.arch }}
run: |
PREFIX="ro-control-${VERSION}"
git archive --format=tar.gz --prefix="${PREFIX}/" --output="${PREFIX}.tar.gz" "${GITHUB_SHA}"
git archive --format=zip --prefix="${PREFIX}/" --output="${PREFIX}.zip" "${GITHUB_SHA}"
RPM_FILE="$(find dist/rpm -maxdepth 1 -type f -name "*.${RPM_ARCH}.rpm" | head -n1)"
if [[ -z "${RPM_FILE}" ]]; then
echo "Failed to locate built ${RPM_ARCH} RPM." >&2
exit 1
fi

- name: Build RPM artifacts
rpm -qp --info "${RPM_FILE}" > "dist/rpm/ro-control-${VERSION}-${RPM_ARCH}-info.txt"
rpm -qp --requires "${RPM_FILE}" | sort > "dist/rpm/ro-control-${VERSION}-${RPM_ARCH}-requires.txt"

- name: Install and smoke-test RPM
env:
VERSION: ${{ needs.metadata.outputs.version }}
RPM_ARCH: ${{ matrix.arch }}
run: |
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS
cp "ro-control-${VERSION}.tar.gz" "${HOME}/rpmbuild/SOURCES/"
cp packaging/rpm/ro-control.spec "${HOME}/rpmbuild/SPECS/ro-control.spec"
rpmbuild -ba "${HOME}/rpmbuild/SPECS/ro-control.spec" \
--define "_topdir ${HOME}/rpmbuild"
cp ~/rpmbuild/SRPMS/*.src.rpm .
cp ~/rpmbuild/RPMS/*/*.rpm .
RPM_FILE="$(find dist/rpm -maxdepth 1 -type f -name "*.${RPM_ARCH}.rpm" | head -n1)"
dnf install -y --nogpgcheck "${RPM_FILE}"

- name: Generate checksums
INSTALLED_VERSION="$(ro-control --version | tr -d '\n')"
if [[ "${INSTALLED_VERSION}" != "${VERSION}" ]]; then
echo "Installed CLI version (${INSTALLED_VERSION}) does not match release version (${VERSION})." >&2
exit 1
fi

ro-control --help > /dev/null

- name: Generate per-arch checksums
env:
VERSION: ${{ needs.metadata.outputs.version }}
RPM_ARCH: ${{ matrix.arch }}
run: |
sha256sum \
"ro-control-${VERSION}.tar.gz" \
"ro-control-${VERSION}.zip" \
*.rpm \
*.src.rpm > "ro-control-${VERSION}-SHA256SUMS.txt"
(
cd dist/rpm
sha256sum * > "ro-control-${VERSION}-${RPM_ARCH}-SHA256SUMS.txt"
)

- name: Upload release artifacts
- name: Upload RPM artifacts
uses: actions/upload-artifact@v4
with:
name: ro-control-release-${{ env.VERSION }}
path: |
ro-control-${{ env.VERSION }}.tar.gz
ro-control-${{ env.VERSION }}.zip
*.rpm
*.src.rpm
ro-control-${{ env.VERSION }}-SHA256SUMS.txt
name: ro-control-rpm-${{ matrix.arch }}-${{ needs.metadata.outputs.version }}
path: dist/rpm/*

release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: artifacts

permissions:
contents: write
needs: [metadata, source-archives, rpm]

steps:
- name: Derive release version
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"

- name: Download release artifacts
- name: Download all release artifacts
uses: actions/download-artifact@v4
with:
name: ro-control-release-${{ env.VERSION }}
pattern: ro-control-*
path: dist
merge-multiple: true

- name: Publish release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.metadata.outputs.tag_name }}
target_commitish: ${{ github.sha }}
generate_release_notes: true
files: |
dist/ro-control-${{ env.VERSION }}.tar.gz
dist/ro-control-${{ env.VERSION }}.zip
dist/ro-control-${{ needs.metadata.outputs.version }}.tar.gz
dist/ro-control-${{ needs.metadata.outputs.version }}.zip
dist/*.rpm
dist/*.src.rpm
dist/ro-control-${{ env.VERSION }}-SHA256SUMS.txt
dist/*SHA256SUMS.txt
dist/*-requires.txt
dist/*-info.txt
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Test suite expanded to cover monitor metric ranges and detector reporting
- Repository metadata and packaging references aligned with the active GitHub organization
- Privileged command flow now uses a dedicated allowlisted helper instead of raw `pkexec` command dispatch
- GitHub release automation now targets Fedora `x86_64` and `aarch64` RPM publication from tagged builds

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

---

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Additional PNG screenshots should be added before wider store distribution.

### RPM Package

Download the latest `.rpm` from [Releases](https://github.com/Project-Ro-ASD/ro-Control/releases):
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`):

```bash
sudo dnf install ./ro-control-*.rpm
Expand Down
2 changes: 1 addition & 1 deletion README.tr.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Daha geniş mağaza / distro dağıtımı öncesinde PNG ekran görüntüleri ek

### RPM Paketi

[Releases](https://github.com/Project-Ro-ASD/ro-Control/releases) sayfasından en son `.rpm` dosyasını indirin:
[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:

```bash
sudo dnf install ./ro-control-*.rpm
Expand Down
6 changes: 4 additions & 2 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ Use this checklist for every production release.
## 4. Packaging

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

## 5. Tag and Publish

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

## 6. Post-release

Expand Down
22 changes: 22 additions & 0 deletions packaging/rpm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This directory contains the RPM recipe for ro-Control.
- Produce a reproducible RPM from a release tarball
- Require translation tooling so localized builds are never emitted partially
- Run the upstream Qt test suite during `%check`
- Publish GitHub Release RPMs for both `x86_64` and `aarch64`

## Source archive expectations

Expand Down Expand Up @@ -34,6 +35,14 @@ spectool -g -R packaging/rpm/ro-control.spec
rpmbuild -ba packaging/rpm/ro-control.spec
```

To build a different release version from the same spec, override the version
macro explicitly:

```bash
rpmbuild -ba packaging/rpm/ro-control.spec \
--define "upstream_version 0.1.0"
```

If you build from a Git checkout instead of a published source archive, create
the tarball first so `%Source0` matches the spec contract.

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

It also installs the CLI manual page and shell completions for Bash, Zsh, and
Fish so command discovery works out of the box on release systems.

## Release automation

The GitHub release workflow builds:

- source archives (`.tar.gz`, `.zip`)
- one Fedora binary RPM for `x86_64`
- one Fedora binary RPM for `aarch64`
- one source RPM

Each architecture job also performs a smoke install with `dnf install` and
verifies that `ro-control --version` matches the tagged release version before
publishing assets.
Loading
Loading