diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 17982f3a..1554ba6b 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -7,6 +7,7 @@ on: - develop2 - develop - master + workflow_dispatch: jobs: build-and-deploy: @@ -20,6 +21,7 @@ jobs: TOOL_NODE_FLAGS: '--max-old-space-size=4096' with: node-version: 20 + registry-url: 'https://registry.npmjs.org' - uses: pnpm/action-setup@v3 name: Install pnpm with: @@ -32,6 +34,39 @@ jobs: - name: Execute build.sh run: | sh ./scripts/build.sh + # dev 채널: develop push 마다 새 prerelease 를 dev 태그로 배포한다. + # 버전은 러너에서만 바꾸고 커밋하지 않으므로, publish 후 package.json 을 원복해 + # 뒤따르는 deploy.sh 가 dist 브랜치에 담는 내용물은 기존과 동일하게 유지한다. + - name: publish dev + if: github.ref == 'refs/heads/develop' + shell: bash + run: | + set -euo pipefail + # npx semver 는 쓰지 않는다. pnpm 이 만든 node_modules/.pnpm 에 semver 가 + # 이미 있어 npx 가 설치를 건너뛰지만 .bin/semver 가 없어 실패한다. + NEXT=$(node -p "const v = require('./package.json').version.split('-')[0].split('.').map(Number); v[2] += 1; v.join('.')") + # github.run_number 는 이 워크플로 전체의 누적 실행 횟수라 dev 채널 도입 시점에 이미 41 이었다. + # dev 번호를 1 부터 시작시키려고 도입 직전 실행 번호를 기준점으로 뺀다. + # master/develop2/deploy 브랜치 push 도 같은 카운터를 올리므로 번호는 건너뛸 수 있지만, + # 재publish 가 거부되지 않도록 단조증가하기만 하면 되므로 연속성은 필요하지 않다. + DEV_SEQ=$(( ${{ github.run_number }} - 41 )) + (( DEV_SEQ >= 1 )) || { echo "::error::dev 번호가 1 미만입니다 (run_number=${{ github.run_number }}, 기준점=41)"; exit 1; } + VERSION="$NEXT-dev.$DEV_SEQ" + # 버전 계산이 조용히 실패한 채 publish 되는 것을 막는다. + [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-dev\.[0-9]+$ ]] || { echo "::error::계산된 버전이 올바르지 않습니다: $VERSION"; exit 1; } + echo "publish @entrylabs/tool@$VERSION (dist-tag: dev)" + npm pkg set version="$VERSION" + npm publish --tag dev + git checkout -- package.json + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + # latest 채널: master push 시, package.json 버전이 npm 에 아직 없을 때만 배포된다. + # 이미 있는 버전이면 액션이 조용히 skip 하므로 master push 마다 돌려도 안전하다. + - name: publish latest + if: github.ref == 'refs/heads/master' + uses: JS-DevTools/npm-publish@v3 + with: + token: ${{ secrets.NPM_TOKEN }} - name: Execute deploy.sh run: | sh ./scripts/deploy.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index c239da26..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: 'release' -on: - release: - types: [created] - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v3 - with: - version: 9 - - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - run: pnpm install - - run: pnpm build - - uses: JS-DevTools/npm-publish@v3 - with: - token: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index 199345a0..5baf8ed3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@entrylabs/tool", - "version": "2.0.8", + "version": "2.0.9", "license": "MIT", "repository": { "type": "git", diff --git a/src/components/widget/Chart/Bar.jsx b/src/components/widget/Chart/Bar.jsx index a3fe3a97..3c98ff82 100644 --- a/src/components/widget/Chart/Bar.jsx +++ b/src/components/widget/Chart/Bar.jsx @@ -14,7 +14,7 @@ import _unzip from 'lodash/unzip'; import _findIndex from 'lodash/findIndex'; const setChartXCount = (chartObj, categories, windowWidth) => () => { - const categoryWordLength = categories?.[0].toString().length * 5; + const categoryWordLength = categories?.[0]?.toString().length * 5; const padding = 100; if (windowWidth > categoryWordLength * categories.length + padding) { chartObj.tickCount = categories.length; @@ -55,7 +55,7 @@ const Bar = ({ chart, table, size }) => { .slice(1) .map((row, index) => (isAddedOption ? index + 1 : row[xIndex])); const columns = deduplicationColumn( - [...categoryIndexes].map((index) => _unzip(orderedTable)[index]) + [...categoryIndexes].map((index) => _unzip(orderedTable)[index]).filter(Array.isArray) ); const chartObj = bb.generate({ diff --git a/src/components/widget/Chart/Line.jsx b/src/components/widget/Chart/Line.jsx index 997102b9..ce12c3a8 100644 --- a/src/components/widget/Chart/Line.jsx +++ b/src/components/widget/Chart/Line.jsx @@ -14,7 +14,7 @@ import _unzip from 'lodash/unzip'; import _findIndex from 'lodash/findIndex'; const setChartXCount = (chartObj, categories, windowWidth) => () => { - const categoryWordLength = categories?.[0].toString().length * 5; + const categoryWordLength = categories?.[0]?.toString().length * 5; const padding = 100; if (windowWidth > categoryWordLength * categories.length + padding) { chartObj.tickCount = categories.length; @@ -53,7 +53,7 @@ const Line = ({ chart, table, size }) => { .slice(1) .map((row, index) => (isAddedOption ? index + 1 : row[xIndex])); const columns = deduplicationColumn( - [...categoryIndexes].map((index) => _unzip(orderedTable)[index]) + [...categoryIndexes].map((index) => _unzip(orderedTable)[index]).filter(Array.isArray) ); const chartObj = bb.generate({ diff --git a/src/utils/dataAnalytics.js b/src/utils/dataAnalytics.js index c28c6bed..a7a171c1 100644 --- a/src/utils/dataAnalytics.js +++ b/src/utils/dataAnalytics.js @@ -190,8 +190,8 @@ export const getBinWidth = (table, categoryIndexes = [], boundary, bin) => { if (!categoryIndexes.length) { return '-'; } - let min = Number(table[1][categoryIndexes]) || Number.MAX_SAFE_INTEGER; - let max = Number(table[1][categoryIndexes]) || Number.MIN_SAFE_INTEGER; + let min = Number(table?.[1]?.[categoryIndexes]) || Number.MAX_SAFE_INTEGER; + let max = Number(table?.[1]?.[categoryIndexes]) || Number.MIN_SAFE_INTEGER; _forEach(categoryIndexes, (index) => { _forEach(table.slice(1), (row) => { const value = Number(row[index]);