blob: 57041610386ae53fa36be382ccab817838cf8b9b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
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
|