Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/pgboss_queue_test
74 changes: 74 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Test

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run lint

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build

test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pgboss_queue_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run test
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/pgboss_queue_test

node-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- run: bun install --frozen-lockfile
- run: bun run build
- run: node --version
- run: node scripts/assert-node-package.mjs

complete:
if: always()
needs: [lint, build, test, node-package]
runs-on: ubuntu-latest
steps:
- name: Require all test jobs to pass
run: |
if [[ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
exit 1
fi
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
26
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ A PR with no `docs/plans/` diff is only OK when the change is truly unrelated (t

## Tooling (once Phase 1 exists)

This is a **Bun + TypeScript** project. Use `bun`, never `npm` or `npx`, for install/test/run. Use `bunx` if you need a package runner. PRs must stay green on `.github/workflows/test.yaml` (lint, build, `bun test` against Postgres).
This is a **Bun + TypeScript** project. Use `bun`, never `npm` or `npx`, for install/lint/build/test. Use `bunx` if you need a package runner. PRs must stay green on `.github/workflows/test.yaml` (lint, build, `bun test` against Postgres, Node package import).

```bash
bun install # install
bun test # bun:test, needs Postgres
node scripts/assert-node-package.mjs # after build; must use Node, not bun
bun run lint # biome check
bun run format # biome write
bun run build # tsc / bun build of src → dist
bun run build # tsc of src → dist, plus test typecheck
bun docs:dev # VitePress (Phase 9)
```

Local Postgres (Phase 1 `docker-compose.yml`):
Local Postgres: set `DATABASE_URL` (see `.env.example`). CI starts Postgres as a workflow service; there is no `docker-compose.yml`.

```bash
docker compose up -d postgres
# DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/pgboss_queue_test
```

Expand Down Expand Up @@ -131,11 +131,11 @@ Do **not** accept `pkg: "ioredis"`, `redis: Redis`, or `database: number`. Those

## Coding conventions

- **TypeScript strict.** No `as any`. Use `@ts-expect-error` with a comment when the type system cannot express something.
- **TypeScript strict (`noImplicitAny`).** No `any` and no `as any`. Biome `noExplicitAny` is an error. Use `@ts-expect-error` with a comment when the type system cannot express something.
- **JSDoc on every public class, method, and exported type.** `@param` for each parameter (including edge cases), `@returns` when non-obvious, `@throws` when applicable. Match node-resque's documented Queue methods.
- **No Python.** New scripts, CLIs, and tooling are Bun + TypeScript.
- **Biome** for format/lint (keryx-style), not Prettier.
- **Tests use `bun:test`**, not Jest. Port node-resque tests faithfully: same `describe` / `test` names, same assertions, Postgres `specHelper` instead of Redis.
- **Tests use `bun:test`**, not Jest. Port node-resque tests faithfully: same `describe` / `test` names, same assertions, Postgres `specHelper` instead of Redis. Node must still be able to import the compiled package (`node scripts/assert-node-package.mjs`); do not run the Bun suite on Node.
- **Every behavior change ships with tests.** A PR with no test changes is a red flag unless it is docs-only.
- **Do not add dependencies** unless a phase plan names them. Expected runtime deps: `pg-boss`, `pg`. Dev: `typescript`, `@types/pg`, `biome`, `bun` types.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ Raise your Postgres pool `max` when using a large `maxTaskProcessors`. Events ma

## Requirements

- Node.js 20+ or [Bun](https://bun.sh)
- Node.js 26+ or [Bun](https://bun.sh)
- PostgreSQL 13+ (`SKIP LOCKED`)

```bash
Expand Down
17 changes: 17 additions & 0 deletions __tests__/smoke.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { afterAll, describe, expect, test } from "bun:test";
import { connect, disconnect } from "./utils/specHelper";

describe("Postgres smoke test", () => {
afterAll(disconnect);

test("DATABASE_URL is defined", () => {
expect(process.env.DATABASE_URL).toBeDefined();
});

test("SELECT 1 returns 1", async () => {
const pool = await connect();
const result = await pool.query<{ value: number }>("SELECT 1 AS value");

expect(result.rows[0]?.value).toBe(1);
});
});
38 changes: 38 additions & 0 deletions __tests__/utils/specHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Pool, type PoolConfig } from "pg";

const connectionString = process.env.DATABASE_URL;

if (!connectionString) {
throw new Error(
"DATABASE_URL is required to run the test suite. See .env.example.",
);
}

export const connectionDetails: PoolConfig = { connectionString };
export const timeout = 500;
export const queue = "default";
export const schema = "pgboss_queue_test";

let pool: Pool | undefined;

export async function connect(): Promise<Pool> {
pool ??= new Pool(connectionDetails);
await pool.query("SELECT 1");
return pool;
}

export async function disconnect(): Promise<void> {
if (!pool) return;

await pool.end();
pool = undefined;
}

export async function cleanup(): Promise<void> {
const connection = await connect();
await connection.query("SELECT 1");
}

export async function popFromQueue(): Promise<never> {
throw new Error("not implemented");
}
41 changes: 41 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.10/schema.json",
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
},
"files": {
"includes": [
"**",
"!**/node_modules",
"!**/dist",
"!**/docs/.vitepress/dist",
"!**/docs/.vitepress/cache",
"!**/*.md"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80
},
"linter": {
"enabled": true,
"rules": {
"preset": "recommended",
"suspicious": {
"noExplicitAny": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "all"
}
}
}
118 changes: 118 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading