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
159 changes: 156 additions & 3 deletions .github/workflows/pipboy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ jobs:
contents: read
outputs:
base: ${{ steps.changes.outputs.base }}
base_history: ${{ steps.changes.outputs.base_history }}
footprint: ${{ steps.changes.outputs.footprint }}
tool: ${{ steps.changes.outputs.tool }}
rust: ${{ steps.changes.outputs.rust }}
native: ${{ steps.changes.outputs.native }}
native_matrix: ${{ steps.changes.outputs.native_matrix }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
Expand All @@ -37,14 +41,41 @@ jobs:
env:
EVENT: ${{ github.event_name }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PUSH_BEFORE: ${{ github.event.before }}
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
# The binaries the release ships, one build per target as in release.yaml.
# `linux` builds on any Rust change; the rest build on platform-specific
# changes or the `ci: native-all` label, which is read on the next push.
NATIVE_ALL: >-
[
{"target":"x86_64-unknown-linux-musl","platform":"linux-x64","runner":"depot-ubuntu-24.04-8","ext":"","tier":"linux"},
{"target":"aarch64-unknown-linux-musl","platform":"linux-arm64","runner":"depot-ubuntu-24.04-arm-8","ext":"","tier":"all"},
{"target":"x86_64-apple-darwin","platform":"darwin-x64","runner":"depot-ubuntu-24.04-8","ext":"","tier":"all"},
{"target":"aarch64-apple-darwin","platform":"darwin-arm64","runner":"depot-ubuntu-24.04-8","ext":"","tier":"all"},
{"target":"x86_64-pc-windows-gnu","platform":"win32-x64","runner":"depot-ubuntu-24.04-8","ext":".exe","tier":"all"}
]
run: |
RUST='^(sandbox-agent/(.*\.rs|(.*/)?Cargo\.(toml|lock)|deny\.toml|docker/release/.*)$|scripts/pipboy/|\.github/workflows/pipboy\.yml$)'
PLATFORM_SENSITIVE='^sandbox-agent/((.*/)?Cargo\.(toml|lock)|(.*/)?build\.rs|docker/release/.*)$'
matrix() { jq -c --arg tier "$1" 'map(select($tier == "all" or .tier == $tier))' <<< "$NATIVE_ALL"; }

if [ "$EVENT" != "pull_request" ]; then
# Pushes to main record baselines. Natives build only when Rust changed,
# and then for every platform. Hygiene stores no baseline, so it skips main.
echo "footprint=true" >> "$GITHUB_OUTPUT"
echo "tool=true" >> "$GITHUB_OUTPUT"
echo "rust=false" >> "$GITHUB_OUTPUT"
native=none
if ! files="$(git diff --name-only "$PUSH_BEFORE" HEAD 2>/dev/null)" || grep -qE "$RUST" <<< "$files"; then
native=all
fi
echo "native=$native" >> "$GITHUB_OUTPUT"
echo "native_matrix=$(matrix "$native")" >> "$GITHUB_OUTPUT"
exit 0
fi
base="$(git merge-base "$PR_BASE_SHA" HEAD)"
echo "base=$base" >> "$GITHUB_OUTPUT"
echo "base_history=$(git rev-list --first-parent -n 200 "$base" | paste -sd, -)" >> "$GITHUB_OUTPUT"
files="$(git diff --name-only "$base" HEAD)"
footprint=false
if grep -qE '^(packages/|sandbox-agent/sdks/|(sandbox-agent/)?pnpm-(lock|workspace)\.yaml|scripts/pipboy/|\.github/workflows/pipboy\.yml)' <<< "$files"; then
Expand All @@ -56,6 +87,20 @@ jobs:
tool=true
fi
echo "tool=$tool" >> "$GITHUB_OUTPUT"
rust=false
native=none
if grep -qE "$RUST" <<< "$files"; then
rust=true
native=linux
if grep -qE "$PLATFORM_SENSITIVE" <<< "$files" \
|| git diff -U0 "$base" HEAD -- 'sandbox-agent/*.rs' | grep -qE '^\+.*(cfg\(target_|target_os|target_arch)' \
|| jq -e 'index("ci: native-all")' <<< "$LABELS" > /dev/null; then
native=all
fi
fi
echo "rust=$rust" >> "$GITHUB_OUTPUT"
echo "native=$native" >> "$GITHUB_OUTPUT"
echo "native_matrix=$(matrix "$native")" >> "$GITHUB_OUTPUT"

self-test:
name: self-test
Expand Down Expand Up @@ -157,15 +202,119 @@ jobs:
if-no-files-found: ignore
retention-days: 30

hygiene:
name: hygiene
needs: changes
if: needs.changes.outputs.rust == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
fetch-depth: 0
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
sandbox-agent/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile --filter 'pipboy...'
- uses: taiki-e/install-action@8cca0918f8471c33515202b73f56ab27f2bed283 # v2.87.29
with:
tool: cargo-deny@0.20.2,cargo-shear@1.14.0
# cargo deny reads every crate's manifest; caching the registry skips the downloads.
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
key: cargo-registry-${{ hashFiles('sandbox-agent/Cargo.lock') }}
restore-keys: cargo-registry-
- name: Check out the base
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ needs.changes.outputs.base }}
run: git worktree add "$RUNNER_TEMP/base-src" "$BASE_SHA"
- name: Diff findings
env:
EVENT: ${{ github.event_name }}
run: |
mkdir -p "$RUNNER_TEMP/reports"
base=()
if [ "$EVENT" = "pull_request" ]; then base=(--base-root "$RUNNER_TEMP/base-src"); fi
pnpm --silent --filter pipboy pipboy hygiene "${base[@]}" --out "$RUNNER_TEMP/reports/hygiene.json"
- if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: report-hygiene
path: ${{ runner.temp }}/reports/hygiene.json
if-no-files-found: ignore
retention-days: 30

