mirror of
https://github.com/Viren070/MediaFusion.git
synced 2025-12-01 23:21:11 +01:00
Add automated repository generation and version updates (#344)
* Add automated repository generation and version updates Implemented a new Makefile target for updating versions and generating repositories. Added a Python script for automating kodi repository XML generation. Enhanced GitHub Actions to support automatic version updates, build, and deployment to GitHub Pages. * Add Claude API integration for automated release notes
This commit is contained in:
@@ -5,12 +5,53 @@ on:
|
||||
types: [ created ]
|
||||
|
||||
jobs:
|
||||
update_version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
previous_version: ${{ steps.extract_versions.outputs.PREVIOUS_VERSION }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Extract versions
|
||||
id: extract_versions
|
||||
run: |
|
||||
# Extract current version from release body
|
||||
BODY="${{ github.event.release.body }}"
|
||||
if ! PREVIOUS_VERSION=$(echo "$BODY" | grep -o '/compare/.*\.\.\.' | sed 's/\/compare\///' | sed 's/\.\.\.//' || true); then
|
||||
echo "Error: Failed to extract previous version from release body"
|
||||
exit 1
|
||||
fi
|
||||
VERSION="${GITHUB_REF#refs/tags/v}"
|
||||
echo "PREVIOUS_VERSION=${PREVIOUS_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Update version numbers
|
||||
if: "!github.event.release.prerelease"
|
||||
run: |
|
||||
make update-version VERSION_NEW=${{ steps.extract_versions.outputs.VERSION }}
|
||||
|
||||
- name: Commit and push version updates
|
||||
if: "!github.event.release.prerelease"
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add -A
|
||||
git commit -m "chore: update version to ${{ steps.extract_versions.outputs.VERSION }}"
|
||||
git push origin HEAD:main
|
||||
|
||||
mediafusion_docker_build:
|
||||
needs: update_version
|
||||
if: "!github.event.release.prerelease"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main # Use main branch with updated versions
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
@@ -34,18 +75,22 @@ jobs:
|
||||
push: true
|
||||
build-args: VERSION=${{ github.ref_name }}
|
||||
tags: |
|
||||
mhdzumair/mediafusion:v${{ github.ref_name }}
|
||||
mhdzumair/mediafusion:${{ github.ref_name }}
|
||||
mhdzumair/mediafusion:latest
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
kodi_build:
|
||||
needs: update_version
|
||||
if: "!github.event.release.prerelease"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main # Use main branch with updated versions
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
@@ -57,16 +102,59 @@ jobs:
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel
|
||||
|
||||
- name: Install zip
|
||||
run: sudo apt-get install -y zip
|
||||
- name: Install required packages
|
||||
run: sudo apt-get install -y zip xmlstarlet
|
||||
|
||||
- name: Build addon
|
||||
run: make -C kodi
|
||||
- name: Build addon and repository
|
||||
run: |
|
||||
make -C kodi
|
||||
# Validate build artifacts
|
||||
for file in kodi/plugin.video.mediafusion-*.zip kodi/repository.mediafusion-*.zip; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "Error: Build artifact $file not found"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
- name: List build directory
|
||||
run: ls -la kodi
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: kodi/dist
|
||||
destination_dir: kodi/dist
|
||||
keep_files: true
|
||||
enable_jekyll: false
|
||||
force_orphan: true
|
||||
|
||||
- name: Upload Release Asset
|
||||
- name: Upload Release Assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: kodi/plugin.video.mediafusion-*.zip
|
||||
files: |
|
||||
kodi/plugin.video.mediafusion-*.zip
|
||||
kodi/repository.mediafusion-*.zip
|
||||
prerelease: false
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
generate_release_notes:
|
||||
needs: update_version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install jq
|
||||
run: sudo apt-get install -y jq
|
||||
|
||||
- name: Generate Release Notes
|
||||
env:
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
run: |
|
||||
make generate-notes VERSION_OLD=${{ needs.update_version.outputs.previous_version }} VERSION_NEW=${{ github.ref_name }} > release_notes.md
|
||||
|
||||
- name: Update Release Notes
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: release_notes.md
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -27,11 +27,33 @@ VERSION_OLD ?=
|
||||
VERSION_NEW ?=
|
||||
CONTRIBUTORS ?=
|
||||
|
||||
.PHONY: build tag push prompt
|
||||
# Claude API settings
|
||||
CLAUDE_MODEL ?= claude-3-5-sonnet-20241022
|
||||
MAX_TOKENS ?= 1024
|
||||
ANTHROPIC_VERSION ?= 2023-06-01
|
||||
|
||||
.PHONY: build tag push prompt update-version generate-notes
|
||||
|
||||
build:
|
||||
docker build --build-arg VERSION=$(VERSION) -t $(DOCKER_IMAGE) -f deployment/Dockerfile .
|
||||
|
||||
update-version:
|
||||
ifndef VERSION_NEW
|
||||
@echo "Error: VERSION_NEW is not set. Please set it like: make update-version VERSION_NEW=4.1.0"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Updating version to $(VERSION_NEW)..."
|
||||
# Update main addon.xml
|
||||
@sed -i -e "/<addon\s*id=\"plugin\.video\.mediafusion\"/s/version=\"[^\"]*\"/version=\"$(VERSION_NEW)\"/" kodi/plugin.video.mediafusion/addon.xml
|
||||
# Update repository addon.xml
|
||||
@sed -i -e "/<addon\s*id=\"repository\.mediafusion\"/s/version=\"[^\"]*\"/version=\"$(VERSION_NEW)\"/" kodi/repository.mediafusion/addon.xml
|
||||
# Update docker-compose.yml
|
||||
@sed -i 's|image: $(DOCKER_REPO)/$(IMAGE_NAME):v[0-9.]*|image: $(DOCKER_REPO)/$(IMAGE_NAME):v$(VERSION_NEW)|g' deployment/docker-compose/docker-compose.yml
|
||||
# Update k8s deployment
|
||||
@sed -i 's|image: $(DOCKER_REPO)/$(IMAGE_NAME):v[0-9.]*|image: $(DOCKER_REPO)/$(IMAGE_NAME):v$(VERSION_NEW)|g' deployment/k8s/local-deployment.yaml
|
||||
@echo "Version updated to $(VERSION_NEW) in all files"
|
||||
|
||||
|
||||
build-multi:
|
||||
@if ! docker buildx ls | grep -q $(BUILDER_NAME); then \
|
||||
echo "Creating new builder $(BUILDER_NAME)"; \
|
||||
@@ -49,7 +71,6 @@ push:
|
||||
docker push $(DOCKER_IMAGE)
|
||||
|
||||
prompt:
|
||||
# Check if necessary variables are set and generate prompt
|
||||
ifndef VERSION_OLD
|
||||
@echo "Error: VERSION_OLD is not set. Please set it like: make prompt VERSION_OLD=x.x.x VERSION_NEW=y.y.y CONTRIBUTORS='@user1, @user2'"
|
||||
@exit 1
|
||||
@@ -58,11 +79,7 @@ ifndef VERSION_NEW
|
||||
@echo "Error: VERSION_NEW is not set. Please set it like: make prompt VERSION_OLD=x.x.x VERSION_NEW=y.y.y CONTRIBUTORS='@user1, @user2'"
|
||||
@exit 1
|
||||
endif
|
||||
ifndef CONTRIBUTORS
|
||||
@echo "Warning: CONTRIBUTORS not set. Continuing without contributors."
|
||||
endif
|
||||
|
||||
@echo "Generate a release note for MediaFusion $(VERSION_NEW) by analyzing the following changes. Organize the release note by importance rather than by commit order. highlight the most significant updates first, and streamline the content to focus on what adds the most value to the user. Ensure to dynamically create sections for New Features & Enhancements, Bug Fixes, and Documentation updates only if relevant based on the types of changes listed. Use emojis relevantly at the start of each item to enhance readability and engagement. Keep the format straightforward & shorter, List down the contributors, and provide a direct link to the detailed list of changes:\n"
|
||||
@echo "Generate a release note for MediaFusion $(VERSION_NEW) by analyzing the following changes. Organize the release note by importance rather than by commit order. highlight the most significant updates first, and streamline the content to focus on what adds the most value to the user. Ensure to dynamically create sections for New Features & Enhancements, Bug Fixes, and Documentation updates only if relevant based on the types of changes listed. Use emojis relevantly at the start of each item to enhance readability and engagement. Keep the format straightforward & shorter, provide a direct link to the detailed list of changes:\n"
|
||||
@echo "## 🚀 MediaFusion $(VERSION_NEW) Released\n"
|
||||
@echo "### Commit Messages and Descriptions:\n"
|
||||
@git log --pretty=format:'%s%n%b' $(VERSION_OLD)..$(VERSION_NEW) | awk 'BEGIN {RS="\n\n"; FS="\n"} { \
|
||||
@@ -75,8 +92,30 @@ endif
|
||||
if (message != "") print "- " message; \
|
||||
if (description != "") printf "%s", description; \
|
||||
}'
|
||||
@echo "\n### 🤝 Contributors: $(CONTRIBUTORS)\n"
|
||||
@echo "### 📄 Full Changelog:\n- https://github.com/mhdzumair/MediaFusion/compare/$(VERSION_OLD)...$(VERSION_NEW)"
|
||||
@echo "--- \n### 🤝 Contributors: $(CONTRIBUTORS)\n\n### 📄 Full Changelog:\nhttps://github.com/mhdzumair/MediaFusion/compare/$(VERSION_OLD)...$(VERSION_NEW)";
|
||||
|
||||
generate-notes:
|
||||
ifndef VERSION_OLD
|
||||
@echo "Error: VERSION_OLD is not set"
|
||||
@exit 1
|
||||
endif
|
||||
ifndef VERSION_NEW
|
||||
@echo "Error: VERSION_NEW is not set"
|
||||
@exit 1
|
||||
endif
|
||||
ifndef CONTRIBUTORS
|
||||
@echo "Warning: CONTRIBUTORS not set. Continuing without contributors."
|
||||
endif
|
||||
ifndef ANTHROPIC_API_KEY
|
||||
@echo "Error: ANTHROPIC_API_KEY is not set"
|
||||
@exit 1
|
||||
endif
|
||||
@PROMPT_CONTENT=`make prompt VERSION_OLD=$(VERSION_OLD) VERSION_NEW=$(VERSION_NEW) | tr '\n' ' ' | sed 's/"/\\\\"/g'`; \
|
||||
curl -s https://api.anthropic.com/v1/messages \
|
||||
--header "x-api-key: $(ANTHROPIC_API_KEY)" \
|
||||
--header "anthropic-version: $(ANTHROPIC_VERSION)" \
|
||||
--header "content-type: application/json" \
|
||||
--data "{\"model\":\"$(CLAUDE_MODEL)\",\"max_tokens\":$(MAX_TOKENS),\"messages\":[{\"role\":\"user\",\"content\":\"$$PROMPT_CONTENT\"}]}" \
|
||||
| jq -r '.content[] | select(.type=="text") | .text';
|
||||
|
||||
all: build-multi
|
||||
|
||||
+34
-14
@@ -1,37 +1,57 @@
|
||||
# Define the addon directory, build directory, and zip file name
|
||||
ADDON_DIR = plugin.video.mediafusion
|
||||
BUILD_DIR = build/$(ADDON_DIR)
|
||||
LIB_DIR = $(BUILD_DIR)/lib
|
||||
REPO_DIR = repository.mediafusion
|
||||
BUILD_DIR = build
|
||||
DIST_DIR = dist
|
||||
VERSION := $(shell sed -ne "s/.*version=\"\([0-9a-z\.\-]*\)\"\sname=.*/\1/p" $(ADDON_DIR)/addon.xml)
|
||||
RANDOM_STRING = $(shell head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)
|
||||
NEW_VERSION := $(VERSION)-$(RANDOM_STRING)
|
||||
ZIP_FILE := $(ADDON_DIR)-$(VERSION).zip
|
||||
DEV_ZIP_FILE := $(ADDON_DIR)-dev-$(NEW_VERSION).zip
|
||||
REPO_ZIP_FILE := $(REPO_DIR)-$(VERSION).zip
|
||||
|
||||
# Default target
|
||||
all: $(ZIP_FILE)
|
||||
all: $(ZIP_FILE) repository
|
||||
|
||||
# Create the zip file
|
||||
# Create the plugin zip file
|
||||
$(ZIP_FILE): install_dependencies
|
||||
@echo "Creating zip file for $(ADDON_DIR)..."
|
||||
@cd build && zip -r ../$(ZIP_FILE) $(ADDON_DIR)
|
||||
@echo "Zip file created: $(ZIP_FILE)"
|
||||
|
||||
# Install dependencies
|
||||
install_dependencies: $(BUILD_DIR)
|
||||
install_dependencies: prepare_build
|
||||
@echo "Installing dependencies..."
|
||||
@pip install -r requirements.txt -t $(LIB_DIR)
|
||||
@pip install -r requirements.txt -t $(BUILD_DIR)/$(ADDON_DIR)/lib
|
||||
|
||||
# Prepare build directory
|
||||
$(BUILD_DIR): clean
|
||||
prepare_build: clean
|
||||
@echo "Preparing build directory..."
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
@cp -r $(ADDON_DIR)/* $(BUILD_DIR)
|
||||
@mkdir -p $(BUILD_DIR)/$(ADDON_DIR)
|
||||
@mkdir -p $(BUILD_DIR)/$(REPO_DIR)
|
||||
@mkdir -p $(DIST_DIR)/zips/$(ADDON_DIR)
|
||||
@mkdir -p $(DIST_DIR)/zips/$(REPO_DIR)
|
||||
@cp -r $(ADDON_DIR)/* $(BUILD_DIR)/$(ADDON_DIR)
|
||||
|
||||
# Repository setup
|
||||
repository: $(ZIP_FILE)
|
||||
@echo "Setting up repository..."
|
||||
@cp -r $(REPO_DIR)/* $(BUILD_DIR)/$(REPO_DIR)
|
||||
@cd $(BUILD_DIR) && zip -r ../$(REPO_ZIP_FILE) $(REPO_DIR)
|
||||
|
||||
# Copy files to dist structure
|
||||
@cp $(ZIP_FILE) $(DIST_DIR)/zips/$(ADDON_DIR)/
|
||||
@cp $(ADDON_DIR)/addon.xml $(DIST_DIR)/zips/$(ADDON_DIR)/
|
||||
@cp $(REPO_ZIP_FILE) $(DIST_DIR)/zips/$(REPO_DIR)/
|
||||
@cp $(REPO_DIR)/addon.xml $(DIST_DIR)/zips/$(REPO_DIR)/
|
||||
|
||||
# Generate repository files
|
||||
@python3 generate_repository.py
|
||||
|
||||
# Clean up generated files
|
||||
clean:
|
||||
@echo "Cleaning up..."
|
||||
@rm -rf $(ADDON_DIR)-*.zip build
|
||||
@rm -rf $(ADDON_DIR)-*.zip build dist
|
||||
@rm -rf $(HOME)/Downloads/$(ADDON_DIR)-*.zip
|
||||
|
||||
# Dev target
|
||||
@@ -46,10 +66,10 @@ $(DEV_ZIP_FILE): install_dev_dependencies
|
||||
@echo "Dev zip file copied to $(HOME)/Downloads/$(DEV_ZIP_FILE)"
|
||||
|
||||
# Install dev dependencies
|
||||
install_dev_dependencies: $(BUILD_DIR)
|
||||
install_dev_dependencies: prepare_build
|
||||
@echo "Installing dev dependencies..."
|
||||
@pip install -r requirements.txt -t $(LIB_DIR)
|
||||
@pip install -r dev-requirements.txt -t $(LIB_DIR)
|
||||
@pip install -r requirements.txt -t $(BUILD_DIR)/$(ADDON_DIR)/lib
|
||||
@pip install -r dev-requirements.txt -t $(BUILD_DIR)/$(ADDON_DIR)/lib
|
||||
|
||||
# Phony targets
|
||||
.PHONY: all clean dev install_dependencies install_dev_dependencies
|
||||
.PHONY: all clean dev install_dependencies install_dev_dependencies repository prepare_build
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
import hashlib
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
DIST_DIR = Path("dist")
|
||||
ZIPS_DIR = DIST_DIR / "zips"
|
||||
|
||||
|
||||
def generate_md5(file_path):
|
||||
"""Generate MD5 hash of a file."""
|
||||
hash_md5 = hashlib.md5()
|
||||
with open(file_path, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(4096), b""):
|
||||
hash_md5.update(chunk)
|
||||
return hash_md5.hexdigest()
|
||||
|
||||
|
||||
def generate_addons_xml():
|
||||
"""Generate addons.xml file."""
|
||||
addon_xmls = []
|
||||
errors = []
|
||||
# Get all addon.xml files from the zips directory
|
||||
for addon_dir in ZIPS_DIR.iterdir():
|
||||
if addon_dir.is_dir():
|
||||
addon_xml_path = addon_dir / "addon.xml"
|
||||
if addon_xml_path.exists():
|
||||
try:
|
||||
tree = ET.parse(addon_xml_path)
|
||||
root = tree.getroot()
|
||||
# Basic validation
|
||||
if root.tag != "addon":
|
||||
raise ValueError(f"Invalid root tag in {addon_xml_path}")
|
||||
addon_xmls.append(root)
|
||||
except (ET.ParseError, ValueError) as e:
|
||||
errors.append(f"Error processing {addon_xml_path}: {e}")
|
||||
if errors:
|
||||
raise ValueError("\n".join(errors))
|
||||
# Sort addons by ID for consistent output
|
||||
addon_xmls.sort(key=lambda x: x.get("id", ""))
|
||||
# Create addons.xml
|
||||
xml_root = ET.Element("addons")
|
||||
for addon in addon_xmls:
|
||||
xml_root.append(addon)
|
||||
# Use proper XML declaration with encoding
|
||||
xml_str = ET.tostring(xml_root, encoding="utf-8", xml_declaration=True)
|
||||
# Save addons.xml
|
||||
addons_xml_path = ZIPS_DIR / "addons.xml"
|
||||
with open(addons_xml_path, "wb") as f:
|
||||
f.write(xml_str)
|
||||
# Generate MD5
|
||||
md5_path = ZIPS_DIR / "addons.xml.md5"
|
||||
with open(md5_path, "w") as f:
|
||||
f.write(generate_md5(addons_xml_path))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_addons_xml()
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="4.1.1" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="repository.mediafusion" version="4.1.1" name="MediaFusion Repository" provider-name="Mohamed Zumair">
|
||||
<extension point="xbmc.addon.repository" name="MediaFusion Repository">
|
||||
<dir>
|
||||
<info compressed="false">https://mhdzumair.github.io/MediaFusion/kodi/dist/zips/addons.xml</info>
|
||||
<checksum>https://mhdzumair.github.io/MediaFusion/kodi/dist/zips/addons.xml.md5</checksum>
|
||||
<datadir zip="true">https://mhdzumair.github.io/MediaFusion/kodi/dist/zips/</datadir>
|
||||
</dir>
|
||||
</extension>
|
||||
<extension point="xbmc.addon.metadata">
|
||||
<summary>MediaFusion Repository</summary>
|
||||
<description>Repository for MediaFusion Kodi addon</description>
|
||||
<platform>all</platform>
|
||||
<assets>
|
||||
<icon>mediafusion_logo.png</icon>
|
||||
<fanart>mediafusion_logo.png</fanart>
|
||||
</assets>
|
||||
</extension>
|
||||
</addon>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 219 KiB |
Reference in New Issue
Block a user