diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 9f223c3..be39523 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -47,26 +47,21 @@ on: # base image. See scripts/ci/setup-slackware-buildenv.sh for how missing # build dependencies are bootstrapped on top of whatever this image ships. # -# 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 -# git and its missing shared libraries from Slackware's own official -# package mirror, pinned by exact filename + verified SHA256, before -# actions/checkout runs — see that step for the full dependency chain -# (found by trial: git needs libnghttp2, which needs nothing extra, but -# git also dlopens libbrotlidec and libsasl2 for HTTPS transport). +# vbatts/slackware:15.0 ships tar but NOT git (needed by actions/checkout), +# nor any of the shared libraries git's HTTPS transport needs. The +# "Install git" step below uses slackpkg (already present and pre- +# configured with a mirror in this image) rather than hand-picking package +# files: git's HTTPS support pulls in nghttp2/brotli/cyrus-sasl, and +# hand-pinning those separately from the base 15.0 release directory (as +# 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: 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: build: @@ -82,31 +77,28 @@ jobs: set -eu command -v tar > /dev/null || (echo "!! base image is missing tar — see SLACKWARE_IMAGE in this workflow" && exit 1) - cd /tmp - for pkg in "$CA_CERTIFICATES_PKG" "$NGHTTP2_PKG" "$BROTLI_PKG" "$CYRUS_SASL_PKG" "$GIT_PKG"; do - wget -q --tries=3 "$SLACKWARE_MIRROR/$pkg" - done - echo "${CA_CERTIFICATES_PKG_SHA256} $(basename "$CA_CERTIFICATES_PKG")" | sha256sum -c - - echo "${NGHTTP2_PKG_SHA256} $(basename "$NGHTTP2_PKG")" | sha256sum -c - - echo "${BROTLI_PKG_SHA256} $(basename "$BROTLI_PKG")" | sha256sum -c - - echo "${CYRUS_SASL_PKG_SHA256} $(basename "$CYRUS_SASL_PKG")" | sha256sum -c - - echo "${GIT_PKG_SHA256} $(basename "$GIT_PKG")" | sha256sum -c - - - # installpkg has no dependency resolver (unlike slackpkg) — install - # git's runtime libs first, then git itself. - installpkg "$(basename "$CA_CERTIFICATES_PKG")" - installpkg "$(basename "$NGHTTP2_PKG")" - installpkg "$(basename "$BROTLI_PKG")" - installpkg "$(basename "$CYRUS_SASL_PKG")" - installpkg "$(basename "$GIT_PKG")" + # CHECKGPG is turned off: 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 on + # this project's self-hosted Gitea Actions runner). CHECKMD5 + # (on by default) still verifies every package against the + # mirror's own CHECKSUMS.md5 as a transit-integrity check. + sed -i 's/^CHECKGPG=on/CHECKGPG=off/' /etc/slackpkg/slackpkg.conf + slackpkg -batch=on -default_answer=y update + # git and curl's HTTPS transport need nghttp2/brotli/cyrus-sasl at + # runtime, but slackpkg does not resolve shared-library + # dependencies (Slackware packages carry no such metadata) — list + # them explicitly so they come from the same slackpkg pass (and + # therefore the same mutually-consistent build) as git itself. + slackpkg -batch=on -default_answer=y install \ + git ca-certificates nghttp2 brotli cyrus-sasl # ca-certificates ships individual certs under # /usr/share/ca-certificates/ — this builds the combined bundle - # git needs to actually trust HTTPS remotes (without it, cloning - # from a Gitea instance over HTTPS fails cert verification even - # though the certs are installed). + # git (and later, curl) need to actually trust HTTPS remotes. update-ca-certificates 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 diff --git a/scripts/ci/setup-slackware-buildenv.sh b/scripts/ci/setup-slackware-buildenv.sh index f3da58c..e989c83 100755 --- a/scripts/ci/setup-slackware-buildenv.sh +++ b/scripts/ci/setup-slackware-buildenv.sh @@ -5,14 +5,22 @@ # Prepares a Slackware container (see .github/workflows/build-packages.yml) # 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 -# install already provides gcc/make/autotools/glib2/libcap/fuse3) and only -# bootstrap what's genuinely missing (libseccomp, yajl — neither ships in -# stock Slackware — plus the Go and Rust toolchains, which no Slackware -# install ships). This makes the script tolerant of small differences -# between Slackware base image variants instead of assuming one exact image -# layout, while still failing loudly if something we cannot self-provision -# (a C compiler, basically) is missing. +# Strategy: vbatts/slackware:15.0 (the image build-packages.yml runs this +# in) is a minimal rootfs — it ships none of the 'D' (development) series, +# nor glib2/libcap/fuse3/curl. Step 0 below uses slackpkg (already present +# and pre-configured with a mirror in that image) to install the toolchain +# packages by name. Slackware packages carry no dependency metadata at all +# (unlike apt/dnf), so slackpkg does NOT resolve dependencies — the list +# below must name every package explicitly, including curl's HTTPS +# 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 # provisioned — this script is meant to run early in CI so failures surface @@ -49,6 +57,29 @@ require_pkgconfig() { 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. # -----------------------------------------------------------------------------