From ceb16bde996878851083f4efd83bc82e0a744156 Mon Sep 17 00:00:00 2001 From: SonyLeo <746591437@qq.com> Date: Fri, 26 Dec 2025 00:33:53 +0800 Subject: [PATCH 1/2] feat: add reusable CI workflows for building and E2E testing --- .github/workflows/pr-ci-build.yml | 11 +- .github/workflows/pr-ci-e2e-test.yml | 4 +- .github/workflows/pr-ci-publish-packages.yml | 72 +++++++++++ .github/workflows/pr-ci.yml | 8 +- .github/workflows/pr-cleanup.yml | 7 +- ...r-ci-preview.yml => pr-deploy-preview.yml} | 119 ++++++++---------- 6 files changed, 145 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/pr-ci-publish-packages.yml rename .github/workflows/{pr-ci-preview.yml => pr-deploy-preview.yml} (57%) diff --git a/.github/workflows/pr-ci-build.yml b/.github/workflows/pr-ci-build.yml index d4caa4441..6387a4887 100644 --- a/.github/workflows/pr-ci-build.yml +++ b/.github/workflows/pr-ci-build.yml @@ -42,12 +42,21 @@ jobs: - name: Build components run: pnpm build + - name: Build docs + run: pnpm -F docs build + + - name: Save PR number + if: github.event_name == 'pull_request' + run: echo "${{ github.event.number }}" > pr_number.txt + - name: Upload build artifacts uses: actions/upload-artifact@v4 with: - name: build-${{ github.sha }} + name: build-${{ github.event.pull_request.head.sha || github.sha }} path: | packages/components/dist packages/kit/dist packages/svgs/dist + docs/dist + pr_number.txt retention-days: 1 diff --git a/.github/workflows/pr-ci-e2e-test.yml b/.github/workflows/pr-ci-e2e-test.yml index 600ad414f..a66b6f801 100644 --- a/.github/workflows/pr-ci-e2e-test.yml +++ b/.github/workflows/pr-ci-e2e-test.yml @@ -38,8 +38,8 @@ jobs: - name: Download build artifacts uses: actions/download-artifact@v4 with: - name: build-${{ github.sha }} - path: packages + name: build-${{ github.event.pull_request.head.sha || github.sha }} + path: . - name: Install Playwright Browser run: | diff --git a/.github/workflows/pr-ci-publish-packages.yml b/.github/workflows/pr-ci-publish-packages.yml new file mode 100644 index 000000000..5f4eed1b8 --- /dev/null +++ b/.github/workflows/pr-ci-publish-packages.yml @@ -0,0 +1,72 @@ +name: 'CI: Publish Packages' + +on: + workflow_call: + inputs: + pr-number: + description: 'Pull Request number' + type: number + required: true + +jobs: + preview-job: + name: preview + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + + - name: Get pnpm store directory + id: pnpm-cache + run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm i --no-frozen-lockfile + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-${{ github.event.pull_request.head.sha || github.sha }} + path: . + + - name: Publish to pkg.pr.new + id: pkg-pr-new + run: | + npx pkg-pr-new publish \ + ./packages/components \ + ./packages/kit \ + ./packages/svgs \ + --pnpm \ + --json output.json \ + --comment=off + + - name: Save pkg.pr.new output + run: | + if [ -f output.json ]; then + cp output.json pkg-pr-new-output.json + fi + + - name: Upload pkg.pr.new output + uses: actions/upload-artifact@v4 + with: + name: pkg-pr-new-output-${{ github.event.pull_request.head.sha || github.sha }} + path: pkg-pr-new-output.json + retention-days: 1 + if-no-files-found: ignore diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index a1c4d353d..35ef891ee 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -28,16 +28,16 @@ jobs: with: skip-playground: true - # 生成预览(依赖构建,仅 PR 事件) - preview: + # 发布包预览(依赖构建,仅 PR 事件) + publish-packages: needs: [build] if: github.event_name == 'pull_request' - uses: ./.github/workflows/pr-ci-preview.yml + uses: ./.github/workflows/pr-ci-publish-packages.yml with: pr-number: ${{ github.event.pull_request.number }} secrets: inherit - # E2E 测试(依赖构建,与预览并行) + # E2E 测试(依赖构建) e2e-test: needs: [build] uses: ./.github/workflows/pr-ci-e2e-test.yml diff --git a/.github/workflows/pr-cleanup.yml b/.github/workflows/pr-cleanup.yml index 11b74472a..5cef83e1c 100644 --- a/.github/workflows/pr-cleanup.yml +++ b/.github/workflows/pr-cleanup.yml @@ -1,9 +1,12 @@ -name: PR Docs Cleanup +name: 'CI: Docs Cleanup' on: - pull_request: + pull_request_target: types: [closed] +permissions: + pull-requests: write + jobs: cleanup: runs-on: ubuntu-latest diff --git a/.github/workflows/pr-ci-preview.yml b/.github/workflows/pr-deploy-preview.yml similarity index 57% rename from .github/workflows/pr-ci-preview.yml rename to .github/workflows/pr-deploy-preview.yml index 17f7153e4..92d7c795e 100644 --- a/.github/workflows/pr-ci-preview.yml +++ b/.github/workflows/pr-deploy-preview.yml @@ -1,95 +1,80 @@ -name: 'CI: Preview' +name: 'CI: Deploy Preview' on: - workflow_call: - inputs: - pr-number: - description: 'Pull Request number' - type: number - required: true + workflow_run: + workflows: ["ci"] + types: + - completed + +permissions: + pull-requests: write + actions: read + contents: read jobs: - preview-job: - name: preview + deploy: + # 只在 PR 触发且 CI 成功时运行 + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - registry-url: 'https://registry.npmjs.org' - - - name: Get pnpm store directory - id: pnpm-cache - run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT - - - name: Setup pnpm cache - uses: actions/cache@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 with: - path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- + name: build-${{ github.event.workflow_run.head_sha }} + path: artifacts + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} - - name: Install dependencies - run: pnpm i --no-frozen-lockfile + - name: Read PR Number + id: pr + run: | + if [ -f artifacts/pr_number.txt ]; then + echo "number=$(cat artifacts/pr_number.txt)" >> $GITHUB_OUTPUT + else + echo "PR number file not found" + exit 1 + fi - - name: Download build artifacts + - name: Download pkg.pr.new output uses: actions/download-artifact@v4 with: - name: build-${{ github.sha }} - path: packages - - - name: Build docs only (components already built) - run: pnpm -F docs build + name: pkg-pr-new-output-${{ github.event.workflow_run.head_sha }} + path: pkg-artifacts + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + continue-on-error: true - name: Comment build generating - if: github.event_name == 'pull_request' uses: actions-cool/maintain-one-comment@v3.1.1 with: token: ${{ secrets.GITHUB_TOKEN }} body: | [](#) - 🔨 Building packages... + 🔨 Deploying preview... body-include: '' - number: ${{ inputs.pr-number }} - - - name: Publish to pkg.pr.new - id: pkg-pr-new - run: | - npx pkg-pr-new publish \ - ./packages/components \ - ./packages/kit \ - ./packages/svgs \ - --pnpm \ - --json output.json \ - --comment=off + number: ${{ steps.pr.outputs.number }} - name: Post or update pkg.pr.new comment - if: github.event_name == 'pull_request' + if: hashFiles('pkg-artifacts/pkg-pr-new-output.json') != '' uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const output = JSON.parse(fs.readFileSync('output.json', 'utf8')); + const output = JSON.parse(fs.readFileSync('pkg-artifacts/pkg-pr-new-output.json', 'utf8')); - const sha = context.payload.pull_request.head.sha.substring(0, 7); + const sha = '${{ github.event.workflow_run.head_sha }}'.substring(0, 7); const packages = output.packages.map((p) => { const shortUrl = p.url.replace(/@[a-f0-9]{40}/, '@' + sha); return 'pnpm add ' + shortUrl; }).join('\n\n'); - const commitUrl = 'https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/commit/' + sha; + const commitUrl = 'https://github.com/${{ github.repository }}/commit/' + sha; const body = '## 📦 Package Preview\n\n' + packages + '\n\n**commit:** [' + sha + '](' + commitUrl + ')\n\n'; const botCommentIdentifier = ''; @@ -97,7 +82,7 @@ jobs: const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: context.issue.number, + issue_number: ${{ steps.pr.outputs.number }}, }); const existingComment = comments.data.find((comment) => @@ -113,7 +98,7 @@ jobs: }); } else { await github.rest.issues.createComment({ - issue_number: context.issue.number, + issue_number: ${{ steps.pr.outputs.number }}, owner: context.repo.owner, repo: context.repo.repo, body: body, @@ -123,20 +108,20 @@ jobs: - name: Deploy Site to Surge id: deploy run: | - DEPLOY_DOMAIN=preview-${{ inputs.pr-number }}-tiny-robot.surge.sh + DEPLOY_DOMAIN=preview-${{ steps.pr.outputs.number }}-tiny-robot.surge.sh echo "Deploying to: https://$DEPLOY_DOMAIN" - npx surge --project ./docs/dist --domain $DEPLOY_DOMAIN --token $SURGE_TOKEN + npx surge --project ./artifacts/docs/dist --domain $DEPLOY_DOMAIN --token $SURGE_TOKEN echo "url=https://$DEPLOY_DOMAIN" >> $GITHUB_OUTPUT env: SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} - name: Comment build success - if: ${{ success() && github.event_name == 'pull_request' }} + if: success() uses: actions-cool/maintain-one-comment@v3.1.1 with: token: ${{ secrets.GITHUB_TOKEN }} body: | - [](https://preview-${{ inputs.pr-number }}-tiny-robot.surge.sh) + [](https://preview-${{ steps.pr.outputs.number }}-tiny-robot.surge.sh) ✅ Preview build completed successfully! @@ -144,17 +129,17 @@ jobs: > Preview will be automatically removed when this PR is closed. body-include: '' - number: ${{ inputs.pr-number }} + number: ${{ steps.pr.outputs.number }} - name: Comment build failed - if: ${{ failure() && github.event_name == 'pull_request' }} + if: failure() uses: actions-cool/maintain-one-comment@v3.1.1 with: token: ${{ secrets.GITHUB_TOKEN }} body: | [](#) - ❌ Build failed. Please check the logs for details. + ❌ Deploy failed. Please check the logs for details. body-include: '' - number: ${{ inputs.pr-number }} + number: ${{ steps.pr.outputs.number }} From 0547e79479c6c58ce4a1c75e56797feaad3b3637 Mon Sep 17 00:00:00 2001 From: SonyLeo <746591437@qq.com> Date: Fri, 26 Dec 2025 01:28:30 +0800 Subject: [PATCH 2/2] fix(ci): improve pr number handling for artifact upload --- .github/workflows/pr-ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-ci-build.yml b/.github/workflows/pr-ci-build.yml index 6387a4887..6e675b09a 100644 --- a/.github/workflows/pr-ci-build.yml +++ b/.github/workflows/pr-ci-build.yml @@ -47,7 +47,7 @@ jobs: - name: Save PR number if: github.event_name == 'pull_request' - run: echo "${{ github.event.number }}" > pr_number.txt + run: echo "${{ github.event.pull_request.number }}" > pr_number.txt - name: Upload build artifacts uses: actions/upload-artifact@v4