diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..689f7bf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,101 @@ +name: CI + +on: + pull_request: + branches: + - master + push: + branches: + - master + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: 24 + package-manager-cache: false + + - name: Set up pnpm + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 + with: + version: 11.5.1 + run_install: false + cache: false + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run tests + run: pnpm run test + + typecheck: + name: Typecheck + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: 24 + package-manager-cache: false + + - name: Set up pnpm + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 + with: + version: 11.5.1 + run_install: false + cache: false + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run TypeScript checks + run: pnpm exec tsc -p tsconfig.json --noEmit + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: 24 + package-manager-cache: false + + - name: Set up pnpm + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 + with: + version: 11.5.1 + run_install: false + cache: false + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run lint + run: pnpm run lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1eb6063 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,87 @@ +name: Release + +on: + push: + tags: + - v* + +permissions: + contents: read + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + publish: + name: Build and publish + runs-on: ubuntu-latest + environment: npm-publish + permissions: + contents: read + id-token: write + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Verify release tag + shell: bash + run: | + set -euo pipefail + + version="$(node -p "require('./package.json').version")" + tag="${GITHUB_REF_NAME}" + + if [[ "${tag}" != "v${version}" ]]; then + echo "Release tag ${tag} does not match package version ${version}." + exit 1 + fi + + tag_commit="$(git rev-list -n 1 "${tag}")" + git fetch --no-tags origin master + + if ! git merge-base --is-ancestor "${tag_commit}" origin/master; then + echo "Release tag ${tag} does not point to a commit reachable from origin/master." + exit 1 + fi + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + package-manager-cache: false + + - name: Set up pnpm + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 + with: + version: 11.5.1 + run_install: false + cache: false + + - name: Install dependencies without cache + run: pnpm install --frozen-lockfile + + - name: Run tests + run: pnpm run test + + - name: Run TypeScript checks + run: pnpm exec tsc -p tsconfig.json --noEmit + + - name: Run lint + run: pnpm run lint + + - name: Clean build output + run: pnpm run clean + + - name: Build package + run: pnpm run build + + - name: Inspect package contents + run: npm pack --dry-run + + - name: Publish to npm + run: npm publish --access public