251 lines
11 KiB
YAML
251 lines
11 KiB
YAML
name: Build and Release Plugin
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
jobs:
|
|
release:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v3
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup .NET
|
|
uses: actions/setup-dotnet@v3
|
|
with:
|
|
dotnet-version: |
|
|
9.0.x
|
|
10.0.x
|
|
|
|
- name: Build Plugin
|
|
run: dotnet build JellyfinPlugin/JellyfinPlugin.csproj -c Release
|
|
|
|
- name: Create ZIP Archives
|
|
run: |
|
|
cd JellyfinPlugin/bin/Release/
|
|
|
|
# Zip net9.0 (Jellyfin 10.11)
|
|
cd net9.0
|
|
zip -j ../../../../BlackBarRemover_${{ github.ref_name }}_jf10.11.zip *
|
|
cd ..
|
|
|
|
# Zip net10.0 (Jellyfin 12.0)
|
|
cd net10.0
|
|
zip -j ../../../../BlackBarRemover_${{ github.ref_name }}_jf12.0.zip *
|
|
cd ..
|
|
|
|
- name: Generate Checksums
|
|
id: checksum
|
|
run: |
|
|
MD5_SUM_9=$(md5sum BlackBarRemover_${{ github.ref_name }}_jf10.11.zip | awk '{print $1}')
|
|
MD5_SUM_10=$(md5sum BlackBarRemover_${{ github.ref_name }}_jf12.0.zip | awk '{print $1}')
|
|
echo "md5_9=$MD5_SUM_9" >> $GITHUB_OUTPUT
|
|
echo "md5_10=$MD5_SUM_10" >> $GITHUB_OUTPUT
|
|
|
|
- name: Publish Release and Update Manifest
|
|
env:
|
|
API_URL: ${{ github.api_url }}
|
|
REPO: ${{ github.repository }}
|
|
TOKEN: ${{ github.token }}
|
|
TAG: ${{ github.ref_name }}
|
|
MD5_9: ${{ steps.checksum.outputs.md5_9 }}
|
|
MD5_10: ${{ steps.checksum.outputs.md5_10 }}
|
|
run: |
|
|
python3 -c '
|
|
import os, json, urllib.request, base64, datetime
|
|
|
|
api_url = os.environ["API_URL"]
|
|
repo = os.environ["REPO"]
|
|
token = os.environ["TOKEN"]
|
|
tag = os.environ["TAG"]
|
|
md5_9 = os.environ["MD5_9"]
|
|
md5_10 = os.environ["MD5_10"]
|
|
|
|
headers = {
|
|
"Authorization": f"token {token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
# 1. Get or Create Release
|
|
rel_url = f"{api_url}/repos/{repo}/releases/tags/{tag}"
|
|
req = urllib.request.Request(rel_url, headers=headers)
|
|
rel_data = None
|
|
try:
|
|
res = urllib.request.urlopen(req)
|
|
rel_data = json.loads(res.read().decode("utf-8"))
|
|
except Exception:
|
|
pass
|
|
|
|
if not rel_data or "id" not in rel_data:
|
|
is_pre = "beta" in tag or "alpha" in tag or tag.startswith("v0.")
|
|
create_url = f"{api_url}/repos/{repo}/releases"
|
|
body = json.dumps({
|
|
"tag_name": tag,
|
|
"name": f"Release {tag}",
|
|
"body": "Automated release",
|
|
"draft": False,
|
|
"prerelease": is_pre
|
|
}).encode("utf-8")
|
|
create_req = urllib.request.Request(create_url, data=body, headers=headers)
|
|
res = urllib.request.urlopen(create_req)
|
|
rel_data = json.loads(res.read().decode("utf-8"))
|
|
|
|
rel_id = rel_data["id"]
|
|
|
|
# 2. Upload Assets
|
|
for filename in [f"BlackBarRemover_{tag}_jf10.11.zip", f"BlackBarRemover_{tag}_jf12.0.zip"]:
|
|
if not os.path.exists(filename):
|
|
print(f"File {filename} not found, skipping.")
|
|
continue
|
|
|
|
# Delete existing asset if any
|
|
for existing_asset in rel_data.get("assets", []) or []:
|
|
if existing_asset.get("name") == filename:
|
|
del_url = f"{api_url}/repos/{repo}/releases/{rel_id}/assets/{existing_asset['id']}"
|
|
del_req = urllib.request.Request(del_url, headers=headers, method="DELETE")
|
|
try:
|
|
urllib.request.urlopen(del_req)
|
|
print(f"Deleted old asset {existing_asset['id']}")
|
|
except Exception as e:
|
|
print(f"Delete asset notice: {e}")
|
|
|
|
# Upload asset
|
|
with open(filename, "rb") as f:
|
|
file_bytes = f.read()
|
|
|
|
boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"
|
|
body_data = (
|
|
f"--{boundary}\r\n"
|
|
f"Content-Disposition: form-data; name=\"attachment\"; filename=\"{filename}\"\r\n"
|
|
f"Content-Type: application/zip\r\n\r\n"
|
|
).encode("utf-8") + file_bytes + f"\r\n--{boundary}--\r\n".encode("utf-8")
|
|
|
|
upload_headers = {
|
|
"Authorization": f"token {token}",
|
|
"Content-Type": f"multipart/form-data; boundary={boundary}"
|
|
}
|
|
upload_url = f"{api_url}/repos/{repo}/releases/{rel_id}/assets"
|
|
upload_req = urllib.request.Request(upload_url, data=body_data, headers=upload_headers)
|
|
try:
|
|
urllib.request.urlopen(upload_req)
|
|
print(f"Uploaded {filename} successfully.")
|
|
except Exception as e:
|
|
print(f"Asset upload error: {e}")
|
|
|
|
# 3. Build manifest.json dynamically from Gitea Releases API
|
|
rel_list_req = urllib.request.Request(f"{api_url}/repos/{repo}/releases?per_page=100", headers=headers)
|
|
all_releases = []
|
|
try:
|
|
res_list = urllib.request.urlopen(rel_list_req)
|
|
all_releases = json.loads(res_list.read().decode("utf-8"))
|
|
except Exception as e:
|
|
print(f"Notice fetching releases list: {e}")
|
|
|
|
all_versions = []
|
|
for r in all_releases:
|
|
rel_tag = r.get("tag_name")
|
|
if not rel_tag:
|
|
continue
|
|
clean_v = rel_tag.lstrip("v").split("-")[0]
|
|
ts = r.get("published_at") or r.get("created_at") or "2026-09-17T20:00:00Z"
|
|
assets = r.get("assets", [])
|
|
|
|
if rel_tag == tag:
|
|
all_versions.append({
|
|
"version": clean_v,
|
|
"changelog": f"Release {tag} (Jellyfin 12.0)",
|
|
"targetAbi": "12.0.0.0",
|
|
"sourceUrl": f"https://gitea.labus.uk/karol/blackBarRemover/releases/download/{tag}/BlackBarRemover_{tag}_jf12.0.zip",
|
|
"checksum": md5_10,
|
|
"timestamp": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
})
|
|
all_versions.append({
|
|
"version": clean_v,
|
|
"changelog": f"Release {tag} (Jellyfin 10.11)",
|
|
"targetAbi": "10.11.0.0",
|
|
"sourceUrl": f"https://gitea.labus.uk/karol/blackBarRemover/releases/download/{tag}/BlackBarRemover_{tag}_jf10.11.zip",
|
|
"checksum": md5_9,
|
|
"timestamp": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
})
|
|
else:
|
|
a12 = next((a for a in assets if "jf12.0" in a.get("name", "")), None)
|
|
if a12:
|
|
a12_name = a12.get("name")
|
|
all_versions.append({
|
|
"version": clean_v,
|
|
"changelog": f"Release {rel_tag} (Jellyfin 12.0)",
|
|
"targetAbi": "12.0.0.0",
|
|
"sourceUrl": f"https://gitea.labus.uk/karol/blackBarRemover/releases/download/{rel_tag}/{a12_name}",
|
|
"checksum": a12.get("md5") or "",
|
|
"timestamp": ts
|
|
})
|
|
a10 = next((a for a in assets if "jf10.11" in a.get("name", "")), None)
|
|
if a10:
|
|
a10_name = a10.get("name")
|
|
all_versions.append({
|
|
"version": clean_v,
|
|
"changelog": f"Release {rel_tag} (Jellyfin 10.11)",
|
|
"targetAbi": "10.11.0.0",
|
|
"sourceUrl": f"https://gitea.labus.uk/karol/blackBarRemover/releases/download/{rel_tag}/{a10_name}",
|
|
"checksum": a10.get("md5") or "",
|
|
"timestamp": ts
|
|
})
|
|
if not a12 and not a10 and assets:
|
|
alegacy = assets[0]
|
|
leg_name = alegacy.get("name")
|
|
all_versions.append({
|
|
"version": clean_v,
|
|
"changelog": f"Release {rel_tag}",
|
|
"targetAbi": "10.9.0.0",
|
|
"sourceUrl": f"https://gitea.labus.uk/karol/blackBarRemover/releases/download/{rel_tag}/{leg_name}",
|
|
"checksum": alegacy.get("md5") or "",
|
|
"timestamp": ts
|
|
})
|
|
|
|
manifest_data = [
|
|
{
|
|
"guid": "12345678-1234-1234-1234-1234567890ab",
|
|
"name": "Black Bar Remover",
|
|
"description": "Automatically detects and removes black bars from video files.",
|
|
"overview": "Automatically detects and removes black bars from video files via CSS or FFmpeg.",
|
|
"owner": "karol",
|
|
"category": "Playback",
|
|
"imageUrl": "",
|
|
"versions": all_versions
|
|
}
|
|
]
|
|
|
|
b64_manifest = base64.b64encode(json.dumps(manifest_data, indent=4).encode("utf-8")).decode("utf-8")
|
|
|
|
# Update on master and manifest branches
|
|
for target_branch in ["master", "manifest"]:
|
|
get_mf_url = f"{api_url}/repos/{repo}/contents/manifest.json?ref={target_branch}"
|
|
req_mf = urllib.request.Request(get_mf_url, headers=headers)
|
|
file_sha = None
|
|
try:
|
|
res_mf = urllib.request.urlopen(req_mf)
|
|
file_sha = json.loads(res_mf.read().decode("utf-8")).get("sha")
|
|
except Exception:
|
|
pass
|
|
|
|
put_payload = {
|
|
"content": b64_manifest,
|
|
"message": f"Update manifest.json for {tag}",
|
|
"branch": target_branch
|
|
}
|
|
if file_sha:
|
|
put_payload["sha"] = file_sha
|
|
|
|
put_url = f"{api_url}/repos/{repo}/contents/manifest.json"
|
|
put_req = urllib.request.Request(put_url, data=json.dumps(put_payload).encode("utf-8"), headers=headers, method="PUT")
|
|
try:
|
|
urllib.request.urlopen(put_req)
|
|
print(f"manifest.json updated successfully on branch {target_branch}.")
|
|
except Exception as e:
|
|
print(f"Notice updating branch {target_branch}: {e}")
|
|
'
|