14 Commits
Author SHA1 Message Date
Pierre Warnier 90faf4cc86 ci: reject AI tooling artifacts in pull requests (#219)
* ci: reject AI tooling artifacts in pull requests

The project's public face carries no AI tooling attribution, but nothing
enforced it: a session trailer reached a merged commit message and a pull
request body before anyone noticed.

Add a check that runs on pull requests and inspects only what the PR
changes — commit messages, PR title and body, added lines, and any
attempt to track the local-only guidance and review-export files that
are meant to stay gitignored. History is untouched and unrelated files
are not scanned. The clean-room audit records are exempt: they must
describe their own methodology to serve as compliance evidence.

Also drop the tooling credits from README and CHANGELOG.

* ci: fix base-ref fetch in the artifact check

`--depth=0` is rejected by git, and the extra fetch was redundant with
the full-history checkout. Fetch the base branch plainly and diff against
FETCH_HEAD.
2026-09-03 12:06:56 +02:00
Pierre Warnier a5c5e816ea ci: publish release binaries with dist (#207) (#216)
Releases carried no binaries (v0.2.1 shipped zero assets). Add dist
(formerly cargo-dist) 0.32.0 to build and upload them on tag push.

Scope: only the workspace root package is distributed, producing the
single shadow-rs multicall binary that provides all 14 tools via argv[0]
— the same layout as `make install-multicall`. The 14 per-tool crates
carry `dist = false` so a release is one archive per target rather than
fifteen. `[dist.binaries]` pins the archive to `shadow-rs`, keeping the
feature-gated `shadow-rs-completions` helper out of it.

Targets are glibc-only for now: shadow-core::crypt links crypt(3) via
`#[link(name = "crypt")]`, and the self-contained musl target provides
no libcrypt, so an x86_64-unknown-linux-musl cross-build fails at link
time. (Alpine CI passes only because it installs a system libcrypt.)
`[dist.dependencies.apt]` installs libcrypt-dev on the runner for the
same reason.

`[profile.dist]` inherits the hardened release profile, so published
binaries keep LTO, stripped symbols and panic = "abort".

README documents deploying the archive (symlinks + setuid) and why musl
is not published yet.

Verified locally: `dist plan` and `dist build --artifacts=local` produce
uu_shadow-x86_64-unknown-linux-gnu.tar.gz containing shadow-rs plus
README/CHANGELOG/LICENSE and a .sha256; the extracted binary reports
`shadow-rs (uutils shadow-rs) 0.2.1`.

Closes #207.

Claude-Session: https://claude.ai/code/session_011f42R6SMAfQXufTgdjSuhU
2026-09-03 11:54:24 +02:00
renovate[bot] eee120279b chore(deps): update actions/checkout action to v7 2026-06-19 08:21:09 +02:00
Pierre Warnier 8e9324652b ci: polish the image-build retry loop (#174)
Address review feedback on #173:
- Don't sleep after the final build attempt (no retry follows it).
- Forward the workflow-wide CARGO_NET_RETRY into the container with a
  bare '-e CARGO_NET_RETRY' instead of re-hardcoding the value, keeping
  a single source of truth.
2026-06-10 12:45:14 +02:00
Pierre Warnier 4ce4184e38 ci: make the Docker test matrix resilient to registry flakes (#172) (#173)
The Test (debian/alpine/fedora) matrix failed four times in a row on
2026-06-10, each on a transient network error (Docker Hub base-image
pull i/o timeout; crates.io download broken pipe) unrelated to the code.

- fail-fast: false so one distro's flake no longer cancels the others.
- Retry 'docker compose build <target>' (the Docker Hub pull) with backoff.
- Pass CARGO_NET_RETRY into the container and set it for runner-native
  jobs so cargo retries crate downloads; real test failures still fail
  fast (no step-level retry around the test run).

No new third-party actions — a shell retry loop keeps the supply-chain
surface unchanged.

Closes #172.
2026-06-10 12:42:33 +02:00
Pierre Warnier 4ecf63ec1f security: AT_EXECFN validation + audit.yml (#154, #155)
#154: Reject setuid multicall invocations where argv[0] doesn't match
AT_EXECFN from the ELF auxiliary vector. Prevents an attacker from
spoofing argv[0] to route the multicall binary to a different tool
in setuid context. Only enforced when euid != uid.

#155: Add daily cargo-audit workflow matching uutils/coreutils pattern.
Also triggers on Cargo.toml/Cargo.lock changes.

Fixes #154. Fixes #155.
2026-04-22 18:13:36 +02:00
renovate[bot] e7c628256e chore(deps): update actions/checkout action to v6 2026-04-22 13:36:46 +00:00
oech3 e684c218d0 ci.yml: switch to non-versioned URL 2026-04-15 20:37:28 +09:00
oech3 063d47c37e ci.yml: simplify by pre-install toolchain 2026-04-15 17:50:51 +09:00
Pierre Warnier fdb6d46a05 review: address 2 Copilot review comments
- Add homepage.workspace to root package (missing vs subcrates)
- Gate Docker test-docker job to push only (seccomp:unconfined
  and SYS_ADMIN are unsafe for untrusted PR contexts)
2026-04-03 15:01:26 +02:00
Pierre Warnier 5a457b8781 ci: add Docker multi-distro tests, renovate, rust-toolchain
- Add Docker test matrix (debian/alpine/fedora) to GitHub Actions CI
- Add renovate.json for automated dependency updates
- Add rust-toolchain.toml for contributor convenience
2026-04-03 14:45:43 +02:00
Pierre Warnier 83080f53dd CI: upgrade cargo-deny-action to v2 for edition 2024 support
The v1 action bundles an old Cargo that doesn't recognize edition 2024.
v2 uses the host toolchain, so we install stable Rust first.
2026-03-24 15:18:07 +01:00
Pierre Warnier 9e3faa966c address Copilot review: fix docs, feature-gate crypt, MSRV 1.94, CI msrv job 2026-03-24 14:43:38 +01:00
Pierre Warnier 896a4214b6 infra: uutils compliance — edition 2024, unsafe deny, dead_code deny
Fixes #79 — CODE_OF_CONDUCT.md (Contributor Covenant 2.1)
Fixes #80 — locales/en-US.ftl for all 14 tools
Fixes #81 — rust-version = "1.85.0" in workspace
Fixes #82 — edition 2024 (resolver 3, unsafe extern blocks)
Fixes #83 — GitHub Actions CI (fmt, clippy, test, cargo-deny)
Fixes #84 — .clippy.toml with MSRV and quality thresholds
Fixes #85 — deny.toml tightened (multiple-versions=deny)
Fixes #87 — panic=abort, codegen-units=1 in release profile
Fixes #89 — Makefile with install/uninstall/clean targets
Fixes #90 — workspace lints: cargo group, unused_qualifications

Key policy changes enforced by cargo:
- unsafe_code = "deny" workspace-wide. Only pam.rs and crypt.rs
  have #[allow(unsafe_code)] (C FFI boundaries).
- dead_code = "deny" workspace-wide. No unused code allowed.
- Edition 2024: set_var/remove_var are unsafe, so sanitize_env
  returns a Vec instead of mutating. Signal handler removed
  (was unsafe). localtime_r replaced with pure Rust calendar math.

456 tests, zero clippy warnings.
2026-03-24 14:30:22 +01:00