native:
name: native · ${{ matrix.platform }}
needs: changes
if: needs.changes.outputs.native != 'none'
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.changes.outputs.native_matrix) }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
# The release's own build script and Dockerfiles, so the size is what ships.
- name: Build with the release script
working-directory: sandbox-agent
env:
TARGET: ${{ matrix.target }}
run: docker/release/build.sh "$TARGET"
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
# No pnpm cache: this job runs fork code on a Depot runner and doesn't need one.
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
- run: pnpm install --frozen-lockfile --filter 'pipboy...'
- name: Measure
env:
TARGET: ${{ matrix.target }}
PLATFORM: ${{ matrix.platform }}
EXT: ${{ matrix.ext }}
run: |
mkdir -p "$RUNNER_TEMP/reports"
for binary in sandbox-agent gigacode; do
pnpm --silent --filter pipboy pipboy native --target "$binary" --platform "$PLATFORM" \
--artifact "$GITHUB_WORKSPACE/sandbox-agent/dist/$binary-$TARGET$EXT" --out "$RUNNER_TEMP/reports/native-$binary-$PLATFORM.json"
done
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: report-native-sandbox-agent-${{ matrix.platform }}
path: ${{ runner.temp }}/reports/native-sandbox-agent-${{ matrix.platform }}.json
retention-days: 90
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: report-native-gigacode-${{ matrix.platform }}
path: ${{ runner.temp }}/reports/native-gigacode-${{ matrix.platform }}.json
retention-days: 90

report:
name: report
needs: [changes, footprint]
needs: [changes, footprint, hygiene, native]
# Not `always()`: a run cancelled by a newer push must not post its partial results.
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
actions: read # job timings and report artifacts
actions: read # job timings, report artifacts, and native baselines from main
pull-requests: write # the one Pip-Boy comment
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
Expand All @@ -188,12 +337,16 @@ jobs:
- name: Write the comment and run summary
env:
GITHUB_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ github.token }}
# Empty for pushes and fork PRs: they get the run summary only.
PR_NUMBER: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.number || '' }}
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
BASE_HISTORY: ${{ needs.changes.outputs.base_history }}
# Each check job's result, so a failed job is reported as failed, not skipped.
JOB_RESULTS: ${{ toJSON(needs) }}
run: pnpm --silent --filter pipboy pipboy report --reports "$RUNNER_TEMP/reports"
run: |
pnpm --silent --filter pipboy pipboy report --reports "$RUNNER_TEMP/reports" \
--base-history "$BASE_HISTORY"

zizmor:
name: zizmor
Expand Down
24 changes: 24 additions & 0 deletions sandbox-agent/deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# cargo-deny configuration. The Pip-Boy hygiene check runs it on every PR
# that changes Rust and fails only on findings the PR adds.

[licenses]
# The same allow-list as rivet-dev/rivet.
allow = [
"Apache-2.0",
"0BSD",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"MIT",
"MPL-2.0",
"CC0-1.0",
"Unicode-3.0",
"Zlib",
"EPL-2.0",
"Unlicense",
# Boost Software License, not Business Source License (ryu).
"BSL-1.0",
# Mozilla's CA root list (webpki-roots).
"CDLA-Permissive-2.0",
]
unused-allowed-license = "allow"
Loading
Loading