Skip to content

Bump version to 1.8.1 #63

Bump version to 1.8.1

Bump version to 1.8.1 #63

Workflow file for this run

# ─────────────────────────────────────────────────────────────
# 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