fix(attach): shorten Unix socket paths (#742) #1570
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| # Codecov setup: | |
| # 1. Go to https://codecov.io and sign in with GitHub | |
| # 2. Add the covibes/zeroshot repository | |
| # 3. Get the upload token from Settings > General | |
| # 4. Add it as a GitHub secret: Settings > Secrets and variables > Actions > New repository secret | |
| # Name: CODECOV_TOKEN | |
| # Value: <your-token-from-codecov> | |
| on: | |
| push: | |
| branches: [main, dev] | |
| pull_request: | |
| branches: [main, dev] | |
| merge_group: | |
| branches: [main, dev] | |
| workflow_dispatch: | |
| jobs: | |
| # ENFORCE: PRs to main must come from dev branch only | |
| enforce-main-pr-source: | |
| if: github.event_name == 'pull_request' && github.base_ref == 'main' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check PR source branch | |
| run: | | |
| if [[ "${{ github.head_ref }}" != "dev" ]]; then | |
| echo "::error::PRs to main MUST come from the dev branch." | |
| echo "" | |
| echo "❌ BLOCKED: PR from '${{ github.head_ref }}' to main" | |
| echo "" | |
| echo "The dev → main workflow exists so that:" | |
| echo " • All changes are tested on dev first" | |
| echo " • Releases are coherent snapshots of dev" | |
| echo " • main is always a subset of dev (no divergence)" | |
| echo "" | |
| echo "CORRECT WORKFLOW:" | |
| echo " 1. Create PR to dev first: gh pr create --base dev" | |
| echo " 2. After merge to dev, create release PR:" | |
| echo " gh pr create --base main --head dev --title 'Release'" | |
| echo "" | |
| exit 1 | |
| fi | |
| echo "✓ PR from dev to main - allowed" | |
| # Fast quality gates - must pass before anything else | |
| check: | |
| # Wait for branch enforcement on PRs to main | |
| needs: [enforce-main-pr-source] | |
| if: always() && (needs.enforce-main-pr-source.result == 'success' || needs.enforce-main-pr-source.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Setup Rust 1.97.0 | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.97.0 | |
| components: clippy,rustfmt | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Check generated Cluster Protocol artifacts | |
| run: npm run protocol:check | |
| - name: Check Rust formatting | |
| run: cargo fmt --all -- --check | |
| - name: Lint Rust | |
| run: cargo clippy --workspace --all-targets -- -D warnings | |
| - name: Test Rust workspace | |
| run: cargo test --workspace | |
| - name: Security audit | |
| run: npm audit --audit-level=moderate --omit=dev | |
| continue-on-error: false | |
| - name: Lint | |
| run: npm run lint | |
| - name: Duplicate code check | |
| run: npm run dupcheck | |
| - name: Type check | |
| run: npm run typecheck | |
| - name: Check provider CLI helper | |
| run: npm run check:agent-cli-provider:ci | |
| - name: Unit tests with coverage (fast) | |
| run: npm run test:coverage | |
| timeout-minutes: 3 | |
| - name: E2E tests (fake provider) | |
| run: npm run test:e2e | |
| timeout-minutes: 5 | |
| - name: Integration tests (slow) | |
| run: npm run test:slow | |
| timeout-minutes: 15 | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage/lcov.info | |
| flags: unittests | |
| name: codecov-zeroshot | |
| fail_ci_if_error: false | |
| continue-on-error: true | |
| # Tier 2: worktree/container isolation e2e (real Docker). Non-blocking and | |
| # opt-in via workflow_dispatch - the Docker sub-tests in `check`'s | |
| # "Integration tests (slow)" step self-skip under CI (this is what that | |
| # step's Docker coverage was previously silently missing). | |
| e2e-docker: | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Docker isolation e2e | |
| run: npm run test:e2e:docker | |
| timeout-minutes: 15 | |
| # Cross-platform/version compatibility (main only) | |
| # NOTE: macOS runners cost 10x Linux minutes - keep this scoped to main. | |
| install-matrix: | |
| needs: check | |
| if: | | |
| always() && | |
| needs.check.result == 'success' && | |
| ( | |
| github.ref == 'refs/heads/main' || | |
| (github.event_name == 'pull_request' && github.base_ref == 'main') || | |
| (github.event_name == 'merge_group' && ( | |
| github.event.merge_group.base_ref == 'main' || | |
| github.event.merge_group.base_ref == 'refs/heads/main' || | |
| startsWith(github.ref, 'refs/heads/gh-readonly-queue/main/') | |
| )) | |
| ) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| node: 20 | |
| - os: macos-latest | |
| node: 20 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js ${{ matrix.node }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Link CLI | |
| run: npm link | |
| - name: CLI smoke test | |
| run: | | |
| zeroshot --help | |
| zeroshot --version | |
| zeroshot list | |
| - name: Test process-metrics (platform-specific) | |
| run: | | |
| node -e " | |
| (async () => { | |
| const { getProcessMetrics, formatMetrics, getStateIcon, isPlatformSupported, getPlatformInfo } = require('./src/process-metrics'); | |
| const os = require('os'); | |
| console.log('Platform:', os.platform()); | |
| console.log('Supported:', isPlatformSupported()); | |
| console.log('Platform info:', JSON.stringify(getPlatformInfo())); | |
| // Test metrics collection | |
| const metrics = await getProcessMetrics(process.pid, { samplePeriodMs: 100 }); | |
| console.log('Metrics:', JSON.stringify(metrics, null, 2)); | |
| // Validate required fields | |
| if (!metrics.exists) throw new Error('Process should exist'); | |
| if (typeof metrics.cpuPercent !== 'number') throw new Error('cpuPercent must be number'); | |
| if (typeof metrics.memoryMB !== 'number') throw new Error('memoryMB must be number'); | |
| if (!metrics.state) throw new Error('state must be set'); | |
| console.log('Formatted:', formatMetrics(metrics)); | |
| console.log('State icon:', getStateIcon(metrics.state, metrics.network?.hasActivity)); | |
| console.log('✓ Process metrics test passed on', os.platform()); | |
| })().catch(e => { console.error(e); process.exit(1); }); | |
| " | |
| - name: Test status-footer | |
| run: | | |
| node -e " | |
| const { StatusFooter } = require('./src/status-footer'); | |
| const footer = new StatusFooter({ enabled: false }); | |
| footer.setCluster('test-cluster'); | |
| footer.setClusterState('running'); | |
| footer.updateAgent({ id: 'worker', state: 'executing_task', pid: process.pid, iteration: 1 }); | |
| const statusLine = footer.buildStatusLine(80); | |
| if (!statusLine.includes('running')) throw new Error('Status line missing state'); | |
| if (!statusLine.includes('1/1')) throw new Error('Status line missing agent count'); | |
| footer.stop(); | |
| console.log('✓ StatusFooter test passed'); | |
| " | |
| release-preflight: | |
| name: Release preflight | |
| needs: [enforce-main-pr-source] | |
| if: | | |
| always() && | |
| (needs.enforce-main-pr-source.result == 'success' || needs.enforce-main-pr-source.result == 'skipped') && | |
| ( | |
| (github.event_name == 'pull_request' && github.base_ref == 'main') || | |
| (github.event_name == 'merge_group' && ( | |
| github.event.merge_group.base_ref == 'main' || | |
| github.event.merge_group.base_ref == 'refs/heads/main' || | |
| startsWith(github.ref, 'refs/heads/gh-readonly-queue/main/') | |
| )) | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Validate release contract | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: npm run release:preflight |