Skip to content

Commit f6c45f5

Browse files
JulianCataldoCopilot
andcommitted
ci: prepare for (overhauled version) release
Co-authored-by: Copilot <copilot@github.com>
1 parent dabd9ab commit f6c45f5

10 files changed

Lines changed: 2048 additions & 3116 deletions

File tree

.github/workflows/release.yaml

Lines changed: 60 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
22
# See: https://github.com/JulianCataldo/gh-actions
33

4-
# For matrix setup:
5-
# https://github.com/withastro/astro/blob/main/.github/workflows/ci.yml
6-
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow
7-
84
name: CI / Release
95

106
on:
@@ -23,227 +19,141 @@ on:
2319
- beta
2420
- 'feat/*'
2521
- 'fix/*'
26-
# - to-integrate
27-
# - to-integrate-next
2822

2923
permissions:
30-
contents: read # for checkout
24+
contents: read
25+
26+
concurrency:
27+
group: ci-release-${{ github.workflow }}-${{ github.ref }}
28+
cancel-in-progress: true
29+
30+
env:
31+
NODE_VERSION: 24
3132

3233
jobs:
3334
release:
3435
name: CI / Release
35-
36-
permissions:
37-
contents: write # to be able to publish a GitHub release
38-
issues: write # to be able to comment on released issues
39-
pull-requests: write # to be able to comment on released pull requests
40-
id-token: write # to enable use of OIDC for npm provenance
41-
42-
timeout-minutes: 30
43-
4436
runs-on: ubuntu-latest
45-
# TODO:
46-
# runs-on: ${{ matrix.os }}
47-
# timeout-minutes: 25
48-
# # needs: build
49-
# strategy:
50-
# matrix:
51-
# OS: [ubuntu-latest]
52-
# NODE_VERSION: [18, 20]
53-
# include:
54-
# - os: macos-14
55-
# NODE_VERSION: 18
56-
# - os: windows-latest
57-
# NODE_VERSION: 18
58-
# fail-fast: false
59-
# env:
60-
# NODE_VERSION: ${{ matrix.NODE_VERSION }}
37+
timeout-minutes: 30
38+
permissions:
39+
contents: write
40+
issues: write
41+
pull-requests: write
42+
id-token: write
6143

6244
steps:
63-
# MARK: Setup GH Action
64-
65-
- name: 'Harden Runner'
66-
uses: 'step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b' # v2.15.0
45+
- name: Harden runner
46+
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
6747
with:
68-
egress-policy: 'audit'
48+
egress-policy: audit
6949

7050
- name: Git checkout
7151
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
72-
# run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
7352
with:
7453
fetch-depth: 0
7554

76-
# - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
77-
# persist-credentials: false
78-
# env:
79-
# GIT_COMMITTER_NAME: "GitHub Actions Shell"
80-
# GIT_AUTHOR_NAME: "GitHub Actions Shell"
81-
# EMAIL: "github-actions[bot]@users.noreply.github.com"
82-
83-
# MARK: Setup Node env.
84-
8555
- name: Setup PNPM
8656
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
8757

88-
- name: Use Node.js 24
58+
- name: Use Node.js ${{ env.NODE_VERSION }}
8959
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
9060
with:
91-
registry-url: 'https://registry.npmjs.org'
92-
node-version: 24
61+
registry-url: https://registry.npmjs.org
62+
node-version: ${{ env.NODE_VERSION }}
9363
cache: pnpm
9464

9565
- name: Install packages
96-
shell: bash
9766
run: pnpm install --frozen-lockfile
9867

99-
# TODO: More tests
100-
# - name: Syncpack Lint
101-
# shell: bash
102-
# run: node --run syncpack:lint
103-
104-
# NOTE: Audit is for prod only because a lot of root packages (like lerna etc.)
105-
# are used old packages with intricate dependency trees, and they are
106-
# never shipped to the user. But that's not 100% optimal, as devDeps could
107-
# provoke some sec issues, too? A middleground is better than nothing and
108-
# regularly blocked releases for obscure root mono-repo tooling deps.
109-
- name: 'Verify the integrity of provenance attestations and registry
110-
signatures for installed [prod] dependencies'
68+
- name: Verify installed prod dependency attestations
11169
run: node --run audit
11270

113-
# MARK: Lint/Checks pre-build
114-
115-
# TODO: Setup Husky etc.
116-
# - name: Lint last commit — Commitlint
117-
# shell: bash
118-
# run: node --run lint:commit
119-
120-
# - name: Lint CSS — Stylelint
121-
# shell: bash
122-
# run: node --run lint:css
123-
124-
- name: Check all formatting — Prettier
125-
shell: bash
126-
run: node --run format
127-
128-
# MARK: Build packages
129-
13071
- name: Setup Turbo cache
13172
uses: dtinth/setup-github-actions-caching-for-turbo@cc723b4600e40a6b8815b65701d8614b91e2669e # v1.3.0
13273

