name: OpenWork Tests on: pull_request: branches: - dev push: branches: - dev permissions: contents: read jobs: openwork-tests: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [blacksmith-4vcpu-ubuntu-2204, macos-14] steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Node uses: actions/setup-node@v6 with: node-version: 24 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 11.4.0 - name: Install OpenCode CLI shell: bash env: GITHUB_TOKEN: ${{ github.token }} OPENCODE_GITHUB_REPO: ${{ vars.OPENCODE_GITHUB_REPO || 'anomalyco/opencode' }} run: | set -euo pipefail repo="${OPENCODE_GITHUB_REPO:-anomalyco/opencode}" version="$(node -e "const fs=require('fs'); const parsed=JSON.parse(fs.readFileSync('constants.json','utf8')); process.stdout.write(String(parsed.opencodeVersion||'').trim().replace(/^v/,''));")" version="$(echo "$version" | tr -d '\r\n' | sed 's/^v//')" if [ -z "$version" ]; then echo "Unable to resolve OpenCode version from constants.json." >&2 exit 1 fi arch="$(uname -m)" case "${RUNNER_OS}" in Linux) if [ "$arch" = "aarch64" ] || [ "$arch" = "arm64" ]; then opencode_asset="opencode-linux-arm64.tar.gz" else opencode_asset="opencode-linux-x64-baseline.tar.gz" fi ;; macOS) if [ "$arch" = "arm64" ]; then opencode_asset="opencode-darwin-arm64.zip" else opencode_asset="opencode-darwin-x64-baseline.zip" fi ;; *) echo "Unsupported OS: ${RUNNER_OS}" >&2 exit 1 ;; esac url="https://github.com/${repo}/releases/download/v${version}/${opencode_asset}" tmp_dir="$RUNNER_TEMP/opencode" extract_dir="$tmp_dir/extracted" rm -rf "$tmp_dir" mkdir -p "$extract_dir" curl_headers=() if [ -n "${GITHUB_TOKEN:-}" ]; then curl_headers+=( -H "Authorization: Bearer ${GITHUB_TOKEN}" ) fi curl -fsSL --retry 5 --retry-all-errors --retry-delay 2 "${curl_headers[@]}" -o "$tmp_dir/$opencode_asset" "$url" if [[ "$opencode_asset" == *.tar.gz ]]; then tar -xzf "$tmp_dir/$opencode_asset" -C "$extract_dir" else unzip -q "$tmp_dir/$opencode_asset" -d "$extract_dir" fi if [ -f "$extract_dir/opencode" ]; then bin_path="$extract_dir/opencode" elif [ -f "$extract_dir/opencode.exe" ]; then bin_path="$extract_dir/opencode.exe" else echo "OpenCode binary not found in archive" >&2 ls -la "$extract_dir" exit 1 fi install_dir="$HOME/.opencode/bin" mkdir -p "$install_dir" cp "$bin_path" "$install_dir/opencode" chmod 755 "$install_dir/opencode" echo "$install_dir" >> "$GITHUB_PATH" - name: Verify OpenCode run: opencode --version - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: 1.3.14 - name: Get pnpm store path id: pnpm-store shell: bash run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" - name: Cache pnpm store uses: actions/cache@v5 continue-on-error: true with: path: ${{ steps.pnpm-store.outputs.path }} key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml', 'evals/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm- - name: Install dependencies run: pnpm install --frozen-lockfile --prefer-offline - name: Install eval workspace run: pnpm --dir evals install --frozen-lockfile --prefer-offline - name: Run eval spec lane run: pnpm --dir evals run test:pr - name: Run app unit tests run: pnpm --filter @openwork/app test - name: Run server unit tests run: pnpm --filter openwork-server test - name: Run Den API unit tests run: pnpm --filter @openwork-ee/den-api test - name: Run desktop unit tests run: pnpm --filter @openwork/desktop test - name: Run release script tests run: node --test scripts/release/*.test.mjs - name: Run eval runner unit tests run: pnpm test:eval-runner - name: Check outbound access manifest run: pnpm check:outbound-access # The packaged builds bundle the server plugins with `--target node`, # which resolves workspace packages through their published exports # rather than TypeScript paths. Typechecks and bun tests never take that # route, so an unbuildable import reached dev twice before this ran here. - name: Bundle the server plugins the way packaged builds do run: | set -euo pipefail rm -rf packages/types/dist pnpm --filter openwork-server build - name: Typecheck Electron main against the IPC contract run: pnpm --filter @openwork/desktop typecheck:electron - name: Run e2e tests run: pnpm --filter @openwork/app test:e2e # Single stable context for branch rulesets to require. Green only when # every openwork-tests matrix leg succeeded; runs even when legs fail or # are cancelled so the required check always reports instead of hanging. openwork-tests-required: needs: openwork-tests if: always() runs-on: ubuntu-latest steps: - name: Require every openwork-tests matrix leg to pass env: RESULT: ${{ needs.openwork-tests.result }} run: | echo "openwork-tests result: $RESULT" if [ "$RESULT" != "success" ]; then echo "One or more OpenWork Tests matrix legs did not succeed; blocking merge." >&2 exit 1 fi