Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
target
13 changes: 13 additions & 0 deletions .github/ci/Dockerfile.build-deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Pre-baked build environment for the package_ourself CI job: debmagic's base
# tooling plus this repo's Build-Depends, so the in-container
# `apt-get build-dep` only tops up archive drift. Rebuilt whenever
# debian/control, this file, or the weekly freshness bucket changes
# (see the tag key in .github/workflows/ci.yaml).
ARG BASE_IMAGE
FROM ${BASE_IMAGE}
WORKDIR /src
COPY debian /src/debian
RUN apt-get update \
&& apt-get install -y dpkg-dev python3 \
&& apt-get -y build-dep . \
&& rm -rf /var/lib/apt/lists/*
56 changes: 43 additions & 13 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,55 @@ jobs:
# integration / self packaging tests
package_ourself:
runs-on: ubuntu-latest
permissions:
contents: read
# Push of the pre-built CI image is additionally gated to main below.
packages: write
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
with:
enable-cache: true
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Install debmagic (cli)
run: uv pip install packages/debmagic
- name: Cache the debmagic build tree
uses: actions/cache@v4
with:
path: /tmp/debmagic
key: debmagic-build-${{ hashFiles('Cargo.lock', 'debian/changelog', 'debian/control', 'debian/rules') }}
restore-keys: debmagic-build-
- name: Prune stale build trees from the restored cache
run: |
mkdir -p /tmp/debmagic
current="$(head -n1 debian/changelog | sed 's/^\([^ ]*\) (\([^)]*\)).*/\1-\2/')"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uuh

find /tmp/debmagic -mindepth 1 -maxdepth 1 -type d ! -name "$current" -exec rm -rf {} +
- name: Resolve CI image tag
id: image
run: |
codename="$(sed -n 's/^[^(]*([^)]*) \([^;]*\);.*/\1/p' debian/changelog | head -n1)"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could use the proper changelog reading tool dpkg-parsechangelog

key="$(cat debian/control .github/ci/Dockerfile.build-deps | sha256sum | cut -c1-12)-$(date -u +%G-W%V)"
echo "tag=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/debmagic-ci:${codename}-${key}" >> "$GITHUB_OUTPUT"
echo "codename=${codename}" >> "$GITHUB_OUTPUT"
- name: Pull or build the CI image
run: |
if ! docker pull "${{ steps.image.outputs.tag }}"; then
docker build \
--build-arg "BASE_IMAGE=docker.io/debian:${{ steps.image.outputs.codename }}" \
--tag "${{ steps.image.outputs.tag }}" \
--file .github/ci/Dockerfile.build-deps \
.
echo "image_built=true" >> "$GITHUB_ENV"
fi
- name: Run Debmagic build on ourself
run: uv run debmagic build binary --driver=docker
run: |
cargo run --locked -p debmagic -- build binary \
--driver=docker \
--persistent \
--incremental \
--driver-docker-base-image="${{ steps.image.outputs.tag }}"
- name: Push the CI image
if: github.ref == 'refs/heads/main' && env.image_built == 'true'
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.actor }}" --password-stdin
docker push "${{ steps.image.outputs.tag }}"

# TODO: integration tests currently don't work in the CI since they require running apt source on debian trixie -> CI runs on ubuntu
# integration-tests:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/push_on_main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ on:

jobs:
ci:
permissions:
contents: read
# package_ourself pushes the pre-built CI image to ghcr.io on main.
packages: write
uses: ./.github/workflows/ci.yaml
secrets: inherit
2 changes: 2 additions & 0 deletions docs/usage/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ debmagic build binary --driver lxd --persistent \
Use `--incremental` to retain the environment and synchronize only source changes while preserving generated files and unchanged source inodes.
This flag implies `--persistent`, and cannot be combined with `--clean yes`.

The preserved build tree is kept even when the environment itself is *not* reused (e.g. a fresh CI runner where the tree was restored from a cache).


## Selecting a distro/release

Expand Down
10 changes: 6 additions & 4 deletions packages/debmagic/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,16 @@ fn prepare_build_env(
// container-owned files the host user can't remove.
let build = Build::create(&build_config, &config.driver, driver_overrides)
.context(format!("failed to create {:?} build driver", driver_type))?;
if !config.incremental
|| !source_manifest_path(&build_config).is_file()
|| !build.driver.reused_environment()
{
if !config.incremental || !source_manifest_path(&build_config).is_file() {
build
.driver
.reset_build_root()
.context("failed to reset persistent build directory")?;
} else if !build.driver.reused_environment() {
// A fresh environment (e.g. a new CI runner with a restored build
// tree) keeps incremental outputs; cargo's own fingerprinting
// discards whatever the new toolchain/archive state invalidates.
println!("Keeping incremental build tree in a fresh build environment");
}
build_config
.create_dirs()
Expand Down
Loading