fix(actions): fix white background bleed in dark mode when viewport i… #82
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
| # Plugin Release Workflow | |
| # | |
| # This workflow automates the release process for OpenWebUI plugins. | |
| # | |
| # Triggers: | |
| # - Push to main branch when plugins are modified (auto-release) | |
| # - Manual trigger (workflow_dispatch) with custom release notes | |
| # - Push of version tags (v*) | |
| # | |
| # What it does: | |
| # 1. Detects plugin version changes compared to the last release | |
| # 2. Generates release notes with updated plugin information | |
| # 3. Creates a GitHub Release with plugin files as downloadable assets | |
| # 4. Supports multiple plugin updates in a single release | |
| name: Plugin Release | |
| on: | |
| # Auto-trigger on push to main when plugins are modified | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'plugins/**/*.py' | |
| tags: | |
| - 'v*' | |
| # Manual trigger with inputs | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Release version (e.g., v1.0.0). Leave empty for auto-generated version.' | |
| required: false | |
| type: string | |
| release_title: | |
| description: 'Release title (optional)' | |
| required: false | |
| type: string | |
| release_notes: | |
| description: 'Additional release notes (Markdown)' | |
| required: false | |
| type: string | |
| prerelease: | |
| description: 'Mark as pre-release' | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| jobs: | |
| check-changes: | |
| runs-on: ubuntu-latest | |
| env: | |
| LANG: en_US.UTF-8 | |
| LC_ALL: en_US.UTF-8 | |
| outputs: | |
| has_changes: ${{ steps.detect.outputs.has_changes }} | |
| changed_plugins: ${{ steps.detect.outputs.changed_plugins }} | |
| release_notes: ${{ steps.detect.outputs.release_notes }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Configure Git | |
| run: | | |
| git config --global core.quotepath false | |
| git config --global i18n.commitencoding utf-8 | |
| git config --global i18n.logoutputencoding utf-8 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Detect plugin changes | |
| id: detect | |
| run: | | |
| # Get the last release tag | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| echo "No previous release found, treating all plugins as new" | |
| COMPARE_REF="$(git rev-list --max-parents=0 HEAD)" | |
| else | |
| echo "Comparing with last release: $LAST_TAG" | |
| COMPARE_REF="$LAST_TAG" | |
| fi | |
| # Get current plugin versions | |
| python scripts/extract_plugin_versions.py --json --output current_versions.json | |
| # Get previous plugin versions by checking out old plugins | |
| if git worktree add /tmp/old_repo ${COMPARE_REF} 2>/dev/null; then | |
| if [ -d /tmp/old_repo/plugins ]; then | |
| python scripts/extract_plugin_versions.py --plugins-dir /tmp/old_repo/plugins --json --output old_versions.json | |
| else | |
| echo "[]" > old_versions.json | |
| fi | |
| git worktree remove /tmp/old_repo 2>/dev/null || true | |
| else | |
| echo "Failed to create worktree, using empty version list" | |
| echo "[]" > old_versions.json | |
| fi | |
| # Compare versions and generate release notes | |
| python scripts/extract_plugin_versions.py --compare old_versions.json --ignore-removed --output changes.md | |
| python scripts/extract_plugin_versions.py --compare old_versions.json --json --output changes.json | |
| echo "=== Version Changes ===" | |
| cat changes.md | |
| # Check if there are any changes | |
| if grep -q "No changes detected" changes.md; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "changed_plugins=" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| # Extract changed plugin file paths using Python | |
| python3 -c " | |
| import json | |
| with open('changes.json', 'r') as f: | |
| data = json.load(f) | |
| files = [] | |
| for plugin in data.get('added', []): | |
| if 'file_path' in plugin: | |
| files.append(plugin['file_path']) | |
| for update in data.get('updated', []): | |
| if 'current' in update and 'file_path' in update['current']: | |
| files.append(update['current']['file_path']) | |
| print('\n'.join(files)) | |
| " > changed_files.txt | |
| echo "changed_plugins<<EOF" >> $GITHUB_OUTPUT | |
| cat changed_files.txt >> $GITHUB_OUTPUT | |
| echo "" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| fi | |
| # Store release notes | |
| { | |
| echo 'release_notes<<EOF' | |
| cat changes.md | |
| echo "" | |
| echo 'EOF' | |
| } >> $GITHUB_OUTPUT | |
| release: | |
| needs: check-changes | |
| if: needs.check-changes.outputs.has_changes == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| env: | |
| LANG: en_US.UTF-8 | |
| LC_ALL: en_US.UTF-8 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Configure Git | |
| run: | | |
| git config --global core.quotepath false | |
| git config --global i18n.commitencoding utf-8 | |
| git config --global i18n.logoutputencoding utf-8 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Determine version | |
| id: version | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.version }}" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| else | |
| # Auto-generate version based on date and daily release count | |
| TODAY=$(date +'%Y.%m.%d') | |
| TODAY_PREFIX="v${TODAY}-" | |
| # Count existing releases with today's date prefix | |
| # grep -c returns 1 if count is 0, so we use || true to avoid script failure | |
| EXISTING_COUNT=$(gh release list --limit 100 2>/dev/null | grep -c "^${TODAY_PREFIX}" || true) | |
| # Clean up output (handle potential newlines or fallback issues) | |
| EXISTING_COUNT=$(echo "$EXISTING_COUNT" | tr -cd '0-9') | |
| if [ -z "$EXISTING_COUNT" ]; then EXISTING_COUNT=0; fi | |
| NEXT_NUM=$((EXISTING_COUNT + 1)) | |
| VERSION="${TODAY_PREFIX}${NEXT_NUM}" | |
| # Final fallback to ensure VERSION is never empty | |
| if [ -z "$VERSION" ]; then | |
| VERSION="v$(date +'%Y.%m.%d-%H%M%S')" | |
| fi | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Release version: $VERSION" | |
| - name: Extract plugin versions | |
| id: plugins | |
| run: | | |
| python scripts/extract_plugin_versions.py --json --output plugin_versions.json | |
| python scripts/extract_plugin_versions.py --json --output plugin_versions.json | |
| - name: Collect plugin files for release | |
| id: collect_files | |
| run: | | |
| mkdir -p release_plugins | |
| CHANGED_PLUGINS="${{ needs.check-changes.outputs.changed_plugins }}" | |
| if [ -n "$CHANGED_PLUGINS" ]; then | |
| echo "Collecting changed plugin files..." | |
| echo "$CHANGED_PLUGINS" | while read -r file; do | |
| if [ -n "$file" ] && [ -f "$file" ]; then | |
| dir=$(dirname "$file") | |
| mkdir -p "release_plugins/$dir" | |
| cp "$file" "release_plugins/$file" | |
| echo "Added: $file" | |
| fi | |
| done | |
| else | |
| echo "No changed plugins detected. Skipping file collection." | |
| fi | |
| # Create a zip file with error handling | |
| # cd release_plugins | |
| # Zip step removed as per user request | |
| echo "=== Collected Files ===" | |
| find release_plugins -name "*.py" -type f | head -20 | |
| - name: Update plugin icon URLs | |
| run: | | |
| echo "Updating icon_url in plugins to use absolute GitHub URLs..." | |
| # Base URL for raw content using the release tag | |
| REPO_URL="https://raw.githubusercontent.com/${{ github.repository }}/${{ steps.version.outputs.version }}" | |
| find release_plugins -name "*.py" | while read -r file; do | |
| # $file is like release_plugins/plugins/actions/infographic/infographic.py | |
| # Remove release_plugins/ prefix to get the path in the repo | |
| src_file="${file#release_plugins/}" | |
| src_dir=$(dirname "$src_file") | |
| base_name=$(basename "$src_file" .py) | |
| # Check if a corresponding png exists in the source repository | |
| png_file="${src_dir}/${base_name}.png" | |
| if [ -f "$png_file" ]; then | |
| echo "Found icon for $src_file: $png_file" | |
| TARGET_ICON_URL="${REPO_URL}/${png_file}" | |
| # Use python for safe replacement | |
| python3 -c " | |
| import sys | |
| import re | |
| file_path = '$file' | |
| icon_url = '$TARGET_ICON_URL' | |
| try: | |
| with open(file_path, 'r', encoding='utf-8') as f: | |
| content = f.read() | |
| # Replace icon_url: ... with new url | |
| # Matches 'icon_url: ...' and replaces it | |
| new_content = re.sub(r'^icon_url:.*$', f'icon_url: {icon_url}', content, flags=re.MULTILINE) | |
| with open(file_path, 'w', encoding='utf-8') as f: | |
| f.write(new_content) | |
| print(f'Successfully updated icon_url in {file_path}') | |
| except Exception as e: | |
| print(f'Error updating {file_path}: {e}', file=sys.stderr) | |
| sys.exit(1) | |
| " | |
| fi | |
| done | |
| - name: Debug Filenames | |
| run: | | |
| python3 -c "import sys; print(f'Filesystem encoding: {sys.getfilesystemencoding()}')" | |
| ls -R release_plugins | |
| - name: Upload Debug Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: debug-plugins | |
| path: release_plugins/ | |
| - name: Get commit messages | |
| id: commits | |
| if: github.event_name == 'push' | |
| run: | | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -n "$LAST_TAG" ]; then | |
| COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s" --no-merges -- plugins/ | head -20) | |
| else | |
| COMMITS=$(git log --pretty=format:"- %s" --no-merges -10 -- plugins/) | |
| fi | |
| { | |
| echo 'commits<<EOF' | |
| echo "$COMMITS" | |
| echo "" | |
| echo 'EOF' | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Generate release notes | |
| id: notes | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| TITLE: ${{ github.event.inputs.release_title }} | |
| NOTES: ${{ github.event.inputs.release_notes }} | |
| DETECTED_CHANGES: ${{ needs.check-changes.outputs.release_notes }} | |
| COMMITS: ${{ steps.commits.outputs.commits }} | |
| run: | | |
| > release_notes.md | |
| if [ -n "$TITLE" ]; then | |
| echo "## $TITLE" >> release_notes.md | |
| echo "" >> release_notes.md | |
| fi | |
| if [ -n "$DETECTED_CHANGES" ] && ! echo "$DETECTED_CHANGES" | grep -q "No changes detected"; then | |
| echo "## What's Changed" >> release_notes.md | |
| echo "" >> release_notes.md | |
| echo "$DETECTED_CHANGES" >> release_notes.md | |
| echo "" >> release_notes.md | |
| fi | |
| if [ -n "$COMMITS" ]; then | |
| echo "## Commits" >> release_notes.md | |
| echo "" >> release_notes.md | |
| echo "$COMMITS" >> release_notes.md | |
| echo "" >> release_notes.md | |
| fi | |
| if [ -n "$NOTES" ]; then | |
| echo "## Additional Notes" >> release_notes.md | |
| echo "" >> release_notes.md | |
| echo "$NOTES" >> release_notes.md | |
| echo "" >> release_notes.md | |
| fi | |
| cat >> release_notes.md << 'EOF' | |
| ## Download | |
| 📦 **Download the updated plugin files below** | |
| ### Installation | |
| #### From OpenWebUI Community | |
| 1. Open OpenWebUI Admin Panel | |
| 2. Navigate to Functions/Tools | |
| 3. Search for the plugin name | |
| 4. Click Install | |
| #### Manual Installation | |
| 1. Download the plugin file (`.py`) from the assets below | |
| 2. Open OpenWebUI Admin Panel → Functions | |
| 3. Click "Create Function" → Import | |
| 4. Paste the plugin code | |
| --- | |
| 📚 [Documentation](https://fu-jie.github.io/openwebui-extensions/) | |
| 🐛 [Report Issues](https://github.com/Fu-Jie/openwebui-extensions/issues) | |
| EOF | |
| echo "=== Release Notes ===" | |
| cat release_notes.md | |
| - name: Create Git Tag | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| if [ -z "$VERSION" ]; then | |
| echo "Error: Version is empty!" | |
| exit 1 | |
| fi | |
| if ! git rev-parse "$VERSION" >/dev/null 2>&1; then | |
| echo "Creating tag $VERSION" | |
| git tag "$VERSION" | |
| git push origin "$VERSION" | |
| else | |
| echo "Tag $VERSION already exists" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| target_commitish: ${{ github.sha }} | |
| name: ${{ github.event.inputs.release_title || steps.version.outputs.version }} | |
| body_path: release_notes.md | |
| prerelease: ${{ github.event.inputs.prerelease || false }} | |
| make_latest: true | |
| files: | | |
| plugin_versions.json | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload Release Assets | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Check if there are any .py files to upload | |
| if [ -d release_plugins ] && [ -n "$(find release_plugins -type f -name '*.py' 2>/dev/null)" ]; then | |
| echo "Uploading plugin files..." | |
| find release_plugins -type f -name "*.py" -print0 | xargs -0 gh release upload ${{ steps.version.outputs.version }} --clobber | |
| else | |
| echo "No plugin files to upload. Skipping asset upload." | |
| fi | |
| - name: Summary | |
| run: | | |
| echo "## 🚀 Release Created Successfully!" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Updated Plugins" >> $GITHUB_STEP_SUMMARY | |
| echo "${{ needs.check-changes.outputs.release_notes }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |