Skip to content

Commit 048dd62

Browse files
authored
Merge pull request #6 from link-foundation/issue-5-6ad76e6429cf
Add CI workflow and development best practices from template
2 parents 8aa9921 + f748dba commit 048dd62

File tree

78 files changed

+8214
-1883
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+8214
-1883
lines changed

.changeset/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changesets
2+
3+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4+
with multi-package repos, or single-package repos to help you version and publish your code. You can
5+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6+
7+
We have a quick list of common questions to get you started engaging with this project in
8+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

.changeset/add-ci-workflow.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'browser-commander': patch
3+
---
4+
5+
Add CI workflow and development best practices
6+
7+
- Add GitHub Actions workflow for tests on push and PRs
8+
- Add changeset configuration for version management
9+
- Add Prettier for code formatting
10+
- Add ESLint with Prettier integration
11+
- Add jscpd for code duplication detection
12+
- Add Husky pre-commit hooks
13+
- Add release scripts for automated publishing

.changeset/config.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3+
"changelog": "@changesets/cli/changelog",
4+
"commit": false,
5+
"fixed": [],
6+
"linked": [],
7+
"access": "public",
8+
"baseBranch": "main",
9+
"updateInternalDependencies": "patch",
10+
"ignore": []
11+
}

.github/workflows/release.yml

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
name: Checks and release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
types: [opened, synchronize, reopened]
9+
# Manual release support - consolidated here to work with npm trusted publishing
10+
# npm only allows ONE workflow file as trusted publisher, so all publishing
11+
# must go through this workflow (release.yml)
12+
workflow_dispatch:
13+
inputs:
14+
release_mode:
15+
description: 'Manual release mode'
16+
required: true
17+
type: choice
18+
default: 'instant'
19+
options:
20+
- instant
21+
- changeset-pr
22+
bump_type:
23+
description: 'Manual release type'
24+
required: true
25+
type: choice
26+
options:
27+
- patch
28+
- minor
29+
- major
30+
description:
31+
description: 'Manual release description (optional)'
32+
required: false
33+
type: string
34+
35+
concurrency: ${{ github.workflow }}-${{ github.ref }}
36+
37+
jobs:
38+
# Changeset check - only runs on PRs
39+
changeset-check:
40+
name: Check for Changesets
41+
runs-on: ubuntu-latest
42+
if: github.event_name == 'pull_request'
43+
steps:
44+
- uses: actions/checkout@v4
45+
with:
46+
fetch-depth: 0
47+
48+
- name: Setup Node.js
49+
uses: actions/setup-node@v4
50+
with:
51+
node-version: '20.x'
52+
53+
- name: Install dependencies
54+
run: npm install
55+
56+
- name: Check for changesets
57+
env:
58+
# Pass PR context to the validation script
59+
GITHUB_BASE_REF: ${{ github.base_ref }}
60+
GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }}
61+
GITHUB_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
62+
run: |
63+
# Skip changeset check for automated version PRs
64+
if [[ "${{ github.head_ref }}" == "changeset-release/"* ]]; then
65+
echo "Skipping changeset check for automated release PR"
66+
exit 0
67+
fi
68+
69+
# Run changeset validation script
70+
# This validates that exactly ONE changeset was ADDED by this PR
71+
# Pre-existing changesets from other merged PRs are ignored
72+
node scripts/validate-changeset.mjs
73+
74+
# Linting and formatting - runs after changeset check on PRs, immediately on main
75+
lint:
76+
name: Lint and Format Check
77+
runs-on: ubuntu-latest
78+
needs: [changeset-check]
79+
if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
80+
steps:
81+
- uses: actions/checkout@v4
82+
83+
- name: Setup Node.js
84+
uses: actions/setup-node@v4
85+
with:
86+
node-version: '20.x'
87+
88+
- name: Install dependencies
89+
run: npm install
90+
91+
- name: Run ESLint
92+
run: npm run lint
93+
94+
- name: Check formatting
95+
run: npm run format:check
96+
97+
- name: Check code duplication
98+
run: npm run check:duplication
99+
100+
# Test job - runs on Node.js only (browser automation requires specific setup)
101+
test:
102+
name: Test (Node.js on ${{ matrix.os }})
103+
runs-on: ${{ matrix.os }}
104+
needs: [changeset-check]
105+
if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
106+
strategy:
107+
fail-fast: false
108+
matrix:
109+
os: [ubuntu-latest, macos-latest, windows-latest]
110+
steps:
111+
- uses: actions/checkout@v4
112+
113+
- name: Setup Node.js
114+
uses: actions/setup-node@v4
115+
with:
116+
node-version: '20.x'
117+
118+
- name: Install dependencies
119+
run: npm install
120+
121+
- name: Run unit tests
122+
run: npm test
123+
124+
# Release - only runs on main after tests pass (for push events)
125+
release:
126+
name: Release
127+
needs: [lint, test]
128+
# Use always() to ensure this job runs even if changeset-check was skipped
129+
# This is needed because lint/test jobs have a transitive dependency on changeset-check
130+
if: always() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.lint.result == 'success' && needs.test.result == 'success'
131+
runs-on: ubuntu-latest
132+
# Permissions required for npm OIDC trusted publishing
133+
permissions:
134+
contents: write
135+
pull-requests: write
136+
id-token: write
137+
steps:
138+
- uses: actions/checkout@v4
139+
with:
140+
fetch-depth: 0
141+
142+
- name: Setup Node.js
143+
uses: actions/setup-node@v4
144+
with:
145+
node-version: '20.x'
146+
registry-url: 'https://registry.npmjs.org'
147+
148+
- name: Install dependencies
149+
run: npm install
150+
151+
- name: Update npm for OIDC trusted publishing
152+
run: node scripts/setup-npm.mjs
153+
154+
- name: Check for changesets
155+
id: check_changesets
156+
run: |
157+
# Count changeset files (excluding README.md and config.json)
158+
CHANGESET_COUNT=$(find .changeset -name "*.md" ! -name "README.md" | wc -l)
159+
echo "Found $CHANGESET_COUNT changeset file(s)"
160+
echo "has_changesets=$([[ $CHANGESET_COUNT -gt 0 ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
161+
echo "changeset_count=$CHANGESET_COUNT" >> $GITHUB_OUTPUT
162+
163+
- name: Merge multiple changesets
164+
if: steps.check_changesets.outputs.has_changesets == 'true' && steps.check_changesets.outputs.changeset_count > 1
165+
run: |
166+
echo "Multiple changesets detected, merging..."
167+
node scripts/merge-changesets.mjs
168+
169+
- name: Version packages and commit to main
170+
if: steps.check_changesets.outputs.has_changesets == 'true'
171+
id: version
172+
run: node scripts/version-and-commit.mjs --mode changeset
173+
174+
- name: Publish to npm
175+
# Run if version was committed OR if a previous attempt already committed (for re-runs)
176+
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
177+
id: publish
178+
run: node scripts/publish-to-npm.mjs --should-pull
179+
180+
- name: Create GitHub Release
181+
if: steps.publish.outputs.published == 'true'
182+
env:
183+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
184+
run: node scripts/create-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}"
185+
186+
- name: Format GitHub release notes
187+
if: steps.publish.outputs.published == 'true'
188+
env:
189+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
190+
run: node scripts/format-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}"
191+
192+
# Manual Instant Release - triggered via workflow_dispatch with instant mode
193+
# This job is in release.yml because npm trusted publishing
194+
# only allows one workflow file to be registered as a trusted publisher
195+
instant-release:
196+
name: Instant Release
197+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant'
198+
runs-on: ubuntu-latest
199+
# Permissions required for npm OIDC trusted publishing
200+
permissions:
201+
contents: write
202+
pull-requests: write
203+
id-token: write
204+
steps:
205+
- uses: actions/checkout@v4
206+
with:
207+
fetch-depth: 0
208+
209+
- name: Setup Node.js
210+
uses: actions/setup-node@v4
211+
with:
212+
node-version: '20.x'
213+
registry-url: 'https://registry.npmjs.org'
214+
215+
- name: Install dependencies
216+
run: npm install
217+
218+
- name: Update npm for OIDC trusted publishing
219+
run: node scripts/setup-npm.mjs
220+
221+
- name: Version packages and commit to main
222+
id: version
223+
run: node scripts/version-and-commit.mjs --mode instant --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
224+
225+
- name: Publish to npm
226+
# Run if version was committed OR if a previous attempt already committed (for re-runs)
227+
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
228+
id: publish
229+
run: node scripts/publish-to-npm.mjs
230+
231+
- name: Create GitHub Release
232+
if: steps.publish.outputs.published == 'true'
233+
env:
234+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
235+
run: node scripts/create-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}"
236+
237+
- name: Format GitHub release notes
238+
if: steps.publish.outputs.published == 'true'
239+
env:
240+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
241+
run: node scripts/format-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}"
242+
243+
# Manual Changeset PR - creates a pull request with the changeset for review
244+
changeset-pr:
245+
name: Create Changeset PR
246+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'changeset-pr'
247+
runs-on: ubuntu-latest
248+
permissions:
249+
contents: write
250+
pull-requests: write
251+
steps:
252+
- uses: actions/checkout@v4
253+
with:
254+
fetch-depth: 0
255+
256+
- name: Setup Node.js
257+
uses: actions/setup-node@v4
258+
with:
259+
node-version: '20.x'
260+
261+
- name: Install dependencies
262+
run: npm install
263+
264+
- name: Create changeset file
265+
run: node scripts/create-manual-changeset.mjs --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
266+
267+
- name: Format changeset with Prettier
268+
run: |
269+
# Run Prettier on the changeset file to ensure it matches project style
270+
npx prettier --write ".changeset/*.md" || true
271+
272+
echo "Formatted changeset files"
273+
274+
- name: Create Pull Request
275+
uses: peter-evans/create-pull-request@v7
276+
with:
277+
token: ${{ secrets.GITHUB_TOKEN }}
278+
commit-message: 'chore: add changeset for manual ${{ github.event.inputs.bump_type }} release'
279+
branch: changeset-manual-release-${{ github.run_id }}
280+
delete-branch: true
281+
title: 'chore: manual ${{ github.event.inputs.bump_type }} release'
282+
body: |
283+
## Manual Release Request
284+
285+
This PR was created by a manual workflow trigger to prepare a **${{ github.event.inputs.bump_type }}** release.
286+
287+
### Release Details
288+
- **Type:** ${{ github.event.inputs.bump_type }}
289+
- **Description:** ${{ github.event.inputs.description || 'Manual release' }}
290+
- **Triggered by:** @${{ github.actor }}
291+
292+
### Next Steps
293+
1. Review the changeset in this PR
294+
2. Merge this PR to main
295+
3. The automated release workflow will create a version PR
296+
4. Merge the version PR to publish to npm and create a GitHub release

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,6 @@ dist
137137
# Vite logs files
138138
vite.config.js.timestamp-*
139139
vite.config.ts.timestamp-*
140+
141+
# jscpd reports
142+
reports/

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

.jscpd.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"threshold": 0,
3+
"minTokens": 30,
4+
"minLines": 5,
5+
"skipComments": true,
6+
"ignore": [
7+
"**/node_modules/**",
8+
"**/build/**",
9+
"**/dist/**",
10+
"**/*.min.js",
11+
"**/coverage/**",
12+
"**/.changeset/**",
13+
"**/package-lock.json",
14+
"**/pnpm-lock.yaml",
15+
"**/yarn.lock"
16+
],
17+
"format": "console",
18+
"reporters": ["console", "html"],
19+
"output": "./reports/jscpd"
20+
}

.prettierignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
coverage
3+
dist
4+
*.min.js
5+
package-lock.json
6+
.eslintcache
7+
CLAUDE.md

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "es5",
4+
"singleQuote": true,
5+
"printWidth": 80,
6+
"tabWidth": 2,
7+
"useTabs": false,
8+
"arrowParens": "always",
9+
"endOfLine": "lf"
10+
}

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## 0.1.0
6+
7+
### Minor Changes
8+
9+
- Initial release of browser-commander with unified Playwright and Puppeteer API

0 commit comments

Comments
 (0)