~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

7
74 lines · 3.7 KB Raw History
# The scenario tracks (harness/scenarios.mjs): agents doing a day's git
# work through the MCP server. Each run costs model usage, so this never
# runs on a push or a pull, only when the owner asks for it by name:
#
#   knotless rerun knotless://chadtmiller.com/knotless --ref refs/heads/main \
#     --workflow scenarios [-e TRACKS="team solo"] [-e SCENARIO_MODEL=...]
#
# TRACKS names the tracks, all of them but `ci` by default: its runner
# needs Docker, which a run's container does not have. The report is the
# end of the log; the check passes whatever the agents tripped on, and
# fails only when the tracks could not run.
#
# The agents are Claude Code sessions, on whichever credentials the
# runner's secrets file on the host grants main: ANTHROPIC_API_KEY (the
# API), CLAUDE_CODE_OAUTH_TOKEN (a subscription, from `claude
# setup-token`), or OPENROUTER_API_KEY, which goes through OpenRouter
# instead and is used first when granted. SCENARIO_MODEL picks the model,
# through OpenRouter any it has (-e SCENARIO_MODEL=openai/gpt-5), though
# Claude Code is made for Anthropic's.
image: rust:1.98
on:
  asked: {refs: [refs/heads/main]}
secrets: [ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, OPENROUTER_API_KEY]
cache: [target, /usr/local/cargo/registry, /usr/local/rustup, /opt/node, /opt/atproto, harness/node_modules]
env:
  TRACKS: contribution mentions moderation owners private review revert solo team
  # As test.yml's, for the tracks that need the spaces alpha.
  ATPROTO_COMMIT: 11c5d98cd50261c5e1201fedc5c6c05a7b8d1ccf
  ALPHA_BUILD: "2"
steps:
  - uses: chadtmiller.com/steps/node@1
    with: {version: 24.22.1}
  - name: claude
    run: |
      export PATH=/opt/node/bin:$PATH
      [ -x /opt/node/bin/claude ] || npm install -g --no-audit --no-fund @anthropic-ai/claude-code
      claude --version
  - uses: chadtmiller.com/steps/npm-ci@1
    name: harness
    with: {dir: harness, omit: dev}
  - name: spaces alpha
    run: |
      case " $TRACKS " in *" private "*) ;; *) exit 0 ;; esac
      [ "$(cat /opt/atproto/.built 2>/dev/null)" = "$ATPROTO_COMMIT $ALPHA_BUILD" ] && exit 0
      export PATH=/opt/node/bin:$PATH COREPACK_ENABLE_DOWNLOAD_PROMPT=0 COREPACK_HOME=/opt/atproto/.corepack
      find /opt/atproto -mindepth 1 -delete
      cd /opt/atproto
      git init -q . && git fetch -q --depth 1 https://github.com/bluesky-social/atproto.git "$ATPROTO_COMMIT" && git checkout -q FETCH_HEAD
      mkdir .bin && corepack enable --install-directory /opt/atproto/.bin
      export PATH=/opt/atproto/.bin:$PATH
      pnpm install --frozen-lockfile --ignore-scripts
      pnpm run build:tooling --force
      pnpm --filter '@atproto/dev-env^...' --filter @atproto/dev-env run --if-present prebuild
      pnpm exec tsc --build packages/dev-env/tsconfig.build.json
      pnpm --filter @atproto/oauth-provider-ui run build:ui
      cd "$(dirname "$(node -p "require.resolve('better-sqlite3/package.json', { paths: ['/opt/atproto/packages/pds'] })")")"
      [ -f build/Release/better_sqlite3.node ] || npm run install
      echo "$ATPROTO_COMMIT $ALPHA_BUILD" > /opt/atproto/.built
  - name: build
    run: cargo build -q --workspace --bins
  - name: scenarios
    # Tracks go side by side, each step of one a session of up to 20
    # minutes, in turn.
    timeout: 240
    run: |
      export PATH=/opt/node/bin:$PATH KNOTLESS_SPACES_DEV_ENV=/opt/atproto/packages/dev-env
      # OpenRouter speaks Claude Code's own protocol; the Anthropic key
      # must be empty, not unset, or it is tried first.
      if [ -n "${OPENROUTER_API_KEY:-}" ]; then
        export ANTHROPIC_BASE_URL=https://openrouter.ai/api ANTHROPIC_AUTH_TOKEN=$OPENROUTER_API_KEY ANTHROPIC_API_KEY=
      fi
      rm -rf target/scenarios
      node harness/scenarios.mjs $TRACKS
      cat target/scenarios/*/report.md