From 003b979ae2ce2db98946fd5be5d273dd982f3265 Mon Sep 17 00:00:00 2001 From: supahgreg Date: Thu, 16 Oct 2025 03:17:00 +0000 Subject: Test out a (generated) plugin JSON-building workflow. --- .github/workflows/update-plugins-json.yml | 292 ++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 .github/workflows/update-plugins-json.yml diff --git a/.github/workflows/update-plugins-json.yml b/.github/workflows/update-plugins-json.yml new file mode 100644 index 000000000..570416103 --- /dev/null +++ b/.github/workflows/update-plugins-json.yml @@ -0,0 +1,292 @@ +name: Update Plugins JSON + +on: + schedule: + # Run weekly on Mondays at 00:00 UTC + - cron: '0 0 * * 1' + # Allow manual triggering + workflow_dispatch: + +permissions: + contents: write + +jobs: + update-plugins: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + tools: none + + - name: Fetch and process plugin repositories + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + #!/bin/bash + set -e + + cat > /tmp/parse_plugin.php << 'PHPEOF' + $class_name, 'description' => $description], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + PHPEOF + + # Get all repositories from tt-rss organization that start with tt-rss-plugin- + echo "Fetching repositories from tt-rss organization..." + + plugins_json="[]" + page=1 + + while true; do + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/orgs/tt-rss/repos?type=public&per_page=100&page=$page") + + # Check for API errors + if echo "$response" | jq -e '.message' >/dev/null 2>&1; then + echo "API Error: $(echo "$response" | jq -r '.message')" + exit 1 + fi + + # Check if we got an empty array (no more pages) + if [ "$(echo "$response" | jq '. | length')" -eq 0 ]; then + break + fi + + # Filter repositories that start with tt-rss-plugin- and are not archived + filtered=$(echo "$response" | jq '[.[] | select(.name | startswith("tt-rss-plugin-")) | select(.archived == false)]') + + # Process each repository + for repo in $(echo "$filtered" | jq -r '.[] | @base64'); do + _jq() { + echo "$repo" | base64 --decode | jq -r "$1" + } + + repo_name=$(_jq '.name') + full_name=$(_jq '.full_name') + html_url=$(_jq '.html_url') + clone_url=$(_jq '.clone_url') + repo_description=$(_jq '.description // ""') + + echo "Processing repository: $repo_name" + + # Get the latest commit timestamp + commits_response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$full_name/commits?per_page=1") + + # Check if commits response is valid + if echo "$commits_response" | jq -e '.[0]' >/dev/null 2>&1; then + last_update=$(echo "$commits_response" | jq -r '.[0].commit.committer.date') + else + echo " Warning: Could not fetch commit info for $repo_name" + last_update="" + fi + + # Skip if no last_update (indicates repository might be empty or inaccessible) + if [ -z "$last_update" ]; then + echo " Skipping $repo_name: no commit history found" + continue + fi + + # Try to fetch init.php + init_php=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3.raw" \ + "https://api.github.com/repos/$full_name/contents/init.php" 2>/dev/null || echo "") + + # Try to extract the class name and plugin description from init.php + class_name="" + description="" + + if [ -n "$init_php" ]; then + # Save init.php to temporary file for PHP processing + temp_file=$(mktemp) + echo "$init_php" > "$temp_file" + + php_output=$(php /tmp/parse_plugin.php "$temp_file" 2>/dev/null || echo '{"class_name":"","description":""}') + + class_name=$(echo "$php_output" | jq -r '.class_name // ""') + description=$(echo "$php_output" | jq -r '.description // ""') + + rm -f "$temp_file" + fi + + # Skip if no class name was found + if [ -z "$class_name" ]; then + echo " Skipping $repo_name: no class name found in init.php" + continue + fi + + # Fallback to repository description if no description was found + if [ -z "$description" ]; then + description="$repo_description" + fi + + # Placeholder description if still empty + if [ -z "$description" ]; then + description="" + fi + + # Create topics array + topics=$(echo "$class_name" | tr '[:upper:]' '[:lower:]') + topics_json="[\"$topics\"]" + + # Build plugin JSON object + plugin_json=$(jq -n \ + --arg name "$class_name" \ + --arg description "$description" \ + --argjson topics "$topics_json" \ + --arg html_url "$html_url" \ + --arg clone_url "$clone_url" \ + --arg last_update "$last_update" \ + '{ + name: $name, + description: $description, + topics: $topics, + html_url: $html_url, + clone_url: $clone_url, + last_update: $last_update + }') + + # Append to plugins array + plugins_json=$(echo "$plugins_json" | jq --argjson plugin "$plugin_json" '. += [$plugin]') + done + + page=$((page + 1)) + done + + # Sort by name and save + echo "$plugins_json" | jq 'sort_by(.name)' > plugins.json + + echo "Plugin list updated successfully!" + cat plugins.json + + - name: Deploy to gh-pages branch + run: | + # Save plugins.json to a safe location + cp plugins.json /tmp/plugins.json + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Fetch gh-pages branch + git fetch origin gh-pages 2>/dev/null || true + + if git rev-parse --verify origin/gh-pages >/dev/null 2>&1; then + # gh-pages exists, check it out + git checkout gh-pages + else + # Create new orphan gh-pages branch + git checkout --orphan gh-pages + git rm -rf . 2>/dev/null || true + fi + + # Restore plugins.json from safe location + cp /tmp/plugins.json plugins.json + git add plugins.json + + # Check if there are changes to commit + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "Update plugins list [automated]" + git push origin gh-pages + fi -- cgit v1.2.3-54-g00ecf