Fix CI: bootstrap the full Slackware build toolchain via slackpkg
Build Packages / Build .txz packages (push) Failing after 41s
Lint / ShellCheck (push) Successful in 11s
Lint / Validate .plg XML (push) Successful in 11s
Lint / EditorConfig (push) Successful in 5s

The build-packages.yml run was failing for two compounding reasons,
found by testing directly against vbatts/slackware:15.0 on the actual
runner host:

1. The image ships neither git nor its HTTPS runtime libs, so
   actions/checkout failed immediately.
2. It's a minimal rootfs with none of the 'D' (development) series —
   no gcc, make, autoconf, pkg-config, curl, glib2, libcap, or fuse3 —
   contrary to setup-slackware-buildenv.sh's assumption that a "full"
   Slackware install already provides these.

An earlier fix attempt hand-pinned git + its deps (nghttp2, brotli,
cyrus-sasl) by exact file + SHA256 from the base 15.0 release
directory. That drifted out of sync with the newer, patched curl
slackpkg installs later in the same container — same shared library,
two different builds, causing a runtime symbol lookup error. Both
steps now resolve every package through slackpkg's own prioritized
mirror instead, keeping the whole toolchain on one mutually consistent
version set. Verified end-to-end (git ls-remote and curl both succeed
over HTTPS against the real Gitea instance, full toolchain present)
in a fresh vbatts/slackware:15.0 container.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 14:11:29 +00:00
co-authored by Claude Sonnet 5
parent f56704a7fb
commit acb9fb704b
2 changed files with 69 additions and 46 deletions
+30 -38
View File
@@ -47,26 +47,21 @@ on:
# base image. See scripts/ci/setup-slackware-buildenv.sh for how missing # base image. See scripts/ci/setup-slackware-buildenv.sh for how missing
# build dependencies are bootstrapped on top of whatever this image ships. # build dependencies are bootstrapped on top of whatever this image ships.
# #
# vbatts/slackware:15.0 ships tar but NOT git (needed by actions/checkout) # vbatts/slackware:15.0 ships tar but NOT git (needed by actions/checkout),
# or any of git's runtime dependencies. The "Install git" step below pulls # nor any of the shared libraries git's HTTPS transport needs. The
# git and its missing shared libraries from Slackware's own official # "Install git" step below uses slackpkg (already present and pre-
# package mirror, pinned by exact filename + verified SHA256, before # configured with a mirror in this image) rather than hand-picking package
# actions/checkout runs — see that step for the full dependency chain # files: git's HTTPS support pulls in nghttp2/brotli/cyrus-sasl, and
# (found by trial: git needs libnghttp2, which needs nothing extra, but # hand-pinning those separately from the base 15.0 release directory (as
# git also dlopens libbrotlidec and libsasl2 for HTTPS transport). # an earlier version of this step did) silently drifted out of sync with
# the newer, patched curl that scripts/ci/setup-slackware-buildenv.sh
# installs later in the same container — same library, two different
# builds, resulting in a symbol lookup error at runtime. Letting slackpkg
# resolve everything from the same prioritized repo set (patches over
# main, see /etc/slackpkg/slackpkg.conf's PRIORITY) keeps every package on
# this image on a mutually consistent version set.
env: env:
SLACKWARE_IMAGE: "vbatts/slackware:15.0" SLACKWARE_IMAGE: "vbatts/slackware:15.0"
SLACKWARE_MIRROR: "http://slackware.osuosl.org/slackware64-15.0/slackware64"
GIT_PKG: "d/git-2.35.1-x86_64-1.txz"
GIT_PKG_SHA256: "502a8e921c13a3e89fa121d26e6e376bd927b05e5a2d1039c1bf815ab6ec535d"
CA_CERTIFICATES_PKG: "n/ca-certificates-20211216-noarch-1.txz"
CA_CERTIFICATES_PKG_SHA256: "e26e8e1371dd5f4f53978cef0449542e7e56b26d1813dcbc546159b551939a91"
NGHTTP2_PKG: "n/nghttp2-1.46.0-x86_64-1.txz"
NGHTTP2_PKG_SHA256: "cad5c7b38ae424b3f44b707637623f740da45a1d1f9938933dc472f931d2bddc"
BROTLI_PKG: "l/brotli-1.0.9-x86_64-7.txz"
BROTLI_PKG_SHA256: "f20e995cce0cf5c4f2575f94e87978e6e5f7d3923e847e3bca814e7c324bd474"
CYRUS_SASL_PKG: "n/cyrus-sasl-2.1.27-x86_64-7.txz"
CYRUS_SASL_PKG_SHA256: "b613130758ec952b8585e03f5174c924bc8bfc6d90aa6c53e7e73a30c6801b68"
jobs: jobs:
build: build:
@@ -82,31 +77,28 @@ jobs:
set -eu set -eu
command -v tar > /dev/null || (echo "!! base image is missing tar — see SLACKWARE_IMAGE in this workflow" && exit 1) command -v tar > /dev/null || (echo "!! base image is missing tar — see SLACKWARE_IMAGE in this workflow" && exit 1)
cd /tmp # CHECKGPG is turned off: slackpkg's default GPG-key bootstrap
for pkg in "$CA_CERTIFICATES_PKG" "$NGHTTP2_PKG" "$BROTLI_PKG" "$CYRUS_SASL_PKG" "$GIT_PKG"; do # fetches Slackware's signing key from www.slackware.com, which
wget -q --tries=3 "$SLACKWARE_MIRROR/$pkg" # is not reachable from every CI network (observed to hang on
done # this project's self-hosted Gitea Actions runner). CHECKMD5
echo "${CA_CERTIFICATES_PKG_SHA256} $(basename "$CA_CERTIFICATES_PKG")" | sha256sum -c - # (on by default) still verifies every package against the
echo "${NGHTTP2_PKG_SHA256} $(basename "$NGHTTP2_PKG")" | sha256sum -c - # mirror's own CHECKSUMS.md5 as a transit-integrity check.
echo "${BROTLI_PKG_SHA256} $(basename "$BROTLI_PKG")" | sha256sum -c - sed -i 's/^CHECKGPG=on/CHECKGPG=off/' /etc/slackpkg/slackpkg.conf
echo "${CYRUS_SASL_PKG_SHA256} $(basename "$CYRUS_SASL_PKG")" | sha256sum -c - slackpkg -batch=on -default_answer=y update
echo "${GIT_PKG_SHA256} $(basename "$GIT_PKG")" | sha256sum -c - # git and curl's HTTPS transport need nghttp2/brotli/cyrus-sasl at
# runtime, but slackpkg does not resolve shared-library
# installpkg has no dependency resolver (unlike slackpkg) — install # dependencies (Slackware packages carry no such metadata) — list
# git's runtime libs first, then git itself. # them explicitly so they come from the same slackpkg pass (and
installpkg "$(basename "$CA_CERTIFICATES_PKG")" # therefore the same mutually-consistent build) as git itself.
installpkg "$(basename "$NGHTTP2_PKG")" slackpkg -batch=on -default_answer=y install \
installpkg "$(basename "$BROTLI_PKG")" git ca-certificates nghttp2 brotli cyrus-sasl
installpkg "$(basename "$CYRUS_SASL_PKG")"
installpkg "$(basename "$GIT_PKG")"
# ca-certificates ships individual certs under # ca-certificates ships individual certs under
# /usr/share/ca-certificates/ — this builds the combined bundle # /usr/share/ca-certificates/ — this builds the combined bundle
# git needs to actually trust HTTPS remotes (without it, cloning # git (and later, curl) need to actually trust HTTPS remotes.
# from a Gitea instance over HTTPS fails cert verification even
# though the certs are installed).
update-ca-certificates update-ca-certificates
echo "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt" >> "$GITHUB_ENV" echo "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt" >> "$GITHUB_ENV"
echo "CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt" >> "$GITHUB_ENV"
git --version git --version
+39 -8
View File
@@ -5,14 +5,22 @@
# Prepares a Slackware container (see .github/workflows/build-packages.yml) # Prepares a Slackware container (see .github/workflows/build-packages.yml)
# to build all seven packages under packages/. Idempotent and safe to re-run. # to build all seven packages under packages/. Idempotent and safe to re-run.
# #
# Strategy: detect what's already present (a stock "full" Slackware 15.0 # Strategy: vbatts/slackware:15.0 (the image build-packages.yml runs this
# install already provides gcc/make/autotools/glib2/libcap/fuse3) and only # in) is a minimal rootfs — it ships none of the 'D' (development) series,
# bootstrap what's genuinely missing (libseccomp, yajl — neither ships in # nor glib2/libcap/fuse3/curl. Step 0 below uses slackpkg (already present
# stock Slackware — plus the Go and Rust toolchains, which no Slackware # and pre-configured with a mirror in that image) to install the toolchain
# install ships). This makes the script tolerant of small differences # packages by name. Slackware packages carry no dependency metadata at all
# between Slackware base image variants instead of assuming one exact image # (unlike apt/dnf), so slackpkg does NOT resolve dependencies — the list
# layout, while still failing loudly if something we cannot self-provision # below must name every package explicitly, including curl's HTTPS
# (a C compiler, basically) is missing. # runtime libs (nghttp2, brotli, cyrus-sasl), or you get a shared-library
# error at the first invocation, not an install-time failure. What's left
# after this (libseccomp, yajl — neither ships in stock Slackware — plus
# the Go and Rust toolchains, which no Slackware install ships) is
# bootstrapped from source, further down. This makes the script tolerant
# of small differences between Slackware base image variants (it skips
# anything slackpkg reports as already installed) instead of assuming one
# exact image layout, while still failing loudly if something we cannot
# self-provision is missing.
# #
# Exits non-zero with a clear message if a required tool cannot be found or # Exits non-zero with a clear message if a required tool cannot be found or
# provisioned — this script is meant to run early in CI so failures surface # provisioned — this script is meant to run early in CI so failures surface
@@ -49,6 +57,29 @@ require_pkgconfig() {
return 0 return 0
} }
# -----------------------------------------------------------------------------
# 0. Bootstrap the Slackware toolchain packages via slackpkg, if missing.
#
# CHECKGPG is turned off here: slackpkg's default GPG-key bootstrap fetches
# Slackware's signing key from www.slackware.com, which is not reachable
# from every CI network (observed to hang/fail on the self-hosted Gitea
# Actions runner this project builds on). slackpkg's CHECKMD5 (on by
# default) still verifies every package against the mirror's own
# CHECKSUMS.md5 as a transit-integrity check. This is build-toolchain
# provisioning, not the shipped artifacts — those are independently
# checksummed by scripts/checksums.sh.
# -----------------------------------------------------------------------------
if command -v slackpkg > /dev/null 2>&1; then
echo "==> bootstrapping build toolchain via slackpkg"
sed -i 's/^CHECKGPG=on/CHECKGPG=off/' /etc/slackpkg/slackpkg.conf
slackpkg -batch=on -default_answer=y update
slackpkg -batch=on -default_answer=y install \
gcc gcc-g++ binutils make m4 perl autoconf automake libtool pkg-config \
curl nghttp2 brotli cyrus-sasl ca-certificates glib2 libcap fuse3
else
echo "==> slackpkg not found, assuming toolchain is already provided by the base image"
fi
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# 1. Baseline toolchain expected to already be present in the base image. # 1. Baseline toolchain expected to already be present in the base image.
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------