feat: Implement tag-based version synchronization and direct publishing for releases.
Some checks failed
Code Quality / lint-and-build (push) Failing after 46s
Release Packages / release (push) Failing after 32s

This commit is contained in:
2026-02-02 01:02:14 +01:00
parent 83b4ea8807
commit 10a6b5e11a
4 changed files with 105 additions and 22 deletions

View File

@@ -4,6 +4,8 @@ on:
push: push:
branches: branches:
- main - main
tags:
- 'v*'
jobs: jobs:
release: release:
@@ -31,6 +33,13 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Create Release Pull Request or Publish - name: Release Packages
id: changesets run: |
run: pnpm release if [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "🏷️ Tag detected, performing sync release..."
pnpm sync-versions
pnpm release:tag
else
echo "🚀 Push detected, looking for changesets..."
pnpm release
fi

View File

@@ -9,7 +9,9 @@
"test": "pnpm -r test", "test": "pnpm -r test",
"changeset": "changeset", "changeset": "changeset",
"version-packages": "changeset version", "version-packages": "changeset version",
"sync-versions": "tsx scripts/sync-versions.ts",
"release": "pnpm build && changeset publish", "release": "pnpm build && changeset publish",
"release:tag": "pnpm build && pnpm -r publish --no-git-checks --access public",
"prepare": "husky" "prepare": "husky"
}, },
"devDependencies": { "devDependencies": {
@@ -32,6 +34,7 @@
"jsdom": "^27.4.0", "jsdom": "^27.4.0",
"lint-staged": "^16.2.7", "lint-staged": "^16.2.7",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"tsx": "^4.21.0",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"typescript-eslint": "^8.54.0", "typescript-eslint": "^8.54.0",
"vitest": "^4.0.18" "vitest": "^4.0.18"

56
pnpm-lock.yaml generated
View File

@@ -37,7 +37,7 @@ importers:
version: 19.2.3(@types/react@19.2.10) version: 19.2.3(@types/react@19.2.10)
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^5.1.2 specifier: ^5.1.2
version: 5.1.2(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) version: 5.1.2(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
eslint: eslint:
specifier: ^9.39.2 specifier: ^9.39.2
version: 9.39.2(jiti@2.6.1) version: 9.39.2(jiti@2.6.1)
@@ -65,6 +65,9 @@ importers:
prettier: prettier:
specifier: ^3.8.1 specifier: ^3.8.1
version: 3.8.1 version: 3.8.1
tsx:
specifier: ^4.21.0
version: 4.21.0
typescript: typescript:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.9.3 version: 5.9.3
@@ -73,7 +76,7 @@ importers:
version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
vitest: vitest:
specifier: ^4.0.18 specifier: ^4.0.18
version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.30)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.4.0)(terser@5.46.0)(yaml@2.8.2) version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.30)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.4.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
apps/sample-website: apps/sample-website:
dependencies: dependencies:
@@ -138,7 +141,7 @@ importers:
version: 2.4.9 version: 2.4.9
tsup: tsup:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2) version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
typescript: typescript:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.9.3 version: 5.9.3
@@ -205,7 +208,7 @@ importers:
version: 8.5.6 version: 8.5.6
tailwindcss: tailwindcss:
specifier: ^3.4.17 specifier: ^3.4.17
version: 3.4.19(yaml@2.8.2) version: 3.4.19(tsx@4.21.0)(yaml@2.8.2)
typescript: typescript:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.9.3 version: 5.9.3
@@ -266,7 +269,7 @@ importers:
version: 9.39.2(jiti@2.6.1) version: 9.39.2(jiti@2.6.1)
tsup: tsup:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2) version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
typescript: typescript:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.9.3 version: 5.9.3
@@ -4094,6 +4097,11 @@ packages:
typescript: typescript:
optional: true optional: true
tsx@4.21.0:
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
engines: {node: '>=18.0.0'}
hasBin: true
type-check@0.4.0: type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@@ -6045,7 +6053,7 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1': '@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true optional: true
'@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))': '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies: dependencies:
'@babel/core': 7.28.6 '@babel/core': 7.28.6
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6)
@@ -6053,7 +6061,7 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-beta.53 '@rolldown/pluginutils': 1.0.0-beta.53
'@types/babel__core': 7.20.5 '@types/babel__core': 7.20.5
react-refresh: 0.18.0 react-refresh: 0.18.0
vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -6066,13 +6074,13 @@ snapshots:
chai: 6.2.2 chai: 6.2.2
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
'@vitest/mocker@4.0.18(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2))': '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies: dependencies:
'@vitest/spy': 4.0.18 '@vitest/spy': 4.0.18
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.21 magic-string: 0.30.21
optionalDependencies: optionalDependencies:
vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
'@vitest/pretty-format@4.0.18': '@vitest/pretty-format@4.0.18':
dependencies: dependencies:
@@ -7994,20 +8002,22 @@ snapshots:
camelcase-css: 2.0.1 camelcase-css: 2.0.1
postcss: 8.5.6 postcss: 8.5.6
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2): postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2):
dependencies: dependencies:
lilconfig: 3.1.3 lilconfig: 3.1.3
optionalDependencies: optionalDependencies:
jiti: 1.21.7 jiti: 1.21.7
postcss: 8.5.6 postcss: 8.5.6
tsx: 4.21.0
yaml: 2.8.2 yaml: 2.8.2
postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.8.2): postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2):
dependencies: dependencies:
lilconfig: 3.1.3 lilconfig: 3.1.3
optionalDependencies: optionalDependencies:
jiti: 2.6.1 jiti: 2.6.1
postcss: 8.5.6 postcss: 8.5.6
tsx: 4.21.0
yaml: 2.8.2 yaml: 2.8.2
postcss-nested@6.2.0(postcss@8.5.6): postcss-nested@6.2.0(postcss@8.5.6):
@@ -8520,7 +8530,7 @@ snapshots:
tailwind-merge@2.6.1: {} tailwind-merge@2.6.1: {}
tailwindcss@3.4.19(yaml@2.8.2): tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2):
dependencies: dependencies:
'@alloc/quick-lru': 5.2.0 '@alloc/quick-lru': 5.2.0
arg: 5.0.2 arg: 5.0.2
@@ -8539,7 +8549,7 @@ snapshots:
postcss: 8.5.6 postcss: 8.5.6
postcss-import: 15.1.0(postcss@8.5.6) postcss-import: 15.1.0(postcss@8.5.6)
postcss-js: 4.1.0(postcss@8.5.6) postcss-js: 4.1.0(postcss@8.5.6)
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2) postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2)
postcss-nested: 6.2.0(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6)
postcss-selector-parser: 6.1.2 postcss-selector-parser: 6.1.2
resolve: 1.22.11 resolve: 1.22.11
@@ -8626,7 +8636,7 @@ snapshots:
tslib@2.8.1: {} tslib@2.8.1: {}
tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2): tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2):
dependencies: dependencies:
bundle-require: 5.1.0(esbuild@0.27.2) bundle-require: 5.1.0(esbuild@0.27.2)
cac: 6.7.14 cac: 6.7.14
@@ -8637,7 +8647,7 @@ snapshots:
fix-dts-default-cjs-exports: 1.0.1 fix-dts-default-cjs-exports: 1.0.1
joycon: 3.1.1 joycon: 3.1.1
picocolors: 1.1.1 picocolors: 1.1.1
postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.8.2) postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2)
resolve-from: 5.0.0 resolve-from: 5.0.0
rollup: 4.57.1 rollup: 4.57.1
source-map: 0.7.6 source-map: 0.7.6
@@ -8654,6 +8664,13 @@ snapshots:
- tsx - tsx
- yaml - yaml
tsx@4.21.0:
dependencies:
esbuild: 0.27.2
get-tsconfig: 4.13.1
optionalDependencies:
fsevents: 2.3.3
type-check@0.4.0: type-check@0.4.0:
dependencies: dependencies:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
@@ -8772,7 +8789,7 @@ snapshots:
uuid@9.0.1: {} uuid@9.0.1: {}
vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2): vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
dependencies: dependencies:
esbuild: 0.27.2 esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
@@ -8785,12 +8802,13 @@ snapshots:
fsevents: 2.3.3 fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
terser: 5.46.0 terser: 5.46.0
tsx: 4.21.0
yaml: 2.8.2 yaml: 2.8.2
vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.30)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.4.0)(terser@5.46.0)(yaml@2.8.2): vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.30)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.4.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
dependencies: dependencies:
'@vitest/expect': 4.0.18 '@vitest/expect': 4.0.18
'@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2)) '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
'@vitest/pretty-format': 4.0.18 '@vitest/pretty-format': 4.0.18
'@vitest/runner': 4.0.18 '@vitest/runner': 4.0.18
'@vitest/snapshot': 4.0.18 '@vitest/snapshot': 4.0.18
@@ -8807,7 +8825,7 @@ snapshots:
tinyexec: 1.0.2 tinyexec: 1.0.2
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(yaml@2.8.2) vite: 7.3.1(@types/node@20.19.30)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0

