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
40 changes: 25 additions & 15 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
name: CI

permissions:
actions: read
contents: read

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

# don't waste job slots on superseded code
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
CI: 1
RUSTUP_MAX_RETRIES: 10
RUST_BACKTRACE: short

jobs:
semver-checks:
Expand All @@ -27,14 +28,27 @@ jobs:
# Pinned until cargo-semver-checks supports rustdoc format v57 (Rust 1.93+)
rust-toolchain: "1.92.0"

linting:
name: Lints
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Rust
uses: bootc-dev/actions/setup-rust@main
- name: Install tools
uses: taiki-e/install-action@v2
with:
tool: just
- name: Install rustfmt and clippy
run: rustup component add rustfmt clippy
- name: just lint
run: just lint

build-test:
name: Build+Test
runs-on: ubuntu-latest
container: quay.io/coreos-assembler/fcos-buildroot:testing-devel
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -43,16 +57,12 @@ jobs:
fetch-depth: 20
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2
- name: cargo fmt (check)
run: cargo fmt -- --check -l
- name: Compile (no features)
run: cargo test --no-run
- name: Compile (all features)
run: cargo test --no-run --all-features
- name: Test
run: cargo test --all-features -- --nocapture --quiet
- name: cargo clippy (non-gating)
run: cargo clippy
- name: Checkout ostree-rs-ext
uses: actions/checkout@v6
with:
Expand Down
19 changes: 19 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,22 @@ tempfile = "3.20.0"

[lib]
path = "src/imageproxy.rs"

# Synchronized with https://github.com/bootc-dev/bootc/blob/main/Cargo.toml
[lints.rust]
# Require an extra opt-in for unsafe
unsafe_code = "deny"
# 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"

[lints.clippy]
# 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"
33 changes: 33 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Build everything
build:
cargo build --all-targets --all-features

# Run all tests using nextest
test:
#!/bin/bash
set -euo pipefail
if command -v cargo-nextest &>/dev/null; then
cargo nextest run --all-features
else
cargo test --all-targets --all-features
fi
# https://github.com/rust-lang/cargo/issues/6669
cargo test --doc --all-features

# Check formatting
fmt-check:
cargo fmt -- --check -l

# Run clippy
clippy:
cargo clippy --all-targets --all-features -- -D warnings

# Full lint check (formatting + clippy), mirrors CI
lint: fmt-check clippy

# Run semver checks against the last published version
semver-check:
cargo semver-checks

# Lint and test (used by CI, and for local development)
ci: lint test
10 changes: 5 additions & 5 deletions examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct Metadata {
}

impl CommonOpts {
fn to_config(self) -> ImageProxyConfig {
fn into_config(self) -> ImageProxyConfig {
let mut r = ImageProxyConfig::default();
if self.debug {
r.debug = true;
Expand All @@ -81,7 +81,7 @@ impl CommonOpts {
}

async fn get_metadata(o: GetMetadataOpts) -> Result<()> {
let config = o.common.to_config();
let config = o.common.into_config();
let proxy = containers_image_proxy::ImageProxy::new_with_config(config).await?;
let img = proxy.open_image(&o.reference).await?;
let (digest, manifest) = proxy.fetch_manifest(&img).await?;
Expand All @@ -91,7 +91,7 @@ async fn get_metadata(o: GetMetadataOpts) -> Result<()> {
}

async fn get_blob(o: GetBlobOpts) -> Result<()> {
let config = o.common.to_config();
let config = o.common.into_config();
let proxy = containers_image_proxy::ImageProxy::new_with_config(config).await?;
let img = proxy.open_image(&o.reference).await?;
let (mut blob, driver) = proxy.get_blob(&img, &o.digest, o.size).await?;
Expand All @@ -115,7 +115,7 @@ async fn get_blob(o: GetBlobOpts) -> Result<()> {
}

async fn get_blob_raw(o: GetBlobOpts) -> Result<()> {
let config = o.common.to_config();
let config = o.common.into_config();
let proxy = containers_image_proxy::ImageProxy::new_with_config(config).await?;
let img = proxy.open_image(&o.reference).await?;
let (_, mut datafd, err) = proxy.get_raw_blob(&img, &o.digest).await?;
Expand All @@ -139,7 +139,7 @@ async fn get_blob_raw(o: GetBlobOpts) -> Result<()> {
}

async fn fetch_container_to_devnull(o: FetchContainerToDevNullOpts) -> Result<()> {
let config = o.metaopts.common.to_config();
let config = o.metaopts.common.into_config();
let proxy = containers_image_proxy::ImageProxy::new_with_config(config).await?;
let img = &proxy.open_image(&o.metaopts.reference).await?;
let manifest = proxy.fetch_manifest(img).await?.1;
Expand Down
2 changes: 2 additions & 0 deletions src/imageproxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ impl TryFrom<ImageProxyConfig> for Command {
// By default, we set up pdeathsig to "lifecycle bind" the child process to us.
let mut c = config.skopeo_cmd.unwrap_or_else(|| {
let mut c = std::process::Command::new("skopeo");
// SAFETY: set_parent_process_death_signal is async-signal-safe
#[allow(unsafe_code)]
unsafe {
c.pre_exec(|| {
Ok(rustix::process::set_parent_process_death_signal(Some(
Expand Down
Loading