Skip to content
This repository was archived by the owner on Mar 9, 2026. It is now read-only.
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
30 changes: 30 additions & 0 deletions .github/actions/setup-environment/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Setup Environment
description: Setup Bun and install dependencies with caching

runs:
using: composite
steps:
- name: Setup Bun
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2

- name: Restore dependences cache
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
id: restore-bun-dependences-cache
with:
path: node_modules
key: ${{ runner.os }}-bun-dependences-${{ hashFiles('**/bun.lock') }}

- name: Install dependencies
# Install only if cache is not matched.
if: ${{ !contains(steps.restore-bun-dependences-cache.outputs.cache-matched-key, steps.restore-bun-dependences-cache.outputs.cache-primary-key) }}
run: bun install --frozen-lockfile
shell: bash

- name: Save dependences cache
# Execute cache by default branch only.
if: ${{ github.ref_name == github.event.repository.default_branch && !contains(steps.restore-bun-dependences-cache.outputs.cache-matched-key, steps.restore-bun-dependences-cache.outputs.cache-primary-key) }}
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
id: save-dependences-cache
with:
path: node_modules
key: ${{ runner.os }}-bun-dependences-${{ hashFiles('**/bun.lock') }}
30 changes: 30 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Codecov configuration for safe-formdata
# This project requires 100% test coverage

coverage:
precision: 2
round: down
range: "100...100"

status:
project:
default:
target: 100%
threshold: 0%
if_ci_failed: error

patch:
default:
target: 100%
threshold: 0%
if_ci_failed: error

comment:
layout: "header, diff, flags, components"
behavior: default
require_changes: false
require_base: false
require_head: true

github_checks:
annotations: true
22 changes: 22 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
changelog:
exclude:
labels:
- "ignore for release"

categories:
- title: Security Fixes
labels: ["Type: Security", "security"]
- title: Breaking Changes
labels: ["Type: Breaking Change"]
- title: Features
labels: ["Type: Feature"]
- title: Bug Fixes
labels: ["Type: Bug"]
- title: Documentation
labels: ["Type: Documentation"]
- title: CI
labels: ["Type: CI"]
- title: Dependency Updates
labels: ["Type: Dependencies", "dependencies"]
- title: Other Changes
labels: ["*"]
30 changes: 30 additions & 0 deletions .github/workflows/assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Auto Assign
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

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

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

defaults:
run:
shell: bash

jobs:
assign:
runs-on: ubuntu-slim
timeout-minutes: 2
permissions:
pull-requests: write
steps:
- name: Assign PR to author if no assignees
if: ${{ github.event.pull_request.user.type != 'Bot' && toJSON(github.event.pull_request.assignees) == '[]' }}
run: gh pr edit $NUMBER --add-assignee $ASSIGNEE
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
ASSIGNEE: ${{ github.event.pull_request.user.login }}
30 changes: 30 additions & 0 deletions .github/workflows/call-dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Dependency Review (workflow_call)
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on: workflow_call

permissions:
contents: read
pull-requests: write

defaults:
run:
shell: bash

jobs:
dependency-review:
name: Review Dependencies
runs-on: ubuntu-slim
timeout-minutes: 2
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Dependency Review
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
with:
deny-licenses: GPL-2.0, GPL-3.0
fail-on-severity: moderate
comment-summary-in-pr: always
35 changes: 35 additions & 0 deletions .github/workflows/call-export-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Export Validation (workflow_call)
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on: workflow_call

defaults:
run:
shell: bash

jobs:
export-validation:
name: Export Validation
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Initialize
uses: ./.github/actions/setup-environment

- name: Build package
run: bun run build

- name: Verify build outputs
run: |
test -f dist/index.js || (echo "dist/index.js not found" && exit 1)
test -f dist/index.js.map || (echo "dist/index.js.map not found" && exit 1)
test -f dist/index.d.ts || (echo "dist/index.d.ts not found" && exit 1)
echo "Build verification successful"

- name: Validate exports
run: bun run check:package
25 changes: 25 additions & 0 deletions .github/workflows/call-lint-format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lint & Format Check (workflow_call)
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on: workflow_call

defaults:
run:
shell: bash

jobs:
lint-format:
name: Lint & Format Check
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Initialize
uses: ./.github/actions/setup-environment

- name: Run Lint & Format Check
run: bun run check:source
36 changes: 36 additions & 0 deletions .github/workflows/call-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Test (workflow_call)
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on:
workflow_call:
secrets:
CODECOV_TOKEN:
description: Token for Codecov upload
required: true

defaults:
run:
shell: bash

jobs:
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Initialize
uses: ./.github/actions/setup-environment

- name: Run tests with coverage
run: bun run test:coverage

- name: Upload coverage to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
25 changes: 25 additions & 0 deletions .github/workflows/call-type-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Type Check (workflow_call)
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on: workflow_call

defaults:
run:
shell: bash

jobs:
type-check:
name: TypeScript Type Check
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Initialize
uses: ./.github/actions/setup-environment

- name: Run type check
run: bun run check:type
82 changes: 82 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI
run-name: "${{ github.workflow }} (${{ github.ref_name }}): ${{ github.event.pull_request.title }}"

on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened, ready_for_review]

defaults:
run:
shell: bash

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# This workflow contains core CI jobs that run on push/pull_request events.
# For additional jobs, create separate workflow_call files (e.g., call-*.yml)
# and invoke them from this workflow. See .github/workflows/call-dependency-review.yml for reference.
jobs:
setup:
name: Setup
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: read
if: ${{ !github.event.pull_request.draft }}
outputs:
dependencies: ${{ steps.filter.outputs.dependencies }}
typescript: ${{ steps.filter.outputs.typescript }}
steps:
- name: Checkout Repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Initialize
uses: ./.github/actions/setup-environment

- name: Check diff targets by path filters
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
dependencies:
- 'bun.lock'
typescript:
- 'bun.lock'
- '**/tsconfig*.json'
- '**/*.ts'
- '**/*.tsx'

lint-format:
needs: [setup]
uses: ./.github/workflows/call-lint-format.yml

type-check:
needs: [setup]
if: ${{ needs.setup.outputs.typescript == 'true' }}
uses: ./.github/workflows/call-type-check.yml

test:
needs: [setup]
uses: ./.github/workflows/call-test.yml
secrets:
CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"

export-validation:
needs: [setup, lint-format, type-check, test]
if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/call-export-validation.yml

status-check:
name: Status Check
runs-on: ubuntu-slim
timeout-minutes: 1
needs: [setup, lint-format, type-check, test, export-validation]
if: always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled'))
steps:
- run: exit 1
Loading