Skip to content

perf(tcp): linear frame parser (O(F²)→O(F)) + copy elision + O(Q²) cl… #636

perf(tcp): linear frame parser (O(F²)→O(F)) + copy elision + O(Q²) cl…

perf(tcp): linear frame parser (O(F²)→O(F)) + copy elision + O(Q²) cl… #636

Workflow file for this run

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
```