Skip to content

Commit d110c25

Browse files
authored
Refactor GitHub Actions workflow for index generation
1 parent 4177506 commit d110c25

1 file changed

Lines changed: 86 additions & 82 deletions

File tree

.github/workflows/generate-index.yml

Lines changed: 86 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,92 +6,96 @@ on:
66
pull_request:
77
branches: [ main, master ]
88

9+
permissions:
10+
contents: write
11+
912
jobs:
1013
generate-index:
1114
runs-on: ubuntu-latest
12-
15+
1316
steps:
14-
- name: Checkout repository
15-
uses: actions/checkout@v4
16-
17-
- name: Install jq
18-
run: sudo apt-get install -y jq
19-
20-
- name: Generate index.json
21-
run: |
22-
# Start the JSON structure
23-
echo '{ "last_updated": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'", "semesters": [] }' > index.json
24-
25-
# Loop through all directories (except hidden ones)
26-
for dir in */; do
27-
# Skip hidden folders and .github
28-
if [[ "$dir" == .*/ || "$dir" == ".github/" ]]; then
29-
continue
30-
fi
31-
32-
dirname=$(basename "$dir")
33-
echo "📁 Processing folder: $dirname"
34-
35-
# Check for meta.json for custom display name
36-
display_name="$dirname"
37-
if [ -f "${dir}meta.json" ]; then
38-
custom_name=$(jq -r '.display_name // empty' "${dir}meta.json" 2>/dev/null)
39-
if [ -n "$custom_name" ]; then
40-
display_name="$custom_name"
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
22+
- name: Install jq
23+
run: sudo apt-get update && sudo apt-get install -y jq
24+
25+
- name: Generate index.json
26+
run: |
27+
set -euo pipefail
28+
29+
# Start JSON
30+
jq -n --arg ts "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" '{ last_updated: $ts, semesters: [] }' > index.json
31+
32+
for dir in */; do
33+
[[ "$dir" == .*/ || "$dir" == ".github/" ]] && continue
34+
35+
dirname="$(basename "$dir")"
36+
echo "📁 Processing folder: $dirname"
37+
38+
display_name="$dirname"
39+
if [[ -f "${dir}meta.json" ]]; then
40+
custom_name="$(jq -r '.display_name // empty' "${dir}meta.json" 2>/dev/null || true)"
41+
[[ -n "$custom_name" ]] && display_name="$custom_name"
42+
fi
43+
44+
files_json='[]'
45+
46+
shopt -s nullglob
47+
for file in "$dir"*.apkg "$dir"*.json; do
48+
[[ "$file" == *"meta.json" ]] && continue
49+
50+
filename="$(basename "$file")"
51+
size_bytes="$(stat -c%s "$file")"
52+
size_mb="$(awk -v b="$size_bytes" 'BEGIN{printf "%.2f", b/1048576}')"
53+
54+
name="${filename%.*}"
55+
pretty_name="$(echo "$name" | sed 's/[_-]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')"
56+
57+
files_json="$(echo "$files_json" | jq \
58+
--arg path "$file" \
59+
--arg name "$pretty_name" \
60+
--argjson size_mb "$size_mb" \
61+
'. + [{path:$path, name:$name, size_mb:$size_mb}]'
62+
)"
63+
64+
echo " 📄 Found: $filename (${size_mb} MB)"
65+
done
66+
shopt -u nullglob
67+
68+
file_count="$(echo "$files_json" | jq 'length')"
69+
if [[ "$file_count" -gt 0 ]]; then
70+
tmp="$(mktemp)"
71+
jq --arg name "$dirname" \
72+
--arg display "$display_name" \
73+
--argjson files "$files_json" \
74+
'.semesters += [{name:$name, display_name:$display, files:$files}]' \
75+
index.json > "$tmp" && mv "$tmp" index.json
76+
77+
echo " ✅ Added $file_count files from $dirname"
4178
fi
42-
fi
43-
44-
# Find all .apkg and .json deck files (not meta.json)
45-
files_json="[]"
46-
47-
for file in "$dir"*.apkg "$dir"*.json; do
48-
# Skip if no matches or if it's meta.json
49-
[ -e "$file" ] || continue
50-
[[ "$file" == *"meta.json" ]] && continue
51-
52-
filename=$(basename "$file")
53-
filepath="$file"
54-
55-
# Get file size in MB
56-
size_bytes=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
57-
size_mb=$(echo "scale=2; $size_bytes / 1048576" | bc)
58-
59-
# Extract name without extension
60-
name="${filename%.*}"
61-
# Convert underscores and hyphens to spaces, capitalize
62-
pretty_name=$(echo "$name" | sed 's/[_-]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')
63-
64-
# Add to files array
65-
files_json=$(echo "$files_json" | jq \
66-
--arg path "$filepath" \
67-
--arg name "$pretty_name" \
68-
--arg size "$size_mb" \
69-
'. += [{"path": $path, "name": $name, "size_mb": ($size | tonumber)}]')
70-
71-
echo " 📄 Found: $filename ($size_mb MB)"
7279
done
73-
74-
# Only add semester if it has files
75-
file_count=$(echo "$files_json" | jq '. | length')
76-
if [ "$file_count" -gt 0 ]; then
77-
# Add this semester to the index
78-
tmp=$(mktemp)
79-
jq --arg name "$dirname" \
80-
--arg display "$display_name" \
81-
--argjson files "$files_json" \
82-
'.semesters += [{"name": $name, "display_name": $display, "files": $files}]' \
83-
index.json > "$tmp" && mv "$tmp" index.json
84-
85-
echo " ✅ Added $file_count files from $dirname"
80+
81+
echo ""
82+
echo "📋 Generated index.json:"
83+
jq . index.json
84+
85+
- name: Commit and push index.json
86+
if: github.event_name == 'push'
87+
run: |
88+
set -euo pipefail
89+
git config user.name "github-actions[bot]"
90+
git config user.email "github-actions[bot]@users.noreply.github.com"
91+
92+
git add index.json
93+
94+
# If nothing changed, do nothing
95+
if git diff --cached --quiet; then
96+
echo "No changes to commit."
97+
exit 0
8698
fi
87-
done
88-
89-
echo ""
90-
echo "📋 Generated index.json:"
91-
cat index.json | jq .
92-
93-
- name: Upload index.json as artifact
94-
uses: actions/upload-artifact@v4
95-
with:
96-
name: deck-index
97-
path: index.json
99+
100+
git commit -m "chore: update deck index [skip ci]"
101+
git push

0 commit comments

Comments
 (0)