将文档构建工具迁移至 Starlight #457
Workflow file for this run
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: PR Preview | ||
| on: | ||
| schedule: | ||
| - cron: 0 0 */6 * * | ||
| issue_comment: | ||
| types: [created] | ||
| pull_request_target: | ||
| types: [labeled, synchronize, closed] | ||
| concurrency: | ||
| group: pr-preview | ||
| cancel-in-progress: false | ||
| env: | ||
| GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }} | ||
| jobs: | ||
| cache-refresh: | ||
| if: ${{ !github.event.repository.fork && github.event_name == 'schedule' && github.event.schedule == '0 0 */6 * *' }} | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Cache Refresh | ||
| uses: actions/cache/restore@v4 | ||
| with: | ||
| key: pages-${{ github.run_id }} | ||
| path: /home/runner/gh-pages | ||
| restore-keys: pages- | ||
| preview-remove: | ||
| if: | ||
| ${{ | ||
| !github.event.repository.fork && ( | ||
| ( github.event_name == 'pull_request_target' && ( | ||
| github.event.action == 'closed' || ( | ||
| github.event.action == 'labeled' && | ||
| github.event.label.name == 'preview/remove' | ||
| ) | ||
| ) | ||
| ) || ( | ||
| github.event_name == 'issue_comment' && | ||
| github.event.issue.pull_request && | ||
| github.event.comment.body == '/preview remove' && | ||
| contains('OWNER,MEMBER', github.event.comment.author_association) | ||
| ) | ||
| ) | ||
| }} | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| actions: write | ||
| contents: write | ||
| pull-requests: write | ||
| steps: | ||
| - id: restore-pages | ||
| name: Restore Pages | ||
| uses: actions/cache/restore@v4 | ||
| with: | ||
| key: pages-${{ github.run_id }} | ||
| path: /home/runner/gh-pages | ||
| restore-keys: pages- | ||
| - name: Prepare Pages | ||
| run: | | ||
| mkdir -p /home/runner/gh-pages/data/{files,refs} | ||
| rm -rf /home/runner/gh-pages/PR${{ env.GITHUB_PR_NUMBER }} | ||
| grep -rlw 'PR${{ env.GITHUB_PR_NUMBER }}' /home/runner/gh-pages/data/refs | xargs -r sed -i '/\<PR${{ env.GITHUB_PR_NUMBER }}\>/d' | ||
| for ref in /home/runner/gh-pages/data/refs/*; do | ||
| if [ ! -s "$ref" ]; then | ||
| base=$(basename "$ref") | ||
| rm -f "/home/runner/gh-pages/data/files/$base" | ||
| rm -f "$ref" | ||
| fi | ||
| done | ||
| echo "[$(date)] Remove Preview PR${{ env.GITHUB_PR_NUMBER }}" > /home/runner/gh-pages/index.html | ||
| - name: Save Pages | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| key: pages-${{ github.run_id }} | ||
| path: /home/runner/gh-pages | ||
| - if: ${{ github.event_name == 'issue_comment' }} | ||
| id: comment-message | ||
| name: Comment Message (issue_comment) | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.updateComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| comment_id: context.payload.comment.id, | ||
| issue_number: context.issue.number, | ||
| body: "[Preview] Preview has been removed." | ||
| }); | ||
| - if: ${{ (github.event_name == 'pull_request_target' && github.event.action != 'closed') || steps.comment-message.outcome == 'failure' }} | ||
| name: Comment Message | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: "[Preview] Preview has been removed." | ||
| }); | ||
| - if: ${{ steps.restore-pages.outputs.cache-matched-key }} | ||
| name: Remove History Cache | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.actions.deleteActionsCacheByKey({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| key: "${{ steps.restore-pages.outputs.cache-matched-key }}" | ||
| }); | ||
| - if: ${{ contains(github.event.pull_request.labels.*.name, 'preview/remove') || contains(github.event.issue.labels.*.name, 'preview/remove') }} | ||
| name: Remove Label (preview/remove) | ||
| continue-on-error: true | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.removeLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| name: "preview/remove" | ||
| }); | ||
| - if: ${{ contains(github.event.pull_request.labels.*.name, 'preview/watch') || contains(github.event.issue.labels.*.name, 'preview/watch') }} | ||
| name: Remove Label (preview/watch) | ||
| continue-on-error: true | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.removeLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| name: "preview/watch" | ||
| }); | ||
| preview-create-init: | ||
| if: | ||
| ${{ | ||
| !github.event.repository.fork && ( | ||
| ( github.event_name == 'pull_request_target' && ( | ||
| ( github.event.action == 'labeled' && contains(fromJSON('["preview/create", "preview/watch"]'), github.event.label.name) ) || | ||
| ( github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'preview/watch') ) | ||
| ) | ||
| ) || ( | ||
| github.event_name == 'issue_comment' && | ||
| github.event.issue.pull_request && | ||
| contains(fromJSON('["/preview create", "/preview watch"]'), github.event.comment.body) && | ||
| contains('OWNER,MEMBER', github.event.comment.author_association) | ||
| ) | ||
| ) | ||
| }} | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| checks: write | ||
| pull-requests: write | ||
| outputs: | ||
| sha: ${{ steps.init.outputs.sha }} | ||
| domain: ${{ steps.init.outputs.domain }} | ||
| pathname: ${{ steps.init.outputs.pathname }} | ||
| repository: ${{ steps.init.outputs.repository }} | ||
| check-id: ${{ steps.init.outputs.check-id }} | ||
| steps: | ||
| - id: init | ||
| name: Init | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| const { owner, repo } = context.repo; | ||
| const pages = (await octokit.rest.repos.getPages({ owner, repo })).data; | ||
| const domain = pages.cname || `${owner.toLowerCase()}.github.io`; | ||
| core.setOutput('domain', domain); | ||
| core.setOutput('pathname', (pages.cname || repo.toLowerCase() === domain) ? '' : `/${repo}`); | ||
| const pr = context.payload.pull_request || (await github.rest.pulls.get({ | ||
| owner, repo, | ||
| pull_number: context.issue.number | ||
| })).data; | ||
| core.setOutput('sha', pr.head.sha); | ||
| core.setOutput('repository', pr.head.repo.full_name); | ||
| const { data: check } = await github.rest.checks.create({ | ||
| owner, repo, | ||
| name: "Create preview", | ||
| head_sha: pr.head.sha, | ||
| status: "in_progress", | ||
| started_at: new Date().toISOString(), | ||
| details_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{ github.run_id }}`, | ||
| output: { | ||
| title: "Create preview by command", | ||
| summary: "Preview is being created..." | ||
| } | ||
| }); | ||
| core.setOutput('check-id', check.id); | ||
| - if: ${{ github.event_name == 'issue_comment' && github.event.comment.body == '/preview watch' }} | ||
| name: Add Label (preview/watch) | ||
| continue-on-error: true | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| labels: ["preview/watch"] | ||
| }); | ||
| preview-create-build: | ||
| needs: preview-create-init | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| PUBLIC_SITE_URL: https://${{ needs.preview-create-init.outputs.domain }}${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }} | ||
| outputs: | ||
| artifact-id: ${{ steps.upload-site.outputs.artifact-id }} | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Merge PR | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git fetch https://github.com/${{ needs.preview-create-init.outputs.repository }} ${{ needs.preview-create-init.outputs.sha }} | ||
| git merge --squash ${{ needs.preview-create-init.outputs.sha }} --no-edit | ||
| git commit -m "Merge #${{ env.GITHUB_PR_NUMBER }} for preview build" | ||
| - name: Setup Node | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: 24 | ||
| - name: Build | ||
| run: | | ||
| npm install | ||
| npm run build -- --outDir /home/runner/site | ||
| - id: upload-site | ||
| name: Upload Site | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: site | ||
| path: /home/runner/site | ||
| preview-create-deploy: | ||
| needs: [preview-create-init, preview-create-build] | ||
| runs-on: ubuntu-latest | ||
| environment: | ||
| name: github-pages | ||
| url: https://${{ needs.preview-create-init.outputs.domain }}${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }} | ||
| permissions: | ||
| actions: write | ||
| pages: write | ||
| id-token: write | ||
| contents: write | ||
| steps: | ||
| - id: restore-pages | ||
| name: Restore Pages | ||
| uses: actions/cache/restore@v4 | ||
| with: | ||
| key: pages-${{ github.run_id }} | ||
| path: /home/runner/gh-pages | ||
| restore-keys: pages- | ||
| - name: Merge Site Before | ||
| run: | | ||
| mkdir -p /home/runner/gh-pages/data/{files,refs} | ||
| rm -rf /home/runner/gh-pages/PR${{ env.GITHUB_PR_NUMBER }} | ||
| grep -rlw 'PR${{ env.GITHUB_PR_NUMBER }}' /home/runner/gh-pages/data/refs | xargs -r sed -i '/\<PR${{ env.GITHUB_PR_NUMBER }}\>/d' | ||
| - name: Merge Site | ||
| uses: actions/download-artifact@v5 | ||
| with: | ||
| name: site | ||
| path: /home/runner/gh-pages/PR${{ env.GITHUB_PR_NUMBER }} | ||
| - name: Merge Site After | ||
| run: | | ||
| find /home/runner/gh-pages/PR${{ env.GITHUB_PR_NUMBER }} -type f | while read file; do | ||
| hash=$(sha256sum "$file" | cut -d' ' -f1) | ||
| size=$(stat -c%s "$file") | ||
| key="${hash}-${size}" | ||
| target="/home/runner/gh-pages/data/files/$key" | ||
| if [ ! -f "$target" ]; then | ||
| mv "$file" "$target" | ||
| else | ||
| rm -f "$file" | ||
| fi | ||
| ln -s "$(realpath --relative-to="$(dirname "$file")" "$target")" "$file" | ||
| echo "PR${{ env.GITHUB_PR_NUMBER }}" >> "/home/runner/gh-pages/data/refs/$key" | ||
| done | ||
| for ref in /home/runner/gh-pages/data/refs/*; do | ||
| if [ ! -s "$ref" ]; then | ||
| base=$(basename "$ref") | ||
| rm -f "/home/runner/gh-pages/data/files/$base" | ||
| rm -f "$ref" | ||
| fi | ||
| done | ||
| echo "[$(date)] Preview PR${{ env.GITHUB_PR_NUMBER }}" > /home/runner/gh-pages/index.html | ||
| - id: upload-pages | ||
| name: Upload Pages | ||
| uses: actions/upload-pages-artifact@v4 | ||
| with: | ||
| name: github-pages | ||
| path: /home/runner/gh-pages | ||
| - name: Deploy Pages | ||
| uses: actions/deploy-pages@v4 | ||
| with: | ||
| artifact_name: github-pages | ||
| - name: Save Pages | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| key: pages-${{ github.run_id }} | ||
| path: /home/runner/gh-pages | ||
| - if: ${{ steps.restore-pages.outputs.cache-matched-key }} | ||
| name: Remove History Cache | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.actions.deleteActionsCacheByKey({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| key: "${{ steps.restore-pages.outputs.cache-matched-key }}" | ||
| }); | ||
| - if: ${{ steps.upload-pages.outputs.artifact_id }} | ||
| name: Remove Pages Artifact | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.actions.deleteArtifact({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| artifact_id: "${{ steps.upload-pages.outputs.artifact_id }}", | ||
| }); | ||
| - if: ${{ needs.preview-create-build.outputs.artifact-id }} | ||
| name: Remove Temp Artifact | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.actions.deleteArtifact({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| artifact_id: "${{ needs.preview-create-build.outputs.artifact-id }}" | ||
| }); | ||
| preview-create-finally: | ||
| if: ${{ always() && needs.preview-create-init.result == 'success' }} | ||
| needs: [preview-create-init, preview-create-deploy] | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| checks: write | ||
| pull-requests: write | ||
| steps: | ||
| - if: ${{ github.event_name == 'issue_comment' }} | ||
| id: comment-message | ||
| name: Comment Message (issue_comment) | ||
| env: | ||
| PREVIEW_URL: https://${{ needs.preview-create-init.outputs.domain }}${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }} | ||
| continue-on-error: true | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.updateComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| comment_id: context.payload.comment.id, | ||
| issue_number: context.issue.number, | ||
| body: "${{ needs.preview-create-deploy.result == 'success' && format('[Preview] {0}', env.PREVIEW_URL) || '[Preview] Failed, see logs for more information.' }}" | ||
| }); | ||
| - if: ${{ steps.comment-message.outcome == 'failure' }} | ||
| name: Comment Message | ||
| env: | ||
| PREVIEW_URL: https://${{ needs.preview-create-init.outputs.domain }}${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }} | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: "${{ needs.preview-create-deploy.result == 'success' && format('[Preview] {0}', env.PREVIEW_URL) || '[Preview] Failed, see logs for more information.' }}" | ||
| }); | ||
| - if: ${{ contains(github.event.pull_request.labels.*.name, 'preview/create') || contains(github.event.issue.labels.*.name, 'preview/create') }} | ||
| name: Remove Label (preview/create) | ||
| continue-on-error: true | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.issues.removeLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| name: "preview/create" | ||
| }); | ||
| - name: Check Over | ||
| env: | ||
| PREVIEW_URL: https://${{ needs.preview-create-init.outputs.domain }}${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }} | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| github.rest.checks.update({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| check_run_id: ${{ needs.preview-create-init.outputs.check-id }}, | ||
| status: "completed", | ||
| conclusion: "${{ needs.preview-create-deploy.result == 'success' && 'success' || 'failure' }}", | ||
| completed_at: new Date().toISOString(), | ||
| details_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/runs/${{ github.run_id }}`, | ||
| output: { | ||
| title: "Create preview ${{ needs.preview-create-deploy.result == 'success' && 'success' || 'failure' }}", | ||
| summary: "${{ needs.preview-create-deploy.result == 'success' && format('[Preview] {0}', env.PREVIEW_URL) || '[Preview] Failed, see logs for more information.' }}" | ||
| } | ||
| }); | ||