HMCL-docs/.github/workflows/pr-preview.yml
neveler 70ba60e045
为预览站点添加提示信息 (#319)
Co-authored-by: Burning_TNT <pangyl08@163.com>
2025-11-02 22:32:42 +08:00

387 lines
16 KiB
YAML

name: PR Preview
on:
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 }}
JEKYLL_ENV: production
jobs:
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' || 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
outputs:
artifact-id: ${{ steps.upload-site.outputs.artifact-id }}
steps:
- name: Checkout PR
uses: actions/checkout@v5
with:
ref: ${{ needs.preview-create-init.outputs.sha }}
repository: ${{ needs.preview-create-init.outputs.repository }}
fetch-depth: 1
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
bundler-cache: true
cache-version: pr${{ env.GITHUB_PR_NUMBER }}
- name: Jekyll Build
run: |
echo "url: https://${{ needs.preview-create-init.outputs.domain }}" > _action.yml
echo "baseurl: ${{ needs.preview-create-init.outputs.pathname }}/PR${{ env.GITHUB_PR_NUMBER }}" >> _action.yml
echo "source: ${{ github.workspace }}" >> _action.yml
echo "destination: /home/runner/site" >> _action.yml
echo "preview:" >> _action.yml
echo " pr-number: ${{ env.GITHUB_PR_NUMBER }}" >> _action.yml
bundle exec jekyll build --config _config.yml,_action.yml
- 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.' }}"
}
});