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
50 changes: 16 additions & 34 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,36 @@ on:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened, edited, ready_for_review]
workflow_call:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm tsc
- run: pnpm lint
- name: Check formatting
run: pnpm exec oxfmt --check .
- run: pnpm test --coverage
# --- repository-specific steps (package-content check, size budget, e2e, docs, ...) go here ---
- name: Verify published packages include dist
run: |
for pkg in packages/hdrify packages/cli packages/hdrify-react; do
Expand All @@ -31,17 +43,11 @@ jobs:
exit 1
}
done
- name: Generate OpenCLI spec
run: node packages/cli/dist/index.js docgen --output packages/cli/opencli.json
- uses: bhouston/clidoc-action@v1
with:
files: packages/cli/opencli.json
- run: pnpm tsc
- run: pnpm lint
- run: pnpm test --coverage
- run: pnpm release:check
- name: Bundle size budget
run: pnpm size | tee -a "$GITHUB_STEP_SUMMARY"
- name: Package VS Code extension
run: pnpm --filter hdrify-vscode-extension run package
- name: Audit dependencies
id: audit
continue-on-error: true
Expand All @@ -54,32 +60,8 @@ jobs:
name: coverage-${{ github.run_id }}-${{ github.job }}
path: coverage/
- uses: codecov/codecov-action@v5
if: ${{ !cancelled() && hashFiles('coverage/lcov.info') != '' }}
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage/lcov.info
fail_ci_if_error: false

contribution:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Validate issue link
run: node scripts/check-pr.mjs
- name: Lint PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint
- name: Lint feature commits
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: pnpm exec commitlint --from "$BASE_SHA" --to "$HEAD_SHA"
39 changes: 39 additions & 0 deletions .github/workflows/pr-policy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: pr-policy

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

permissions:
contents: read

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

jobs:
contribution:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts
- name: Validate target branch and linked issue
run: node scripts/check-pr.mjs
- name: Lint PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint
- name: Lint PR commits
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: pnpm exec commitlint --from "$BASE_SHA" --to "$HEAD_SHA"
32 changes: 23 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ on:
type: boolean
default: false

concurrency:
group: npm-release
cancel-in-progress: false

permissions:
contents: read

concurrency:
group: release
cancel-in-progress: false

jobs:
guard:
runs-on: ubuntu-latest
Expand All @@ -24,35 +24,49 @@ jobs:
run: |
echo "::error::Release must be dispatched with ref=main (got ${{ github.ref }})."
exit 1

checks:
needs: guard
uses: ./.github/workflows/ci.yml
secrets: inherit

