Merge branch 'main' into deploy #31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Check and Deploy to NPM | |
| on: | |
| push: | |
| branches: | |
| - deploy | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed packages | |
| id: set-matrix | |
| run: | | |
| # 获取最后一次成功运行的提交SHA或默认为一个空树 | |
| git fetch origin refs/tags/last-deploy 2>/dev/null || true | |
| if git rev-parse -q --verify refs/tags/last-deploy >/dev/null; then | |
| BASE_SHA=$(git rev-parse refs/tags/last-deploy) | |
| echo "Using last successful deploy tag as base: $BASE_SHA" | |
| else | |
| echo "No last-deploy tag found, using first commit in history" | |
| BASE_SHA=$(git rev-list --max-parents=0 HEAD) | |
| fi | |
| HEAD_SHA=${{ github.sha }} | |
| echo "Comparing $BASE_SHA...$HEAD_SHA" | |
| PACKAGE_DIRS=$(find . -name "package.json" -not -path "*/node_modules/*" -not -path "./package.json" -exec dirname {} \; | sed 's/^\.\///') | |
| CHANGED_PACKAGES=() | |
| for dir in $PACKAGE_DIRS; do | |
| if git diff --quiet --diff-filter=ACMRT $BASE_SHA $HEAD_SHA -- "$dir"; then | |
| echo "No changes in $dir" | |
| else | |
| echo "Detected changes in $dir" | |
| # Only add first-level directories (no slashes in the path) | |
| if [[ "$dir" != *"/"* ]]; then | |
| CHANGED_PACKAGES+=("$dir") | |
| fi | |
| fi | |
| done | |
| if [ ${#CHANGED_PACKAGES[@]} -eq 0 ]; then | |
| echo "matrix={\"package\":[]}" >> $GITHUB_OUTPUT | |
| echo "No packages changed" | |
| else | |
| JSON_ARRAY=$(printf '"%s",' "${CHANGED_PACKAGES[@]}" | sed 's/,$//') | |
| echo "matrix={\"package\":[$JSON_ARRAY]}" >> $GITHUB_OUTPUT | |
| echo "Changed packages: ${CHANGED_PACKAGES[@]}" | |
| fi | |
| build-and-publish: | |
| needs: detect-changes | |
| if: ${{ github.event_name == 'push' && needs.detect-changes.outputs.matrix != '{"package":[]}' && github.ref == 'refs/heads/deploy'}} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: ${{ fromJson(needs.detect-changes.outputs.matrix) }} | |
| fail-fast: false | |
| steps: | |
| - name: Check UPDATE_ALL flag | |
| id: check-update-all | |
| run: | | |
| if [[ "${{ secrets.UPDATE_ALL }}" == "true" ]]; then | |
| echo "should_skip=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "should_skip=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: echo matrix | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| run: echo "${{ toJson(matrix) }}" | |
| - name: Checkout code | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| uses: actions/checkout@v3 | |
| with: | |
| token: ${{ secrets.GHB_TOKEN }} | |
| - name: Setup Node.js | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| registry-url: ${{ secrets.REGISTRY_URL }} | |
| - name: Install dependencies | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| run: | | |
| cd ${{ matrix.package }} | |
| npm ci || npm install | |
| - name: 配置 npm | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| run: | | |
| npm config set fetch-timeout 600000 | |
| npm config set fetch-retry-mintimeout 20000 | |
| npm config set fetch-retry-maxtimeout 120000 | |
| - name: Build package | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| run: | | |
| cd ${{ matrix.package }} | |
| npm run build --if-present | |
| - name: Publish to NPM | |
| if: steps.check-update-all.outputs.should_skip != 'true' | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| cd ${{ matrix.package }} | |
| # 获取当前版本号 | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| PACKAGE_NAME=$(node -p "require('./package.json').name") | |
| echo "Current version: $CURRENT_VERSION" | |
| # 检查当前版本是否已在 NPM registry 上发布 | |
| if npm view $PACKAGE_NAME@$CURRENT_VERSION version &> /dev/null; then | |
| echo "版本 $CURRENT_VERSION 已存在,尝试取消发布..." | |
| npm unpublish $PACKAGE_NAME@$CURRENT_VERSION --force | |
| fi | |
| # 等待一段时间确保取消发布生效 | |
| sleep 5 | |
| # 发布 | |
| npm publish --access public | |
| build-and-publish-all: | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/deploy' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check UPDATE_ALL flag | |
| id: check-update-all | |
| run: | | |
| if [[ "${{ secrets.UPDATE_ALL }}" == "true" ]]; then | |
| echo "should_run=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Checkout code | |
| if: steps.check-update-all.outputs.should_run == 'true' | |
| uses: actions/checkout@v3 | |
| with: | |
| token: ${{ secrets.GHB_TOKEN }} | |
| - name: Setup Node.js | |
| if: steps.check-update-all.outputs.should_run == 'true' | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| registry-url: ${{ secrets.REGISTRY_URL }} | |
| - name: Publish to NPM | |
| if: steps.check-update-all.outputs.should_run == 'true' | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| PACKAGE_DIRS=$(find . -name "package.json" -not -path "*/node_modules/*" -not -path "./package.json" -exec dirname {} \; | sed 's/^\.\///') | |
| echo "Found packages: $PACKAGE_DIRS" | |
| # 仅保留一级目录 | |
| FIRST_LEVEL_DIRS=() | |
| for dir in $PACKAGE_DIRS; do | |
| if [[ "$dir" != *"/"* ]]; then | |
| FIRST_LEVEL_DIRS+=("$dir") | |
| fi | |
| done | |
| echo "要发布的一级目录包: ${FIRST_LEVEL_DIRS[*]}" | |
| for dir in "${FIRST_LEVEL_DIRS[@]}"; do | |
| if [ ! -d "$dir" ]; then | |
| echo "目录 $dir 不存在,跳过..." | |
| continue | |
| fi | |
| cd $dir | |
| echo "发布 $dir" | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| PACKAGE_NAME=$(node -p "require('./package.json').name") | |
| echo "当前版本: $CURRENT_VERSION" | |
| if npm view $PACKAGE_NAME@$CURRENT_VERSION version &> /dev/null; then | |
| echo "版本 $CURRENT_VERSION 已存在,尝试取消发布..." | |
| npm unpublish $PACKAGE_NAME@$CURRENT_VERSION --force | |
| fi | |
| sleep 5 | |
| npm publish --access public | |
| cd .. | |
| done | |
| update-last-deploy-tag: | |
| needs: [detect-changes, build-and-publish] | |
| # 当build-and-publish成功运行时,或者当没有变更需要发布时运行 | |
| if: | | |
| always() && | |
| (needs.build-and-publish.result == 'success' || | |
| (needs.detect-changes.result == 'success' && needs.detect-changes.outputs.matrix == '{"package":[]}')) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| with: | |
| token: ${{ secrets.GHB_TOKEN }} | |
| - name: Update last deploy tag | |
| run: | | |
| git tag -f last-deploy ${{ github.sha }} | |
| git push -f origin last-deploy |