From c932b91800bd67fffa3d25e971643df25e62a2e1 Mon Sep 17 00:00:00 2001 From: Eli Bosley Date: Wed, 10 Sep 2025 11:29:36 -0400 Subject: [PATCH] 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. --- .github/scripts/generate-pr-plugin.sh | 190 ++++++++++++++++++++++++++ .github/workflows/pr-plugin-build.yml | 154 +++++++++++++++++++++ 2 files changed, 344 insertions(+) create mode 100755 .github/scripts/generate-pr-plugin.sh create mode 100644 .github/workflows/pr-plugin-build.yml diff --git a/.github/scripts/generate-pr-plugin.sh b/.github/scripts/generate-pr-plugin.sh new file mode 100755 index 000000000..e1040f4b8 --- /dev/null +++ b/.github/scripts/generate-pr-plugin.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +# Generate PR plugin file for Unraid +# Usage: ./generate-pr-plugin.sh + +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 " + 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' + + + + + + + + + +]> + + + + +##&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 + + + + + + + + + + + +/boot/config/plugins/&tarball; +&sha256; + + + + + + "$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" +]]> + + + + + + + + + + + +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" \ No newline at end of file diff --git a/.github/workflows/pr-plugin-build.yml b/.github/workflows/pr-plugin-build.yml new file mode 100644 index 000000000..5e6bf6ecf --- /dev/null +++ b/.github/workflows/pr-plugin-build.yml @@ -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<> $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: + +
+ Click to expand file list + + ``` + ${{ steps.format-files.outputs.files }} + ``` + +
+ + ### 🔄 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 }} + ``` + + --- + 🤖 This comment is automatically generated and will be updated with each new push to this PR. + edit-mode: replace \ No newline at end of file