release:
needs: checks
needs: [guard, checks]
runs-on: ubuntu-latest
environment: npm
permissions:
contents: write
id-token: write
env:
HUSKY: '0'
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false
- name: Verify main has not advanced since dispatch
env:
GH_TOKEN: ${{ github.token }}
run: |
head="$(gh api "repos/${{ github.repository }}/git/ref/heads/main" --jq .object.sha)"
if [ "$head" != "$GITHUB_SHA" ]; then
echo "::error::main moved from $GITHUB_SHA to $head after dispatch; dispatch the release again."
exit 1
fi
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Require an existing release baseline
run: git rev-parse --verify refs/tags/v1.1.4
- run: pnpm build
- name: Release packages and changelog
- name: Release
run: pnpm release ${{ inputs.dry_run && '--dry-run' || '' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
- name: Summary
if: inputs.dry_run
run: echo "Dry run complete — no packages were published, no tag was created." >> "$GITHUB_STEP_SUMMARY"
run: echo "Dry run complete; nothing was published and no tag was created." >> "$GITHUB_STEP_SUMMARY"
2 changes: 1 addition & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"singleQuote": true,
"printWidth": 120,
"ignorePatterns": ["submodule/**", "**/routeTree.gen.ts"]
"ignorePatterns": ["**/*.gen.ts"]
}
5 changes: 3 additions & 2 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
"plugins": ["eslint", "typescript", "oxc", "unicorn", "react", "jsx-a11y"],
"rules": {
"eslint/no-underscore-dangle": "off",
"no-unused-private-class-members": "off",
"eslint/no-unused-private-class-members": "error",
"react/react-in-jsx-scope": "off",
"typescript/no-explicit-any": "error",
"unicorn/no-new-array": "off"
},
"overrides": [
{
"files": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"],
"files": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx", "**/test/**", "**/tests/**"],
"plugins": ["eslint", "typescript", "oxc", "unicorn", "react", "jsx-a11y", "vitest"]
}
]
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
submodule/**
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
"build": "pnpm -r build",
"dev": "pnpm -r --parallel dev",
"clean": "rimraf dist packages/**/dist .nx node_modules packages/**/node_modules",
"check": "pnpm lint && pnpm format",
"tsc": "pnpm -r tsc",
"test": "pnpm vitest",
"test": "vitest run",
"test:profile": "PROFILE=1 pnpm vitest run --no-coverage",
"test:profile:main": "node --cpu-prof --cpu-prof-dir=./profile-output ./node_modules/vitest/vitest.mjs run --no-coverage",
"profile:analyze": "node scripts/analyze-cpuprofile.mjs",
Expand All @@ -21,8 +20,7 @@
"hdrify": "node ./packages/cli/dist/index.js",
"release": "semantic-release",
"release:check": "node --test scripts/release.test.mjs",
"size": "size-limit",
"format:check": "oxfmt --check ."
"size": "size-limit"
},
"devDependencies": {
"@anolilab/semantic-release-pnpm": "^8.1.25",
Expand Down Expand Up @@ -77,7 +75,7 @@
}
],
"engines": {
"node": ">=26.0.0"
"node": ">=22.0.0"
},
"packageManager": "pnpm@11.27.0"
}
2 changes: 1 addition & 1 deletion packages/hdrify-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
"react-dom": "^18.0.0 || ^19.0.0"
},
"engines": {
"node": ">=26.0.0"
"node": ">=22.0.0"
}
}
2 changes: 1 addition & 1 deletion packages/hdrify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@
"exifreader": "^4.36.0"
},
"engines": {
"node": ">=26.0.0"
"node": ">=22.0.0"
}
}
7 changes: 0 additions & 7 deletions scripts/release-vscode-extension.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ export function setVersion(version) {
// and Open VSX (the registry Cursor and other VS Code-compatible editors
// use). Requires VSCE_PAT / OVSX_PAT in the environment.
export function publish() {
const missing = [!process.env.VSCE_PAT && 'VSCE_PAT', !process.env.OVSX_PAT && 'OVSX_PAT'].filter(Boolean);
if (missing.length > 0) {
throw new Error(
`Cannot publish the VS Code extension: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} not set. Configure ${missing.length > 1 ? 'them' : 'it'} as repository secret(s) (see RELEASING.md) before dispatching a release.`,
);
}

execFileSync('pnpm', ['--filter', 'hdrify-vscode-extension', 'run', 'build'], { stdio: 'inherit' });
execFileSync('pnpm', ['--filter', 'hdrify-vscode-extension', 'exec', 'vsce', 'package', '--no-dependencies'], {
stdio: 'inherit',
Expand Down
13 changes: 0 additions & 13 deletions scripts/release.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { resolve } from 'node:path';
import test from 'node:test';
import { analyzeCommits } from '@semantic-release/commit-analyzer';
import { checkPullRequest } from './check-pr.mjs';
import { publish as publishExtension } from './release-vscode-extension.mjs';

// Published via pnpm publish directly (see release.config.js): pnpm rewrites
// workspace:* deps and packs the `files` field natively, so these packages
Expand Down Expand Up @@ -41,18 +40,6 @@ for (const [message, expected] of [
});
}

test('VS Code extension publish fails fast with a clear error when VSCE_PAT/OVSX_PAT are unset', () => {
const { VSCE_PAT, OVSX_PAT } = process.env;
delete process.env.VSCE_PAT;
delete process.env.OVSX_PAT;
try {
assert.throws(() => publishExtension(), /VSCE_PAT and OVSX_PAT are not set/);
} finally {
if (VSCE_PAT !== undefined) process.env.VSCE_PAT = VSCE_PAT;
if (OVSX_PAT !== undefined) process.env.OVSX_PAT = OVSX_PAT;
}
});

test('PR policy enforces issue link and integration target, not branch name', () => {
const pr = {
base: { ref: 'main' },
Expand Down
Loading