Skip to content
Merged
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: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,43 @@ jobs:
"Update the worked example AND docs/packaging-plugins.md together."
)
PY

# Every other job installs with `uv sync`, which uses uv.lock and the dev
# group. This one installs the built wheels with pip, as a user or the
# container image does, and runs one audit. It fails when darnit imports
# something it does not declare, or when a new release of a dependency
# breaks a fresh install. See #573.
non_dev_install_smoke:
name: Non-dev install smoke (wheels + one audit)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v5
with:
# 3.12 to match the container image (python:3.12-slim)
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v4
with:
version: ${{ env.UV_VERSION }}
enable-cache: true

- name: Build wheels
run: |
for package in darnit-mcp darnit-core darnit-baseline darnit-gittuf darnit-reproducibility; do
uv build --wheel --package "$package"
done

# The smallest set that can run a baseline audit. A sibling package can
# declare a dependency that core forgot, so the full install alone is
# not enough.
- name: Minimal install (core + baseline) and one audit
run: scripts/non-dev-install-smoke.sh dist darnit-core darnit-baseline

- name: Full install (everything darnit-mcp pulls in) and one audit
run: scripts/non-dev-install-smoke.sh dist
68 changes: 68 additions & 0 deletions scripts/non-dev-install-smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
#
# non-dev-install-smoke.sh - Install built wheels the way a user does, then run one audit
#
# Usage: scripts/non-dev-install-smoke.sh [dist-dir [package ...]]
#
# Installs the darnit wheels from dist-dir (default: dist) into a new virtual
# environment with pip: a fresh dependency resolve, no lockfile, no development
# dependencies. Then audits a throwaway repository and fails if the audit
# crashes, reports a dependency as "not installed", or passes no control.
#
# `uv sync` hides both kinds of breakage this catches: a dependency darnit
# imports without declaring it (the dev group supplies it), and a newly
# published release of a dependency that uv.lock pins away. See #573.
#
# With no package names it installs everything darnit-mcp pulls in. Pass a
# smaller set (darnit-core darnit-baseline) as well: a sibling package can
# declare a dependency that core forgot, which hides the gap in a full install.
#
# Requirements: python3 (with venv and pip), git, network access to PyPI.

set -euo pipefail

dist="${1:-dist}"
if [ $# -gt 1 ]; then
shift
packages=("$@")
else
packages=(darnit-mcp darnit-core darnit-baseline darnit-gittuf darnit-reproducibility)
fi

fail() { echo "FAIL: $*" >&2; exit 1; }

wheels=()
for name in "${packages[@]}"; do
matches=("$dist"/"${name//-/_}"-*.whl)
if [ ! -e "${matches[0]}" ]; then
fail "no $name wheel in $dist"
fi
wheels+=("${matches[0]}")
done

work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT

python3 -m venv "$work/venv"
"$work/venv/bin/pip" install --quiet --disable-pip-version-check "${wheels[@]}"

mkdir "$work/repo"
git -C "$work/repo" init -q
echo "# fixture" > "$work/repo/README.md"

out="$work/audit.txt"
status=0
"$work/venv/bin/darnit" -q audit --no-fail --framework openssf-baseline --tags level=1 "$work/repo" >"$out" 2>&1 || status=$?
cat "$out"

if [ "$status" -ne 0 ]; then
fail "darnit audit exited with status $status"
fi
if grep -q -E 'Traceback|not installed' "$out"; then
fail "the audit reported a crash or a dependency as not installed"
fi
if ! grep -q -E '^Total: .*\| Pass: [1-9]' "$out"; then
fail "no control passed; the expression-based controls should pass on a near-empty repository"
fi

echo "OK: the wheels install without dev dependencies and the audit runs"
Loading