From 29222a1a0ffb5e898374eef021016f6e63d668ee Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 1 Nov 2025 11:51:51 -0400 Subject: [PATCH] Add build+test infra mirroring bootc This introduces a Justfile and Dockerfile to enable building rpm-ostree from source in a container, following the pattern established in the bootc project. See the `Justfile` for key entrypoints. Those are now used in a new GHA flow, which we'll try to move things over to. A key difference though vs bootc is because rpm-ostree has a lot of C++ too we use sccache which greatly speeds things up across incremental rebuilds. Just one side cleanup of this is before it was *terribly* painful and manual to hack on `test-container.sh`, and now it's easy, fast and optimized. Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: Colin Walters --- .copr/Makefile | 2 +- .dockerignore | 57 +++++++++++- .github/workflows/container-build.yml | 58 ++++++++++++ Cargo.toml | 25 ++++++ Dockerfile | 123 ++++++++++++++++++++++++++ Justfile | 46 ++++++++++ ci/integration-runtime.txt | 4 + ci/packages-build-extra.txt | 8 ++ ci/test-container.sh | 11 --- packaging/.dockerignore | 5 ++ packaging/Containerfile | 61 +++++++++++++ packaging/Makefile.dist-packaging | 8 ++ 12 files changed, 393 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/container-build.yml create mode 100644 Dockerfile create mode 100644 Justfile create mode 100644 ci/integration-runtime.txt create mode 100644 ci/packages-build-extra.txt create mode 100644 packaging/.dockerignore create mode 100644 packaging/Containerfile diff --git a/.copr/Makefile b/.copr/Makefile index 8c748918..bc73ef7b 100644 --- a/.copr/Makefile +++ b/.copr/Makefile @@ -5,7 +5,7 @@ srpm: # if we have a git repo with remotes, fetch tags so `git describe` gives a nice NEVRA when # building the RPM if git remote | grep origin; then git fetch origin --tags; fi - git submodule update --init --recursive + if [ -d .git ]; then git submodule update --init --recursive; fi # Our primary CI build goes via RPM rather than direct to binaries # to better test that path, including our vendored spec file, etc. make -C packaging -f Makefile.dist-packaging srpm diff --git a/.dockerignore b/.dockerignore index 25085f8e..b1cc17a0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,54 @@ -.cosa -target -compose-cache/ +# Exclude everything by default, then include just what we need +# Especially note this means that .git is not included, and not tests/ +# to avoid spurious rebuilds. +* + +# Autotools build files +!Makefile*.am +!Makefile-*.am +!Makefile*.inc +!Makefile.bindings +!configure.ac +!autogen.sh + +# Generated C++/Rust bridge files (checked into git) +!rpmostree-cxxrs.h +!rpmostree-cxxrs.cxx +!rpmostree-cxxrsutil.hpp + +# Build configuration +!buildutil/ +!build-aux/ +!m4/ + +# Source code +!src/ +!rust/ + +# Rust build files +!Cargo.toml +!Cargo.lock +!build.rs +!.cargo/ + +# Git submodules (needed by autogen.sh) +!libglnx/ +!libdnf/ + +# Build system integration +!packaging/ +!ci/ +!.copr/ + +# Test data for integration tests +!tests/ + +# Documentation (for man pages, etc.) +!docs/ +!man/ + +# Shell completion +!completion/ + +# API documentation generation +!api-doc/ diff --git a/.github/workflows/container-build.yml b/.github/workflows/container-build.yml new file mode 100644 index 00000000..79999f5d --- /dev/null +++ b/.github/workflows/container-build.yml @@ -0,0 +1,58 @@ +# Container Build CI Workflow +# +# Builds rpm-ostree from source in a container using the Dockerfile and Justfile. +# This workflow follows the pattern established in bootc for containerized builds. +name: Container Build + +permissions: + actions: read + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: {} + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + # Build container and run basic validation + build-and-validate: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + base_image: + - name: fedora-42 + image: quay.io/fedora/fedora-bootc:42 + # TODO: Enable CentOS Stream 10 once tests support it + # - name: centos-10 + # image: quay.io/centos-bootc/centos-bootc:stream10 + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + submodules: true + + - name: Bootc Ubuntu Setup + uses: ./.github/actions/bootc-ubuntu-setup + + - name: Run validation + run: | + just validate + + - name: Build container + run: | + set -xeuo pipefail + just build --build-arg=base=${{ matrix.base_image.image }} + + - name: Run container integration tests + run: | + just test-container-integration diff --git a/Cargo.toml b/Cargo.toml index cdd10969..f4172770 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,3 +134,28 @@ bin-unit-tests = [] sanitizers = [] default = [] + +[lints] +workspace = true + +[workspace.lints.rust] +# Absolutely must handle errors +unused_must_use = "forbid" +missing_debug_implementations = "deny" +# Feel free to comment this one out locally during development of a patch. +dead_code = "deny" + +# We aren't using these yet +# [workspace.lints.rust] +# unsafe_code = "deny" +# missing_docs = "deny" + +[workspace.lints.clippy] +disallowed_methods = "deny" +# These should only be in local code +dbg_macro = "deny" +todo = "deny" +# These two are in my experience the lints which are most likely +# to trigger, and among the least valuable to fix. +needless_borrow = "allow" +needless_borrows_for_generic_args = "allow" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..10ad7e78 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,123 @@ +# Build this project from source and write the updated content +# (i.e. /usr/bin/rpm-ostree and related binaries) to a new derived container +# image. See the `Justfile` for an example +# +# Use e.g. --build-arg=base=quay.io/centos-bootc/centos-bootc:stream10 to target +# CentOS instead. + +ARG base=quay.io/fedora/fedora-bootc:42 + +# This first image captures a snapshot of the source code, +# note all the exclusions in .dockerignore. +FROM scratch as src +COPY . /src + +# This is basically a no-op now, but we could make any other final tweaks we want +# here. +FROM $base as base + +# Fetch sccache +FROM base as sccache +ARG SCCACHE_VERSION=0.8.2 +# Install sccache for compiler caching +RUN < /etc/rpm/macros +RUN make -f Makefile.dist-packaging rpm + +# Extract RPMs to /out for easy access +RUN mkdir -p /out && cp -v *.rpm x86_64/*.rpm /out/ + +FROM scratch +COPY --from=build /out/ / diff --git a/packaging/Makefile.dist-packaging b/packaging/Makefile.dist-packaging index 6a90e23b..1b465f8d 100644 --- a/packaging/Makefile.dist-packaging +++ b/packaging/Makefile.dist-packaging @@ -1,8 +1,16 @@ # -*- mode: Makefile -*- +# Handle builds both with and without a git repository +ifeq ($(shell test -d ../.git && echo yes),yes) GITREV = $$(git describe --always --tags) GITREV_FOR_PKG = $(shell echo "$(GITREV)" | sed -e 's,-,\.,g' -e 's,^v,,') GITTIMESTAMP = $$(git show --no-patch --format=%ci) +else +# Fallback when no git repo is available +GITREV = unknown +GITREV_FOR_PKG = 9999.0.0 +GITTIMESTAMP = $(shell date -u +"%Y-%m-%d %H:%M:%S %z") +endif srcdir=$(shell dirname `pwd`) PACKAGE=rpm-ostree