133-
- name: Build all packages
134-
shell: bash
135-
run: node --run build
74+
- name: Clean build outputs
75+
run: node --run clean
13676

137-
# MARK: Lint/Checks post-build
77+
- name: Build packages
78+
run: node --run build
13879

13980
- name: Cache ESLint results
14081
uses: actions/cache@v4
14182
with:
14283
path: .eslintcache
143-
key: eslint-${{ hashFiles('pnpm-lock.yaml', 'eslint.config.js') }}
84+
key: eslint-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'eslint.config.js') }}
14485

145-
- name: Lint JS/TS — ESLint
146-
shell: bash
86+
- name: Lint JS and TS
14787
run: node --run lint:es
14888

149-
# MARK:Tests
89+
- name: Lint CSS
90+
run: node --run lint:style
15091

151-
- name: Tests — Units
152-
shell: bash
153-
run: node --run test:unit
92+
- name: Check formatting
93+
run: node --run format
15494

155-
# - name: Tests — Integration
156-
# shell: bash
157-
# run: node --run test:integration
95+
- name: Tests - units
96+
run: node --run test:unit
15897

159-
# TODO: Build and launch example-app
160-
# - name: Tests — E2E
161-
# shell: bash
162-
# run: node --run test:e2e
98+
- name: Cache Playwright browsers
99+
uses: actions/cache@v4
100+
with:
101+
path: ~/.cache/ms-playwright
102+
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
163103

164-
# MARK: Publish packages
104+
- name: Install Playwright browsers
105+
working-directory: e2e
106+
run: pnpm exec playwright install --with-deps chromium
165107

166-
# NOTE: Auth is configured by setup-node's registry-url above.
167-
# The NPM_TOKEN secret MUST be a Granular Access Token (or classic Automation
168-
# token) to bypass 2FA/OTP requirements in CI.
108+
- name: Tests - E2E
109+
run: node --run test:e2e
169110

170111
- name: Git user configuration
112+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next'
171113
run: |
172114
git config --global user.name "${{ github.actor }}"
173115
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
174116
175-
# MARK: [MAIN]
176-
# --force-git-tag: a prior interrupted CI run may have left orphan tags
177-
# (e.g. @jsfe/engine@0.5.0) that collide with graduation.
178-
- name: 'Lerna publish [main]'
179-
# if: github.ref == 'refs/heads/to-integrate'
117+
- name: Publish [main]
180118
if: github.ref == 'refs/heads/main'
181-
# https://github.com/lerna/lerna/issues/2532
182119
id: graduateRelease
183120
continue-on-error: true
184121
env:
185-
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
186-
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
122+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
123+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
187124
NPM_CONFIG_PROVENANCE: 'true'
188125
run: |
189-
pnpm lerna publish --message 'chore: publish [main] release [skip ci]' --create-release=github --conventional-graduate --force-git-tag --yes
190-
191-
# Fallback for https://github.com/lerna/lerna/issues/2532 (newly introduced
192-
# packages that fail --conventional-graduate). Fail explicitly if neither
193-
# the graduate nor the fallback actually published anything.
194-
- name: 'Lerna publish [main] — fallback (non-graduate)'
195-
if: ${{ always() && github.ref == 'refs/heads/main' &&
196-
steps.graduateRelease.outcome == 'failure' }}
126+
pnpm exec lerna publish --message 'chore: publish [main] release [skip ci]' --create-release=github --conventional-graduate --force-git-tag --yes
127+
128+
- name: Publish [main] fallback
129+
if: ${{ always() && github.ref == 'refs/heads/main' && steps.graduateRelease.outcome == 'failure' }}
197130
env:
198-
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
199-
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
131+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
132+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
200133
NPM_CONFIG_PROVENANCE: 'true'
201134
run: |
202-
echo "Graduate publish failed attempting recovery"
135+
echo "Graduate publish failed - attempting recovery"
203136
git stash || true
204137
205-
# Recovery 1: from-package (handles Sigstore/Rekor TLOG_CREATE_ENTRY_ERROR 409)
206-
# Queries npm directly and publishes any package versions not yet in the registry,
207-
# regardless of git tags — safe to run even if some packages are already published.
208138
echo "==> from-package: recovering partial publish"
209-
FROM_PKG_OUT=$(pnpm lerna publish from-package --yes 2>&1)
139+
FROM_PKG_OUT=$(pnpm exec lerna publish from-package --yes 2>&1)
210140
FROM_PKG_EXIT=$?
211141
echo "$FROM_PKG_OUT"
212142
213-
# Recovery 2: non-graduate lerna publish (handles lerna#2532: newly introduced
214-
# packages that have no pre-release version to graduate from).
215143
echo "==> non-graduate: publishing new or changed packages"
216-
OUTPUT=$(pnpm lerna publish --message 'chore: publish [main] release [skip ci]' --create-release=github --yes 2>&1) || true
144+
OUTPUT=$(pnpm exec lerna publish --message 'chore: publish [main] release [skip ci]' --create-release=github --yes 2>&1) || true
217145
echo "$OUTPUT"
218146
219-
# Fail explicitly only when BOTH approaches published nothing useful.
220147
if [ "$FROM_PKG_EXIT" -ne 0 ] && echo "$OUTPUT" | grep -q 'No changed packages to publish'; then
221148
echo "::error::Neither from-package nor conventional fallback published anything"
222149
exit 1
223150
fi
224151
225-
# # TRY: https://www.jessesquires.com/blog/2021/10/17/github-actions-workflows-for-automatic-rebasing-and-merging/
226-
# - name: Merge (rebase) back main into next
227-
# env:
228-
# GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
229-
# run: |
230-
# git checkout next
231-
# git rebase main
232-
# git push
233-
234-
# MARK: [NEXT]
235-
- name: 'Lerna publish [next]'
152+
- name: Publish [next]
236153
if: github.ref == 'refs/heads/next'
237-
# if: github.ref == 'refs/heads/to-integrate-next'
238154
env:
239-
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
240-
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
155+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
156+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
241157
NPM_CONFIG_PROVENANCE: 'true'
242-
243-
# --canary next
244-
# https://github.com/lerna/lerna/issues/1433
245-
# pnpm lerna publish --conventional-prerelease --dist-tag=next --preid=next --no-changelog --yes
246-
# pnpm lerna publish --conventional-prerelease --pre-dist-tag=next --preid=next --yes
247-
# pnpm lerna publish --force-publish='*' --canary --pre-dist-tag=next --preid=next --yes
248158
run: |
249-
pnpm lerna publish --message 'chore: publish [next] pre-release' --conventional-prerelease --pre-dist-tag=next --preid=next --yes
159+
pnpm exec lerna publish --message 'chore: publish [next] pre-release' --conventional-prerelease --pre-dist-tag=next --preid=next --yes

