name: CI on: push: branches: [main] pull_request: jobs: gates: name: lint / typecheck / build / test (unit + integration) runs-on: ubuntu-latest strategy: matrix: node-version: [22, 24] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: 10 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Lint run: pnpm run lint - name: Typecheck run: pnpm run typecheck # The integration suite boots a real dsh process from the checkout's # built lib/, so Build must land before Test. - name: Build run: pnpm run build # Feishu is mocked via FEISHU_TRANSPORT=memory and the LLM via a local # mock server — no real credentials are needed. The profile links the # checkout; see docs/development.md → "Integration test". # Each integration suite gets its OWN dsh home: vitest runs the suites # in parallel and each spawns a real dsh process — sharing # `_dev/dsh-home/feishu/session-map.json` raced concurrent writes and # silently dropped one suite's chat→session binding (CI-only flakes, # e.g. the session-lifecycle test reading the file and finding its # chat missing). - name: Prepare integration-test profiles env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-attachments run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" - name: Prepare integration-test profile (rich-text) env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-rich-text run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" - name: Prepare integration-test profile (wait-instruction) env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-wait-instruction run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" - name: Prepare integration-test profile (real-composition) env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-real run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" - name: Prepare integration-test profile (outbound) env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-outbound run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" - name: Prepare integration-test profile (turn-produced-files) env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-turn-produced-files run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" # The scenario suite boots its own dsh home too. - name: Prepare scenario integration-test profile env: DSH_HOME: ${{ github.workspace }}/_dev/dsh-home-scenarios run: pnpm exec dsh plugin --profile feishu-dev add "link:${{ github.workspace }}" # FEISHU_INT_REQUIRED turns a missing prerequisite (dsh CLI, profile, # build) into a hard failure instead of the local graceful skip. - name: Test (unit + integration) env: DSH_BIN: ${{ github.workspace }}/node_modules/.bin/dsh FEISHU_INT_REQUIRED: '1' run: pnpm run test