# app-buildA Forgejo action for our in-house apps (layer-wizard, dnf-package-store,swap-watchdog, …): on every push to an app's `main`,1. build it as an RPM for **x86_64 and aarch64**, packaged by the app's own`packaging/<name>.spec`, in a Fedora container per architecture: eachnatively on its own runner (runner-x86-linux, runner-arm64-linux), froma matrix in the app's workflow;2. upload the RPMs to the forge's `quine` RPM group,https://forge.in.quineglobal.com/api/packages/quine-global-labs/rpm/quine,which quine-linux's image installs them from.The build itself lives here, so a fix (a new Flutter release, anotherarchitecture) lands in every app at once.## Using itIn the app's repo, `.forgejo/workflows/rpm.yml`:```yamlname: RPMon:push:branches: [main]workflow_dispatch:concurrency:group: rpm-${{ github.ref }}cancel-in-progress: truejobs:rpm:strategy:matrix:include:- arch: amd64runner: runner-x86-linux- arch: arm64runner: runner-arm64-linuxruns-on: ${{ matrix.runner }}steps:- uses: https://forge.in.quineglobal.com/quine-global-labs/mirror-actions-checkout@v4with:fetch-depth: 0- uses: https://forge.in.quineglobal.com/quine-global/app-build@v1with:name: swap-watchdogkind: goarchs: ${{ matrix.arch }}go-packages: ./cmd/swap-watchdog ./cmd/force-quit-guidnf-packages: gtk3-develregistry-username: ${{ vars.REGISTRY_USER || github.actor }}registry-password: ${{ secrets.REGISTRY_TOKEN }}````fetch-depth: 0` isn't needed for the build, but the release number usesthe commit's short hash.Inputs (action.yml has them all):| Input | ||---|---|| `name` | Package name; the spec is `packaging/<name>.spec` || `kind` | `flutter` or `go` || `go-packages` | Go only: packages built into `bin/` || `dnf-packages` | Extra Fedora packages for the build (e.g. `gtk3-devel` for cgo GTK) || `archs` | What to build here; default `amd64 arm64`, both on one runner (the other one under QEMU emulation, slow). With the matrix above, each job builds its runner's own || `fedora` | Default `44` |## What the spec gets`rpmbuild` defines `version_`, `release_` (`<UTC timestamp>.git<hash>`) and`srcdir` (the checkout). Specs install from what the build left thereinstead of building in `%build`:- **go:** the binaries in `%{srcdir}/bin/`; version `0`.- **flutter:** `%{bundle}`, the release bundle(`build/linux/<x64|arm64>/release/bundle`); the version is`pubspec.yaml`'s.The spec needs `ExclusiveArch: x86_64 aarch64` (or whatever `archs` builds).## Versions`@v1` follows compatible changes; a change that needs apps to change (aninput renamed, the spec contract) gets `v2`.