diff --git a/.github/workflows/release-custom-tag.yml b/.github/workflows/release-custom-tag.yml index 92a7101a810..0c958290d77 100644 --- a/.github/workflows/release-custom-tag.yml +++ b/.github/workflows/release-custom-tag.yml @@ -43,16 +43,25 @@ jobs: run: | npm install -g npm yarn install - yarn build - - name: publish + - name: version run: | git config user.email ${{ secrets.BOT_GIT_EMAIL }} git config user.name ${{ secrets.BOT_GIT_USERNAME }} - ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish ${{ github.event.inputs.release_type }} \ + ${GITHUB_WORKSPACE}/node_modules/.bin/lerna version ${{ github.event.inputs.release_type }} \ --dist-tag ${{ github.event.inputs.npm_tag }} env: GH_TOKEN: ${{ secrets.ACCESS_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} NPM_CONFIG_PROVENANCE: true + + - name: build + run: yarn build + + - name: publish to npm + run: ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish from-git + env: + GH_TOKEN: ${{ secrets.ACCESS_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + NPM_CONFIG_PROVENANCE: true diff --git a/.github/workflows/release-snapshot.yml b/.github/workflows/release-snapshot.yml index 570ae28e1cf..2b11134a9b0 100644 --- a/.github/workflows/release-snapshot.yml +++ b/.github/workflows/release-snapshot.yml @@ -34,23 +34,34 @@ jobs: run: | npm install -g npm yarn install - yarn build - - name: publish + - name: version run: | git config user.email ${{ secrets.BOT_GIT_EMAIL }} git config user.name ${{ secrets.BOT_GIT_USERNAME }} git_hash=$(git rev-parse --short "$GITHUB_SHA") current_branch=$(node -p -e "'${{ github.ref }}'.replace('refs/heads/', '')") + echo "current_branch=${current_branch}" >> "$GITHUB_ENV" - ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish "0.0.0-${git_hash}" \ + ${GITHUB_WORKSPACE}/node_modules/.bin/lerna version "0.0.0-${git_hash}" \ --exact \ --no-push \ --no-git-tag-version \ - --pre-dist-tag dev \ - --allow-branch ${current_branch} + --allow-branch ${{ env.current_branch }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + NPM_CONFIG_PROVENANCE: true + - name: build + run: yarn build + + - name: publish to npm + run: | + ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish from-git \ + --pre-dist-tag dev \ + --allow-branch ${{ env.current_branch }} env: + GH_TOKEN: ${{ secrets.ACCESS_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} NPM_CONFIG_PROVENANCE: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7af06d17127..20c771fa2c0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,16 +72,15 @@ jobs: run: | npm install -g npm yarn install --immutable - yarn build - - name: publish + - name: version run: | npm config set //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} git config user.email ${{ secrets.BOT_GIT_EMAIL }} git config user.name ${{ secrets.BOT_GIT_USERNAME }} - ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish ${{ github.event.inputs.release_type }} \ + ${GITHUB_WORKSPACE}/node_modules/.bin/lerna version ${{ github.event.inputs.release_type }} \ ${{ (github.event.inputs.prerelease == 'true' && '--conventional-prerelease') || '--conventional-graduate' }} \ --create-release github env: @@ -89,6 +88,16 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} NPM_CONFIG_PROVENANCE: true + - name: build + run: yarn build + + - name: publish to npm + run: ${GITHUB_WORKSPACE}/node_modules/.bin/lerna publish from-git + env: + GH_TOKEN: ${{ secrets.ACCESS_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + NPM_CONFIG_PROVENANCE: true + ### Semantic Release Bot comments for issues and PRs ### - name: Add release comments to issues and PRs uses: actions/github-script@v7 diff --git a/.gitignore b/.gitignore index 97571e7714f..5eaf2ee10f6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,6 @@ packages/cypress-commands/api.json packages/main/scripts/wrapperGeneration/json packages/main/tmp +packages/*/src/generated/ .nx/cache diff --git a/package.json b/package.json index 9dac2eac2a1..38f5270f593 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start": "yarn setup && yarn create-cypress-commands-docs && npm-run-all -p start:watcher start:storybook", "start:watcher": "lerna run watch:css", "start:storybook": "storybook dev -p 6006", - "setup": "lerna run build:i18n && lerna run build:css && lerna run build:css-bundle && rimraf node_modules/@types/mocha", + "setup": "lerna run build:i18n && lerna run build:css && lerna run build:css-bundle && lerna run build:version-info && rimraf node_modules/@types/mocha", "build": "yarn setup && tsc --build tsconfig.build.json && lerna run build:client && lerna run build:wrapper", "build:storybook": "yarn build && yarn create-cypress-commands-docs && storybook build -o .out", "build:storybook-sitemap": "node ./scripts/create-storybook-sitemap.js --directory .out", diff --git a/packages/base/package.json b/packages/base/package.json index eb3c4290a8d..baaec516a57 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -26,7 +26,8 @@ "license": "Apache-2.0", "sideEffects": false, "scripts": { - "clean": "rimraf dist" + "clean": "rimraf dist", + "build:version-info": "node ../../scripts/generate-version-info.js" }, "peerDependencies": { "@types/react": "*", diff --git a/packages/base/src/index.ts b/packages/base/src/index.ts index 22f5ff132fa..cb28cb169aa 100644 --- a/packages/base/src/index.ts +++ b/packages/base/src/index.ts @@ -1,4 +1,5 @@ import * as Device from './Device/index.js'; +import VersionInfo from './generated/VersionInfo.js'; import * as hooks from './hooks/index.js'; import { I18nStore } from './stores/I18nStore.js'; import { StyleStore } from './stores/StyleStore.js'; @@ -9,3 +10,4 @@ export * from './utils/index.js'; export * from './hooks/index.js'; export { I18nStore, StyleStore, ThemingParameters, Device, hooks }; +export const version = VersionInfo.version; diff --git a/packages/charts/package.json b/packages/charts/package.json index bd7d789c465..3a361941044 100644 --- a/packages/charts/package.json +++ b/packages/charts/package.json @@ -30,6 +30,7 @@ "clean": "rimraf dist", "build:css": "postcss --base src --dir dist/css src/**/*.css", "build:css-bundle": "node ../../config/merge-css-modules.js", + "build:version-info": "node ../../scripts/generate-version-info.js", "watch:css": "yarn build:css --watch" }, "dependencies": { diff --git a/packages/charts/src/index.ts b/packages/charts/src/index.ts index 9fb8b5ad792..a1e4ec16937 100644 --- a/packages/charts/src/index.ts +++ b/packages/charts/src/index.ts @@ -20,6 +20,7 @@ import { ScatterChart } from './components/ScatterChart/ScatterChart.js'; import { TimelineChartPlaceholder } from './components/TimelineChart/Placeholder.js'; import { TimelineChart } from './components/TimelineChart/TimelineChart.js'; import { TimelineChartAnnotation } from './components/TimelineChart/TimelineChartAnnotation.js'; +import VersionInfo from './generated/VersionInfo.js'; export { BarChart, @@ -45,3 +46,4 @@ export { ColumnChartWithTrendPlaceholder, TimelineChartPlaceholder }; +export const version = VersionInfo.version; diff --git a/packages/compat/package.json b/packages/compat/package.json index 85007d2e474..de5055e15d6 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -30,6 +30,7 @@ "clean": "rimraf dist tmp", "build:css": "postcss --base src --dir dist/css src/**/*.css", "build:css-bundle": "node ../../config/merge-css-modules.js", + "build:version-info": "node ../../scripts/generate-version-info.js", "watch:css": "yarn build:css --watch" }, "dependencies": { diff --git a/packages/compat/src/index.ts b/packages/compat/src/index.ts index dae78941495..c265d54a6d7 100644 --- a/packages/compat/src/index.ts +++ b/packages/compat/src/index.ts @@ -1,3 +1,5 @@ +import VersionInfo from './generated/VersionInfo.js'; + export * from './components/Loader/index.js'; export * from './components/OverflowToolbarButton/index.js'; export * from './components/OverflowToolbarToggleButton/index.js'; @@ -13,3 +15,4 @@ export * from './components/ToolbarSpacer/index.js'; export { LoaderType } from './enums/LoaderType.js'; export { ToolbarDesign } from './enums/ToolbarDesign.js'; export { ToolbarStyle } from './enums/ToolbarStyle.js'; +export const version = VersionInfo.version; diff --git a/packages/main/package.json b/packages/main/package.json index a84e628da4d..e9ba50f7dc4 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -44,6 +44,7 @@ "build:wrapper": "babel src --out-dir wrappers --extensions .ts,.tsx --env-name wrapper && tsc --project tsconfig.build.json --declarationDir wrappers", "build:css": "postcss --base src --dir dist/css src/**/*.css", "build:css-bundle": "node ../../config/merge-css-modules.js", + "build:version-info": "node ../../scripts/generate-version-info.js", "watch:css": "yarn build:css --watch" }, "dependencies": { diff --git a/packages/main/src/components/ThemeProvider/index.tsx b/packages/main/src/components/ThemeProvider/index.tsx index 7f11bc0c459..451b66721c6 100644 --- a/packages/main/src/components/ThemeProvider/index.tsx +++ b/packages/main/src/components/ThemeProvider/index.tsx @@ -8,20 +8,11 @@ import { attachThemeLoaded, detachThemeLoaded } from '@ui5/webcomponents-base/di import { I18nStore, StyleStore, useIsomorphicLayoutEffect, useStylesheet } from '@ui5/webcomponents-react-base'; import type { FC, ReactNode } from 'react'; import { useEffect, useId } from 'react'; -import pkgJson from '../../../package.json'; -import { parseSemVer } from '../../internal/utils.js'; +import VersionInfo from '../../generated/VersionInfo.js'; import { styleData } from './ThemeProvider.css.js'; -let _versionInfo = null; let _versionInfoInjected = false; -function getVersionInfo() { - if (!_versionInfo) { - _versionInfo = parseSemVer(pkgJson.version); - } - return _versionInfo; -} - function ThemeProviderStyles() { const uniqueId = useId(); useStylesheet(styleData, `${ThemeProvider.displayName}-${uniqueId}`); @@ -95,15 +86,14 @@ const ThemeProvider: FC = (props: ThemeProviderPropTypes if (_versionInfoInjected) { return; } - const versionInfo = getVersionInfo(); globalThis['@ui5/webcomponents-react'] ??= {}; globalThis['@ui5/webcomponents-react'].Runtimes ??= []; - globalThis['@ui5/webcomponents-react'].Runtimes.push(versionInfo); + globalThis['@ui5/webcomponents-react'].Runtimes.push(VersionInfo); _versionInfoInjected = true; return () => { globalThis['@ui5/webcomponents-react'].Runtimes = globalThis['@ui5/webcomponents-react'].Runtimes.filter( - (info) => info !== versionInfo + (info) => info !== VersionInfo ); _versionInfoInjected = false; }; diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index 142fe435c8f..872627fe8ae 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -1,4 +1,5 @@ import * as AnalyticalTableHooks from './components/AnalyticalTable/pluginHooks/AnalyticalTableHooks.js'; +import VersionInfo from './generated/VersionInfo.js'; export * from './components/ActionSheet/index.js'; export * from './components/AnalyticalCardHeader/index.js'; @@ -37,3 +38,4 @@ export type { CommonProps, Ui5CustomEvent, Ui5DomRef, UI5WCSlotsNode, Nullable } export * from './webComponents/index.js'; export { AnalyticalTableHooks }; +export const version = VersionInfo.version; diff --git a/scripts/generate-version-info.js b/scripts/generate-version-info.js new file mode 100644 index 00000000000..0bf6d20356c --- /dev/null +++ b/scripts/generate-version-info.js @@ -0,0 +1,34 @@ +import fs from 'fs/promises'; + +const generate = async () => { + const version = JSON.parse(await fs.readFile('package.json')).version; + + // Parse version + const matches = version.match(/^([0-9]+)\.([0-9]+)\.([0-9]+)(.*)$/); + if (!matches) { + throw new Error('Unsupported version format'); + } + + const isNext = version.match(/[a-f0-9]{9}$/); + const buildTime = Math.floor(new Date().getTime() / 1000); + + const fileContent = `const VersionInfo = { + version: '${version}', + major: ${matches[1]}, + minor: ${matches[2]}, + patch: ${matches[3]}, + suffix: '${matches[4]}', + isNext: ${isNext ? 'true' : 'false'}, + buildTime: ${buildTime} +}; + +export default VersionInfo; +`; + + await fs.mkdir('src/generated/', { recursive: true }); + await fs.writeFile('src/generated/VersionInfo.ts', fileContent); +}; + +generate().then(() => { + console.log('Version info file generated.'); +});