diff --git a/.forgejo/workflows/beta-release.yml b/.forgejo/workflows/beta-release.yml new file mode 100644 index 0000000..54198b5 --- /dev/null +++ b/.forgejo/workflows/beta-release.yml @@ -0,0 +1,92 @@ +name: beta release + +# Publishes a beta-track build on every push to `beta` — a frozen +# stabilization branch cut from `dev` when ready to stabilize; only +# fix/ branches merged into `beta` should land here afterward. +# See bread-ecosystem's docs/release-channels.md for the three-track policy. +on: + push: + branches: ['beta'] + +jobs: + build: + runs-on: [self-hosted, hestia] + steps: + - name: checkout + run: | + set -euo pipefail + rm -rf src && mkdir src + git clone --branch beta --depth 1 \ + "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" src + + # bos-settings is a Tauri app: Cargo.toml lives at src/src/Cargo.toml + # (checkout root is named "src" by convention above; the repo's own + # Rust backend is also in a dir called "src", not the usual + # src-tauri — hence src/src below), and the Rust build expects the + # frontend already built at frontend/build (tauri.conf.json's + # frontendDist) — that only happens automatically under `cargo + # tauri build`, so it's run explicitly here since this workflow + # just uses plain `cargo build`. + - name: build frontend + run: | + set -euo pipefail + cd src/frontend + npm ci + npm run build + + - name: build + run: cd src/src && cargo build --release --locked + + - name: compute beta version + run: | + set -euo pipefail + cd src + # Base the beta version off the latest published stable tag, + # not Cargo.toml — Cargo.toml can go stale relative to the last + # real release, which would make a beta build sort as OLDER than + # what's already installed and bakery would correctly refuse it. + LATEST_TAG="$(git ls-remote --tags --refs \ + "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" 'v*' \ + | awk -F/ '{print $NF}' | sed 's/^v//' | sort -V | tail -1)" + if [ -n "${LATEST_TAG}" ]; then + CUR="${LATEST_TAG}" + else + CUR="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"(.*)".*/\1/')" + fi + IFS='.' read -r MA MI PA <<< "${CUR}" + SHA="$(git rev-parse --short HEAD)" + TS="$(date -u +%Y%m%d%H%M%S)" + echo "VERSION=${MA}.${MI}.$((PA + 1))-beta.${TS}+${SHA}" >> "$GITHUB_ENV" + + - name: prepare artifacts + run: | + set -euo pipefail + PKG_DIR="/srv/breadway-dl/beta/bos-settings/${VERSION}" + mkdir -p "${PKG_DIR}" + cp "src/src/target/release/bos-settings" "${PKG_DIR}/bos-settings-x86_64" + strip "${PKG_DIR}/bos-settings-x86_64" + sha256sum "${PKG_DIR}/bos-settings-x86_64" | awk '{print $1}' \ + > "${PKG_DIR}/bos-settings-x86_64.sha256" + cp src/packaging/bos-settings.desktop "${PKG_DIR}/" + cp src/LICENSE "${PKG_DIR}/" + cp src/bakery.toml "${PKG_DIR}/bakery.toml" + ln -sfn "${VERSION}" "/srv/breadway-dl/beta/bos-settings/latest" + + # No GitHub Release upload — beta, like dev, is only distributed via + # dl.breadway.dev/beta/. + - name: regenerate beta index.json + env: + MINISIGN_SEC_KEY: ${{ secrets.BAKERY_MINISIGN_SEC_KEY_PATH }} + run: | + set -euo pipefail + if [ -z "${MINISIGN_SEC_KEY:-}" ]; then + echo "::error::BAKERY_MINISIGN_SEC_KEY_PATH secret not set — refusing to regenerate beta index.json unsigned (would leave a stale signature mismatched against fresh content and break bakery for everyone on the beta track)" + exit 1 + fi + rm -rf /tmp/bread-ecosystem-ci-* 2>/dev/null || true + # mktemp: a fixed clone path races when multiple repos' dev/beta + # workflows run close together on the same self-hosted runner. + ECOSYSTEM_CI_DIR="$(mktemp -d /tmp/bread-ecosystem-ci-XXXXXX)" + git clone https://git.breadway.dev/Breadway/bread-ecosystem.git "${ECOSYSTEM_CI_DIR}" + TRACK=beta bash "${ECOSYSTEM_CI_DIR}/scripts/gen-index.sh" + rm -rf "${ECOSYSTEM_CI_DIR}" diff --git a/.forgejo/workflows/dev-release.yml b/.forgejo/workflows/dev-release.yml new file mode 100644 index 0000000..04792d8 --- /dev/null +++ b/.forgejo/workflows/dev-release.yml @@ -0,0 +1,92 @@ +name: dev release + +# Publishes a dev-track build on every push to `dev` — +# separate from release.yml's tag-triggered stable releases. See +# bread-ecosystem's docs/release-channels.md for the three-track policy +# this is part of. +on: + push: + branches: ['dev'] + +jobs: + build: + runs-on: [self-hosted, hestia] + steps: + - name: checkout + run: | + set -euo pipefail + rm -rf src && mkdir src + git clone --branch dev --depth 1 \ + "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" src + + # bos-settings is a Tauri app: Cargo.toml lives at src/src/Cargo.toml + # (checkout root is named "src" by convention above; the repo's own + # Rust backend is also in a dir called "src", not the usual + # src-tauri — hence src/src below), and the Rust build expects the + # frontend already built at frontend/build (tauri.conf.json's + # frontendDist) — that only happens automatically under `cargo + # tauri build`, so it's run explicitly here since this workflow + # just uses plain `cargo build`. + - name: build frontend + run: | + set -euo pipefail + cd src/frontend + npm ci + npm run build + + - name: build + run: cd src/src && cargo build --release --locked + + - name: compute dev version + run: | + set -euo pipefail + cd src + # Base the dev version off the latest published stable tag, + # not Cargo.toml — Cargo.toml can go stale relative to the last + # real release, which would make a dev build sort as OLDER than + # what's already installed and bakery would correctly refuse it. + LATEST_TAG="$(git ls-remote --tags --refs \ + "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" 'v*' \ + | awk -F/ '{print $NF}' | sed 's/^v//' | sort -V | tail -1)" + if [ -n "${LATEST_TAG}" ]; then + CUR="${LATEST_TAG}" + else + CUR="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"(.*)".*/\1/')" + fi + IFS='.' read -r MA MI PA <<< "${CUR}" + SHA="$(git rev-parse --short HEAD)" + TS="$(date -u +%Y%m%d%H%M%S)" + echo "VERSION=${MA}.${MI}.$((PA + 1))-dev.${TS}+${SHA}" >> "$GITHUB_ENV" + + - name: prepare artifacts + run: | + set -euo pipefail + PKG_DIR="/srv/breadway-dl/dev/bos-settings/${VERSION}" + mkdir -p "${PKG_DIR}" + cp "src/src/target/release/bos-settings" "${PKG_DIR}/bos-settings-x86_64" + strip "${PKG_DIR}/bos-settings-x86_64" + sha256sum "${PKG_DIR}/bos-settings-x86_64" | awk '{print $1}' \ + > "${PKG_DIR}/bos-settings-x86_64.sha256" + cp src/packaging/bos-settings.desktop "${PKG_DIR}/" + cp src/LICENSE "${PKG_DIR}/" + cp src/bakery.toml "${PKG_DIR}/bakery.toml" + ln -sfn "${VERSION}" "/srv/breadway-dl/dev/bos-settings/latest" + + # No GitHub Release upload — dev, like the other non-stable track, + # is only distributed via dl.breadway.dev/dev/. + - name: regenerate dev index.json + env: + MINISIGN_SEC_KEY: ${{ secrets.BAKERY_MINISIGN_SEC_KEY_PATH }} + run: | + set -euo pipefail + if [ -z "${MINISIGN_SEC_KEY:-}" ]; then + echo "::error::BAKERY_MINISIGN_SEC_KEY_PATH secret not set — refusing to regenerate dev index.json unsigned (would leave a stale signature mismatched against fresh content and break bakery for everyone on the dev track)" + exit 1 + fi + rm -rf /tmp/bread-ecosystem-ci-* 2>/dev/null || true + # mktemp: a fixed clone path races when multiple repos' dev/beta + # workflows run close together on the same self-hosted runner. + ECOSYSTEM_CI_DIR="$(mktemp -d /tmp/bread-ecosystem-ci-XXXXXX)" + git clone --branch dev https://git.breadway.dev/Breadway/bread-ecosystem.git "${ECOSYSTEM_CI_DIR}" + TRACK=dev bash "${ECOSYSTEM_CI_DIR}/scripts/gen-index.sh" + rm -rf "${ECOSYSTEM_CI_DIR}" diff --git a/.forgejo/workflows/package.yml b/.forgejo/workflows/package.yml deleted file mode 100644 index 4ae3545..0000000 --- a/.forgejo/workflows/package.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Build and publish package - -on: - push: - tags: ['v*'] - -jobs: - package: - runs-on: [self-hosted, hestia] - container: - image: archlinux:latest - steps: - # Note: no actions/checkout — the archlinux image has no Node, which JS - # actions require. Everything runs as shell steps and clones manually. - - name: Build and publish - env: - PUBLISH_TOKEN: ${{ secrets.REGISTRY_TOKEN }} - run: | - set -euo pipefail - VERSION="${GITHUB_REF_NAME#v}" - pacman -Syu --noconfirm base-devel git rust cargo gtk4 glib2 - useradd -m builder - git config --global --add safe.directory '*' - git clone --branch "${GITHUB_REF_NAME}" --depth 1 \ - "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" /home/builder/src - cd /home/builder/src - git archive --format=tar.gz --prefix="bos-settings-${VERSION}/" HEAD \ - > packaging/bos-settings-${VERSION}.tar.gz - SHA=$(sha256sum packaging/bos-settings-${VERSION}.tar.gz | awk '{print $1}') - sed -i "s/^pkgver=.*/pkgver=${VERSION}/" packaging/PKGBUILD - sed -i "s/^sha256sums=.*/sha256sums=('${SHA}')/" packaging/PKGBUILD - chown -R builder:builder /home/builder/src - # --nocheck: packaging builds the artifact; tests belong in a CI job. - su builder -c "cd /home/builder/src/packaging && makepkg -f --noconfirm --nocheck" - PKG=$(find /home/builder/src/packaging -name '*.pkg.tar.zst' | head -1) - curl -fsS -X PUT \ - -H "Authorization: token ${PUBLISH_TOKEN}" \ - -H "Content-Type: application/octet-stream" \ - --data-binary "@${PKG}" \ - "https://git.breadway.dev/api/packages/Breadway/arch/os" diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 8fa9fad..80763d8 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -15,8 +15,23 @@ jobs: git clone --branch "${GITHUB_REF_NAME}" --depth 1 \ "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" src + # bos-settings is a Tauri app: Cargo.toml lives at src/src/Cargo.toml + # (checkout root is named "src" by convention above; the repo's own + # Rust backend is also in a dir called "src", not the usual + # src-tauri — hence src/src below), and the Rust build expects the + # frontend already built at frontend/build (tauri.conf.json's + # frontendDist) — that only happens automatically under `cargo + # tauri build`, so it's run explicitly here since this workflow + # just uses plain `cargo build`. + - name: build frontend + run: | + set -euo pipefail + cd src/frontend + npm ci + npm run build + - name: build - run: cd src && cargo build --release --locked + run: cd src/src && cargo build --release --locked - name: prepare artifacts run: | @@ -24,19 +39,29 @@ jobs: VERSION="${GITHUB_REF_NAME#v}" PKG_DIR="/srv/breadway-dl/bos-settings/${VERSION}" mkdir -p "${PKG_DIR}" - cp "src/target/release/bos-settings" "${PKG_DIR}/bos-settings-x86_64" + cp "src/src/target/release/bos-settings" "${PKG_DIR}/bos-settings-x86_64" strip "${PKG_DIR}/bos-settings-x86_64" sha256sum "${PKG_DIR}/bos-settings-x86_64" | awk '{print $1}' \ > "${PKG_DIR}/bos-settings-x86_64.sha256" + cp src/packaging/bos-settings.desktop "${PKG_DIR}/" + cp src/LICENSE "${PKG_DIR}/" cp src/bakery.toml "${PKG_DIR}/bakery.toml" ln -sfn "${VERSION}" "/srv/breadway-dl/bos-settings/latest" - name: regenerate index.json + env: + MINISIGN_SEC_KEY: ${{ secrets.BAKERY_MINISIGN_SEC_KEY_PATH }} run: | set -euo pipefail - rm -rf /tmp/bread-ecosystem-ci - git clone https://git.breadway.dev/Breadway/bread-ecosystem.git /tmp/bread-ecosystem-ci - bash /tmp/bread-ecosystem-ci/scripts/gen-index.sh + if [ -z "${MINISIGN_SEC_KEY:-}" ]; then + echo "::error::BAKERY_MINISIGN_SEC_KEY_PATH secret not set — refusing to regenerate index.json unsigned (would leave a stale signature mismatched against fresh content and break bakery for everyone)" + exit 1 + fi + rm -rf /tmp/bread-ecosystem-ci-* 2>/dev/null || true + ECOSYSTEM_CI_DIR="$(mktemp -d /tmp/bread-ecosystem-ci-XXXXXX)" + git clone https://git.breadway.dev/Breadway/bread-ecosystem.git "${ECOSYSTEM_CI_DIR}" + bash "${ECOSYSTEM_CI_DIR}/scripts/gen-index.sh" + rm -rf "${ECOSYSTEM_CI_DIR}" - name: upload to GitHub Release env: diff --git a/README.md b/README.md index 08161fe..62c0620 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ System settings app for [BOS (Bread Operating System)](https://git.breadway.dev/Breadway/bos) — GTK4, configures every bread\* app's config plus core system settings (network, sound, power, users, firewall, snapshots, packages, AUR, firmware, Hyprland display/appearance/autostart) non-destructively. -Split out of the `bos` repo into its own repo so a bos-settings release doesn't require a BOS ISO release, and vice versa. Still the only pacman-packaged (not bakery-managed) bread app — see `packaging/README.md`. +Split out of the `bos` repo into its own repo so a bos-settings release doesn't require a BOS ISO release, and vice versa. Distributed via `bakery` — see `bread-ecosystem`'s `CONTRIBUTING.md` for the dev/beta/stable track workflow shared across the bread ecosystem. ## Building @@ -12,4 +12,4 @@ cargo build --release ## Packaging / releasing -See `packaging/README.md`. In short: bump `Cargo.toml`'s version, tag `vX.Y.Z`, push the tag to both remotes — `.forgejo/workflows/package.yml` builds and publishes to the `[breadway]` pacman repo automatically. +Bump `Cargo.toml`'s version, tag `vX.Y.Z`, push the tag to both remotes — `.forgejo/workflows/release.yml` builds and publishes to `dl.breadway.dev` (bakery) automatically. Pushes to `dev`/`beta` publish a dev/beta-track build the same way, no tag needed. diff --git a/bakery.toml b/bakery.toml index 632de76..e4af5f9 100644 --- a/bakery.toml +++ b/bakery.toml @@ -1,9 +1,11 @@ name = "bos-settings" description = "System settings app for Bread OS" binaries = ["bos-settings"] -system_deps = ["gtk4", "glib2"] +system_deps = ["gtk4", "glib2", "hicolor-icon-theme"] optional_system_deps = ["snapper"] bread_deps = [] +license_file = "LICENSE" +desktop_file = "bos-settings.desktop" [config] dir = "~/.config" diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD deleted file mode 100644 index 805df59..0000000 --- a/packaging/PKGBUILD +++ /dev/null @@ -1,38 +0,0 @@ -# Maintainer: Breadway - -pkgname=bos-settings -pkgver=0.1.0 -pkgrel=1 -pkgdesc="System settings app for Bread OS" -arch=('x86_64') -url="https://git.breadway.dev/Breadway/bos-settings" -license=('MIT') -# Some Rust deps (ring/mlua) build vendored C/asm into static archives; makepkg's -# default -flto=auto emits GCC LTO bitcode the Rust (lld) link cannot read, -# causing undefined-symbol errors. Disable LTO. -options=(!lto !debug) -depends=('gtk4' 'glib2' 'hicolor-icon-theme') -optdepends=( - 'snapper: snapshot management view' -) -makedepends=('rust' 'cargo') -source=("${pkgname}-${pkgver}.tar.gz") -sha256sums=('SKIP') - -build() { - cd "${srcdir}/${pkgname}-${pkgver}" - cargo build --release --locked -} - -check() { - cd "${srcdir}/${pkgname}-${pkgver}" - cargo test --release --locked -} - -package() { - cd "${srcdir}/${pkgname}-${pkgver}" - install -Dm755 target/release/bos-settings "${pkgdir}/usr/bin/bos-settings" - install -Dm644 packaging/bos-settings.desktop \ - "${pkgdir}/usr/share/applications/bos-settings.desktop" - install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" -} diff --git a/packaging/README.md b/packaging/README.md deleted file mode 100644 index af5acc0..0000000 --- a/packaging/README.md +++ /dev/null @@ -1,25 +0,0 @@ -Arch packaging -============== - -`PKGBUILD` builds and installs `bos-settings` from source. - -## Local build - -```bash -makepkg -si -``` - -## Before publishing to [breadway] repo - -1. Tag a release on GitHub. -2. Update `pkgver` to match the tag. -3. Update `source` to the release tarball URL. -4. Run `updpkgsums` (or manually set `sha256sums`). - -## Runtime dependencies - -| Package | Required | Notes | -|---------|----------|-------| -| `gtk4` | yes | UI toolkit | -| `glib2` | yes | always | -| `snapper` | optional | snapshot management view |