🏡 index : quine-global/app-build.git

# app-build

A 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: each
   natively on its own runner (runner-x86-linux, runner-arm64-linux), from
   a 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, another
architecture) lands in every app at once.

## Using it

In the app's repo, `.forgejo/workflows/rpm.yml`:

```yaml
name: RPM

on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: rpm-${{ github.ref }}
  cancel-in-progress: true

jobs:
  rpm:
    strategy:
      matrix:
        include:
          - arch: amd64
            runner: runner-x86-linux
          - arch: arm64
            runner: runner-arm64-linux
    runs-on: ${{ matrix.runner }}
    steps:
      - uses: https://forge.in.quineglobal.com/quine-global-labs/mirror-actions-checkout@v4
        with:
          fetch-depth: 0
      - uses: https://forge.in.quineglobal.com/quine-global/app-build@v1
        with:
          name: swap-watchdog
          kind: go
          archs: ${{ matrix.arch }}
          go-packages: ./cmd/swap-watchdog ./cmd/force-quit-gui
          dnf-packages: gtk3-devel
          registry-username: ${{ vars.REGISTRY_USER || github.actor }}
          registry-password: ${{ secrets.REGISTRY_TOKEN }}
```

`fetch-depth: 0` isn't needed for the build, but the release number uses
the 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 there
instead 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 (an
input renamed, the spec contract) gets `v2`.