Skip to content

Commit a2e2277

Browse files
authored
Fix COPR SRPM build: embed both arch tarballs in the SRPM (#20)
v0.1.5's custom-publish-copr job failed at the "Build SRPM" step with: error: Bad file: /home/runner/rpmbuild/SOURCES/quicknode-cli-x86_64- unknown-linux-gnu.tar.xz.sha256: No such file or directory Root cause: `rpmbuild -bs` needs Source files to exist locally in ~/rpmbuild/SOURCES/ to build the SRPM, even when the spec declares them as URLs. The "URLs get fetched at build time" model only kicks in when COPR's mock runs the SRPM, not when the SRPM is initially assembled. There was a second latent bug: the spec used %ifarch to template a single Source URL based on the build host's arch. The runner is x86_64, so the SRPM would have only embedded the x86_64 tarball, and COPR's aarch64 mock builds would have failed for the opposite reason. Both fixed by switching to a single architecture-fat SRPM: * packaging/qn-bin.spec — drops the %ifarch URL templating, drops the curl + sha256 dance in %prep. Declares both arch tarballs as Source0 (x86_64) + Source1 (aarch64). %prep uses %ifarch with %setup -T -b N to extract the right embedded source for the chroot's arch. rpm itself sha256-verifies embedded sources at extract time (sha256s live in the SRPM header), so we don't need to redo it in %prep. * .github/workflows/publish-copr.yml — adds a step that uses gh release download to pull both arch tarballs into SOURCES/ before invoking `rpmbuild -bs`. The SRPM ends up carrying both tarballs (~8 MB) and ships once to COPR. Drops --enable-net=on from `copr-cli build`: now that the SRPM embeds the sources, mock chroots don't need network. The COPR project's "enable net" setting still applies if we ever do need it; this flag was just a per-build override. Single SRPM, single copr-cli dispatch, all chroots build from the same source set. The binary in the resulting RPMs stays bit-identical to what ships everywhere else. v0.1.5 already shipped to crates.io, GHCR, .deb, and the GitHub Release — only COPR was missed. v0.1.6 (next release) will exercise this fix and backfill COPR.
1 parent 3c97c75 commit a2e2277

2 files changed

Lines changed: 42 additions & 47 deletions

File tree

.github/workflows/publish-copr.yml

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ name: Publish RPMs to COPR
1010
# RPM is bit-identical to the one in crates.io, Homebrew, GHCR, .deb,
1111
# and AUR.
1212
#
13-
# `copr-cli build --enable-net=on` is required because the spec's
14-
# %prep stage fetches the tarball over HTTPS from the GitHub Release.
13+
# The SRPM embeds both Linux gnu tarballs (x86_64 + aarch64), so
14+
# COPR's mock chroots can build without network access.
1515
on:
1616
workflow_call:
1717
inputs:
@@ -51,15 +51,27 @@ jobs:
5151
- name: Build SRPM
5252
env:
5353
QN_VERSION: ${{ steps.meta.outputs.version }}
54+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5455
run: |
5556
# Set up the rpmbuild tree.
5657
mkdir -p "$HOME/rpmbuild"/{SOURCES,SPECS,SRPMS}
5758
cp packaging/qn-bin.spec "$HOME/rpmbuild/SPECS/qn-bin.spec"
5859
59-
# SRPM only has the spec — the sources are fetched by mock at
60-
# %prep time (Source0/Source1 are URLs, not local files). We
61-
# pass --nodeps so rpmbuild doesn't try to satisfy
62-
# BuildRequires on the runner; COPR's mock handles that.
60+
# Pre-download both arch tarballs into SOURCES/ — rpmbuild -bs
61+
# needs the actual files present locally to embed them in the
62+
# SRPM, even though the spec's Source0/Source1 are URLs. The
63+
# resulting SRPM carries both tarballs; %prep picks one based
64+
# on the chroot's arch.
65+
cd "$HOME/rpmbuild/SOURCES"
66+
gh release download "v$QN_VERSION" \
67+
--repo quicknode/cli \
68+
--pattern "quicknode-cli-x86_64-unknown-linux-gnu.tar.xz" \
69+
--pattern "quicknode-cli-aarch64-unknown-linux-gnu.tar.xz"
70+
ls -la
71+
cd "$GITHUB_WORKSPACE"
72+
73+
# --nodeps so rpmbuild doesn't try to satisfy BuildRequires on
74+
# the runner; COPR's mock chroot handles that for the real build.
6375
rpmbuild -bs "$HOME/rpmbuild/SPECS/qn-bin.spec" \
6476
--define "_topdir $HOME/rpmbuild" \
6577
--define "qn_version $QN_VERSION" \
@@ -107,6 +119,7 @@ jobs:
107119
exit 1
108120
fi
109121
echo "Uploading $srpm to quicknode/qn..."
110-
# --enable-net=on so COPR's mock chroot can curl the prebuilt
111-
# tarball + sha256 sidecar from the GitHub Release in %prep.
112-
copr-cli build quicknode/qn "$srpm" --enable-net=on
122+
# No --enable-net=on needed: the SRPM already embeds both
123+
# arch tarballs (rpmbuild verifies them at extract time via
124+
# the sha256 baked into the SRPM header).
125+
copr-cli build quicknode/qn "$srpm"

packaging/qn-bin.spec

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
# qn-bin: install the SLSA-attested binary cargo-dist ships, no rebuild.
22
#
3-
# This spec is built on COPR's mock chroots. `%prep` downloads the per-arch
4-
# linux-gnu tarball from the GitHub Release and verifies it against the
5-
# .sha256 sidecar; `%install` lays the binary + docs into the buildroot.
6-
# No Rust toolchain involved on the COPR side — the binary inside the
7-
# resulting RPM is bit-identical to what ships in crates.io,
8-
# Homebrew, .deb, and the GHCR image.
3+
# This spec is built on COPR's mock chroots. The SRPM embeds both Linux
4+
# gnu tarballs (x86_64 + aarch64) cargo-dist published for this release;
5+
# %prep selects the right one for the chroot's arch and %install lays
6+
# the binary + docs into the buildroot. No Rust toolchain involved on
7+
# the COPR side — the binary inside the resulting RPM is bit-identical
8+
# to what ships in crates.io, Homebrew, .deb, AUR, and the GHCR image.
99
#
10-
# Built and uploaded by .github/workflows/publish-copr.yml on each release.
11-
# Requires --enable-net=on at build time (mock fetches the tarball).
12-
13-
%global qn_version %{getenv:QN_VERSION}
14-
15-
%if "%{qn_version}" == ""
16-
%{error: QN_VERSION must be set when building this spec (e.g. rpmbuild --define "qn_version 0.1.4")}
17-
%endif
10+
# Built by .github/workflows/publish-copr.yml on each release. That
11+
# workflow pre-downloads both arch tarballs into ~/rpmbuild/SOURCES/
12+
# before invoking `rpmbuild -bs`, so the resulting SRPM carries the
13+
# sources and COPR's mock can build with --enable-net=off if desired.
1814

1915
Name: qn
2016
Version: %{qn_version}
@@ -23,18 +19,10 @@ Summary: Command-line interface for the Quicknode SDK
2319
License: MIT
2420
URL: https://github.com/quicknode/cli
2521

26-
# cargo-dist emits separate tarballs per Rust target triple. We map COPR's
27-
# arch tokens to those triples; the per-arch Source entry below picks the
28-
# right one at build time.
29-
%ifarch x86_64
30-
%global rust_target x86_64-unknown-linux-gnu
31-
%endif
32-
%ifarch aarch64
33-
%global rust_target aarch64-unknown-linux-gnu
34-
%endif
35-
36-
Source0: https://github.com/quicknode/cli/releases/download/v%{version}/quicknode-cli-%{rust_target}.tar.xz
37-
Source1: https://github.com/quicknode/cli/releases/download/v%{version}/quicknode-cli-%{rust_target}.tar.xz.sha256
22+
# Both arch tarballs ship in the SRPM. %prep picks one based on the
23+
# chroot's arch.
24+
Source0: https://github.com/quicknode/cli/releases/download/v%{version}/quicknode-cli-x86_64-unknown-linux-gnu.tar.xz
25+
Source1: https://github.com/quicknode/cli/releases/download/v%{version}/quicknode-cli-aarch64-unknown-linux-gnu.tar.xz
3826

3927
ExclusiveArch: x86_64 aarch64
4028
BuildRequires: coreutils
@@ -51,18 +39,12 @@ the same SLSA-attested artifact that ships in crates.io, Homebrew, the
5139
GHCR Docker image, the AUR qn-bin package, and Debian .deb files.
5240

5341
%prep
54-
# Verify the tarball matches the sha256 sidecar from the release.
55-
# The sidecar's format is `<hex> *<filename>`; rewrite the filename to
56-
# point at the local SOURCES path so `sha256sum -c` works.
57-
expected_hash=$(awk '{print $1}' < %{SOURCE1})
58-
actual_hash=$(sha256sum %{SOURCE0} | awk '{print $1}')
59-
if [ "$expected_hash" != "$actual_hash" ]; then
60-
echo "Error: sha256 mismatch for %{SOURCE0}" >&2
61-
echo " expected: $expected_hash" >&2
62-
echo " actual: $actual_hash" >&2
63-
exit 1
64-
fi
65-
%setup -q -n quicknode-cli-%{rust_target}
42+
%ifarch x86_64
43+
%setup -q -T -b 0 -n quicknode-cli-x86_64-unknown-linux-gnu
44+
%endif
45+
%ifarch aarch64
46+
%setup -q -T -b 1 -n quicknode-cli-aarch64-unknown-linux-gnu
47+
%endif
6648

6749
%install
6850
install -Dm755 qn %{buildroot}%{_bindir}/qn

0 commit comments

Comments
 (0)