mirror of
https://github.com/LukeHagar/form.git
synced 2025-12-06 04:19:43 +00:00
fix: migrate to use CI/CD system that router uses (#455)
This commit is contained in:
10
package.json
10
package.json
@@ -3,7 +3,6 @@
|
||||
"private": true,
|
||||
"repository": "https://github.com/tanstack/form.git",
|
||||
"packageManager": "pnpm@8.5.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"clean": "pnpm --filter \"./packages/**\" run clean",
|
||||
"preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm",
|
||||
@@ -22,7 +21,8 @@
|
||||
"dev": "pnpm run watch",
|
||||
"prettier": "prettier \"{packages,examples,scripts}/**/*.{md,js,jsx,cjs,ts,tsx,json,vue}\"",
|
||||
"prettier:write": "pnpm run prettier --write",
|
||||
"cipublish": "node scripts/publish.js"
|
||||
"cipublish": "ts-node scripts/publish.ts",
|
||||
"cipublishforce": "CI=true pnpm cipublish"
|
||||
},
|
||||
"nx": {
|
||||
"includedScripts": [
|
||||
@@ -45,12 +45,15 @@
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@testing-library/vue": "^7.0.0",
|
||||
"@types/current-git-branch": "^1.1.4",
|
||||
"@types/jest": "^26.0.4",
|
||||
"@types/jsonfile": "^6.1.1",
|
||||
"@types/luxon": "^2.3.1",
|
||||
"@types/node": "^17.0.25",
|
||||
"@types/react": "^18.0.14",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"@types/semver": "^7.3.13",
|
||||
"@types/stream-to-array": "^2.3.1",
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||
"@typescript-eslint/parser": "^6.4.1",
|
||||
@@ -75,6 +78,7 @@
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"git-log-parser": "^1.2.0",
|
||||
"jsdom": "^22.0.0",
|
||||
"jsonfile": "^6.1.0",
|
||||
@@ -89,9 +93,9 @@
|
||||
"react-dom-17": "npm:react-dom@^17.0.2",
|
||||
"rimraf": "^5.0.1",
|
||||
"semver": "^7.3.8",
|
||||
"fs-extra": "^11.1.1",
|
||||
"solid-js": "^1.6.13",
|
||||
"stream-to-array": "^2.3.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsup": "^7.2.0",
|
||||
"type-fest": "^3.11.0",
|
||||
"typescript": "^5.2.2",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"composite": true,
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./build/lib",
|
||||
"types": ["vitest/globals"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'tsup'
|
||||
import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js'
|
||||
import { legacyConfig, modernConfig } from '../../getTsupConfig.js'
|
||||
|
||||
export default defineConfig([
|
||||
modernConfig({ entry: ['src/*.ts'] }),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"composite": true,
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"outDir": "./build/lib",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'tsup'
|
||||
import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js'
|
||||
import { legacyConfig, modernConfig } from '../../getTsupConfig.js'
|
||||
|
||||
export default defineConfig([
|
||||
modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"composite": true,
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["vitest/globals", "vue/jsx"],
|
||||
"outDir": "./build/lib",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'tsup'
|
||||
import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js'
|
||||
import { legacyConfig, modernConfig } from '../../getTsupConfig.js'
|
||||
|
||||
export default defineConfig([
|
||||
modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
|
||||
|
||||
168
pnpm-lock.yaml
generated
168
pnpm-lock.yaml
generated
@@ -55,9 +55,15 @@ importers:
|
||||
'@testing-library/vue':
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0(@vue/compiler-sfc@3.3.4)(vue@3.3.4)
|
||||
'@types/current-git-branch':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4
|
||||
'@types/jest':
|
||||
specifier: ^26.0.4
|
||||
version: 26.0.24
|
||||
'@types/jsonfile':
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1
|
||||
'@types/luxon':
|
||||
specifier: ^2.3.1
|
||||
version: 2.3.2
|
||||
@@ -73,6 +79,9 @@ importers:
|
||||
'@types/semver':
|
||||
specifier: ^7.3.13
|
||||
version: 7.3.13
|
||||
'@types/stream-to-array':
|
||||
specifier: ^2.3.1
|
||||
version: 2.3.1
|
||||
'@types/testing-library__jest-dom':
|
||||
specifier: ^5.14.5
|
||||
version: 5.14.5(patch_hash=d573maxasnl5kxwdyzebcnmhpm)
|
||||
@@ -196,9 +205,12 @@ importers:
|
||||
stream-to-array:
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0
|
||||
ts-node:
|
||||
specifier: ^10.9.1
|
||||
version: 10.9.1(@types/node@17.0.45)(typescript@5.2.2)
|
||||
tsup:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0(typescript@5.2.2)
|
||||
version: 7.2.0(ts-node@10.9.1)(typescript@5.2.2)
|
||||
type-fest:
|
||||
specifier: ^3.11.0
|
||||
version: 3.11.0
|
||||
@@ -216,7 +228,7 @@ importers:
|
||||
dependencies:
|
||||
'@tanstack/react-form':
|
||||
specifier: ^0.2.1
|
||||
version: link:../../../packages/react-form
|
||||
version: 0.2.1(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
axios:
|
||||
specifier: ^0.26.1
|
||||
version: 0.26.1
|
||||
@@ -241,7 +253,7 @@ importers:
|
||||
dependencies:
|
||||
'@tanstack/vue-form':
|
||||
specifier: ^0.2.2
|
||||
version: link:../../../packages/vue-form
|
||||
version: 0.2.2(vue@3.3.4)
|
||||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4
|
||||
@@ -1733,6 +1745,13 @@ packages:
|
||||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
||||
/@cspotcode/source-map-support@0.8.1:
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
dev: true
|
||||
|
||||
/@esbuild/android-arm64@0.18.20:
|
||||
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -2166,6 +2185,13 @@ packages:
|
||||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
/@jridgewell/trace-mapping@0.3.9:
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: true
|
||||
|
||||
/@mdn/browser-compat-data@5.3.9:
|
||||
resolution: {integrity: sha512-J7lLtHMEizYbI5T0Xlqpg1JXCz9JegZBeb7y3v/Nm8ScRw8TL9v3n+I3g1TFm+bLrRtwA33FKwX5znDwz+WzAQ==}
|
||||
dev: true
|
||||
@@ -2656,6 +2682,34 @@ packages:
|
||||
'@sinonjs/commons': 3.0.0
|
||||
dev: false
|
||||
|
||||
/@tanstack/form-core@0.2.0:
|
||||
resolution: {integrity: sha512-Kabl4c61z6tVDsSOjzyC7bNYKlJoY0k4T6u86YbpIOkBFqkX0S/J688pDw7vxhbgTJ3agVBsp73rptxPbDt7ZA==}
|
||||
dependencies:
|
||||
'@tanstack/store': 0.1.3
|
||||
dev: false
|
||||
|
||||
/@tanstack/react-form@0.2.1(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-2gRdDYYRIh/OW5Cu6GXpOC/tH7+fbwFPpSa0kuJEJq6mW321E5Ak4Fg2Lt3ygERpn6UTq+UwKGxjj747rpKvyg==}
|
||||
peerDependencies:
|
||||
react: ^17.0.0 || ^18.0.0
|
||||
react-dom: ^17.0.0 || ^18.0.0
|
||||
react-native: '*'
|
||||
peerDependenciesMeta:
|
||||
react-dom:
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@tanstack/form-core': 0.2.0
|
||||
'@tanstack/react-store': 0.1.3(react-dom@18.2.0)(react@18.2.0)
|
||||
'@tanstack/store': 0.1.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
use-isomorphic-layout-effect: 1.1.2(@types/react@18.0.15)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@tanstack/react-store@0.1.3(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-nDOgSlarFFbIvVirAi/GcCyqyRMthgpuBhOhN87DkeQEau+ZNGsLKJifzrQYuWB0+4FXmgeoGaY/Dr383MPqZw==}
|
||||
peerDependencies:
|
||||
@@ -2672,6 +2726,22 @@ packages:
|
||||
resolution: {integrity: sha512-GnolmC8Fr4mvsHE1fGQmR3Nm0eBO3KnZjDU0a+P3TeQNM/dDscFGxtA7p31NplQNW3KwBw4t1RVFmz0VeKLxcw==}
|
||||
dev: false
|
||||
|
||||
/@tanstack/vue-form@0.2.2(vue@3.3.4):
|
||||
resolution: {integrity: sha512-v8M08C3BIA7IUtGYmMejKpKSp4mkWA8y4t+WUIZBFA0yLycQHLSy2TLm7Wb+T4Up7c0CBGWum/VWUcu4tlQFhA==}
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.1.2
|
||||
vue: ^2.5.0 || ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@tanstack/form-core': 0.2.0
|
||||
'@tanstack/store': 0.1.3
|
||||
'@tanstack/vue-store': 0.1.3(@vue/composition-api@1.7.2)(vue@3.3.4)
|
||||
vue: 3.3.4
|
||||
vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.4)
|
||||
dev: false
|
||||
|
||||
/@tanstack/vue-store@0.1.3(@vue/composition-api@1.7.2)(vue@3.3.4):
|
||||
resolution: {integrity: sha512-vLG2t0N0nagS2YrCDtTGJiftBDWadX0M7vSkIjfl+I1SaeKDvhg+HbRxt7Vwc5iLcwHljHAIlf7Ak5o4q0Brhg==}
|
||||
peerDependencies:
|
||||
@@ -2783,10 +2853,22 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node10@1.0.9:
|
||||
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node12@1.0.11:
|
||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node14@1.0.3:
|
||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node16@1.0.4:
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
dev: true
|
||||
|
||||
/@types/aria-query@5.0.1:
|
||||
resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==}
|
||||
dev: true
|
||||
@@ -2830,6 +2912,10 @@ packages:
|
||||
resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==}
|
||||
dev: true
|
||||
|
||||
/@types/current-git-branch@1.1.4:
|
||||
resolution: {integrity: sha512-laBj/aFKSEVEqyyOsogGCWoCFnfAQs5uDlSe9FWRsgUwrmhwe8R4fGbjb7q392cVX5BI9PqQw1ZRkTn4gmvDPw==}
|
||||
dev: true
|
||||
|
||||
/@types/estree@1.0.1:
|
||||
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
||||
dev: true
|
||||
@@ -2875,6 +2961,12 @@ packages:
|
||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||
dev: true
|
||||
|
||||
/@types/jsonfile@6.1.1:
|
||||
resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
dev: true
|
||||
|
||||
/@types/luxon@2.3.2:
|
||||
resolution: {integrity: sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==}
|
||||
dev: true
|
||||
@@ -2925,6 +3017,12 @@ packages:
|
||||
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
|
||||
dev: false
|
||||
|
||||
/@types/stream-to-array@2.3.1:
|
||||
resolution: {integrity: sha512-OqV/DIumEm5pT+m4LYGpDFRRLZ0VJRvrz58C8q8rjLGVgP5gRHxThG8eLZfhmK3GVAq9iq3eSvZ0vkZJ5ZH/Pg==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
dev: true
|
||||
|
||||
/@types/testing-library__jest-dom@5.14.5(patch_hash=d573maxasnl5kxwdyzebcnmhpm):
|
||||
resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==}
|
||||
dependencies:
|
||||
@@ -3471,6 +3569,10 @@ packages:
|
||||
resolution: {integrity: sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==}
|
||||
dev: false
|
||||
|
||||
/arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
dev: true
|
||||
|
||||
/argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
dependencies:
|
||||
@@ -4424,6 +4526,10 @@ packages:
|
||||
p-map: 6.0.0
|
||||
dev: true
|
||||
|
||||
/create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
dev: true
|
||||
|
||||
/cross-spawn@5.1.0:
|
||||
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
||||
dependencies:
|
||||
@@ -4648,6 +4754,11 @@ packages:
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/diff@4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
dev: true
|
||||
|
||||
/dir-glob@3.0.1:
|
||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -7051,6 +7162,10 @@ packages:
|
||||
semver: 7.5.4
|
||||
dev: true
|
||||
|
||||
/make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
dev: true
|
||||
|
||||
/makeerror@1.0.12:
|
||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||
dependencies:
|
||||
@@ -8206,7 +8321,7 @@ packages:
|
||||
pathe: 1.1.1
|
||||
dev: true
|
||||
|
||||
/postcss-load-config@4.0.1:
|
||||
/postcss-load-config@4.0.1(ts-node@10.9.1):
|
||||
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
|
||||
engines: {node: '>= 14'}
|
||||
peerDependencies:
|
||||
@@ -8219,6 +8334,7 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
lilconfig: 2.1.0
|
||||
ts-node: 10.9.1(@types/node@17.0.45)(typescript@5.2.2)
|
||||
yaml: 2.3.1
|
||||
dev: true
|
||||
|
||||
@@ -9521,6 +9637,37 @@ packages:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
dev: true
|
||||
|
||||
/ts-node@10.9.1(@types/node@17.0.45)(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@swc/core': '>=1.2.50'
|
||||
'@swc/wasm': '>=1.2.50'
|
||||
'@types/node': '*'
|
||||
typescript: '>=2.7'
|
||||
peerDependenciesMeta:
|
||||
'@swc/core':
|
||||
optional: true
|
||||
'@swc/wasm':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.9
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 17.0.45
|
||||
acorn: 8.10.0
|
||||
acorn-walk: 8.2.0
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
typescript: 5.2.2
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/tsconfig-paths@3.14.2:
|
||||
resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
|
||||
dependencies:
|
||||
@@ -9542,7 +9689,7 @@ packages:
|
||||
/tslib@2.6.2:
|
||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||
|
||||
/tsup@7.2.0(typescript@5.2.2):
|
||||
/tsup@7.2.0(ts-node@10.9.1)(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==}
|
||||
engines: {node: '>=16.14'}
|
||||
hasBin: true
|
||||
@@ -9566,7 +9713,7 @@ packages:
|
||||
execa: 5.1.1
|
||||
globby: 11.1.0
|
||||
joycon: 3.1.1
|
||||
postcss-load-config: 4.0.1
|
||||
postcss-load-config: 4.0.1(ts-node@10.9.1)
|
||||
resolve-from: 5.0.0
|
||||
rollup: 3.28.1
|
||||
source-map: 0.8.0-beta.0
|
||||
@@ -9788,6 +9935,10 @@ packages:
|
||||
engines: {node: '>= 0.4.0'}
|
||||
dev: false
|
||||
|
||||
/v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
dev: true
|
||||
|
||||
/v8-compile-cache@2.3.0:
|
||||
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
|
||||
dev: true
|
||||
@@ -10311,6 +10462,11 @@ packages:
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
/yn@3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
// @ts-check
|
||||
import path from 'path'
|
||||
import { BranchConfig, Package } from './types'
|
||||
|
||||
import { resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
/**
|
||||
* List your npm packages here. The first package will be used as the versioner.
|
||||
* @type {import('./types').Package[]}
|
||||
*/
|
||||
export const packages = [
|
||||
// TODO: List your npm packages here.
|
||||
export const packages: Package[] = [
|
||||
{
|
||||
name: '@tanstack/form-core',
|
||||
packageDir: 'packages/form-core',
|
||||
@@ -35,24 +30,31 @@ export const packages = [
|
||||
// },
|
||||
]
|
||||
|
||||
/**
|
||||
* Contains config for publishable branches.
|
||||
* @type {Record<string, import('./types').BranchConfig>}
|
||||
*/
|
||||
export const branchConfigs = {
|
||||
export const latestBranch = 'main'
|
||||
|
||||
export const branchConfigs: Record<string, BranchConfig> = {
|
||||
main: {
|
||||
prerelease: false,
|
||||
ghRelease: true,
|
||||
},
|
||||
next: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
beta: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
alpha: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
}
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
export const rootDir = resolve(__dirname, '..')
|
||||
export const rootDir = path.resolve(__dirname, '..')
|
||||
export const examplesDirs = [
|
||||
'examples/react',
|
||||
'examples/vue',
|
||||
// 'examples/solid',
|
||||
// 'examples/svelte',
|
||||
]
|
||||
46
scripts/git-log-parser.d.ts
vendored
Normal file
46
scripts/git-log-parser.d.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
declare module 'git-log-parser' {
|
||||
import {
|
||||
SpawnOptions,
|
||||
SpawnOptionsWithoutStdio,
|
||||
SpawnOptionsWithStdioTuple,
|
||||
} from 'child_process'
|
||||
|
||||
interface Config {
|
||||
commit: {
|
||||
long: 'H'
|
||||
short: 'h'
|
||||
}
|
||||
tree: {
|
||||
long: 'T'
|
||||
short: 't'
|
||||
}
|
||||
author: {
|
||||
name: 'an'
|
||||
email: 'ae'
|
||||
date: {
|
||||
key: 'ai'
|
||||
type: Date
|
||||
}
|
||||
}
|
||||
committer: {
|
||||
name: 'cn'
|
||||
email: 'ce'
|
||||
date: {
|
||||
key: 'ci'
|
||||
type: Date
|
||||
}
|
||||
}
|
||||
subject: 's'
|
||||
body: 'b'
|
||||
}
|
||||
|
||||
export function parse(
|
||||
config: object,
|
||||
options?:
|
||||
| SpawnOptionsWithoutStdio
|
||||
| SpawnOptionsWithStdioTuple
|
||||
| SpawnOptions,
|
||||
): NodeJS.ReadableStream
|
||||
|
||||
export const fields: Config
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "scripts",
|
||||
"sourceRoot": "scripts",
|
||||
"targets": {
|
||||
"test:eslint": { "command": "eslint ./scripts" }
|
||||
}
|
||||
}
|
||||
@@ -1,478 +0,0 @@
|
||||
// @ts-check
|
||||
// Originally ported to TS from https://github.com/remix-run/react-router/tree/main/scripts/{version,publish}.js
|
||||
|
||||
import path from 'node:path'
|
||||
import { execSync } from 'node:child_process'
|
||||
import chalk from 'chalk'
|
||||
import jsonfile from 'jsonfile'
|
||||
import * as semver from 'semver'
|
||||
import currentGitBranch from 'current-git-branch'
|
||||
import { parse as parseCommit } from '@commitlint/parse'
|
||||
import log from 'git-log-parser'
|
||||
import streamToArray from 'stream-to-array'
|
||||
import axios from 'axios'
|
||||
import { DateTime } from 'luxon'
|
||||
import { branchConfigs, packages, rootDir } from './config.js'
|
||||
|
||||
/** @param {string} version */
|
||||
const releaseCommitMsg = (version) => `release: v${version}`
|
||||
|
||||
async function run() {
|
||||
const branchName = /** @type {string} */ (
|
||||
process.env.BRANCH ?? currentGitBranch()
|
||||
)
|
||||
|
||||
const isMainBranch = branchName === 'main'
|
||||
const npmTag = isMainBranch ? 'latest' : branchName
|
||||
|
||||
// Get tags
|
||||
/** @type {string[]} */
|
||||
let tags = execSync('git tag').toString().split('\n')
|
||||
|
||||
// Filter tags to our branch/pre-release combo
|
||||
tags = tags
|
||||
.filter((tag) => semver.valid(tag))
|
||||
.filter((tag) => {
|
||||
if (semver.prerelease(tag) === null) {
|
||||
return isMainBranch
|
||||
} else {
|
||||
return !isMainBranch
|
||||
}
|
||||
})
|
||||
// sort by latest
|
||||
.sort(semver.compare)
|
||||
|
||||
// Get the latest tag
|
||||
let latestTag = /** @type {string} */ ([...tags].pop())
|
||||
|
||||
let range = `${latestTag}..HEAD`
|
||||
// let range = ``;
|
||||
|
||||
// If RELEASE_ALL is set via a commit subject or body, all packages will be
|
||||
// released regardless if they have changed files matching the package srcDir.
|
||||
let RELEASE_ALL = false
|
||||
|
||||
if (!latestTag || process.env.TAG) {
|
||||
if (process.env.TAG) {
|
||||
if (!process.env.TAG.startsWith('v')) {
|
||||
throw new Error(
|
||||
`process.env.TAG must start with "v", eg. v0.0.0. You supplied ${process.env.TAG}`,
|
||||
)
|
||||
}
|
||||
console.info(
|
||||
chalk.yellow(
|
||||
`Tag is set to ${process.env.TAG}. This will force release all packages. Publishing...`,
|
||||
),
|
||||
)
|
||||
RELEASE_ALL = true
|
||||
|
||||
// Is it a major version?
|
||||
if (!semver.patch(process.env.TAG) && !semver.minor(process.env.TAG)) {
|
||||
range = `origin/main..HEAD`
|
||||
latestTag = process.env.TAG
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Could not find latest tag! To make a release tag of v0.0.1, run with TAG=v0.0.1',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
console.info(`Git Range: ${range}`)
|
||||
|
||||
/**
|
||||
* Get the commits since the latest tag
|
||||
* @type {import('./types.js').Commit[]}
|
||||
*/
|
||||
const commitsSinceLatestTag = (
|
||||
await new Promise((resolve, reject) => {
|
||||
/** @type {NodeJS.ReadableStream} */
|
||||
const strm = log.parse({
|
||||
_: range,
|
||||
})
|
||||
|
||||
streamToArray(strm, function (err, arr) {
|
||||
if (err) return reject(err)
|
||||
|
||||
Promise.all(
|
||||
arr.map(async (d) => {
|
||||
const parsed = await parseCommit(d.subject)
|
||||
|
||||
return { ...d, parsed }
|
||||
}),
|
||||
).then((res) => resolve(res.filter(Boolean)))
|
||||
})
|
||||
})
|
||||
).filter((/** @type {import('./types.js').Commit} */ commit) => {
|
||||
const exclude = [
|
||||
commit.subject.startsWith('Merge branch '), // No merge commits
|
||||
commit.subject.startsWith(releaseCommitMsg('')), // No example update commits
|
||||
].some(Boolean)
|
||||
|
||||
return !exclude
|
||||
})
|
||||
|
||||
console.info(
|
||||
`Parsing ${commitsSinceLatestTag.length} commits since ${latestTag}...`,
|
||||
)
|
||||
|
||||
/**
|
||||
* Parses the commit messsages, log them, and determine the type of release needed
|
||||
* -1 means no release is necessary
|
||||
* 0 means patch release is necessary
|
||||
* 1 means minor release is necessary
|
||||
* 2 means major release is necessary
|
||||
* @type {number}
|
||||
*/
|
||||
let recommendedReleaseLevel = commitsSinceLatestTag.reduce(
|
||||
(releaseLevel, commit) => {
|
||||
if (commit.parsed.type) {
|
||||
if (['fix', 'refactor', 'perf'].includes(commit.parsed.type)) {
|
||||
releaseLevel = Math.max(releaseLevel, 0)
|
||||
}
|
||||
if (['feat'].includes(commit.parsed.type)) {
|
||||
releaseLevel = Math.max(releaseLevel, 1)
|
||||
}
|
||||
if (commit.body.includes('BREAKING CHANGE')) {
|
||||
releaseLevel = Math.max(releaseLevel, 2)
|
||||
}
|
||||
if (
|
||||
commit.subject.includes('RELEASE_ALL') ||
|
||||
commit.body.includes('RELEASE_ALL')
|
||||
) {
|
||||
RELEASE_ALL = true
|
||||
}
|
||||
}
|
||||
|
||||
return releaseLevel
|
||||
},
|
||||
-1,
|
||||
)
|
||||
|
||||
/**
|
||||
* Uses git diff to determine which files have changed since the latest tag
|
||||
* @type {string[]}
|
||||
*/
|
||||
const changedFiles = process.env.TAG
|
||||
? []
|
||||
: execSync(`git diff ${latestTag} --name-only`)
|
||||
.toString()
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
|
||||
/** Uses packages and changedFiles to determine which packages have changed */
|
||||
const changedPackages = RELEASE_ALL
|
||||
? packages
|
||||
: packages.filter((pkg) => {
|
||||
const changed = changedFiles.some(
|
||||
(file) =>
|
||||
file.startsWith(path.join(pkg.packageDir, 'src')) ||
|
||||
file.startsWith(path.join(pkg.packageDir, 'package.json')),
|
||||
)
|
||||
return changed
|
||||
})
|
||||
|
||||
// If a package has a dependency that has been updated, we need to update the
|
||||
// package that depends on it as well.
|
||||
// run this multiple times so that dependencies of dependencies are also included
|
||||
// changes to query-core affect query-persist-client-core, which affects react-query-persist-client and then indirectly the sync/async persisters
|
||||
for (let runs = 0; runs < 3; runs++) {
|
||||
for (const pkg of packages) {
|
||||
const packageJson = await readPackageJson(
|
||||
path.resolve(rootDir, pkg.packageDir, 'package.json'),
|
||||
)
|
||||
const allDependencies = Object.keys(
|
||||
Object.assign(
|
||||
{},
|
||||
packageJson.dependencies ?? {},
|
||||
packageJson.peerDependencies ?? {},
|
||||
),
|
||||
)
|
||||
|
||||
if (
|
||||
allDependencies.find((dep) =>
|
||||
changedPackages.find((d) => d.name === dep),
|
||||
) &&
|
||||
!changedPackages.find((d) => d.name === pkg.name)
|
||||
) {
|
||||
console.info(
|
||||
'adding package dependency',
|
||||
pkg.name,
|
||||
'to changed packages',
|
||||
)
|
||||
changedPackages.push(pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!process.env.TAG) {
|
||||
if (recommendedReleaseLevel === 2) {
|
||||
console.info(
|
||||
`Major versions releases must be tagged and released manually.`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (recommendedReleaseLevel === -1) {
|
||||
console.info(
|
||||
`There have been no changes since the release of ${latestTag} that require a new version. You're good!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const changelogCommitsMd = process.env.TAG
|
||||
? `Manual Release: ${process.env.TAG}`
|
||||
: await Promise.all(
|
||||
Object.entries(
|
||||
commitsSinceLatestTag.reduce((acc, next) => {
|
||||
const type = next.parsed.type?.toLowerCase() ?? 'other'
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[type]: [...(acc[type] || []), next],
|
||||
}
|
||||
}, /** @type {Record<string, import('./types.js').Commit[]>} */ ({})),
|
||||
)
|
||||
.sort(
|
||||
getSorterFn([
|
||||
([d]) =>
|
||||
[
|
||||
'other',
|
||||
'examples',
|
||||
'docs',
|
||||
'chore',
|
||||
'refactor',
|
||||
'perf',
|
||||
'fix',
|
||||
'feat',
|
||||
].indexOf(d),
|
||||
]),
|
||||
)
|
||||
.reverse()
|
||||
.map(async ([type, commits]) => {
|
||||
return Promise.all(
|
||||
commits.map(async (commit) => {
|
||||
let username = ''
|
||||
|
||||
if (process.env.GH_TOKEN) {
|
||||
const query = `${
|
||||
commit.author.email || commit.committer.email
|
||||
}`
|
||||
|
||||
const res = await axios.get(
|
||||
'https://api.github.com/search/users',
|
||||
{
|
||||
params: {
|
||||
q: query,
|
||||
},
|
||||
headers: {
|
||||
Authorization: `token ${process.env.GH_TOKEN}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
username = res.data.items[0]?.login
|
||||
}
|
||||
|
||||
const scope = commit.parsed.scope
|
||||
? `${commit.parsed.scope}: `
|
||||
: ''
|
||||
const subject = commit.parsed.subject || commit.subject
|
||||
|
||||
return `- ${scope}${subject} (${commit.commit.short}) ${
|
||||
username
|
||||
? `by @${username}`
|
||||
: `by ${commit.author.name || commit.author.email}`
|
||||
}`
|
||||
}),
|
||||
).then((c) => /** @type {const} */ ([type, c]))
|
||||
}),
|
||||
).then((groups) => {
|
||||
return groups
|
||||
.map(([type, commits]) => {
|
||||
return [`### ${capitalize(type)}`, commits.join('\n')].join('\n\n')
|
||||
})
|
||||
.join('\n\n')
|
||||
})
|
||||
|
||||
if (process.env.TAG && recommendedReleaseLevel === -1) {
|
||||
recommendedReleaseLevel = 0
|
||||
}
|
||||
|
||||
/** @type {import('./types.js').BranchConfig | undefined} */
|
||||
const branchConfig = branchConfigs[branchName]
|
||||
|
||||
if (!branchConfig) {
|
||||
console.log(`No publish config found for branch: ${branchName}`)
|
||||
console.log('Exiting...')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const releaseType = branchConfig.prerelease
|
||||
? 'prerelease'
|
||||
: /** @type {const} */ ({ 0: 'patch', 1: 'minor', 2: 'major' })[
|
||||
recommendedReleaseLevel
|
||||
]
|
||||
|
||||
if (!releaseType) {
|
||||
throw new Error(`Invalid release level: ${recommendedReleaseLevel}`)
|
||||
}
|
||||
|
||||
const version = process.env.TAG
|
||||
? semver.parse(process.env.TAG)?.version
|
||||
: semver.inc(latestTag, releaseType, npmTag)
|
||||
|
||||
if (!version) {
|
||||
throw new Error(
|
||||
`Invalid version increment from semver.inc(${[
|
||||
latestTag,
|
||||
recommendedReleaseLevel,
|
||||
branchConfig.prerelease,
|
||||
].join(', ')}`,
|
||||
)
|
||||
}
|
||||
|
||||
const changelogMd = [
|
||||
`Version ${version} - ${DateTime.now().toLocaleString(
|
||||
DateTime.DATETIME_SHORT,
|
||||
)}`,
|
||||
`## Changes`,
|
||||
changelogCommitsMd,
|
||||
`## Packages`,
|
||||
changedPackages.map((d) => `- ${d.name}@${version}`).join('\n'),
|
||||
].join('\n\n')
|
||||
|
||||
console.info('Generating changelog...')
|
||||
console.info()
|
||||
console.info(changelogMd)
|
||||
console.info()
|
||||
|
||||
if (changedPackages.length === 0) {
|
||||
console.info('No packages have been affected.')
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Updating all changed packages to version ${version}...`)
|
||||
// Update each package to the new version
|
||||
for (const pkg of changedPackages) {
|
||||
console.info(` Updating ${pkg.name} version to ${version}...`)
|
||||
|
||||
await updatePackageJson(
|
||||
path.resolve(rootDir, pkg.packageDir, 'package.json'),
|
||||
(config) => {
|
||||
config.version = version
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if (!process.env.CI) {
|
||||
console.warn(
|
||||
`This is a dry run for version ${version}. Push to CI to publish for real or set CI=true to override!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
console.info()
|
||||
console.info(`Publishing all packages to npm with tag "${npmTag}"`)
|
||||
|
||||
// Publish each package
|
||||
changedPackages.forEach((pkg) => {
|
||||
const packageDir = path.join(rootDir, pkg.packageDir)
|
||||
const cmd = `cd ${packageDir} && pnpm publish --tag ${npmTag} --access=public --no-git-checks`
|
||||
console.info(
|
||||
` Publishing ${pkg.name}@${version} to npm with tag "${npmTag}"...`,
|
||||
)
|
||||
execSync(cmd, {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
})
|
||||
})
|
||||
|
||||
console.info()
|
||||
|
||||
console.info(`Committing changes...`)
|
||||
execSync(`git add -A && git commit -m "${releaseCommitMsg(version)}"`)
|
||||
console.info()
|
||||
console.info(` Committed Changes.`)
|
||||
|
||||
console.info(`Pushing changes...`)
|
||||
execSync(`git push`)
|
||||
console.info()
|
||||
console.info(` Changes pushed.`)
|
||||
|
||||
console.info(`Creating new git tag v${version}`)
|
||||
execSync(`git tag -a -m "v${version}" v${version}`)
|
||||
|
||||
console.info(`Pushing tags...`)
|
||||
execSync(`git push --tags`)
|
||||
console.info()
|
||||
console.info(` Tags pushed.`)
|
||||
|
||||
console.info(`Creating github release...`)
|
||||
// Stringify the markdown to excape any quotes
|
||||
execSync(
|
||||
`gh release create v${version} ${
|
||||
!isMainBranch ? '--prerelease' : ''
|
||||
} --notes '${changelogMd.replace(/'/g, '"')}'`,
|
||||
)
|
||||
console.info(` Github release created.`)
|
||||
|
||||
console.info(`All done!`)
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.info(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
/** @param {string} str */
|
||||
function capitalize(str) {
|
||||
return str.slice(0, 1).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} pathName
|
||||
* @returns {Promise<import('type-fest').PackageJson>}
|
||||
*/
|
||||
async function readPackageJson(pathName) {
|
||||
return await jsonfile.readFile(pathName)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} pathName
|
||||
* @param {(json: import('type-fest').PackageJson) => Promise<void> | void} transform
|
||||
*/
|
||||
async function updatePackageJson(pathName, transform) {
|
||||
const json = await readPackageJson(pathName)
|
||||
await transform(json)
|
||||
await jsonfile.writeFile(pathName, json, {
|
||||
spaces: 2,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TItem
|
||||
* @param {((d: TItem) => any)[]} sorters
|
||||
* @returns {(a: TItem, b: TItem) => number}
|
||||
*/
|
||||
function getSorterFn(sorters) {
|
||||
return (a, b) => {
|
||||
let i = 0
|
||||
|
||||
sorters.some((sorter) => {
|
||||
const sortedA = sorter(a)
|
||||
const sortedB = sorter(b)
|
||||
if (sortedA > sortedB) {
|
||||
i = 1
|
||||
return true
|
||||
}
|
||||
if (sortedA < sortedB) {
|
||||
i = -1
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
485
scripts/publish.ts
Normal file
485
scripts/publish.ts
Normal file
@@ -0,0 +1,485 @@
|
||||
import {
|
||||
branchConfigs,
|
||||
examplesDirs,
|
||||
latestBranch,
|
||||
packages,
|
||||
rootDir,
|
||||
} from './config'
|
||||
import { BranchConfig, Commit } from './types'
|
||||
|
||||
// Originally ported to TS from https://github.com/remix-run/router/tree/main/scripts/{version,publish}.js
|
||||
import path from 'path'
|
||||
import { exec, execSync } from 'child_process'
|
||||
import fsp from 'fs/promises'
|
||||
import chalk from 'chalk'
|
||||
import jsonfile from 'jsonfile'
|
||||
import semver from 'semver'
|
||||
import currentGitBranch from 'current-git-branch'
|
||||
import parseCommit from '@commitlint/parse'
|
||||
import log from 'git-log-parser'
|
||||
import streamToArray from 'stream-to-array'
|
||||
import axios from 'axios'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
import { PackageJson } from 'type-fest'
|
||||
|
||||
const releaseCommitMsg = (version: string) => `release: v${version}`
|
||||
|
||||
async function run() {
|
||||
const branchName: string =
|
||||
process.env.BRANCH ??
|
||||
// (process.env.PR_NUMBER ? `pr-${process.env.PR_NUMBER}` : currentGitBranch())
|
||||
(currentGitBranch() as string)
|
||||
|
||||
const branchConfig: BranchConfig = branchConfigs[branchName]
|
||||
|
||||
if (!branchConfig) {
|
||||
console.log(`No publish config found for branch: ${branchName}`)
|
||||
console.log('Exiting...')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const isLatestBranch = branchName === latestBranch
|
||||
const npmTag = isLatestBranch ? 'latest' : branchName
|
||||
|
||||
let remoteURL = execSync('git config --get remote.origin.url').toString()
|
||||
|
||||
remoteURL = remoteURL.substring(0, remoteURL.indexOf('.git'))
|
||||
|
||||
// Get tags
|
||||
let tags: string[] = execSync('git tag').toString().split('\n')
|
||||
|
||||
// Filter tags to our branch/pre-release combo
|
||||
tags = tags
|
||||
.filter((tag) => semver.valid(tag))
|
||||
.filter((tag) => {
|
||||
if (isLatestBranch) {
|
||||
return semver.prerelease(tag) == null
|
||||
}
|
||||
|
||||
return tag.includes(`-${branchName}`)
|
||||
})
|
||||
// sort by latest
|
||||
.sort(semver.compare)
|
||||
|
||||
// Get the latest tag
|
||||
let latestTag = [...tags].pop()
|
||||
|
||||
let range = `${latestTag}..HEAD`
|
||||
// let range = ``;
|
||||
|
||||
let SKIP_TESTS = false
|
||||
|
||||
if (!latestTag || process.env.TAG) {
|
||||
if (process.env.TAG) {
|
||||
if (!process.env.TAG.startsWith('v')) {
|
||||
throw new Error(
|
||||
`process.env.TAG must start with "v", eg. v0.0.0. You supplied ${process.env.TAG}`,
|
||||
)
|
||||
}
|
||||
console.info(
|
||||
chalk.yellow(
|
||||
`Tag is set to ${process.env.TAG}. This will force release all packages. Publishing...`,
|
||||
),
|
||||
)
|
||||
|
||||
// Is it a major version?
|
||||
if (!semver.patch(process.env.TAG) && !semver.minor(process.env.TAG)) {
|
||||
range = `beta..HEAD`
|
||||
latestTag = process.env.TAG
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Could not find latest tag! To make a release tag of v0.0.1, run with TAG=v0.0.1',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
console.info(`Git Range: ${range}`)
|
||||
|
||||
// Get the commits since the latest tag
|
||||
const commitsSinceLatestTag = (
|
||||
await new Promise<Commit[]>((resolve, reject) => {
|
||||
const strm = log.parse({
|
||||
_: range,
|
||||
})
|
||||
|
||||
streamToArray(strm, function (err: any, arr: any[]) {
|
||||
if (err) return reject(err)
|
||||
|
||||
Promise.all(
|
||||
arr.map(async (d) => {
|
||||
const parsed = await parseCommit(d.subject)
|
||||
|
||||
return { ...d, parsed }
|
||||
}),
|
||||
).then((res) => resolve(res.filter(Boolean)))
|
||||
})
|
||||
})
|
||||
).filter((commit: Commit) => {
|
||||
const exclude = [
|
||||
commit.subject.startsWith('Merge branch '), // No merge commits
|
||||
commit.subject.startsWith(releaseCommitMsg('')), // No example update commits
|
||||
].some(Boolean)
|
||||
|
||||
return !exclude
|
||||
})
|
||||
|
||||
console.info(
|
||||
`Parsing ${commitsSinceLatestTag.length} commits since ${latestTag}...`,
|
||||
)
|
||||
|
||||
// Pares the commit messsages, log them, and determine the type of release needed
|
||||
let recommendedReleaseLevel: number = commitsSinceLatestTag.reduce(
|
||||
(releaseLevel, commit) => {
|
||||
if (['fix', 'refactor', 'perf'].includes(commit.parsed.type!)) {
|
||||
releaseLevel = Math.max(releaseLevel, 0)
|
||||
}
|
||||
if (['feat'].includes(commit.parsed.type!)) {
|
||||
releaseLevel = Math.max(releaseLevel, 1)
|
||||
}
|
||||
if (commit.body.includes('BREAKING CHANGE')) {
|
||||
releaseLevel = Math.max(releaseLevel, 2)
|
||||
}
|
||||
if (
|
||||
commit.subject.includes('SKIP_TESTS') ||
|
||||
commit.body.includes('SKIP_TESTS')
|
||||
) {
|
||||
SKIP_TESTS = true
|
||||
}
|
||||
|
||||
return releaseLevel
|
||||
},
|
||||
-1,
|
||||
)
|
||||
|
||||
if (!process.env.TAG) {
|
||||
if (recommendedReleaseLevel === 2) {
|
||||
console.info(
|
||||
`Major versions releases must be tagged and released manually.`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (recommendedReleaseLevel === -1) {
|
||||
console.info(
|
||||
`There have been no changes since the release of ${latestTag} that require a new version. You're good!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function getSorterFn<TItem>(sorters: ((d: TItem) => any)[]) {
|
||||
return (a: TItem, b: TItem) => {
|
||||
let i = 0
|
||||
|
||||
sorters.some((sorter) => {
|
||||
const sortedA = sorter(a)
|
||||
const sortedB = sorter(b)
|
||||
if (sortedA > sortedB) {
|
||||
i = 1
|
||||
return true
|
||||
}
|
||||
if (sortedA < sortedB) {
|
||||
i = -1
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
const changelogCommitsMd = process.env.TAG
|
||||
? `Manual Release: ${process.env.TAG}`
|
||||
: await Promise.all(
|
||||
Object.entries(
|
||||
commitsSinceLatestTag.reduce(
|
||||
(acc, next) => {
|
||||
const type = next.parsed.type?.toLowerCase() ?? 'other'
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[type]: [...(acc[type] || []), next],
|
||||
}
|
||||
},
|
||||
{} as Record<string, Commit[]>,
|
||||
),
|
||||
)
|
||||
.sort(
|
||||
getSorterFn([
|
||||
([d]) =>
|
||||
[
|
||||
'other',
|
||||
'examples',
|
||||
'docs',
|
||||
'chore',
|
||||
'refactor',
|
||||
'perf',
|
||||
'fix',
|
||||
'feat',
|
||||
].indexOf(d),
|
||||
]),
|
||||
)
|
||||
.reverse()
|
||||
.map(async ([type, commits]) => {
|
||||
return Promise.all(
|
||||
commits.map(async (commit) => {
|
||||
let username = ''
|
||||
|
||||
if (process.env.GH_TOKEN) {
|
||||
const query = `${
|
||||
commit.author.email ?? commit.committer.email
|
||||
}`
|
||||
|
||||
const res = await axios.get(
|
||||
'https://api.github.com/search/users',
|
||||
{
|
||||
params: {
|
||||
q: query,
|
||||
},
|
||||
headers: {
|
||||
Authorization: `token ${process.env.GH_TOKEN}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
username = res.data.items[0]?.login
|
||||
}
|
||||
|
||||
const scope = commit.parsed.scope
|
||||
? `${commit.parsed.scope}: `
|
||||
: ''
|
||||
const subject = commit.parsed.subject ?? commit.subject
|
||||
// const commitUrl = `${remoteURL}/commit/${commit.commit.long}`;
|
||||
|
||||
return `- ${scope}${subject} (${commit.commit.short}) ${
|
||||
username
|
||||
? `by @${username}`
|
||||
: `by ${commit.author.name ?? commit.author.email}`
|
||||
}`
|
||||
}),
|
||||
).then((commits) => [type, commits] as const)
|
||||
}),
|
||||
).then((groups) => {
|
||||
return groups
|
||||
.map(([type, commits]) => {
|
||||
return [`### ${capitalize(type)}`, commits.join('\n')].join('\n\n')
|
||||
})
|
||||
.join('\n\n')
|
||||
})
|
||||
|
||||
if (process.env.TAG && recommendedReleaseLevel === -1) {
|
||||
recommendedReleaseLevel = 0
|
||||
}
|
||||
|
||||
const releaseType = branchConfig.prerelease
|
||||
? 'prerelease'
|
||||
: ({ 0: 'patch', 1: 'minor', 2: 'major' } as const)[recommendedReleaseLevel]
|
||||
|
||||
if (!releaseType) {
|
||||
throw new Error(`Invalid release level: ${recommendedReleaseLevel}`)
|
||||
}
|
||||
|
||||
const version = process.env.TAG
|
||||
? semver.parse(process.env.TAG)?.version
|
||||
: semver.inc(latestTag!, releaseType, npmTag)
|
||||
|
||||
if (!version) {
|
||||
throw new Error(
|
||||
`Invalid version increment from semver.inc(${[
|
||||
latestTag,
|
||||
recommendedReleaseLevel,
|
||||
branchConfig.prerelease,
|
||||
].join(', ')}`,
|
||||
)
|
||||
}
|
||||
|
||||
const changelogMd = [
|
||||
`Version ${version} - ${DateTime.now().toLocaleString(
|
||||
DateTime.DATETIME_SHORT,
|
||||
)}`,
|
||||
`## Changes`,
|
||||
changelogCommitsMd,
|
||||
`## Packages`,
|
||||
packages.map((d) => `- ${d.name}@${version}`).join('\n'),
|
||||
].join('\n\n')
|
||||
|
||||
console.info('Generating changelog...')
|
||||
console.info()
|
||||
console.info(changelogMd)
|
||||
console.info()
|
||||
|
||||
console.info('Building packages...')
|
||||
execSync(`pnpm build`, { encoding: 'utf8', stdio: 'inherit' })
|
||||
console.info('')
|
||||
|
||||
console.info('Testing packages...')
|
||||
execSync(`pnpm test:ci ${SKIP_TESTS ? '|| exit 0' : ''}`, {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
console.info('')
|
||||
|
||||
console.info(`Updating all changed packages to version ${version}...`)
|
||||
// Update each package to the new version
|
||||
for (const pkg of packages) {
|
||||
console.info(` Updating ${pkg.name} version to ${version}...`)
|
||||
|
||||
await updatePackageJson(
|
||||
path.resolve(rootDir, 'packages', pkg.packageDir, 'package.json'),
|
||||
(config) => {
|
||||
config.version = version
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
console.info(`Updating all example dependencies...`)
|
||||
await Promise.all(
|
||||
examplesDirs.map(async (examplesDir) => {
|
||||
examplesDir = path.resolve(rootDir, examplesDir)
|
||||
const exampleDirs = await fsp.readdir(examplesDir)
|
||||
for (const exampleName of exampleDirs) {
|
||||
const exampleDir = path.resolve(examplesDir, exampleName)
|
||||
const stat = await fsp.stat(exampleDir)
|
||||
if (!stat.isDirectory()) continue
|
||||
|
||||
console.info(
|
||||
` Updating ${exampleName}'s dependencies to version ${version}.`,
|
||||
)
|
||||
await Promise.all([
|
||||
fsp.rm(path.resolve(exampleDir, 'package-lock.json'), {
|
||||
force: true,
|
||||
}),
|
||||
fsp.rm(path.resolve(exampleDir, 'yarn.lock'), {
|
||||
force: true,
|
||||
}),
|
||||
updatePackageJson(
|
||||
path.resolve(exampleDir, 'package.json'),
|
||||
async (config) => {
|
||||
await Promise.all(
|
||||
packages.map(async (pkg) => {
|
||||
config.dependencies![pkg.name] = version
|
||||
}),
|
||||
)
|
||||
},
|
||||
),
|
||||
])
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
if (!process.env.CI) {
|
||||
console.warn(
|
||||
`This is a dry run for version ${version}. Push to CI to publish for real or set CI=true to override!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Tag and commit
|
||||
console.info(`Creating new git tag v${version}`)
|
||||
execSync(`git tag -a -m "v${version}" v${version}`)
|
||||
|
||||
const taggedVersion = getTaggedVersion()
|
||||
if (!taggedVersion) {
|
||||
throw new Error(
|
||||
'Missing the tagged release version. Something weird is afoot!',
|
||||
)
|
||||
}
|
||||
|
||||
console.info()
|
||||
console.info(`Publishing all packages to npm with tag "${npmTag}"`)
|
||||
|
||||
// Publish each package
|
||||
packages.map((pkg) => {
|
||||
const packageDir = path.join(rootDir, 'packages', pkg.packageDir)
|
||||
const cmd = `cd ${packageDir} && pnpm publish --tag ${npmTag} --access=public --no-git-checks`
|
||||
console.info(
|
||||
` Publishing ${pkg.name}@${version} to npm with tag "${npmTag}"...`,
|
||||
)
|
||||
// execSync(`${cmd} --token ${process.env.NPM_TOKEN}`)
|
||||
execSync(cmd)
|
||||
})
|
||||
|
||||
console.info()
|
||||
|
||||
console.info(`Pushing new tags to branch.`)
|
||||
execSync(`git push --tags`)
|
||||
console.info(` Pushed tags to branch.`)
|
||||
|
||||
if (branchConfig.ghRelease) {
|
||||
console.info(`Creating github release...`)
|
||||
// Stringify the markdown to excape any quotes
|
||||
execSync(
|
||||
`gh release create v${version} ${
|
||||
!isLatestBranch ? '--prerelease' : ''
|
||||
} --notes '${changelogMd}'`,
|
||||
)
|
||||
console.info(` Github release created.`)
|
||||
|
||||
console.info(`Committing changes...`)
|
||||
execSync(`git add -A && git commit -m "${releaseCommitMsg(version)}"`)
|
||||
console.info()
|
||||
console.info(` Committed Changes.`)
|
||||
console.info(`Pushing changes...`)
|
||||
execSync(`git push`)
|
||||
console.info()
|
||||
console.info(` Changes pushed.`)
|
||||
} else {
|
||||
console.info(`Skipping github release and change commit.`)
|
||||
}
|
||||
|
||||
console.info(`Pushing tags...`)
|
||||
execSync(`git push --tags`)
|
||||
console.info()
|
||||
console.info(` Tags pushed.`)
|
||||
console.info(`All done!`)
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.info(err)
|
||||
if (err.stdout) {
|
||||
console.log(err.stdout.toString())
|
||||
}
|
||||
if (err.stderr) {
|
||||
console.log(err.stderr.toString())
|
||||
}
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
function capitalize(str: string) {
|
||||
return str.slice(0, 1).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
async function readPackageJson(pathName: string) {
|
||||
return (await jsonfile.readFile(pathName)) as PackageJson
|
||||
}
|
||||
|
||||
async function updatePackageJson(
|
||||
pathName: string,
|
||||
transform: (json: PackageJson) => Promise<void> | void,
|
||||
) {
|
||||
const json = await readPackageJson(pathName)
|
||||
await transform(json)
|
||||
await jsonfile.writeFile(pathName, json, {
|
||||
spaces: 2,
|
||||
})
|
||||
}
|
||||
|
||||
function updateExampleLockfile(example: string) {
|
||||
// execute npm to update lockfile, ignoring any stdout or stderr
|
||||
const exampleDir = path.join(rootDir, 'examples', example)
|
||||
execSync(`cd ${exampleDir} && pnpm install`, { stdio: 'ignore' })
|
||||
}
|
||||
|
||||
function getPackageNameDirectory(pathName: string) {
|
||||
return pathName
|
||||
.split('/')
|
||||
.filter((d) => !d.startsWith('@'))
|
||||
.join('/')
|
||||
}
|
||||
|
||||
function getTaggedVersion() {
|
||||
const output = execSync('git tag --list --points-at HEAD').toString()
|
||||
return output.replace(/^v|\n+$/g, '')
|
||||
}
|
||||
20
scripts/tsconfig.json
Normal file
20
scripts/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES5",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true,
|
||||
"checkJs": true
|
||||
},
|
||||
"ts-node": {
|
||||
"transpileOnly": true,
|
||||
"files": true,
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"inlineSources": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { RollupOptions } from 'rollup'
|
||||
|
||||
export type Commit = {
|
||||
commit: CommitOrTree
|
||||
tree: CommitOrTree
|
||||
@@ -22,16 +20,16 @@ export type AuthorOrCommitter = {
|
||||
}
|
||||
|
||||
export type Parsed = {
|
||||
type: string | null
|
||||
type: string
|
||||
scope?: string | null
|
||||
subject: string
|
||||
merge?: null
|
||||
header: string
|
||||
body?: null
|
||||
footer?: null
|
||||
notes?: Array<null> | null
|
||||
references?: Array<null> | null
|
||||
mentions?: Array<null> | null
|
||||
notes?: null[] | null
|
||||
references?: null[] | null
|
||||
mentions?: null[] | null
|
||||
revert?: null
|
||||
raw: string
|
||||
}
|
||||
@@ -44,4 +42,5 @@ export type Package = {
|
||||
|
||||
export type BranchConfig = {
|
||||
prerelease: boolean
|
||||
ghRelease: boolean
|
||||
}
|
||||
29
tsconfig.base.json
Normal file
29
tsconfig.base.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2022"],
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"strictNullChecks": true,
|
||||
"declaration": true,
|
||||
"noImplicitReturns": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"allowUnreachableCode": true,
|
||||
"paths": {
|
||||
"@tanstack/form-core": ["packages/form-core"],
|
||||
"@tanstack/react-form": ["packages/react-form"],
|
||||
"@tanstack/vue-form": ["packages/vue-form"]
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,10 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"baseUrl": ".",
|
||||
"checkJs": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["ES2020"],
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"target": "ES2020"
|
||||
},
|
||||
"include": [".eslintrc.cjs", "rollup.config.js", "scripts"]
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "packages/form-core" },
|
||||
{ "path": "packages/react-form" },
|
||||
{ "path": "packages/vue-form" }
|
||||
]
|
||||
// "include": ["examples/*"]
|
||||
// "exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user