Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions .github/scripts/publish/build-zips.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,39 @@ for plugin_dir in plugins/*/; do
fi
release_notes+="**README:** [Plugin README](${readme_url})"

# Upload versioned GitHub Release
# Upload versioned GitHub Release (retry with numeric suffix on immutable tag conflict)
echo " $plugin_name v$version - uploading to GitHub Releases"
gh release create "$release_tag" \
--repo "$GITHUB_REPOSITORY" \
--title "${plugin_name} v${version}" \
--notes "$release_notes" \
"$zip_path"
final_tag="$release_tag"
tag_suffix=0
upload_skipped=false
while true; do
if gh release create "$final_tag" \
--repo "$GITHUB_REPOSITORY" \
--title "${plugin_name} v${version}" \
--notes "$release_notes" \
"$zip_path" 2>/tmp/rel_err; then
break
fi
if grep -q "already exists" /tmp/rel_err; then
echo " $plugin_name v$version - release already exists, skipping upload"
upload_skipped=true
break
elif grep -q "immutable\|Cannot create ref" /tmp/rel_err; then
tag_suffix=$(( tag_suffix + 1 ))
final_tag="${release_tag}-${tag_suffix}"
echo " Tag conflict on $release_tag, retrying as $final_tag"
else
cat /tmp/rel_err >&2; rm -f "$zip_path" /tmp/rel_err; exit 1
fi
done
rm -f /tmp/rel_err

# If the upload was skipped (release already existed), discard the fresh metadata
# so generate-manifest.sh falls back to the existing manifest's checksums, which
# reflect the zip that is actually in the release rather than the one we just built.
if [[ "$upload_skipped" == "true" ]]; then
rm -f "$BUILD_META_DIR/$plugin_key/${plugin_key}-${version}.json"
fi

rm -f "$zip_path"
done
Expand Down
39 changes: 31 additions & 8 deletions .github/scripts/publish/generate-manifest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@ set -e
generated_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
registry_url="https://github.com/${GITHUB_REPOSITORY}"
registry_name="${GITHUB_REPOSITORY}"
root_url="https://github.com/${GITHUB_REPOSITORY}/releases/download"
download_base_url="https://github.com/${GITHUB_REPOSITORY}/releases/download"
raw_releases_url="https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/${RELEASES_BRANCH}"

# Use GitHub Pages URL for metadata if configured; fall back to raw.githubusercontent.com
pages_url=$(gh api "repos/${GITHUB_REPOSITORY}/pages" --jq '.html_url // empty' 2>/dev/null || true)
if [[ -n "$pages_url" ]]; then
metadata_base_url="${pages_url%/}"
else
metadata_base_url="$raw_releases_url"
fi

# GPG signing setup - optional; set GPG_PRIVATE_KEY (armored) and optionally GPG_PASSPHRASE
gpg_key_id=""
gpg_signing_failed=0
Expand Down Expand Up @@ -134,6 +142,16 @@ for plugin_dir in plugins/*/; do
existing_manifest_file="metadata/$plugin_name/manifest.json"
mkdir -p "metadata/$plugin_name"

# Sync icon from source branch; prefer png > svg > jpg > webp
icon_rel=""
for ext in png svg jpg webp; do
if [[ -f "$plugin_dir/logo.$ext" ]]; then
cp "$plugin_dir/logo.$ext" "metadata/$plugin_name/logo.$ext"
icon_rel="metadata/${plugin_name}/logo.$ext"
break
fi
done

