name: Rust CI and Docker Build
on:
push:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]
env:
CARGO_TERM_COLOR: always
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
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: |
if command -v apt-get &> /dev/null; then
sudo apt-get update
# cmake and git are for paho-mqtt-sys, which vendors the
# Paho C library and builds it with cmake from a git
# submodule. Both are preinstalled on GitHub-hosted
# runners and absent from a bare self-hosted container,
# which is why this only started failing on arc-runner-set.
sudo apt-get install -y build-essential pkg-config cmake git libssl-dev libgtk-3-dev libgdk-pixbuf2.0-dev libpango1.0-dev libglib2.0-dev
elif command -v yum &> /dev/null; then
sudo yum install -y pkgconfig cmake git openssl-devel gtk3-devel gdk-pixbuf-devel pango-devel
elif command -v dnf &> /dev/null; then
sudo dnf install -y pkgconfig cmake git openssl-devel
elif command -v pacman &> /dev/null; then
sudo pacman -Sy --noconfirm pkgconf openssl
elif command -v apk &> /dev/null; then
sudo apk add --no-cache pkgconfig openssl-dev
else
echo "Package manager not found. Please install pkg-config and openssl-dev 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/koco
- 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 koco
# 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
with:
name: koco-test-${{ matrix.arch }}-linux
path: target/release/koco
- name: Upload test Debian package
uses: actions/upload-artifact@v4
with:
name: koco-test-${{ matrix.arch }}-linux.deb
path: target/debian/*.deb
- name: Upload test RPM package
uses: actions/upload-artifact@v4
with:
name: koco-test-${{ matrix.arch }}-linux.rpm
path: target/generate-rpm/*.rpm
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: koco-x86_64-linux-gnu.tar.gz
archive_cmd: tar -czf
binary_ext: ""
rust: "1.92"
- os: ubuntu-24.04-arm
runner: ubuntu-24.04-arm
name: koco-aarch64-linux-gnu.tar.gz
archive_cmd: tar -czf
binary_ext: ""
rust: "1.92"
- os: macos-latest
runner: macos-latest
name: koco-aarch64-macos.tar.gz
archive_cmd: tar -czf
binary_ext: ""
rust: "1.92"
- os: windows-latest
runner: windows-latest
name: koco-x86_64-windows.zip
archive_cmd: 7z a
binary_ext: ".exe"
rust: "1.92"
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Install system dependencies (self-hosted Linux)
if: runner.os == 'Linux'
run: |
if command -v apt-get &> /dev/null; then
sudo apt-get update
sudo apt-get install -y build-essential pkg-config cmake git libssl-dev libgtk-3-dev libgdk-pixbuf2.0-dev libpango1.0-dev libglib2.0-dev
elif command -v yum &> /dev/null; then
sudo yum install -y pkgconfig cmake git openssl-devel gtk3-devel gdk-pixbuf-devel pango-devel
elif command -v dnf &> /dev/null; then
sudo dnf install -y pkgconfig cmake git openssl-devel
elif command -v pacman &> /dev/null; then
sudo pacman -Sy --noconfirm pkgconf openssl
elif command -v apk &> /dev/null; then
sudo apk add --no-cache pkgconfig openssl-dev
else
echo "Package manager not found. Please install pkg-config and openssl-dev 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 (Unix)
if: matrix.os != 'windows-latest'
run: |
strip target/release/koco${{ matrix.binary_ext }}
- name: Create release archive (Unix)
if: matrix.os != 'windows-latest'
run: |
cd target/release
tar -czf ../../${{ matrix.name }} koco
cd ../..
- name: Create release archive (Windows)
if: matrix.os == 'windows-latest'
run: |
cd target/release
7z a ../../${{ matrix.name }} koco.exe
cd ../..
- name: Install cargo-deb (Linux)
if: runner.os == 'Linux'
run: cargo install cargo-deb
- name: Build Debian package (Linux)
if: runner.os == 'Linux'
run: cargo deb --no-build --no-strip
- name: Install cargo-generate-rpm (Linux)
if: runner.os == 'Linux'
run: cargo install cargo-generate-rpm
- name: Build RPM package (Linux)
if: runner.os == 'Linux'
run: cargo generate-rpm
- name: Upload release archive
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
path: ${{ matrix.name }}
- name: Upload Debian package
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4
with:
name: koco-${{ matrix.os }}.deb
path: target/debian/*.deb
- name: Upload RPM package
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4
with:
name: koco-${{ matrix.os }}.rpm
path: target/generate-rpm/*.rpm
create-release:
name: Create Release
runs-on: arc-runner-set
if: startsWith(github.ref, 'refs/tags/v')
needs: release
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create release notes
run: |
echo "# koco Release ${GITHUB_REF_NAME}" > release_notes.md
echo "" >> release_notes.md
echo "## Changes in this release" >> release_notes.md
echo "" >> release_notes.md
echo "## Supported Platforms" >> release_notes.md
echo "" >> release_notes.md
echo "- Linux (x86_64)" >> release_notes.md
echo "- Linux (aarch64)" >> release_notes.md
echo "- Windows (x86_64)" >> release_notes.md
echo "- macOS (x86_64 and Apple Silicon)" >> release_notes.md
echo "" >> release_notes.md
echo "## Installation" >> release_notes.md
echo "" >> release_notes.md
echo "1. Download the appropriate archive for your platform" >> release_notes.md
echo "2. Extract the binaries" >> release_notes.md
echo "3. Place them in your PATH" >> release_notes.md
echo "" >> release_notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/*/*.tar.gz
artifacts/*/*.zip
artifacts/*/*.deb
artifacts/*/*.rpm
body_path: release_notes.md
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
neiam
/koco
public · Issues · Pulls · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
13.0 KiB · text
History
773ab5c