name: PR Checks on: pull_request: branches: - main concurrency: group: pr-checks-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: changes: name: PR Change Classification runs-on: ubuntu-latest outputs: pack_all: ${{ steps.changed-files.outputs.pack_all }} pack_packages: ${{ steps.changed-files.outputs.pack_packages }} run_agent_session_replay: ${{ steps.changed-files.outputs.run_agent_session_replay }} run_boundaries: ${{ steps.changed-files.outputs.run_boundaries }} run_contracts: ${{ steps.changed-files.outputs.run_contracts }} run_generated: ${{ steps.changed-files.outputs.run_generated }} run_go: ${{ steps.changed-files.outputs.run_go }} run_pack: ${{ steps.changed-files.outputs.run_pack }} run_ts: ${{ steps.changed-files.outputs.run_ts }} run_ts_tests: ${{ steps.changed-files.outputs.run_ts_tests }} test_all: ${{ steps.changed-files.outputs.test_all }} test_packages: ${{ steps.changed-files.outputs.test_packages }} test_shards: ${{ steps.changed-files.outputs.test_shards }} steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Classify changed files id: changed-files env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/change-classification.mjs --base "${BASE_SHA}" --head "${HEAD_SHA}" --github-output "${GITHUB_OUTPUT}" tooling-consistency: name: Tooling Consistency needs: changes if: always() runs-on: ubuntu-latest steps: - name: Require change classification env: CHANGES_RESULT: ${{ needs.changes.result }} run: test "${CHANGES_RESULT}" = "success" - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version - name: Check changed-file whitespace env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: git diff --check "${BASE_SHA}...${HEAD_SHA}" - name: Check repository naming policy run: node ./tools/scripts/check-tutti-names.mjs - name: Set up pnpm if: >- needs.changes.outputs.run_contracts == 'true' || needs.changes.outputs.run_generated == 'true' || needs.changes.outputs.run_boundaries == 'true' uses: pnpm/action-setup@v4 - name: Set up Go if: >- needs.changes.outputs.run_generated == 'true' || needs.changes.outputs.run_boundaries == 'true' uses: actions/setup-go@v5 with: go-version: "1.24.5" cache-dependency-path: | go.work go.work.sum packages/agent/daemon/go.sum services/tuttid/go.sum - name: Install workspace dependencies if: >- needs.changes.outputs.run_contracts == 'true' || needs.changes.outputs.run_generated == 'true' || needs.changes.outputs.run_boundaries == 'true' run: pnpm install --frozen-lockfile - name: Run repository contract tests if: needs.changes.outputs.run_contracts == 'true' env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/run-repository-checks.mjs --group contracts --base "${BASE_SHA}" --head "${HEAD_SHA}" - name: Run generated contract checks if: needs.changes.outputs.run_generated == 'true' env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/run-repository-checks.mjs --group generated --base "${BASE_SHA}" --head "${HEAD_SHA}" - name: Run repository boundary checks if: needs.changes.outputs.run_boundaries == 'true' env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/run-repository-checks.mjs --group boundaries --base "${BASE_SHA}" --head "${HEAD_SHA}" ts-lint: name: TypeScript Lint needs: changes if: needs.changes.outputs.run_ts == 'true' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Run TypeScript lint env: NODE_OPTIONS: --max-old-space-size=4096 run: pnpm lint:ts typecheck: name: Typecheck needs: changes if: needs.changes.outputs.run_ts == 'true' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Run workspace typecheck run: pnpm typecheck ts-test-shards: name: TypeScript Test Shard ${{ matrix.shard }} needs: changes if: needs.changes.outputs.run_ts_tests == 'true' runs-on: ubuntu-latest strategy: fail-fast: false matrix: shard: ${{ fromJSON(needs.changes.outputs.test_shards) }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Run TypeScript tests env: TEST_ALL: ${{ needs.changes.outputs.test_all }} TEST_PACKAGES: ${{ needs.changes.outputs.test_packages }} TEST_SHARD: ${{ matrix.shard }} run: >- if [ "${TEST_ALL}" = "true" ]; then pnpm test:ts -- --shard "${TEST_SHARD}"; else pnpm test:ts -- --packages-json "${TEST_PACKAGES}" --shard "${TEST_SHARD}"; fi ts-tests: name: TypeScript Tests needs: - changes - ts-test-shards if: always() runs-on: ubuntu-latest steps: - name: Require change classification env: CHANGES_RESULT: ${{ needs.changes.result }} run: test "${CHANGES_RESULT}" = "success" - name: Require selected test shards if: needs.changes.outputs.run_ts_tests == 'true' env: SHARDS_RESULT: ${{ needs.ts-test-shards.result }} run: test "${SHARDS_RESULT}" = "success" - name: No workspace package tests selected if: needs.changes.outputs.run_ts_tests != 'true' run: echo "No workspace package tests selected" npm-package-packs: name: npm Package Pack Check needs: changes if: needs.changes.outputs.run_pack == 'true' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Validate package tarballs env: PACK_ALL: ${{ needs.changes.outputs.pack_all }} PACK_PACKAGES: ${{ needs.changes.outputs.pack_packages }} run: >- if [ "${PACK_ALL}" = "true" ]; then pnpm release:pack:check; else pnpm release:pack:check -- --packages-json "${PACK_PACKAGES}"; fi go-tests: name: Go Tests needs: changes if: needs.changes.outputs.run_go == 'true' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.24.5" cache-dependency-path: | go.work go.work.sum **/go.mod **/go.sum - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Run changed Go tests env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/run-changed-go-validation.mjs --base "${BASE_SHA}" --head "${HEAD_SHA}" --kind test --tail-lines 400 go-lint: name: Go Lint needs: changes if: needs.changes.outputs.run_go == 'true' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm cache-dependency-path: pnpm-lock.yaml - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.24.5" cache-dependency-path: | go.work go.work.sum **/go.mod **/go.sum - name: Install workspace dependencies run: pnpm install --frozen-lockfile - name: Install pinned golangci-lint run: | version=$(tr -d '\n' < services/tuttid/.golangci-lint-version) install_dir="${RUNNER_TEMP}/golangci-lint/bin" installer="${RUNNER_TEMP}/golangci-lint-install.sh" mkdir -p "${install_dir}" curl \ --retry 5 \ --retry-all-errors \ --retry-delay 2 \ --silent \ --show-error \ --fail \ --location \ --output "${installer}" \ https://golangci-lint.run/install.sh sh "${installer}" -b "${install_dir}" "${version}" test -x "${install_dir}/golangci-lint" echo "${install_dir}" >> "${GITHUB_PATH}" - name: Run changed Go lint env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: >- node ./tools/scripts/run-changed-go-validation.mjs --base "${BASE_SHA}" --head "${HEAD_SHA}" --kind lint --tail-lines 400