perf(tcp): linear frame parser (O(F²)→O(F)) + copy elision + O(Q²) cl… #636
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 | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| branches: [main, master] | |
| env: | |
| BUN_VERSION: "latest" | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| # ============================================ | |
| # Code Quality | |
| # ============================================ | |
| lint: | |
| name: Lint & Format | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install --ignore-scripts | |
| - name: Biome check (lint + format) | |
| run: bun run check:biome | |
| typecheck: | |
| name: Type Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install --ignore-scripts | |
| - name: Run type check | |
| run: bun run typecheck | |
| # ============================================ | |
| # Tests | |
| # ============================================ | |
| test: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install --ignore-scripts | |
| - name: Run unit tests | |
| run: bun test | |
| # test-tcp: | |
| # name: TCP Integration Tests | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # | |
| # - uses: oven-sh/setup-bun@v2 | |
| # with: | |
| # bun-version: ${{ env.BUN_VERSION }} | |
| # | |
| # - name: Install dependencies | |
| # run: bun install --ignore-scripts | |
| # | |
| # - name: Run TCP integration tests | |
| # run: bun scripts/tcp/run-all-tests.ts | |
| # test-embedded: | |
| # name: Embedded Integration Tests | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # | |
| # - uses: oven-sh/setup-bun@v2 | |
| # with: | |
| # bun-version: ${{ env.BUN_VERSION }} | |
| # | |
| # - name: Install dependencies | |
| # run: bun install --ignore-scripts | |
| # | |
| # - name: Run embedded integration tests | |
| # run: bun scripts/embedded/run-all-tests.ts | |
| test-websocket: | |
| name: WebSocket/SSE Integration Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install --ignore-scripts | |
| - name: Run WebSocket/SSE integration tests | |
| run: bun scripts/websocket/run-all-tests.ts | |
| # ============================================ | |
| # Version gate — only build binaries / cut a release when package.json | |
| # version is NEW (avoids rebuilding 5×~90MB binaries + a fresh release on | |
| # every docs/chore commit to main, which never bumps the version). | |
| # ============================================ | |
| version-gate: | |
| name: Version gate | |
| runs-on: ubuntu-latest | |
| needs: [lint, typecheck, test, test-websocket] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| outputs: | |
| version: ${{ steps.gate.outputs.version }} | |
| should_release: ${{ steps.gate.outputs.should_release }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Decide whether this version is already released | |
| id: gate | |
| run: | | |
| set -euo pipefail | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| if git ls-remote --exit-code --tags origin "refs/tags/v$VERSION" >/dev/null 2>&1; then | |
| echo "should_release=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::v$VERSION already released — skipping binary build, docker push, and release." | |
| else | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| echo "::notice::v$VERSION is new — building binaries and cutting a release." | |
| fi | |
| # ============================================ | |
| # Build Binaries (only on a new version) | |
| # ============================================ | |
| build: | |
| name: Build (${{ matrix.target }}) | |
| runs-on: ubuntu-latest | |
| needs: [version-gate] | |
| if: needs.version-gate.outputs.should_release == 'true' | |
| strategy: | |
| matrix: | |
| include: | |
| - target: bun-linux-x64 | |
| artifact: bunqueue-linux-x64 | |
| - target: bun-linux-arm64 | |
| artifact: bunqueue-linux-arm64 | |
| - target: bun-darwin-x64 | |
| artifact: bunqueue-darwin-x64 | |
| - target: bun-darwin-arm64 | |
| artifact: bunqueue-darwin-arm64 | |
| - target: bun-windows-x64 | |
| artifact: bunqueue-windows-x64.exe | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install --ignore-scripts | |
| - name: Get version from package.json | |
| id: version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Build executable | |
| run: bun build --compile --minify --target=${{ matrix.target }} src/main.ts --outfile ${{ matrix.artifact }} | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: ${{ matrix.artifact }} | |
| retention-days: 7 | |
| # ============================================ | |
| # Docker Build & Push (only on main) | |
| # ============================================ | |
| docker: | |
| name: Docker | |
| runs-on: ubuntu-latest | |
| needs: [version-gate] | |
| if: needs.version-gate.outputs.should_release == 'true' | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate tags | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=latest | |
| type=sha,prefix= | |
| type=raw,value={{date 'YYYYMMDD-HHmm'}} | |
| - name: Build and push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # ============================================ | |
| # Create Release (only on main) | |
| # ============================================ | |
| release: | |
| name: Release | |
| runs-on: ubuntu-latest | |
| needs: [version-gate, build, docker] | |
| # Explicit gate (not just implicit success() propagation from build/docker): | |
| # only cut a release for a NEW version. | |
| if: needs.version-gate.outputs.should_release == 'true' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Resolve version | |
| id: version | |
| run: echo "version=${{ needs.version-gate.outputs.version }}" >> "$GITHUB_OUTPUT" | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts/ | |
| pattern: bunqueue-* | |
| merge-multiple: true | |
| - name: Prepare release assets | |
| run: | | |
| set -euo pipefail | |
| mkdir -p release | |
| ls -la artifacts/ | |
| # Collect binaries (artifacts may be nested one level depending on the | |
| # upload-artifact version), keeping the canonical names. | |
| for name in bunqueue-linux-x64 bunqueue-linux-arm64 bunqueue-darwin-x64 bunqueue-darwin-arm64 bunqueue-windows-x64.exe; do | |
| cp "artifacts/$name" release/ 2>/dev/null || cp "artifacts/$name/$name" release/ 2>/dev/null || true | |
| done | |
| # Compress each binary before upload: a Bun --compile binary embeds the | |
| # whole runtime (~60–94MB) but compresses ~55–65%, so the DOWNLOAD drops | |
| # to ~30–40MB. Unix → .tar.gz (preserves the +x bit), Windows → .zip. | |
| cd release | |
| for name in bunqueue-linux-x64 bunqueue-linux-arm64 bunqueue-darwin-x64 bunqueue-darwin-arm64; do | |
| [ -f "$name" ] || continue | |
| chmod +x "$name" | |
| tar -czf "$name.tar.gz" "$name" | |
| rm "$name" | |
| done | |
| if [ -f bunqueue-windows-x64.exe ]; then | |
| zip -9 bunqueue-windows-x64.zip bunqueue-windows-x64.exe | |
| rm bunqueue-windows-x64.exe | |
| fi | |
| # Checksums of the published (compressed) artifacts. | |
| sha256sum bunqueue-* > SHA256SUMS | |
| ls -la | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ steps.version.outputs.version }} | |
| name: Release v${{ steps.version.outputs.version }} | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: false | |
| make_latest: true | |
| files: | | |
| release/bunqueue-linux-x64.tar.gz | |
| release/bunqueue-linux-arm64.tar.gz | |
| release/bunqueue-darwin-x64.tar.gz | |
| release/bunqueue-darwin-arm64.tar.gz | |
| release/bunqueue-windows-x64.zip | |
| release/SHA256SUMS | |
| body: | | |
| ## Installation | |
| ### Docker (recommended) | |
| ```bash | |
| docker pull ghcr.io/${{ github.repository }}:latest | |
| docker run -p 6789:6789 -p 6790:6790 ghcr.io/${{ github.repository }}:latest | |
| ``` | |
| ### Binary | |
| Compressed downloads (~30–40MB; extract to get the standalone | |
| executable, which embeds the Bun runtime). Verify with `SHA256SUMS`. | |
| | Platform | Architecture | Download | | |
| |----------|-------------|----------| | |
| | Linux | x64 | `bunqueue-linux-x64.tar.gz` | | |
| | Linux | arm64 | `bunqueue-linux-arm64.tar.gz` | | |
| | macOS | x64 (Intel) | `bunqueue-darwin-x64.tar.gz` | | |
| | macOS | arm64 (Apple Silicon) | `bunqueue-darwin-arm64.tar.gz` | | |
| | Windows | x64 | `bunqueue-windows-x64.zip` | | |
| ```bash | |
| # Example: Linux x64 | |
| tar -xzf bunqueue-linux-x64.tar.gz | |
| chmod +x bunqueue-linux-x64 | |
| ./bunqueue-linux-x64 | |
| ``` |