mirror of
https://github.com/unraid/webgui.git
synced 2026-05-03 16:29:45 -05:00
feat: add GitHub Actions workflow and script for generating PR plugins
- Introduced a new script `generate-pr-plugin.sh` to automate the creation of Unraid PR plugin files. - Added a GitHub Actions workflow `pr-plugin-build.yml` to build and package the plugin when changes are made to the `emhttp` directory. - The workflow includes steps for checking out code, generating versioning, creating a tarball, and uploading the plugin artifact for PR testing.
This commit is contained in:
Executable
+190
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generate PR plugin file for Unraid
|
||||
# Usage: ./generate-pr-plugin.sh <version> <pr_number> <commit_sha> <tarball_name>
|
||||
|
||||
VERSION=$1
|
||||
PR_NUMBER=$2
|
||||
COMMIT_SHA=$3
|
||||
TARBALL_NAME=$4
|
||||
|
||||
if [ -z "$VERSION" ] || [ -z "$PR_NUMBER" ] || [ -z "$COMMIT_SHA" ] || [ -z "$TARBALL_NAME" ]; then
|
||||
echo "Usage: $0 <version> <pr_number> <commit_sha> <tarball_name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PLUGIN_NAME="webgui-pr-${VERSION}.plg"
|
||||
TARBALL_SHA256=$(sha256sum "$TARBALL_NAME" | awk '{print $1}')
|
||||
|
||||
echo "Generating plugin: $PLUGIN_NAME"
|
||||
echo "Tarball SHA256: $TARBALL_SHA256"
|
||||
|
||||
cat > "$PLUGIN_NAME" << 'EOF'
|
||||
<?xml version='1.0' standalone='yes'?>
|
||||
<!DOCTYPE PLUGIN [
|
||||
<!ENTITY name "webgui-pr">
|
||||
<!ENTITY version "VERSION_PLACEHOLDER">
|
||||
<!ENTITY author "unraid">
|
||||
<!ENTITY pluginURL "https://github.com/unraid/webgui">
|
||||
<!ENTITY tarball "TARBALL_PLACEHOLDER">
|
||||
<!ENTITY sha256 "SHA256_PLACEHOLDER">
|
||||
<!ENTITY pr "PR_PLACEHOLDER">
|
||||
<!ENTITY commit "COMMIT_PLACEHOLDER">
|
||||
]>
|
||||
|
||||
<PLUGIN name="&name;-&version;"
|
||||
author="&author;"
|
||||
version="&version;"
|
||||
pluginURL="&pluginURL;"
|
||||
min="6.12.0"
|
||||
icon="wrench"
|
||||
support="&pluginURL;/pull/≺">
|
||||
|
||||
<CHANGES>
|
||||
##&version;
|
||||
- Test build for PR #≺ (commit &commit;)
|
||||
- This plugin installs modified files from the PR for testing
|
||||
- Original files are backed up and restored upon removal
|
||||
</CHANGES>
|
||||
|
||||
<!-- Create backup directory -->
|
||||
<FILE Run="/bin/bash" Method="install">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
echo "===================================="
|
||||
echo "WebGUI PR Test Plugin Installation"
|
||||
echo "===================================="
|
||||
echo "Version: &version;"
|
||||
echo "PR: #≺"
|
||||
echo "Commit: &commit;"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p /boot/config/plugins/&name;
|
||||
mkdir -p /boot/config/plugins/&name;/backups
|
||||
|
||||
echo "Created plugin directories"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
<!-- Download tarball -->
|
||||
<FILE Name="/boot/config/plugins/&name;/&tarball;">
|
||||
<LOCAL>/boot/config/plugins/&tarball;</LOCAL>
|
||||
<SHA256>&sha256;</SHA256>
|
||||
</FILE>
|
||||
|
||||
<!-- Backup and install files -->
|
||||
<FILE Run="/bin/bash" Method="install">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
BACKUP_DIR="/boot/config/plugins/&name;/backups"
|
||||
TARBALL="/boot/config/plugins/&name;/&tarball;"
|
||||
MANIFEST="/boot/config/plugins/&name;/installed_files.txt"
|
||||
|
||||
echo "Starting file deployment..."
|
||||
|
||||
# Clear manifest
|
||||
> "$MANIFEST"
|
||||
|
||||
# Extract and get file list
|
||||
cd /
|
||||
tar -tzf "$TARBALL" | while read -r file; do
|
||||
# Skip directories
|
||||
if [[ "$file" == */ ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Convert tar path to actual system path
|
||||
SYSTEM_FILE="/${file}"
|
||||
|
||||
# Check if file exists and backup
|
||||
if [ -f "$SYSTEM_FILE" ]; then
|
||||
BACKUP_FILE="$BACKUP_DIR/$(echo "$file" | tr '/' '_')"
|
||||
echo "Backing up: $SYSTEM_FILE"
|
||||
cp -p "$SYSTEM_FILE" "$BACKUP_FILE"
|
||||
echo "$SYSTEM_FILE|$BACKUP_FILE" >> "$MANIFEST"
|
||||
else
|
||||
echo "$SYSTEM_FILE|NEW" >> "$MANIFEST"
|
||||
fi
|
||||
done
|
||||
|
||||
# Extract the tarball
|
||||
echo ""
|
||||
echo "Installing modified files..."
|
||||
tar -xzf "$TARBALL" -C /
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation complete!"
|
||||
echo ""
|
||||
echo "The following files have been deployed:"
|
||||
cat "$MANIFEST" | cut -d'|' -f1 | while read -r file; do
|
||||
echo " - $file"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "⚠️ This is a TEST plugin for PR #≺"
|
||||
echo "⚠️ Remove this plugin before applying production updates"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
<!-- Removal script -->
|
||||
<FILE Run="/bin/bash" Method="remove">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
echo "===================================="
|
||||
echo "WebGUI PR Test Plugin Removal"
|
||||
echo "===================================="
|
||||
echo ""
|
||||
|
||||
BACKUP_DIR="/boot/config/plugins/&name;/backups"
|
||||
MANIFEST="/boot/config/plugins/&name;/installed_files.txt"
|
||||
|
||||
if [ -f "$MANIFEST" ]; then
|
||||
echo "Restoring original files..."
|
||||
|
||||
while IFS='|' read -r system_file backup_file; do
|
||||
if [ "$backup_file" == "NEW" ]; then
|
||||
# This was a new file, remove it
|
||||
if [ -f "$system_file" ]; then
|
||||
echo "Removing new file: $system_file"
|
||||
rm -f "$system_file"
|
||||
fi
|
||||
else
|
||||
# Restore from backup
|
||||
if [ -f "$backup_file" ]; then
|
||||
echo "Restoring: $system_file"
|
||||
mv -f "$backup_file" "$system_file"
|
||||
fi
|
||||
fi
|
||||
done < "$MANIFEST"
|
||||
|
||||
echo ""
|
||||
echo "✅ Original files restored"
|
||||
else
|
||||
echo "⚠️ No manifest found, cannot restore files"
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
echo "Cleaning up plugin files..."
|
||||
rm -rf "/boot/config/plugins/&name;"
|
||||
rm -f "/boot/config/plugins/&tarball;"
|
||||
|
||||
echo ""
|
||||
echo "✅ Plugin removed successfully"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
</PLUGIN>
|
||||
EOF
|
||||
|
||||
# Replace placeholders
|
||||
sed -i "s/VERSION_PLACEHOLDER/${VERSION}/g" "$PLUGIN_NAME"
|
||||
sed -i "s/TARBALL_PLACEHOLDER/${TARBALL_NAME}/g" "$PLUGIN_NAME"
|
||||
sed -i "s/SHA256_PLACEHOLDER/${TARBALL_SHA256}/g" "$PLUGIN_NAME"
|
||||
sed -i "s/PR_PLACEHOLDER/${PR_NUMBER}/g" "$PLUGIN_NAME"
|
||||
sed -i "s/COMMIT_PLACEHOLDER/${COMMIT_SHA}/g" "$PLUGIN_NAME"
|
||||
|
||||
echo "Plugin generated: $PLUGIN_NAME"
|
||||
@@ -0,0 +1,154 @@
|
||||
name: Build PR Plugin
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'emhttp/**'
|
||||
- '.github/workflows/pr-plugin-build.yml'
|
||||
- '.github/scripts/**'
|
||||
|
||||
jobs:
|
||||
build-plugin:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
run: |
|
||||
# Get list of changed files in emhttp directory
|
||||
git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^emhttp/' > changed_files.txt || true
|
||||
|
||||
# Output for debugging
|
||||
echo "Changed files:"
|
||||
cat changed_files.txt
|
||||
|
||||
# Check if we have any changes
|
||||
if [ ! -s changed_files.txt ]; then
|
||||
echo "No emhttp files changed"
|
||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Generate plugin version
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
id: version
|
||||
run: |
|
||||
# Generate version based on PR number and short SHA
|
||||
VERSION="pr.${{ github.event.pull_request.number }}.$(git rev-parse --short HEAD)"
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: $VERSION"
|
||||
|
||||
- name: Create plugin package
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
run: |
|
||||
# Create build directory
|
||||
mkdir -p build/usr/local
|
||||
|
||||
# Copy changed files preserving directory structure
|
||||
while IFS= read -r file; do
|
||||
if [ -f "$file" ]; then
|
||||
# Create directory structure in build
|
||||
dir=$(dirname "$file")
|
||||
mkdir -p "build/usr/local/$dir"
|
||||
cp "$file" "build/usr/local/$dir/"
|
||||
echo "Added: $file"
|
||||
fi
|
||||
done < changed_files.txt
|
||||
|
||||
# Create tarball
|
||||
cd build
|
||||
tar -czf ../webgui-pr-${{ steps.version.outputs.version }}.tar.gz usr/
|
||||
cd ..
|
||||
|
||||
# Generate file list for plugin
|
||||
find build/usr/local/emhttp -type f | sed 's|^build||' > file_list.txt
|
||||
|
||||
- name: Generate plugin file
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
run: |
|
||||
bash .github/scripts/generate-pr-plugin.sh \
|
||||
"${{ steps.version.outputs.version }}" \
|
||||
"${{ github.event.pull_request.number }}" \
|
||||
"$(git rev-parse --short HEAD)" \
|
||||
"webgui-pr-${{ steps.version.outputs.version }}.tar.gz"
|
||||
|
||||
- name: Upload plugin artifact
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webgui-pr-plugin-${{ github.event.pull_request.number }}
|
||||
path: |
|
||||
webgui-pr-*.plg
|
||||
webgui-pr-*.tar.gz
|
||||
retention-days: 30
|
||||
|
||||
- name: Format changed files list
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
id: format-files
|
||||
run: |
|
||||
# Format the file list for the comment
|
||||
echo "files<<EOF" >> $GITHUB_OUTPUT
|
||||
cat changed_files.txt
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Comment on PR
|
||||
if: steps.changed-files.outputs.has_changes == 'true'
|
||||
uses: peter-evans/create-or-update-comment@v4
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## 🔧 PR Test Plugin Available
|
||||
|
||||
A test plugin has been generated for this PR that includes the modified files.
|
||||
|
||||
**Version:** `${{ steps.version.outputs.version }}`
|
||||
**Build:** [View Workflow Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
### 📥 Installation Instructions:
|
||||
|
||||
1. **Download the plugin files** from the [workflow artifacts](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
- Click on the `webgui-pr-plugin-${{ github.event.pull_request.number }}` artifact
|
||||
- Extract the downloaded ZIP file
|
||||
|
||||
2. **Copy files to your Unraid server:**
|
||||
- `webgui-pr-${{ steps.version.outputs.version }}.plg` → `/boot/config/plugins/`
|
||||
- `webgui-pr-${{ steps.version.outputs.version }}.tar.gz` → `/boot/config/plugins/webgui-pr/`
|
||||
|
||||
3. **Install the plugin:**
|
||||
- Via Plugins tab: Navigate to Install Plugin, use the file browser to select the .plg file
|
||||
- Via command line: `installplg /boot/config/plugins/webgui-pr-${{ steps.version.outputs.version }}.plg`
|
||||
|
||||
### ⚠️ Important Notes:
|
||||
|
||||
- **Testing only:** This plugin is for testing PR changes
|
||||
- **Backup included:** Original files are automatically backed up
|
||||
- **Easy removal:** Files are restored when plugin is removed
|
||||
- **Conflicts:** Remove this plugin before installing production updates
|
||||
|
||||
### 📝 Modified Files:
|
||||
|
||||
<details>
|
||||
<summary>Click to expand file list</summary>
|
||||
|
||||
```
|
||||
${{ steps.format-files.outputs.files }}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### 🔄 To Remove:
|
||||
|
||||
Navigate to Plugins → Installed Plugins and remove `webgui-pr-${{ steps.version.outputs.version }}`, or run:
|
||||
```bash
|
||||
removepkg webgui-pr-${{ steps.version.outputs.version }}
|
||||
```
|
||||
|
||||
---
|
||||
<sub>🤖 This comment is automatically generated and will be updated with each new push to this PR.</sub>
|
||||
edit-mode: replace
|
||||
Reference in New Issue
Block a user