# Discover published versions from GitHub Releases (newest first)
versioned_tags=$(echo "$all_release_tags" \
| grep "^${plugin_name}-" \
Expand All @@ -145,10 +163,11 @@ for plugin_dir in plugins/*/; do
while IFS= read -r release_tag; do
[[ -z "$release_tag" ]] && continue
zip_version="${release_tag#${plugin_name}-}"
zip_url="${plugin_name}-${zip_version}/${plugin_name}-${zip_version}.zip"
# Strip a plain-integer migration retry suffix (e.g. 1.0.0-1 -> 1.0.0) so the
# canonical version is used for metadata lookup and manifest entries.
# Strip a plain-integer retry suffix (e.g. 1.0.0-1 -> 1.0.0) for metadata lookup and the ZIP filename.
canonical_version=$(sed 's/-[0-9][0-9]*$//' <<< "$zip_version")
# Release directory uses the full tag version (may include retry suffix);
# the ZIP asset filename uses the canonical version (how build-zips.sh named it).
zip_url="${plugin_name}-${zip_version}/${plugin_name}-${canonical_version}.zip"

# Fresh metadata from this run takes priority; fall back to existing manifest
fresh_meta_file="${BUILD_META_DIR:-}/$plugin_key/${plugin_key}-${canonical_version}.json"
Expand Down Expand Up @@ -201,7 +220,10 @@ for plugin_dir in plugins/*/; do
# Use the actual tag-derived zip_version (which may include a retry suffix) for the URL,
# so the URL resolves to the real release asset.
latest_url=""
[[ -n "$latest_zip_version" ]] && latest_url="${plugin_name}-${latest_zip_version}/${plugin_name}-${latest_zip_version}.zip"
if [[ -n "$latest_zip_version" ]]; then
latest_canonical=$(sed 's/-[0-9][0-9]*$//' <<< "$latest_zip_version")
latest_url="${plugin_name}-${latest_zip_version}/${plugin_name}-${latest_canonical}.zip"
fi

# Overwrite min/max_dispatcharr_version for the current version's entry from plugin.json,
# so metadata-only updates (no version bump) are reflected without a rebuild.
Expand Down Expand Up @@ -276,8 +298,8 @@ for plugin_dir in plugins/*/; do
desc_trimmed="$desc_raw"
fi

# manifest_url is absolute: per-plugin manifest stays in the releases branch (raw.githubusercontent.com)
plugin_manifest_url="${raw_releases_url}/metadata/${plugin_name}/manifest.json"
# manifest_url is relative: clients compose with metadata_base_url from the root manifest
plugin_manifest_url="metadata/${plugin_name}/manifest.json"

root_entry=$(jq -n \
--argjson latest_metadata "$latest_metadata" \
Expand Down Expand Up @@ -318,7 +340,8 @@ inner_root=$(
echo '{'
echo ' "registry_url": '"$(jq -n --arg u "$registry_url" '$u')"','
echo ' "registry_name": '"$(jq -n --arg u "$registry_name" '$u')"','
echo ' "root_url": '"$(jq -n --arg u "$root_url" '$u')"','
echo ' "download_base_url": '"$(jq -n --arg u "$download_base_url" '$u')"','
echo ' "metadata_base_url": '"$(jq -n --arg u "$metadata_base_url" '$u')"','
echo ' "plugins": ['
first=true
for entry in "${root_entries[@]}"; do
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/publish/plugin-readmes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ shields_encode() {
printf '%s' "$s"
}

# Read root_url from the root manifest (set by generate-manifest.sh)
root_url=$(jq -r '.manifest.root_url // ""' "manifest.json" 2>/dev/null || echo "")
# Read download_base_url from the root manifest (set by generate-manifest.sh)
root_url=$(jq -r '.manifest.download_base_url // ""' "manifest.json" 2>/dev/null || echo "")

for plugin_dir in plugins/*/; do
[[ ! -d "$plugin_dir" ]] && continue
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/publish/releases-readme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ render_plugin() {

local manifest_file="./metadata/${plugin_name}/manifest.json"
local root_url
root_url=$(jq -r '.manifest.root_url // ""' "manifest.json" 2>/dev/null || echo "")
root_url=$(jq -r '.manifest.download_base_url // ""' "manifest.json" 2>/dev/null || echo "")
local latest_url_path=""
[[ -f "$manifest_file" ]] && latest_url_path=$(jq -r '.manifest.latest.latest_url // empty' "$manifest_file")
local zip_url=""
Expand Down
Loading