Skip to content

docs(home): rebuild the benchmark simulator as an honest throughput m… #689

docs(home): rebuild the benchmark simulator as an honest throughput m…

docs(home): rebuild the benchmark simulator as an honest throughput m… #689

Workflow file for this run

name: CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
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
timeout-minutes: 20
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
timeout-minutes: 20
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
# ============================================
# Docs site: the bunqueue.dev build must stay green
# ============================================
docs:
name: Docs Build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
with:
# full history: the sitemap derives real per-page lastmod from git log
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Install docs dependencies
working-directory: docs
run: bun install --ignore-scripts
- name: Build docs site
working-directory: docs
run: bun run build
- name: Sanity-check output
working-directory: docs
run: |
set -euo pipefail
test -f dist/index.html
test -f dist/rss.xml
# @astrojs/sitemap emits a single minified line, so `grep -c` (which
# counts matching LINES) would report 1. Count <loc> OCCURRENCES.
URLS=$(grep -o "<loc>" dist/sitemap-0.xml | wc -l | tr -d '[:space:]')
echo "sitemap URLs: $URLS"
test "$URLS" -ge 60
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-tcp, test-embedded, test-websocket, docs]
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
```