Repository navigation
135 lines (120 loc) · 5.47 KB
/
Copy pathci.yml
File metadata and controls
135 lines (120 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
name: ci
env:
WARM_TAG: sandbox-ci-warm:latest
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
static:
name: static (shellcheck + sync + JSON parse)
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- uses: actions/checkout@v4
# srt-settings.json is a vendored render of the srt-policy-packs
# generic-agent pack. Without this checkout the drift check SKIPs and
# a hand-edit of the policy would sail through CI unnoticed.
- uses: actions/checkout@v4
with:
repository: cheshirecode/srt-policy-packs
path: .srt-policy-packs
- name: Install shellcheck
run: sudo apt-get update -qq && sudo apt-get install -y shellcheck
- name: Run static suite
env:
SRT_POLICY_PACKS: ${{ github.workspace }}/.srt-policy-packs
run: ./tests/run.sh static
build-and-functional:
name: build + functional
runs-on: ubuntu-latest
timeout-minutes: 15
needs: static
steps:
- uses: actions/checkout@v4
# Identity-isolation principle: a CI runner must NEVER hold a real
# personal credential. The test harness uses literal fake-token
# strings to exercise the entrypoint's read-and-shred path. Unset
# any auth env that GitHub Actions injects by default so it can't
# leak into the container.
- name: Unset auth env for identity-isolation
run: |
echo "GITHUB_TOKEN=" >> "$GITHUB_ENV"
echo "GH_TOKEN=" >> "$GITHUB_ENV"
# bwrap inside the container needs userns + mount propagation; the
# Ubuntu 24.04 runner's apparmor blocks it by default (observed:
# "bwrap: Failed to make / slave: Permission denied"). Same sysctl
# the srt-policy-packs CI uses.
- name: allow unprivileged userns (Ubuntu 24.04 apparmor)
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
- uses: docker/setup-buildx-action@v3
# Build once with the GHA layer cache and hand the loaded image to
# tests/run.sh build via SANDBOX_PREBUILT_IMAGE (a classic `docker
# build` cannot see a buildx builder's cache, so warming alone would
# not help). The Dockerfile still fully builds (cached), and run.sh
# still runs its size budget against the tagged image.
- name: Build image via GHA layer cache
uses: docker/build-push-action@v6
with:
context: .
build-args: |
HOST_UID=1001
HOST_GID=1001
tags: ${{ env.WARM_TAG }}
load: true
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build image
env:
SANDBOX_PREBUILT_IMAGE: ${{ env.WARM_TAG }}
run: ./tests/run.sh build
- name: Functional tests
run: ./tests/run.sh functional
- name: Documented CI skips
run: |
echo "Skipped in CI (require interactive auth or platform):"
echo " - real gh auth login --with-token against api.github.com"
echo " - OrbStack-specific behavior (CI is Linux, no OrbStack)"
echo " - apt install package-discovery diff (slow, mirror-dependent)"
fresh-machine-emulation:
name: fresh-machine setup-from-scratch (Linux parity)
runs-on: ubuntu-latest
timeout-minutes: 15
needs: static
# Proves the reproducibility promise: a vanilla Linux runner with no
# pre-existing state can clone this repo + run bin/setup-from-scratch.sh
# + come up to a working sandbox. Exercises the no-host-credentials path
# that real macOS users don't hit (because their host has Claude Code +
# Codex), but a fork on Linux/WSL2 absolutely does.
steps:
- uses: actions/checkout@v4
- name: Unset auth env for identity-isolation
run: |
echo "GITHUB_TOKEN=" >> "$GITHUB_ENV"
echo "GH_TOKEN=" >> "$GITHUB_ENV"
- name: Confirm clean starting state (no host LLM creds, no prior sandbox)
run: |
test ! -f ~/.claude/.credentials.json && echo " OK no Anthropic creds"
test ! -f ~/.codex/auth.json && echo " OK no Codex creds"
docker volume ls --format '{{.Name}}' | grep -E '(toolchains|gh|claude|codex)$' || echo " OK no leftover named volumes"
- name: Run bin/setup-from-scratch.sh (--skip-smoke because gh auth is missing in CI)
# The full smoke requires `gh auth token` which CI doesn't have.
# We exercise stages 1-4 (prereqs, identity probe, LLM probe, build)
# which are the reproducibility-critical path. Stage 5 (interactive
# `up`) is the part real users run; CI verifies the build alone.
run: ./bin/setup-from-scratch.sh --skip-smoke
- name: Prove nuke leaves a true fresh state
run: |
# Need a require_token bypass for the nuke smoke; nuke doesn't
# need it, but sourcing mounts.env does require SANDBOX_LOGIN
# detection which works without gh on CI (falls back to $USER).
./bin/sandbox.sh nuke
docker image inspect "$(source mounts.env && echo $IMAGE_NAME:$IMAGE_TAG)" 2>&1 \
| grep -q "No such image" && echo " OK image removed by nuke"
docker volume ls --format '{{.Name}}' | grep -E '(toolchains|gh|claude|codex)$' \
&& echo " FAIL volumes survived nuke" && exit 1 \
|| echo " OK no named volumes after nuke"
- name: Re-run setup-from-scratch to confirm idempotency
run: ./bin/setup-from-scratch.sh --skip-smoke