diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index 94a38c5d5..9926bc7f5 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -28,10 +28,10 @@ permissions: jobs: actionlint: - runs-on: blacksmith-2vcpu-ubuntu-2404 + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-24.04' || 'blacksmith-2vcpu-ubuntu-2404' }} timeout-minutes: 5 steps: - - uses: useblacksmith/checkout@v1 + - uses: actions/checkout@v7 - name: Download actionlint run: bash <(curl -sSf https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.12 - name: Run actionlint diff --git a/.github/workflows/api-acceptance.yml b/.github/workflows/api-acceptance.yml index cbfde3e3d..cee86b15a 100644 --- a/.github/workflows/api-acceptance.yml +++ b/.github/workflows/api-acceptance.yml @@ -36,7 +36,7 @@ concurrency: jobs: official-client: - runs-on: blacksmith-2vcpu-ubuntu-2404 + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-24.04' || 'blacksmith-2vcpu-ubuntu-2404' }} timeout-minutes: 20 services: postgres: @@ -53,7 +53,7 @@ jobs: --health-timeout 5s --health-retries 10 steps: - - uses: useblacksmith/checkout@v1 + - uses: actions/checkout@v7 - uses: actions/setup-go@v7 with: go-version-file: go.mod diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index ea5cfdbd3..26a91cb3a 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -19,8 +19,8 @@ concurrency: cancel-in-progress: true jobs: - check: - runs-on: blacksmith-16vcpu-ubuntu-2204 + backend: + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} timeout-minutes: 40 services: postgres: @@ -37,10 +37,10 @@ jobs: --health-timeout 5s --health-retries 10 steps: - - uses: useblacksmith/checkout@v1 + - uses: actions/checkout@v7 with: ref: ${{ inputs.ref || github.sha }} - - name: Select shared Go caches + - name: Select Go caches id: source run: | echo "revision=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" @@ -55,24 +55,147 @@ jobs: path: | ~/.oac/cache/go-build ~/.oac/cache/go-mod - key: core-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-${{ steps.source.outputs.revision }} + key: core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-backend-${{ steps.source.outputs.revision }} restore-keys: | + core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-backend- core-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}- - uses: actions/setup-node@v6 with: node-version: '22' - - name: Install pinned check prerequisites + - name: Install native Go prerequisites run: | - npm install --global pnpm@10.30.3 sudo apt-get update sudo apt-get install -y build-essential pkg-config libssl-dev - - name: Install Web acceptance browser - run: | - pnpm install --frozen-lockfile - pnpm exec playwright install --with-deps chrome - - name: Check standalone repository + - name: Verify dedicated test database env: OAC_TEST_DATABASE_URL: postgres://agents_api:core_test_only@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/oac_core_ci_tests?sslmode=disable - run: make check + run: | + echo "OAC_TEST_DATABASE_URL=$OAC_TEST_DATABASE_URL" >> "$GITHUB_ENV" + make check-database + - name: Verify generated SQL queries + run: make check-sqlc + - name: Test Runtime and shared Go contracts + run: make check-go + - name: Test microsandbox provider and Linux helper + run: make check-microsandbox-provider + - name: Build and test standalone Core and persistence + run: make check-core - name: Build execution daemon run: make build-daemon + + tooling: + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} + timeout-minutes: 20 + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ inputs.ref || github.sha }} + - name: Select Go caches + id: source + run: | + echo "revision=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + echo "GOCACHE=$HOME/.oac/cache/go-build" >> "$GITHUB_ENV" + echo "GOMODCACHE=$HOME/.oac/cache/go-mod" >> "$GITHUB_ENV" + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + cache: false + - uses: actions/cache@v6 + with: + path: | + ~/.oac/cache/go-build + ~/.oac/cache/go-mod + key: core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-tooling-${{ steps.source.outputs.revision }} + restore-keys: | + core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-tooling- + core-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}- + - uses: actions/setup-node@v6 + with: + node-version: '22' + - name: Install pinned pnpm + run: npm install --global pnpm@10.30.3 + - name: Install dependencies and example acceptance browser + run: | + make node-deps + pnpm exec playwright install --with-deps chrome + - name: Verify Harness catalog + run: make check-harness-catalog + - name: Verify repository names + run: make check-names + - name: Test distribution, installer and console packaging + run: make check-distribution + - name: Test and package Claude SDK adapter + run: make check-claude-sdk + - name: Test and build optional example with browser acceptance + run: make check-example + - name: Verify MiniMax companion scripts + run: make check-mcode-harness + + web: + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} + timeout-minutes: 15 + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ inputs.ref || github.sha }} + - uses: actions/setup-node@v6 + with: + node-version: '22' + - name: Install pinned pnpm + run: npm install --global pnpm@10.30.3 + - name: Typecheck, test and build Web and clients + run: make check-web-unit + + web-acceptance: + strategy: + fail-fast: false + matrix: + shard: [1, 2] + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} + timeout-minutes: 15 + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ inputs.ref || github.sha }} + - uses: actions/setup-node@v6 + with: + node-version: '22' + - name: Install pinned pnpm + run: npm install --global pnpm@10.30.3 + - name: Install dependencies and Web acceptance browser + run: | + make node-deps + pnpm exec playwright install --with-deps chrome + - name: Verify Web workflows against isolated fixtures + run: make check-web-acceptance OAC_WEB_TEST_SHARD=${{ matrix.shard }}/2 + - name: Upload browser failure evidence + if: failure() + uses: actions/upload-artifact@v6 + with: + name: web-acceptance-${{ matrix.shard }}-${{ github.run_attempt }} + path: | + playwright-report/ + test-results/ + retention-days: 7 + compression-level: 0 + if-no-files-found: ignore + + # Preserve the required check name, and fail closed for skipped/cancelled jobs. + check: + if: always() + needs: [backend, tooling, web, web-acceptance] + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} + timeout-minutes: 5 + steps: + - name: Require every full-gate partition to succeed + env: + RESULTS: ${{ toJSON(needs) }} + run: | + python3 - <<'PY' + import json, os, sys + results = json.loads(os.environ['RESULTS']) + failed = [name for name, job in results.items() if job['result'] != 'success'] + if failed: + sys.exit('Full gate did not pass: ' + ', '.join(failed)) + print('OpenAgentCore checks passed.') + PY diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index f91b4e11a..6b63cecd6 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -43,8 +43,18 @@ jobs: strategy: fail-fast: false matrix: - os: [blacksmith-4vcpu-ubuntu-2204, blacksmith-6vcpu-macos-15, blacksmith-4vcpu-windows-2025] - runs-on: ${{ matrix.os }} + include: + - platform: linux-amd64 + runner: blacksmith-2vcpu-ubuntu-2204 + github-runner: ubuntu-22.04 + - platform: darwin-arm64 + runner: macos-15 + github-runner: macos-15 + - platform: windows-amd64 + runner: blacksmith-2vcpu-windows-2025 + github-runner: windows-2025 + name: platform (${{ matrix.platform }}) + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && matrix.github-runner || matrix.runner }} timeout-minutes: 30 defaults: run: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fa1731069..141f1700f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,13 +38,13 @@ jobs: build: needs: native - runs-on: blacksmith-4vcpu-ubuntu-2204 + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} timeout-minutes: 120 outputs: revision: ${{ steps.source.outputs.revision }} release_tag: ${{ steps.source.outputs.release_tag }} steps: - - uses: useblacksmith/checkout@v1 + - uses: actions/checkout@v7 with: ref: ${{ inputs.ref || github.sha }} persist-credentials: false @@ -83,8 +83,10 @@ jobs: path: | ~/.oac/cache/go-build ~/.oac/cache/go-mod - key: core-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-${{ steps.source.outputs.revision }} + key: core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-release-${{ steps.source.outputs.revision }} restore-keys: | + core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-release- + core-go-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}-backend- core-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/go.mod', '**/go.sum') }}- - uses: actions/setup-node@v6 with: @@ -135,11 +137,11 @@ jobs: release: if: github.event_name == 'push' || inputs.draft_release needs: [check, build] - runs-on: blacksmith-4vcpu-ubuntu-2204 + runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }} permissions: contents: write steps: - - uses: useblacksmith/checkout@v1 + - uses: actions/checkout@v7 with: ref: ${{ needs.build.outputs.revision }} persist-credentials: false diff --git a/Makefile b/Makefile index d36c81471..a9ecabffb 100644 --- a/Makefile +++ b/Makefile @@ -89,12 +89,20 @@ check-claude-sdk: node-deps pnpm --filter @oac/claude-sdk-adapter test $(MAKE) build-claude-sdk-runtime -check-web: node-deps +.PHONY: check-web-unit check-web-acceptance +check-web: override OAC_WEB_TEST_SHARD := +check-web: check-web-unit check-web-acceptance + +check-web-unit: node-deps pnpm typecheck pnpm test:core-doctor pnpm test:web pnpm --filter @oac/web build - pnpm test:web:acceptance + +# CI shards run in separate jobs, each with its own fixture and Web server. +# An unset shard keeps the complete local make check gate. +check-web-acceptance: node-deps + pnpm test:web:acceptance $(if $(OAC_WEB_TEST_SHARD),--shard=$(OAC_WEB_TEST_SHARD)) build-claude-sdk-runtime: ./scripts/build-claude-sdk-runtime.sh diff --git a/docs/maintainers.md b/docs/maintainers.md index a25d557f6..fb1ce0561 100644 --- a/docs/maintainers.md +++ b/docs/maintainers.md @@ -128,7 +128,7 @@ The workflow runs three jobs on the tagged commit: `check` (the full `make check `install.sh` resolves the latest stable release once, or the release named by `--version`, verifies the control archive and runs that bundle's installer; the [installation guide](getting-started/install.md#install) covers its use. -The `check` and `build` jobs share Go module and build caches under `~/.oac/cache/`, keyed by runner OS and architecture, the Go module files and the commit. An older cache only seeds downloads and compilation; every check still runs. New keys are saved only after a successful job. +Go check and build jobs share Go module and compiler-cache directories under `~/.oac/cache/`, keyed by runner OS and architecture, all Go module files, the check/build partition and the commit. Partitioned keys prevent concurrent jobs from saving different compiler subsets under one key. Release builds can seed their cache from backend checks as well as earlier release builds. An older cache only seeds downloads and compilation; every check still runs. New keys are saved only after a successful job. Never move a release tag or overwrite published assets. If the `release` job fails, inspect the Release first: publication may have completed despite a lost response. Leave a complete published Release as it is. For an incomplete draft, delete that draft (the job refuses any existing Release or draft for the tag), then rerun the failed `release` job, which reuses the original Actions artifact. Do not rerun the build or recreate the tag to recover a failed upload. @@ -152,7 +152,7 @@ With `draft_release=true` the result is an unpublished `build-` draft | Workflow | Runs on | Covers | | --- | --- | --- | -| `core-check` (`check.yml`) | Pushes to `main`, every pull request, releases | `make check` with a PostgreSQL service and the Playwright browser, then a daemon build | +| `core-check` (`check.yml`) | Pushes to `main`, every pull request, releases | All `make check` checks in concurrent partitions, plus a daemon build; see the partitions below | | `api-acceptance` | Pushes to `main` and pull requests that touch Core, its contracts, clients, shared Go code or build scripts | Standalone commands and migration, the pinned official client over HTTP, and the standalone container | | `native-check` (`native.yml`) | Pull requests that touch native sources, shared dependencies or packaging inputs; manual runs; releases | Daemon, process lifecycle, Harness protocols and the installer bundle on Linux, macOS and Windows; uploads the native installers | | `actionlint` | Changes to workflows | Workflow syntax | @@ -160,6 +160,28 @@ With `draft_release=true` the result is an unpublished `build-` draft Changes limited to Web or to documentation outside `contracts/agents-api` do not start `native-check`. A newer `core-check`, `api-acceptance` or `native-check` run on the same branch or pull request cancels the older one. +The full gate starts these partitions concurrently: + +| Job | Checks | +| --- | --- | +| `backend` | Dedicated PostgreSQL guard, sqlc freshness, Runtime/shared Go tests, Linux microsandbox helper, standalone Core build and service/client tests, daemon build | +| `tooling` | Harness catalog, name guard, distribution/installer, Claude SDK packaging, optional example including browser acceptance, MiniMax companion scripts | +| `web` | TypeScript checks, doctor and Web/client tests, Web build | +| `web-acceptance` (two shards) | The complete Web Playwright suite, split by test files between two isolated runners | + +Each check has its own named step. Only the backend job needs a database. Each browser job starts its own fixture and Web server, retaining one Playwright worker per runner so tests never share mutable fixtures across concurrent jobs. Failed Web shards upload their reports and traces for seven days. The final `check` job runs after every partition and succeeds only when all results are `success`; failed, cancelled or skipped jobs cannot produce a green required gate. Releases use this same workflow. Local `make check` still runs every check and the unsharded Web suite; `make check-web-unit` and `make check-web-acceptance` expose its Web parts. `OAC_WEB_TEST_SHARD=1/2` selects a shard for focused CI validation. + +### CI runners and free allowance + +Linux jobs use Blacksmith's 2-vCPU Ubuntu 22.04 or 24.04 runners; native Windows uses its 2-vCPU Windows 2025 runner. Blacksmith has no 2-vCPU macOS runner, so native macOS uses the standard GitHub `macos-15` ARM64 runner. Release building and publication also use 2-vCPU Blacksmith runners. + +Set the repository Actions variable `OAC_USE_GITHUB_RUNNERS` to `true` to run all jobs on standard GitHub-hosted runners instead. Linux keeps its matching Ubuntu version, Windows uses `windows-2025`, and macOS continues using `macos-15`. Remove the variable or set it to `false` to return to Blacksmith's 2-vCPU defaults. For example, maintainers can switch when the organization's free allowance is used up, then restore Blacksmith after the allowance resets: + +```sh +gh variable set OAC_USE_GITHUB_RUNNERS --body true --repo MiniMax-AI/OpenAgentCore +``` + +This is an explicit operator switch, not an automatic billing balance probe. Runner selection applies to newly scheduled runs. Check current allowance and platform conversion rates in [Blacksmith's runner documentation](https://docs.blacksmith.sh/blacksmith-runners/overview) before treating 2-vCPU usage as free; Windows minutes consume more allowance than Linux minutes. Standard GitHub runner usage follows the repository's visibility and GitHub plan. These workflows request no Blacksmith runner larger than 2 vCPU and no paid cache add-on. ## Run Core without the installer The standalone archive and container give you Core alone: no Web, no `oac` command and no `config.json`. They suit development, testing and operators who supervise Core themselves. Core reads only its environment; the [configuration appendix](configuration.md#appendix-core-environment-without-the-installer) lists the variables. `OAC_DATABASE_URL` and `OAC_CORE_KEY_DIGESTS_FILE` are required; set `OAC_PUBLIC_URL` to the origin machines use to reach Core, or Core runs without the daemon transport.