| # The harness image: built when its inputs change, to show the Dockerfile still builds, and | |
| # never published; machines build their own with `make image`. It holds harnesses under | |
| # their vendors' own licences, Claude Code and Copilot CLI among them, which the project | |
| # may not redistribute, and it is built from unreleased source (images/harness/README.md). | |
| # scripts/no-image-push.sh, run by `make check`, fails any file here that would send an | |
| # image to a registry, and `packages: none` below says so in this file (with other | |
| # permissions named, GitHub gives none for packages anyway). Pins are bumped by a daily | |
| # check that opens a pull request, and a pull request that touches them has its lockfile | |
| # checked against package.json. Never on a run: `amem launch` uses the tag it is given. | |
| name: image | |
| on: | |
| push: | |
| branches: [main] | |
| paths: ["images/harness/**", "crates/**", "Cargo.*", ".github/workflows/image.yml"] | |
| pull_request: | |
| paths: ["images/harness/**", "scripts/bump-harness-versions.sh", ".github/workflows/image.yml"] | |
| schedule: | |
| - cron: "41 5 * * *" # daily pin check | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| packages: none | |
| jobs: | |
| # Daily: bump the pins and open (or update) a pull request. CI runs on it like any PR | |
| # once a person approves the workflow run, since it is opened with the workflow token. | |
| bump: | |
| if: github.event_name == 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | |
| with: | |
| node-version: 24 | |
| - name: Bump pins | |
| id: bump | |
| run: | | |
| changes=$(scripts/bump-harness-versions.sh) | |
| echo "$changes" | |
| { echo "changes<<EOF"; echo "$changes"; echo "EOF"; } >> "$GITHUB_OUTPUT" | |
| - name: Open a pull request | |
| if: steps.bump.outputs.changes != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| git config user.name "harness-image bot" | |
| git config user.email "noreply@github.com" | |
| git checkout -B bot/harness-pins | |
| git add images/harness/Dockerfile images/harness/package.json images/harness/package-lock.json | |
| git commit -m "image: bump harness pins" -m "${{ steps.bump.outputs.changes }}" | |
| git push -f origin bot/harness-pins | |
| gh pr create --fill --base main --head bot/harness-pins \ | |
| --title "image: bump harness pins" \ | |
| --body "$(printf 'Daily pin check.\n\n%s' "${{ steps.bump.outputs.changes }}")" \ | |
| || gh pr edit bot/harness-pins --body "$(printf 'Daily pin check.\n\n%s' "${{ steps.bump.outputs.changes }}")" | |
| # On a pull request: package.json and package-lock.json agree, so `npm ci` in the build | |
| # takes the lock as it stands. A hand edit of one without the other fails here, not on main. | |
| lock: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | |
| with: | |
| node-version: 24 | |
| - name: The lock matches package.json | |
| run: cd images/harness && npm ci --dry-run --ignore-scripts --no-audit --no-fund | |
| # On a change to the inputs on main, or by hand: build with the release binary, to show | |
| # the image still builds. Nothing is pushed. | |
| build: | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins | |
| with: | |
| toolchain: stable | |
| # dm-web's build script builds the browser reader for this target | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 | |
| - name: Build the amem binary | |
| # staged as `memory`: the Dockerfile copies that file to /opt/memory/memory | |
| run: cargo build --release --locked -p amem && cp target/release/amem images/harness/memory | |
| - name: Build the image | |
| run: docker build --pull -t harness:${{ github.sha }} images/harness |