Bump version to 1.8.1 #63
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
| # ───────────────────────────────────────────────────────────── | |
| # Moonfin Plugin — CI Build Workflow | |
| # ───────────────────────────────────────────────────────────── | |
| # | |
| # Triggers: | |
| # • Push to master → build + package ZIP artifact | |
| # • PR to master → build + upload result artifact | |
| # | |
| # Security: | |
| # Uses pull_request (not pull_request_target) so untrusted fork | |
| # code never runs with write access. PR comments are posted by | |
| # a separate workflow (comment.yml) triggered via workflow_run. | |
| # | |
| # Build flow: | |
| # 1. Frontend install (npm ci) | |
| # 2. Frontend build (node build.js) — skipped if (1) fails | |
| # 3. Sync web files (cp to backend/Web/) — skipped if (2) fails | |
| # 4. Backend build (dotnet build) — skipped if (2) fails | |
| # 5. Gate step — fails the job if any of (1)-(4) didn't succeed | |
| # | |
| # Error handling: | |
| # Build steps (1), (2), (4) use continue-on-error so the job keeps | |
| # running even on failure. Their output is captured to log files via | |
| # tee. The gate step (5) re-fails the job so the overall status is | |
| # correct. On PRs, build results (outcomes + logs) are uploaded as | |
| # an artifact for the comment.yml workflow to pick up. | |
| # | |
| # Packaging (master only, after successful build): | |
| # Reads version + ABI from the .csproj, creates a release ZIP with | |
| # the DLL + meta.json, and uploads it as a workflow artifact. | |
| # ───────────────────────────────────────────────────────────── | |
| name: Build | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| branches: [master] | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| name: Build Plugin | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: 8.0.x | |
| # ── Frontend ────────────────────────────────────────────── | |
| # continue-on-error: lets the job continue so we can upload | |
| # build results even when a step fails. | |
| # set -o pipefail: ensures the pipe returns the command's exit | |
| # code, not tee's (which always succeeds). | |
| # 2>&1 | tee: captures stdout+stderr to a log file for the | |
| # PR comment, while still printing to the Actions console. | |
| - name: Install frontend dependencies | |
| id: frontend_install | |
| continue-on-error: true | |
| working-directory: frontend | |
| run: | | |
| set -o pipefail | |
| npm ci 2>&1 | tee "${{ runner.temp }}/frontend-install.log" | |
| - name: Build frontend | |
| if: steps.frontend_install.outcome == 'success' | |
| id: frontend_build | |
| continue-on-error: true | |
| working-directory: frontend | |
| run: | | |
| set -o pipefail | |
| node build.js 2>&1 | tee "${{ runner.temp }}/frontend-build.log" | |
| # ── Sync web files into backend ─────────────────────────── | |
| - name: Sync web files | |
| if: steps.frontend_build.outcome == 'success' | |
| run: | | |
| mkdir -p backend/Web | |
| cp frontend/dist/plugin.js backend/Web/plugin.js | |
| cp frontend/dist/plugin.css backend/Web/plugin.css | |
| # ── Backend ─────────────────────────────────────────────── | |
| - name: Build backend | |
| if: steps.frontend_build.outcome == 'success' | |
| id: backend_build | |
| continue-on-error: true | |
| run: | | |
| set -o pipefail | |
| dotnet build backend/Moonfin.Server.csproj -c Release 2>&1 | tee "${{ runner.temp }}/backend-build.log" | |
| # ── Gate ─────────────────────────────────────────────────── | |
| # continue-on-error masks failures from the job status. This | |
| # gate step re-fails the job when any build step didn't | |
| # succeed (covers both 'failure' and 'skipped' outcomes). | |
| - name: Fail if build failed | |
| id: build_gate | |
| if: | | |
| steps.frontend_install.outcome != 'success' || | |
| steps.frontend_build.outcome != 'success' || | |
| steps.backend_build.outcome != 'success' | |
| run: exit 1 | |
| # ── Upload build results for PR comment workflow ────────── | |
| # Always runs on PRs so the comment.yml workflow can post | |
| # results even on failure. Writes step outcomes + PR number | |
| # to a metadata file alongside the log files. | |
| - name: Save build results | |
| if: always() && github.event_name == 'pull_request' | |
| run: | | |
| mkdir -p "${{ runner.temp }}/build-results" | |
| cat > "${{ runner.temp }}/build-results/outcomes.json" <<EOF | |
| { | |
| "pr_number": ${{ github.event.pull_request.number }}, | |
| "sha": "${{ github.event.pull_request.head.sha }}", | |
| "frontend_install": "${{ steps.frontend_install.outcome }}", | |
| "frontend_build": "${{ steps.frontend_build.outcome }}", | |
| "backend_build": "${{ steps.backend_build.outcome }}" | |
| } | |
| EOF | |
| # Copy any log files that exist | |
| for f in frontend-install.log frontend-build.log backend-build.log; do | |
| [ -f "${{ runner.temp }}/$f" ] && cp "${{ runner.temp }}/$f" "${{ runner.temp }}/build-results/" | |
| done | |
| - name: Upload build results | |
| if: always() && github.event_name == 'pull_request' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-results | |
| path: ${{ runner.temp }}/build-results/ | |
| # ── Package (master only) ───────────────────────────────── | |
| - name: Read version from csproj | |
| if: github.event_name == 'push' && steps.backend_build.outcome == 'success' | |
| id: version | |
| run: | | |
| VERSION=$(grep -oPm1 '(?<=<AssemblyVersion>)[^<]+' backend/Moonfin.Server.csproj) | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Read target ABI from csproj | |
| if: github.event_name == 'push' && steps.backend_build.outcome == 'success' | |
| id: abi | |
| run: | | |
| ABI=$(grep 'Jellyfin.Controller' backend/Moonfin.Server.csproj | grep -oP 'Version="\K[^"]+') | |
| echo "abi=${ABI}.0" >> "$GITHUB_OUTPUT" | |
| - name: Package release ZIP | |
| if: github.event_name == 'push' && steps.backend_build.outcome == 'success' | |
| id: package | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| TARGET_ABI="${{ steps.abi.outputs.abi }}" | |
| PLUGIN_GUID="8c5d0e91-4f2a-4b6d-9e3f-1a7c8d9e0f2b" | |
| TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| mkdir -p release | |
| cp backend/bin/Release/net8.0/Moonfin.Server.dll release/ | |
| cat > release/meta.json <<EOF | |
| { | |
| "category": "General", | |
| "changelog": "", | |
| "description": "Moonfin brings a modern TV-style UI to Jellyfin web. Features include: custom navbar, media bar with featured content, Jellyseerr integration, and cross-device settings synchronization.", | |
| "guid": "${PLUGIN_GUID}", | |
| "name": "Moonfin", | |
| "overview": "Custom UI and settings sync for Jellyfin", | |
| "owner": "RadicalMuffinMan", | |
| "targetAbi": "${TARGET_ABI}", | |
| "timestamp": "${TIMESTAMP}", | |
| "version": "${VERSION}", | |
| "status": "Active", | |
| "autoUpdate": true, | |
| "assemblies": ["Moonfin.Server.dll"] | |
| } | |
| EOF | |
| ZIP_NAME="Moonfin.Server-${VERSION}.zip" | |
| cd release && zip -r "../${ZIP_NAME}" . && cd .. | |
| CHECKSUM=$(md5sum "$ZIP_NAME" | awk '{print toupper($1)}') | |
| echo "zip_name=$ZIP_NAME" >> "$GITHUB_OUTPUT" | |
| echo "checksum=$CHECKSUM" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Upload build artifact | |
| if: github.event_name == 'push' && steps.backend_build.outcome == 'success' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.package.outputs.zip_name }} | |
| path: ${{ steps.package.outputs.zip_name }} | |
| - name: Build summary (master) | |
| if: github.event_name == 'push' && steps.backend_build.outcome == 'success' | |
| run: | | |
| echo "## ✅ Build Successful" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|---|---|" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Version** | \`${{ steps.version.outputs.version }}\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Checksum (MD5)** | \`${{ steps.package.outputs.checksum }}\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Artifact** | \`${{ steps.package.outputs.zip_name }}\` |" >> $GITHUB_STEP_SUMMARY |