name: Rust CI
on:
push:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
strategy:
matrix:
include:
- runner: arc-runner-set
arch: x86_64
- runner: ubuntu-24.04-arm
arch: aarch64
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
# rumqttc does TLS through native-tls, which links the system
# OpenSSL (found with pkg-config); zbus is pure Rust. So a linker,
# pkg-config and the OpenSSL headers are what a bare self-hosted
# container is missing.
if command -v apt-get &> /dev/null; then
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev
elif command -v dnf &> /dev/null; then
sudo dnf install -y gcc pkgconfig openssl-devel
elif command -v yum &> /dev/null; then
sudo yum install -y gcc pkgconfig openssl-devel
else
echo "Package manager not found. Please install a C toolchain, pkg-config and the OpenSSL headers manually."
exit 1
fi
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.92"
components: rustfmt, clippy
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy -- -D warnings
- name: Check
run: cargo check
- name: Build release artifact
run: cargo build --release --verbose
- name: Strip binary
run: strip target/release/apollos-dbus
- name: Install cargo-deb
run: cargo install cargo-deb
- name: Install cargo-generate-rpm
run: cargo install cargo-generate-rpm
# Every CI build has to carry a distinct version, or the second
# one publishes the same filename with different bytes and the
# registry correctly refuses it with a 409 — and no machine that
# installed the first ever sees the second.
#
# `+` rather than `-`: RPM forbids `-` in a version outright, and
# in both ecosystems `0.1.2+dev.<stamp>` sorts *after* 0.1.2,
# which is what you want from a repository you added in order to
# run the latest build. A tag publishes the bare Cargo version.
#
# One stamp for the whole job, so the .deb and the .rpm from a
# single run agree about what they are.
- name: Stamp the package version
id: version
run: |
set -euo pipefail
base=$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)
if [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
version="$base"
else
version="$base+dev.$(date -u +%s)"
fi
echo "version: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
# Rewritten after the release build, so the binary is cached
# on the unstamped manifest and only the packaging sees this.
sed -i "0,/^version = .*/s//version = \"$version\"/" Cargo.toml
- name: Build test Debian package
run: cargo deb --no-build --no-strip
- name: Build RPM package
run: cargo generate-rpm
# `vars.CI_FORGE_URL` is what the forge injects into a run; fall
# back to what the runner already knows, and say so plainly if
# neither resolves rather than handing curl an empty URL.
- name: Resolve the forge URL
env:
CI_FORGE_URL: ${{ vars.CI_FORGE_URL }}
run: |
set -euo pipefail
forge_url=${CI_FORGE_URL:-${GITHUB_SERVER_URL:-}}
if [ -z "$forge_url" ]; then
echo "No forge URL available." >&2
echo "Set a CI_FORGE_URL variable on this repository or its org." >&2
exit 1
fi
echo "FORGE_URL=$forge_url" >> "$GITHUB_ENV"
# `${{ github.token }}` is minted for this job and authorized to
# publish to THIS repository's packages and nowhere else, so
# there is no secret to create first.
#
# Pull requests don't publish: a PR build is a check, and a
# registry that carries every proposed change is not a registry
# anyone can install from.
- name: Publish the .deb and the .rpm to the forge
if: github.event_name != 'pull_request'
env:
REPOSITORY: ${{ github.repository }}
TOKEN: ${{ github.token }}
run: |
set -euo pipefail
for deb in target/debian/*.deb; do
echo "publishing $deb"
curl --fail-with-body -sS \
-u "gitgud-actions:$TOKEN" \
-H "Content-Type: application/vnd.debian.binary-package" \
--data-binary "@$deb" \
"$FORGE_URL/pkg/deb/$REPOSITORY/upload?dist=stable&component=main"
echo
done
for rpm in target/generate-rpm/*.rpm; do
echo "publishing $rpm"
curl --fail-with-body -sS \
-u "gitgud-actions:$TOKEN" \
-H "Content-Type: application/x-rpm" \
--data-binary "@$rpm" \
"$FORGE_URL/pkg/rpm/$REPOSITORY/upload"
echo
done
- name: How to install it
if: github.event_name != 'pull_request'
env:
REPOSITORY: ${{ github.repository }}
OWNER: ${{ github.repository_owner }}
run: |
cat <<EOF
# Debian / Ubuntu
curl -fsSL $FORGE_URL/pkg/_keys/deb/$OWNER | sudo tee /etc/apt/keyrings/$OWNER.asc >/dev/null
echo "deb [signed-by=/etc/apt/keyrings/$OWNER.asc] $FORGE_URL/pkg/deb/$OWNER/_all stable main" | sudo tee /etc/apt/sources.list.d/$OWNER.list
sudo apt update && sudo apt install apollos-dbus
# Fedora / RHEL / openSUSE — /etc/yum.repos.d/$OWNER.repo
[$OWNER]
name=$OWNER
baseurl=$FORGE_URL/pkg/rpm/$OWNER/_all
enabled=1
repo_gpgcheck=1
gpgcheck=0
gpgkey=$FORGE_URL/pkg/_keys/rpm/$OWNER
EOF
- name: Upload test artifact
uses: actions/upload-artifact@v4
# Artifact storage is a GitHub feature; this forge has none, so
# these steps have nothing to upload to. They used to run and
# fail with `continue-on-error`, which is a red step on every
# single run — and a build that is always a bit red teaches
# everyone to stop reading it. Skipping says the same thing
# honestly and leaves the badge meaningful.
#
# The packages are published to the forge's registries instead,
# which is the thing anyone actually installs from.
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: apollos-dbus-test-${{ matrix.arch }}-linux
path: target/release/apollos-dbus
- name: Upload test Debian package
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: apollos-dbus-test-${{ matrix.arch }}-linux.deb
path: target/debian/*.deb
- name: Upload test RPM package
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: apollos-dbus-test-${{ matrix.arch }}-linux.rpm
path: target/generate-rpm/*.rpm
# A D-Bus service with a systemd user unit: Linux is the only platform
# it means anything on, so no macOS or Windows builds.
release:
name: Release
if: startsWith(github.ref, 'refs/tags/v')
needs: build
permissions:
contents: write
packages: write
strategy:
matrix:
include:
- os: ubuntu-latest
runner: arc-runner-set
name: apollos-dbus-x86_64-linux-gnu.tar.gz
rust: "1.92"
- os: ubuntu-24.04-arm
runner: ubuntu-24.04-arm
name: apollos-dbus-aarch64-linux-gnu.tar.gz
rust: "1.92"
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: |
# rumqttc does TLS through native-tls, which links the system
# OpenSSL (found with pkg-config); zbus is pure Rust. So a linker,
# pkg-config and the OpenSSL headers are what a bare self-hosted
# container is missing.
if command -v apt-get &> /dev/null; then
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev
elif command -v dnf &> /dev/null; then
sudo dnf install -y gcc pkgconfig openssl-devel
elif command -v yum &> /dev/null; then
sudo yum install -y gcc pkgconfig openssl-devel
else
echo "Package manager not found. Please install a C toolchain, pkg-config and the OpenSSL headers manually."
exit 1
fi
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.os }}-${{ matrix.rust }}
- name: Build release binary
run: cargo build --release --verbose
- name: Strip binary
run: strip target/release/apollos-dbus
- name: Create release archive
run: tar -czf ${{ matrix.name }} -C target/release apollos-dbus
- name: Install cargo-deb
run: cargo install cargo-deb
- name: Build Debian package
run: cargo deb --no-build --no-strip
- name: Install cargo-generate-rpm
run: cargo install cargo-generate-rpm
- name: Build RPM package
run: cargo generate-rpm
# Artifact storage is a GitHub feature; see the build job.
- name: Upload release archive
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: ${{ matrix.name }}
path: ${{ matrix.name }}
- name: Upload Debian package
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: apollos-dbus-${{ matrix.os }}.deb
path: target/debian/*.deb
- name: Upload RPM package
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.server_url, 'https://github.com') }}
with:
name: apollos-dbus-${{ matrix.os }}.rpm
path: target/generate-rpm/*.rpm
create-release:
name: Create Release
runs-on: arc-runner-set
# Makes a *GitHub* Release out of artifacts a GitHub runner uploaded;
# off GitHub there is nothing to download. Tagged builds still publish
# their packages to the forge from the build job.
if: >-
startsWith(github.ref, 'refs/tags/v') &&
startsWith(github.server_url, 'https://github.com')
needs: release
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/*/*.tar.gz
artifacts/*/*.deb
artifacts/*/*.rpm
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
neiam
/apollos-dbus
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
11.8 KiB · text
History
b4b277e