Skip to content
Closed
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
61 changes: 61 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always

jobs:
checks:
name: checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: extractions/setup-just@v2

# Cache the build toolchain image as a portable tar archive.
# Podman's overlay storage can't be cached directly (tar fails
# on overlay whiteout files), so we round-trip through podman
# save/load. The cache key is the hash of build.Containerfile.
# The image is tagged with a short hash of the Containerfile so
# that build-image in the justfile recognizes it and skips the
# build.
- uses: actions/cache@v4
id: image-cache
with:
path: /tmp/mujina-build.tar
key: build-image-${{ hashFiles('build.Containerfile') }}

- name: Load cached build image
if: steps.image-cache.outputs.cache-hit == 'true'
run: podman load -i /tmp/mujina-build.tar

# Cache compiled dependencies to speed up builds. The key
# includes the toolchain (Containerfile) so a compiler bump
# invalidates stale artifacts. restore-keys lets a partial
# hit (new dependency added) still warm the cache.
- uses: actions/cache@v4
with:
path: target
key: cargo-target-${{ hashFiles('build.Containerfile') }}-${{ hashFiles('Cargo.lock') }}
restore-keys: |
cargo-target-${{ hashFiles('build.Containerfile') }}-

- run: just ci

# Prune project crate artifacts before the cache saves,
# keeping only compiled dependencies.
- name: Prune project artifacts from target cache
run: |
find target -name 'mujina*' -delete 2>/dev/null || true
find target -name 'libmujina*' -delete 2>/dev/null || true

- name: Save build image for cache
if: steps.image-cache.outputs.cache-hit != 'true'
run: |
TAG=$(sha256sum build.Containerfile | cut -c1-12)
podman save -o /tmp/mujina-build.tar "mujina-build:$TAG"
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = ["mujina-miner", "tools/mujina-dissect"]
resolver = "2"

[workspace.package]
# When bumping the compiler version, also update build.Containerfile.
edition = "2024"
license = "GPL-3.0-or-later"
authors = ["Ryan Kuester <rkuester@insymbols.com>"]
Expand Down
21 changes: 21 additions & 0 deletions build.Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Build toolchain image for running checks in a reproducible environment.
#
# The Rust compiler and just are pinned to exact versions. The base
# image is pinned by digest. Apt packages come from the Debian
# bookworm repos bundled in the base image; their exact versions can
# drift across builds but are stable system libraries that don't
# affect build output.

FROM docker.io/library/rust:1.94-bookworm@sha256:b2fe2c0f26e0e1759752b6b2eb93b119d30a80b91304f5b18069b31ea73eaee8

# These are pinned to the exact toolchain release by the base image digest.
RUN rustup component add rustfmt clippy

RUN apt-get update && apt-get install -y --no-install-recommends \
libudev-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*

RUN cargo install just --version 1.40.0

WORKDIR /workspace
24 changes: 24 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ test:
run:
cargo run --bin mujina-minerd

BUILD_IMAGE := "mujina-build"
BUILD_TAG := `sha256sum build.Containerfile | cut -c1-12`

# Build the build toolchain image (skips if unchanged)
[group('container')]
build-image:
podman image exists {{BUILD_IMAGE}}:{{BUILD_TAG}} || \
podman build -t {{BUILD_IMAGE}}:{{BUILD_TAG}} -f build.Containerfile .

# Run a just recipe inside the build toolchain image
[group('container')]
in-container *args: build-image
podman run --rm \
-v "$(pwd)":/workspace:Z \
-v mujina-cargo-registry:/usr/local/cargo/registry \
-v mujina-cargo-git:/usr/local/cargo/git \
-w /workspace \
{{BUILD_IMAGE}}:{{BUILD_TAG}} \
just {{args}}

# The CI pipeline. This is what GitHub Actions runs.
[group('ci')]
ci: (in-container "checks")

[group('container')]
container-build tag=`git rev-parse --abbrev-ref HEAD`:
podman build -t mujina-minerd:{{tag}} -f Containerfile .
Expand Down