53
scripts/sync-versions.ts Normal file
View File

@@ -0,0 +1,53 @@
import * as fs from "fs";
import * as path from "path";
import { execSync } from "child_process";
const tag = process.env.GITHUB_REF_NAME || process.env.TAG;
if (!tag || !tag.startsWith("v")) {
console.error("❌ No valid tag found (must start with v, e.g., v1.0.0)");
process.exit(1);
}
const version = tag.replace(/^v/, "");
console.log(`🚀 Syncing all packages to version: ${version}`);
const rootPkg = JSON.parse(fs.readFileSync("package.json", "utf-8"));
const packagesDir = "packages";
const appsDir = "apps";
function updatePkg(pkgPath: string) {
if (!fs.existsSync(pkgPath)) return;
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
pkg.version = version;
// Also update workspace dependencies if they match our packages
if (pkg.dependencies) {
for (const dep in pkg.dependencies) {
if (pkg.dependencies[dep].startsWith("workspace:")) {
pkg.dependencies[dep] = "workspace:*"; // Keep workspace protocol
}
}
}
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
console.log(`✅ Updated ${pkg.name} to ${version}`);
}
// Update root
rootPkg.version = version;
fs.writeFileSync("package.json", JSON.stringify(rootPkg, null, 2) + "\n");
// Update all packages
const packages = fs.readdirSync(packagesDir);
for (const p of packages) {
updatePkg(path.join(packagesDir, p, "package.json"));
}
// Update all apps
const apps = fs.readdirSync(appsDir);
for (const a of apps) {
updatePkg(path.join(appsDir, a, "package.json"));
}
console.log("✨ All versions synced!");