Linux: let the shared makepkg job build the Arch package (#2322)

package.sh built its own Arch package with nfpm while the shared release
workflow also built one with makepkg, because has-arch defaults to true. Both
wrote designcraft-<version>-linux-<arch>.pkg.tar.zst, the draft release merges
the release-* artifacts last-writer-wins, and 0.17.0 shipped the nfpm copy,
which declared fewer dependencies than the makepkg template.

Drop arch from the formats this script builds and remove the archlinux section
from nfpm.yaml, so the shared action is the single builder. It names the
package after the .desktop bundle id, declares the same provides/conflicts
against the AUR packages, and adds the optdepends nfpm could not express.
This commit is contained in:
Dylan M. Taylor authored and GitHub committed 2026-11-04 14:46:58 -05:00
1 parent f3bcc886dc
commit ef6c368615
2 files changed
+23 -62

No files matched your search

+2 -21
View File
@@ -1,6 +1,6 @@
# .deb/.rpm/Arch packages (nfpm: https://nfpm.goreleaser.com). Run by package.sh, which stages
# .deb/.rpm packages (nfpm: https://nfpm.goreleaser.com). Run by package.sh, which stages
# the file tree, substitutes its path for ${STAGE} (nfpm doesn't expand env vars in `src`) and
# exports VERSION and NFPM_ARCH.
# exports VERSION and NFPM_ARCH. The Arch package is built by the release workflow's makepkg job.
#
# nfpm package -f packaging/linux/nfpm.yaml -p deb -t dist/release/
name: designcraft
@@ -63,25 +63,6 @@ overrides:
- libXrandr
- mesa-vulkan-drivers
- xdg-desktop-portal
# Named ai.storyteller.designcraft, not designcraft: the AUR already has designcraft, designcraft-bin and
# designcraft-git, and an AUR helper treats any installed package with an AUR name as its own and
# rebuilds it on the next update. ArtCraft Launcher also uses the bundle id to tell this package
# (which it updates with `pacman -U`) from an AUR build (which it leaves to the AUR helper).
# nfpm has no optdepends for Arch, so the recommends above have no equivalent here.
archlinux:
depends:
- glibc
- gcc-libs
- hicolor-icon-theme
- libxkbcommon
- libxkbcommon-x11
- vulkan-icd-loader
provides:
- designcraft
conflicts:
- designcraft
- designcraft-bin
- designcraft-git
contents:
- src: ${STAGE}/usr/bin/designcraft
+21 -41
View File
@@ -5,12 +5,17 @@
# $DIST/designcraft-<version>-linux-<arch>.AppImage.zsync delta updates (needs zsyncmake)
# $DIST/designcraft-<version>-linux-<arch>.deb Debian, Ubuntu, Mint, Pop!_OS, ...
# $DIST/designcraft-<version>-linux-<arch>.rpm Fedora, openSUSE, RHEL, ...
# $DIST/designcraft-<version>-linux-<arch>.pkg.tar.zst Arch, Manjaro, EndeavourOS, ...
# $DIST/designcraft-<version>-linux-<arch>.tar.gz plain FHS-style tree (bin/, share/)
#
# Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm arch tar"]
# The Arch package (.pkg.tar.zst) is not built here. The release workflow builds it with
# craft-common-actions/actions/arch-package from this script's tarball, which names it after the
# .desktop bundle id (ai.storyteller.designcraft, not designcraft, so an AUR helper does not claim
# it) and declares provides/conflicts against the AUR packages. Building a second one here under
# the same asset name is what made the published package depend on upload order.
#
# Needs: cargo; nfpm for deb/rpm/arch (https://nfpm.goreleaser.com); appimagetool for the AppImage
# Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"]
#
# Needs: cargo; nfpm for deb/rpm (https://nfpm.goreleaser.com); appimagetool for the AppImage
# (downloaded into $CARGO_TARGET_DIR if missing). Build on an old distro (CI: Ubuntu 22.04,
# glibc 2.35) so the binaries run on newer ones. Optional: desktop-file-validate, appstreamcli,
# zsyncmake (the zsync package) for the AppImage's .zsync.
@@ -21,7 +26,7 @@ HERE="$ROOT/packaging/linux"
APP_ID=ai.storyteller.designcraft
SKIP_BUILD=0
FORMATS="appimage deb rpm arch tar"
FORMATS="appimage deb rpm tar"
while [[ $# -gt 0 ]]; do
case "$1" in
--skip-build) SKIP_BUILD=1; shift ;;
@@ -43,6 +48,16 @@ BASENAME="designcraft-$VERSION-linux-$ARCH"
echo "==> DesignCraft $VERSION for Linux $ARCH ($FORMATS)"
has() {
local fmt="$1"
case " $FORMATS " in *" $fmt "*) return 0 ;; *) return 1 ;; esac
}
if has arch; then
echo "error: the Arch package is built by the release workflow's makepkg job, not by this script" >&2
exit 2
fi
if [[ "$SKIP_BUILD" = 0 ]]; then
if [[ -n "${CROSS_TARGET:-}" ]]; then
(cd "$ROOT" && cargo build --release --locked -p designcraft -p designcraft-cli --target "$CROSS_TARGET")
@@ -77,11 +92,6 @@ if command -v appstreamcli >/dev/null; then
appstreamcli validate --no-net --explain "$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml"
fi
has() {
local fmt="$1"
case " $FORMATS " in *" $fmt "*) return 0 ;; *) return 1 ;; esac
}
# ---- .tar.gz ------------------------------------------------------------------------------------
if has tar; then
mkdir -p "$WORK/tar"
@@ -90,8 +100,8 @@ if has tar; then
echo "wrote $DIST/$BASENAME.tar.gz"
fi
# ---- .deb / .rpm / .pkg.tar.zst -----------------------------------------------------------------
if has deb || has rpm || has arch; then
# ---- .deb / .rpm --------------------------------------------------------------------------------
if has deb || has rpm; then
command -v nfpm >/dev/null || { echo "error: nfpm not found (https://nfpm.goreleaser.com/install/)" >&2; exit 1; }
export VERSION
export NFPM_ARCH="$DEB_ARCH"
@@ -100,36 +110,6 @@ if has deb || has rpm || has arch; then
for fmt in deb rpm; do
if has "$fmt"; then (cd "$ROOT" && nfpm package -f "$WORK/nfpm.yaml" -p "$fmt" -t "$DIST/$BASENAME.$fmt"); fi
done
# The Arch package is named by the bundle id (see `archlinux` in nfpm.yaml), which nfpm can't
# override per format, and `archlinux.packager` isn't env-expanded, so both are written here.
if has arch; then
sed "s|^name: designcraft\$|name: $APP_ID|" "$WORK/nfpm.yaml" >"$WORK/nfpm-arch.yaml"
grep -qx "name: $APP_ID" "$WORK/nfpm-arch.yaml" || { echo "error: couldn't rename the Arch package" >&2; exit 1; }
printf 'archlinux:\n packager: "%s"\n' "$DESIGNCRAFT_MAINTAINER" >>"$WORK/nfpm-arch.yaml"
# nfpm (2.47, 2.48) writes Go's directory bit into the mode of each directory a `type: tree`
# entry walks (0o20000000755), and pacman then warns "directory permissions differ" on every
# shared directory under /usr/share. List the tree's files one by one instead: nfpm gives their
# parent directories a plain 0755.
if find "$STAGE/usr/share" ! -type d ! -type f | grep -q .; then
echo "error: only plain files can be listed in the Arch package's usr/share" >&2; exit 1
fi
find "$STAGE/usr/share" -type f | LC_ALL=C sort | while IFS= read -r f; do
printf ' - src: "%s"\n dst: "%s"\n' "$f" "${f#"$STAGE"}"
done >"$WORK/arch-share.yaml"
awk -v files="$WORK/arch-share.yaml" -v tree=" - src: $STAGE/usr/share/" '
$0 == tree { while ((getline line < files) > 0) print line; skip = 2; next }
skip > 0 { skip--; next }
{ print }
' "$WORK/nfpm-arch.yaml" >"$WORK/nfpm-arch.yaml.new"
mv "$WORK/nfpm-arch.yaml.new" "$WORK/nfpm-arch.yaml"
if grep -q 'type: tree' "$WORK/nfpm-arch.yaml"; then
echo "error: couldn't list the Arch package's files" >&2; exit 1
fi
# Without a fixed time nfpm stamps the files and .MTREE a moment apart, and `pacman -Qkk`
# reports every file as modified. The commit time also makes the package reproducible.
epoch="${SOURCE_DATE_EPOCH:-$(git -C "$ROOT" log -1 --format=%ct 2>/dev/null || date +%s)}"
(cd "$ROOT" && SOURCE_DATE_EPOCH="$epoch" nfpm package -f "$WORK/nfpm-arch.yaml" -p archlinux -t "$DIST/$BASENAME.pkg.tar.zst")
fi
fi
# ---- AppImage -----------------------------------------------------------------------------------