feat: Add WebUI auto-build workflow
This commit is contained in:
parent
8e878f0cb4
commit
2782953d79
|
|
@ -0,0 +1,231 @@
|
||||||
|
name: WebUI Auto-Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/webui-auto-build.yml"
|
||||||
|
- "tools/server/webui/**"
|
||||||
|
- "!tools/server/webui/README.md"
|
||||||
|
- "!tools/server/public/index.html.gz"
|
||||||
|
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/webui-auto-build.yml"
|
||||||
|
- "tools/server/webui/**"
|
||||||
|
- "!tools/server/webui/README.md"
|
||||||
|
- "!tools/server/public/index.html.gz"
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pr_number:
|
||||||
|
description: "PR number to rebuild (leave empty for all open PRs)"
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: webui-auto-build-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
identify-prs:
|
||||||
|
name: Identify PRs to Rebuild
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
pr_numbers: ${{ steps.get-prs.outputs.pr_numbers }}
|
||||||
|
steps:
|
||||||
|
- name: Get PR numbers
|
||||||
|
id: get-prs
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
let prNumbers = [];
|
||||||
|
|
||||||
|
// If triggered by a PR event, only rebuild that PR
|
||||||
|
if (context.eventName === 'pull_request') {
|
||||||
|
prNumbers = [context.payload.pull_request.number];
|
||||||
|
}
|
||||||
|
// If manually triggered with a specific PR number
|
||||||
|
else if (context.eventName === 'workflow_dispatch' && context.payload.inputs.pr_number) {
|
||||||
|
prNumbers = [parseInt(context.payload.inputs.pr_number)];
|
||||||
|
}
|
||||||
|
// If triggered by master push or manual without PR number, rebuild all open PRs
|
||||||
|
else {
|
||||||
|
const { data: pullRequests } = await github.rest.pulls.list({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
state: 'open',
|
||||||
|
per_page: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter PRs that have webui changes
|
||||||
|
for (const pr of pullRequests) {
|
||||||
|
const { data: files } = await github.rest.pulls.listFiles({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
pull_number: pr.number
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasWebuiChanges = files.some(file =>
|
||||||
|
file.filename.startsWith('tools/server/webui/') &&
|
||||||
|
!file.filename.endsWith('README.md') &&
|
||||||
|
file.filename !== 'tools/server/public/index.html.gz'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasWebuiChanges) {
|
||||||
|
prNumbers.push(pr.number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`PRs to rebuild: ${prNumbers.join(', ')}`);
|
||||||
|
core.setOutput('pr_numbers', JSON.stringify(prNumbers));
|
||||||
|
|
||||||
|
rebuild-webui:
|
||||||
|
name: Rebuild WebUI for PR #${{ matrix.pr_number }}
|
||||||
|
needs: identify-prs
|
||||||
|
if: needs.identify-prs.outputs.pr_numbers != '[]'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
pr_number: ${{ fromJson(needs.identify-prs.outputs.pr_numbers) }}
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 3
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Get PR details
|
||||||
|
id: pr-details
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { data: pr } = await github.rest.pulls.get({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
pull_number: ${{ matrix.pr_number }}
|
||||||
|
});
|
||||||
|
|
||||||
|
core.setOutput('head_ref', pr.head.ref);
|
||||||
|
core.setOutput('head_sha', pr.head.sha);
|
||||||
|
core.setOutput('head_repo', pr.head.repo.full_name);
|
||||||
|
core.setOutput('base_ref', pr.base.ref);
|
||||||
|
|
||||||
|
- name: Checkout PR branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: ${{ steps.pr-details.outputs.head_repo }}
|
||||||
|
ref: ${{ steps.pr-details.outputs.head_ref }}
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "22"
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: "tools/server/webui/package-lock.json"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
working-directory: tools/server/webui
|
||||||
|
|
||||||
|
- name: Build WebUI
|
||||||
|
run: npm run build
|
||||||
|
working-directory: tools/server/webui
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check-changes
|
||||||
|
run: |
|
||||||
|
# Decompress the newly built file and compute its hash
|
||||||
|
NEW_HASH=$(gunzip -c tools/server/public/index.html.gz | sha256sum | cut -d' ' -f1)
|
||||||
|
echo "New build hash: $NEW_HASH"
|
||||||
|
|
||||||
|
# Get the original file from git, decompress it, and compute its hash
|
||||||
|
if git show HEAD:tools/server/public/index.html.gz 2>/dev/null | gunzip -c | sha256sum > /tmp/old-hash.txt 2>&1; then
|
||||||
|
OLD_HASH=$(cut -d' ' -f1 /tmp/old-hash.txt)
|
||||||
|
echo "Original hash: $OLD_HASH"
|
||||||
|
|
||||||
|
# Compare hashes
|
||||||
|
if [ "$NEW_HASH" = "$OLD_HASH" ]; then
|
||||||
|
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "✓ No changes detected in static output (HTML content is identical)"
|
||||||
|
else
|
||||||
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✓ Changes detected in static output"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# File doesn't exist in repo yet (new file)
|
||||||
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✓ New static output file detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
rm -f /tmp/old-hash.txt
|
||||||
|
|
||||||
|
- name: Commit and push changes
|
||||||
|
if: steps.check-changes.outputs.has_changes == 'true'
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
git add tools/server/public/index.html.gz
|
||||||
|
git commit -m "chore(webui): auto-rebuild static output [skip ci]"
|
||||||
|
git push origin ${{ steps.pr-details.outputs.head_ref }}
|
||||||
|
|
||||||
|
- name: Add comment to PR
|
||||||
|
if: steps.check-changes.outputs.has_changes == 'true'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { data: comments } = await github.rest.issues.listComments({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: ${{ matrix.pr_number }}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if we already commented about auto-rebuild
|
||||||
|
const botComment = comments.find(comment =>
|
||||||
|
comment.user.type === 'Bot' &&
|
||||||
|
comment.body.includes('🤖 WebUI static output auto-rebuilt')
|
||||||
|
);
|
||||||
|
|
||||||
|
const message = `🤖 **WebUI static output auto-rebuilt**
|
||||||
|
|
||||||
|
The static build has been automatically updated to reflect the latest changes.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Build details</summary>
|
||||||
|
|
||||||
|
- **Workflow run**: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||||
|
- **Commit**: ${{ steps.pr-details.outputs.head_sha }}
|
||||||
|
- **Triggered by**: ${context.eventName === 'pull_request' ? 'PR update' : 'master branch update'}
|
||||||
|
|
||||||
|
</details>`;
|
||||||
|
|
||||||
|
if (botComment) {
|
||||||
|
// Update existing comment
|
||||||
|
await github.rest.issues.updateComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
comment_id: botComment.id,
|
||||||
|
body: message
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Create new comment
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: ${{ matrix.pr_number }},
|
||||||
|
body: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Report no changes
|
||||||
|
if: steps.check-changes.outputs.has_changes == 'false'
|
||||||
|
run: |
|
||||||
|
echo "✓ Static output is already up to date"
|
||||||
Loading…
Reference in New Issue