example-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"@vitejs/plugin-react": "^4.4.1",
2222
"@vtaits/react-signals": "^1.0.2",
2323
"arktype": "^2.1.20",
24-
"hono": "^4.7.7",
24+
"hono": "^4.12.18",
2525
"lit": "catalog:",
2626
"react": "catalog:",
2727
"react-dom": "^19.1.0",

knip.jsonc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"workspaces": {
3+
".": {
4+
"entry": [
5+
"custom-elements-manifest.config.js",
6+
"local-ci.sh",
7+
"scripts/**/*.{js,cjs,mjs}",
8+
],
9+
"project": ["*.{js,cjs,mjs}", "scripts/**/*.{js,cjs,mjs}"],
10+
"ignoreDependencies": ["web-elements-analyzer"],
11+
},
12+
"example-app": {
13+
"entry": [
14+
"src/document.ts",
15+
"src/document.client.ts",
16+
"src/routes/**/*.ts",
17+
"src/routes/**/*.tsx",
18+
],
19+
"project": ["**/*.{ts,tsx,js}", "!public/**"],
20+
},
21+
"e2e": {
22+
"entry": ["tests/**/*.ts"],
23+
"project": ["**/*.{ts,js}", "!test-results/**"],
24+
},
25+
"packages/engine": {
26+
"project": ["src/**/*.ts"],
27+
},
28+
"packages/generics": {
29+
"entry": ["wea.config.jsonc"],
30+
"project": ["src/**/*.{ts,tsx,js}", "*.ts"],
31+
},
32+
"packages/webawesome": {
33+
"entry": ["vite.common.ts", "vite.config.lib.ts"],
34+
"project": ["src/**/*.{ts,tsx,js}", "*.ts"],
35+
},
36+
},
37+
}

lerna.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
{
2-
"$schema": "./node_modules/lerna/schemas/lerna-schema.json",
2+
"$schema": "./node_modules/@lerna-lite/cli/schemas/lerna-schema.json",
33
"version": "independent",
44
"npmClient": "pnpm",
5+
"conventionalCommits": true,
6+
"changelogPreset": "conventional-changelog-conventionalcommits",
7+
"exact": true,
58
"command": {
69
"publish": {
7-
"message": "chore: publish release"
10+
"cleanupTempFiles": true,
11+
"message": "chore: publish release",
12+
"stripPackageKeys": ["devDependencies", "scripts"]
813
}
914
},
1015
"ignoreChanges": [
@@ -21,7 +26,6 @@
2126
"starter-projects/**"
2227
],
2328
"packages": [
24-
//
2529
"./packages/engine",
2630
"./packages/generics",
2731
"./packages/webawesome"

local-ci.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ set -e
44

55
pnpm install --frozen-lockfile
66

7+
node --run audit
8+
79
node --run clean
810
node --run build
911

@@ -14,5 +16,4 @@ node --run lint:style
1416
node --run format
1517

1618
node --run test:unit
17-
1819
node --run test:e2e

0 commit comments

Comments
 (0)