mirror of
https://git.tt-rss.org/fox/tt-rss.git
synced 2026-05-04 23:26:09 +02:00
Test out a (generated) plugin JSON-building workflow.
This commit is contained in:
parent
703d310e40
commit
003b979ae2
292
.github/workflows/update-plugins-json.yml
vendored
Normal file
292
.github/workflows/update-plugins-json.yml
vendored
Normal file
@ -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'
|
||||
<?php
|
||||
$content = file_get_contents($argv[1]);
|
||||
|
||||
// Use token_get_all to parse PHP code more reliably
|
||||
$tokens = token_get_all($content);
|
||||
$class_name = '';
|
||||
$description = '';
|
||||
|
||||
// Find class declaration
|
||||
for ($i = 0; $i < count($tokens); $i++) {
|
||||
if (is_array($tokens[$i]) && $tokens[$i][0] === T_CLASS) {
|
||||
// Skip whitespace
|
||||
$j = $i + 1;
|
||||
while ($j < count($tokens) && is_array($tokens[$j]) && $tokens[$j][0] === T_WHITESPACE) {
|
||||
$j++;
|
||||
}
|
||||
// Get class name
|
||||
if ($j < count($tokens) && is_array($tokens[$j]) && $tokens[$j][0] === T_STRING) {
|
||||
$class_name = $tokens[$j][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find about() function and extract description from return array
|
||||
$in_about = false;
|
||||
$in_return = false;
|
||||
$array_depth = 0;
|
||||
$strings = [];
|
||||
|
||||
for ($i = 0; $i < count($tokens); $i++) {
|
||||
$token = $tokens[$i];
|
||||
|
||||
// Skip non-array tokens unless we're in return statement
|
||||
if (!is_array($token)) {
|
||||
if ($in_return) {
|
||||
if ($token === '[') {
|
||||
$array_depth++;
|
||||
} elseif ($token === ']' || $token === ')') {
|
||||
$array_depth--;
|
||||
if ($array_depth === 0) {
|
||||
break; // End of return array
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for 'function about'
|
||||
if ($token[0] === T_FUNCTION) {
|
||||
// Check if next non-whitespace token is 'about'
|
||||
$j = $i + 1;
|
||||
while ($j < count($tokens) && is_array($tokens[$j]) && $tokens[$j][0] === T_WHITESPACE) {
|
||||
$j++;
|
||||
}
|
||||
if ($j < count($tokens) && is_array($tokens[$j]) && $tokens[$j][0] === T_STRING && $tokens[$j][1] === 'about') {
|
||||
$in_about = true;
|
||||
$i = $j;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($in_about && $token[0] === T_RETURN) {
|
||||
$in_return = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($in_return) {
|
||||
// Track array() syntax
|
||||
if ($token[0] === T_ARRAY) {
|
||||
// Look ahead for opening parenthesis (skip whitespace)
|
||||
$k = $i + 1;
|
||||
while ($k < count($tokens) && is_array($tokens[$k]) && $tokens[$k][0] === T_WHITESPACE) {
|
||||
$k++;
|
||||
}
|
||||
if ($k < count($tokens) && $tokens[$k] === '(') {
|
||||
$array_depth++;
|
||||
}
|
||||
} elseif ($token[0] === T_CONSTANT_ENCAPSED_STRING) {
|
||||
// This is a string literal
|
||||
$str = $token[1];
|
||||
// Remove quotes and decode
|
||||
$str = substr($str, 1, -1);
|
||||
$str = stripcslashes($str);
|
||||
$strings[] = $str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Description is at index 1
|
||||
if (isset($strings[1])) {
|
||||
$description = $strings[1];
|
||||
}
|
||||
|
||||
echo json_encode(['class_name' => $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
|
||||
Loading…
x
Reference in New Issue
Block a user