Skip to content
Open
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
13 changes: 13 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Summary

<!-- What changed, and why. -->

## Test plan

- [ ] `pnpm run format:check` passes
- [ ] `pnpm run lint` passes
- [ ] `pnpm run build` passes
- [ ] `pnpm test` passes
- [ ] Docs / `CHANGELOG.md` updated if this is user-facing

Closes #
30 changes: 30 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Setup
description: Install pnpm, Node.js, and dependencies from the lockfile.

inputs:
node-version:
description: Node.js version to install
required: true
registry-url:
description: Optional npm registry URL (needed for publish)
required: false
default: ""

runs:
using: composite
steps:
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
if: ${{ inputs.registry-url == '' }}
with:
node-version: ${{ inputs.node-version }}
cache: pnpm
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
if: ${{ inputs.registry-url != '' }}
with:
node-version: ${{ inputs.node-version }}
cache: pnpm
registry-url: ${{ inputs.registry-url }}
- name: Install dependencies
shell: bash
run: pnpm install --frozen-lockfile
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
github-actions:
patterns:
- "*"

- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
77 changes: 77 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CI

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

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

# Unit and mocked integration tests live under src/__tests__ and do not call
# provider APIs. A live Playwright job would need secrets that fork PRs never
# receive; add one when a real E2E suite exists, gated on push to main.

jobs:
quality:
name: Lint, format, and typecheck
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
node-version: "22"
- name: Prettier
run: pnpm run format:check
- name: ESLint
run: pnpm run lint
- name: Typecheck
run: pnpm run build

test:
name: Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
node-version: [18, 20, 22, 24]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
node-version: ${{ matrix.node-version }}
- name: Test
run: pnpm test
- name: Coverage
if: matrix.node-version == 22
run: pnpm run test:coverage
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: matrix.node-version == 22
with:
name: coverage
path: coverage/
if-no-files-found: error

ci:
name: CI
needs: [quality, test]
if: always()
runs-on: ubuntu-24.04
timeout-minutes: 2
steps:
- name: Required jobs passed
run: |
test "${{ needs.quality.result }}" = "success"
test "${{ needs.test.result }}" = "success"
39 changes: 39 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CodeQL

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "27 3 * * 1"
workflow_dispatch:

concurrency:
group: codeql-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
analyze:
name: Analyze
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
security-events: write
packages: read
actions: read
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
with:
languages: javascript-typescript
build-mode: none
- uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
with:
category: "/language:javascript-typescript"
32 changes: 32 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: PR title

on:
pull_request:
types: [opened, edited, synchronize, reopened, ready_for_review]

permissions:
pull-requests: read

jobs:
lint:
name: Conventional title
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
style
refactor
perf
test
build
ci
chore
revert
requireScope: false
30 changes: 30 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Release

on:
release:
types: [published]
workflow_dispatch:

permissions:
contents: read
id-token: write

jobs:
publish:
name: Publish to npm
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
node-version: "22"
registry-url: https://registry.npmjs.org
- name: Build
run: pnpm run build
- name: Publish
run: pnpm publish --access public --no-git-checks --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
dist
node_modules
coverage
.pnpm-store
.DS_Store
.env
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- GitHub Actions CI/CD: Prettier, ESLint, typecheck, tests on Node 18–24, CodeQL, conventional PR titles, and npm publish (with provenance) on GitHub Release
- **OpenCode Zen gateway support**: set `gateway: "opencodezen"` in `configure()` and provide `OPENCODEZEN_API_KEY` to route all model requests through [OpenCode Zen](https://opencode.ai/docs/ko/zen/) (`https://opencode.ai/zen/v1`), an OpenAI-compatible gateway with 30+ curated models including Claude, Gemini, GPT, Qwen, and more.
- **OpenAI Support**: Direct integration with OpenAI models via `@ai-sdk/openai` and `OPENAI_API_KEY`
- `maxRetries` option to `AssertionOptions` (default: `1`) to control how many times a failed assertion is retried with a fresh page snapshot and screenshot. Setting it to `0` disables retries.
Expand Down
29 changes: 20 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@ Thank you for your interest in contributing to Passmark! This document provides

1. **Fork** the repository
2. **Clone** your fork locally
3. **Install dependencies**: `npm install`
3. **Install dependencies**: `pnpm install` (this repo is pinned to `pnpm@10.33.0` via `packageManager`)
4. **Create a branch** for your change: `git checkout -b feature/your-feature`

## Development Setup

### Prerequisites

- Node.js >= 18.0.0
- Redis instance (local or remote)
- API keys for Anthropic and Google Generative AI (for running tests)
- Playwright: `npx playwright install`
- pnpm 10 (`corepack enable` will use the version in `package.json`)
- Redis instance (local or remote) — only needed for live cache / `{{global.*}}` flows
- API keys for Anthropic and Google Generative AI — only needed for live AI runs, not for `pnpm test`
- Playwright: `npx playwright install` — only needed for running tests against a real browser

### Building
### Checks (same as CI)

```bash
npm run build
pnpm run format:check
pnpm run lint
pnpm run build
pnpm test
```

This runs the TypeScript compiler (`tsc`). Fix any type errors before submitting.
`pnpm run build` runs the TypeScript compiler (`tsc`). Fix any type errors before submitting.

CI runs these on every pull request to `main` (tests on Node 18, 20, 22, and 24). The unit suite is mocked and does not need API keys, Redis, or a browser.

## Code Style

Expand All @@ -42,25 +48,30 @@ This runs the TypeScript compiler (`tsc`). Fix any type errors before submitting
- `feature/description` for new features
- `fix/description` for bug fixes
- `docs/description` for documentation changes
- `ci/description` for CI/CD changes

### Commit Messages

Use clear, concise commit messages:
Use conventional commit messages. PR titles are checked the same way:

```
feat: add support for custom model providers
fix: handle empty email extraction gracefully
docs: update environment variables table
```

Allowed prefixes: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.

### Pull Requests

1. Ensure `npm run build` passes with no errors
1. Ensure CI would pass locally (`pnpm run format:check`, `pnpm run lint`, `pnpm run build`, `pnpm test`)
2. Update documentation if your change affects the public API
3. Add entries to `CHANGELOG.md` under an `[Unreleased]` section
4. Keep PRs focused on a single change
5. Provide a clear description of what changed and why

Publishing to npm is automated: creating a GitHub Release on `main` runs `.github/workflows/release.yml`. That workflow needs an `NPM_TOKEN` repository secret with publish access to the `passmark` package.

## Project Structure

```
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<a href="https://x.com/bug0inc"><img src="https://img.shields.io/badge/follow-%40bug0inc-black?logo=x" alt="Follow on X"></a>
<a href="https://www.linkedin.com/company/bug0"><img src="https://img.shields.io/badge/LinkedIn-bug0-blue?logo=linkedin" alt="LinkedIn"></a>
<a href="https://bug0.com"><img src="https://img.shields.io/badge/website-bug0.com-brightgreen" alt="Website"></a>
<a href="https://github.com/bug0inc/passmark/actions/workflows/ci.yml"><img src="https://github.com/bug0inc/passmark/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://www.npmjs.com/package/passmark"><img src="https://img.shields.io/npm/v/passmark" alt="npm package version"></a>
<a href="https://github.com/bug0inc/passmark/blob/main/LICENSE.md"><img src="https://img.shields.io/badge/license-FSL--1.1--ALv2-blue" alt="License"></a>
</p>
Expand Down