Files
skins/.gitea/workflows/ci.yml
2025-06-20 16:07:56 +02:00

222 lines
8.1 KiB
YAML

name: Update Community Skins README
on:
schedule:
- cron: '*/5 * * * *'
workflow_dispatch:
env:
IMAGE_NAME: osc/skins-image
GITEA_API: https://${{ vars.CONTAINER_REGISTRY }}/api/v1
README_PATH: "README.md"
jobs:
fetch_and_process_data:
name: Fetch and Process Skin Data
runs-on: ubuntu-latest
container:
image: ${{ vars.CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
outputs:
user_rows_file: ${{ steps.generate_data.outputs.user_rows_file }}
avatar_rows_file: ${{ steps.generate_data.outputs.avatar_rows_file }}
total_valid_entries: ${{ steps.generate_data.outputs.total_valid_entries }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ secrets.TOKEN }}
- name: Pull latest changes
run: git pull --rebase origin main || echo "Nothing to rebase"
- name: Generate Skin Data Files
id: generate_data
shell: bash
run: |
set -euo pipefail
total_valid_entries=0
user_rows_file=$(mktemp)
avatar_rows_file=$(mktemp)
page=1
users_data_found=true
while "$users_data_found"; do
echo "Fetching users page $page..." >&2
users_json=$(curl --fail --retry 3 --retry-delay 5 -sSL \
-H "Authorization: token ${{ secrets.TOKEN }}" \
"$GITEA_API/admin/users?limit=50&page=$page&_ts=$(date +%s)")
if [ "$(echo "$users_json" | jq 'length')" -eq 0 ]; then
users_data_found=false
break
fi
mapfile -t user_logins < <(echo "$users_json" | jq -r '.[].login')
for user_login in "${user_logins[@]}"; do
echo "Processing user: $user_login" >&2
repos_json=$(curl --fail --retry 3 --retry-delay 5 -sSL \
-H "Authorization: token ${{ secrets.TOKEN }}" \
"$GITEA_API/users/$user_login/repos?limit=50&page=1&_ts=$(date +%s)")
if ! echo "$repos_json" | jq -e '.[0]' >/dev/null; then
continue
fi
mapfile -t repo_details < <(echo "$repos_json" | jq -r '.[] | .owner.login, .name, .html_url')
for ((i=0; i<${#repo_details[@]}; i+=3)); do
owner="${repo_details[i]}"
repo="${repo_details[i+1]}"
html_url="${repo_details[i+2]}"
echo " Checking repo: $repo" >&2
curl -sSL -w "%{http_code}" -o readme_content.json \
-H "Authorization: token ${{ secrets.TOKEN }}" \
"$GITEA_API/repos/$owner/$repo/contents/README.md?_ts=$(date +%s)" > http_code.txt
http_code=$(cat http_code.txt)
rm -f http_code.txt
if [ "$http_code" != "200" ]; then
echo "README not found for $owner/$repo (HTTP $http_code)" >&2
continue
fi
readme_content=$(jq -r '.content' readme_content.json | base64 -d || echo "")
rm -f readme_content.json
if echo "$readme_content" | grep -qE "^---$" && \
echo "$readme_content" | grep -qE "^gitea: none" && \
echo "$readme_content" | grep -qE "^include_toc: true" && \
echo "$readme_content" | grep -qE "^# Skins"; then
osu_id=$(echo "$readme_content" | awk '/osuid:[ ]*[0-9]+/ { match($0, /[0-9]+/); print substr($0, RSTART, RLENGTH); exit }')
if [ -n "$osu_id" ]; then
user_data=$(curl --fail --retry 3 --retry-delay 5 -s \
"https://osu.ppy.sh/api/get_user?k=${{ secrets.OSUAPIV1 }}&u=$osu_id&type=id&_ts=$(date +%s)")
if ! echo "$user_data" | jq -e '.[0]' >/dev/null; then
echo "No osu! data found for ID: $osu_id" >&2
continue
fi
pp_rank=$(echo "$user_data" | jq -r '.[0].pp_rank // "9999999"')
pp_country_rank=$(echo "$user_data" | jq -r '.[0].pp_country_rank // "-"')
username=$(echo "$user_data" | jq -r --arg owner "$owner" '.[0].username // $owner')
padded_rank=$(printf "%07d" "$pp_rank")
printf "%s|<tr><td>%s</td><td>%s</td><td>%s</td><td><a href=\"https://osu.ppy.sh/users/%s\">Profile</a></td><td><a href=\"%s\">Skins</a></td></tr>\n" \
"$padded_rank" "$username" "$pp_rank" "$pp_country_rank" "$osu_id" "$html_url" >> "$user_rows_file"
timestamp=$(( $(date +%s) / 86400 * 86400 ))
printf "%s|<a href=\"%s\"><img src=\"https://a.ppy.sh/%s?%s\" width=175 height=175></a>\n" \
"$padded_rank" "$html_url" "$osu_id" "$timestamp" >> "$avatar_rows_file"
total_valid_entries=$((total_valid_entries + 1))
else
echo "osu! ID not found in README for $owner/$repo" >&2
fi
else
echo "README for $owner/$repo does not match required format" >&2
fi
done
done
page=$((page + 1))
done
{
echo "user_rows_file=$user_rows_file"
echo "avatar_rows_file=$avatar_rows_file"
echo "total_valid_entries=$total_valid_entries"
} >> "$GITHUB_OUTPUT"
update_and_push_readme:
name: Update README and Push Changes
runs-on: ubuntu-latest
needs: fetch_and_process_data
container:
image: ${{ vars.CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ secrets.TOKEN }}
- name: Update README with user skins
run: |
user_rows_file="${{ needs.fetch_and_process_data.outputs.user_rows_file }}"
avatar_rows_file="${{ needs.fetch_and_process_data.outputs.avatar_rows_file }}"
cat > "$README_PATH" <<-EOF
# osu! Swiss Community Skin collection
Welcome to the osu! Swiss Community Skin collection, this repository archives and showcases Skins osc members use.
Enjoy looking around, click file names to download the skins and click on the images to see more about the skins.
## How do I add my skins here?
If you're interested in adding your skins here please follow this tutorial [how-to-use](/how-to-use.md)
## Skins
<details>
<summary>list instead of icons</summary>
<br />
<table border="1" cellpadding="5" cellspacing="0">
<thead>
<tr>
<th>Name</th>
<th>Global Rank</th>
<th>Country Rank</th>
<th>Profile</th>
<th>Skins</th>
</tr>
</thead>
<tbody>
EOF
sort -t '|' -k1,1n "$user_rows_file" | cut -d'|' -f2- | sed 's/^/ /' >> "$README_PATH"
cat >> "$README_PATH" <<-EOF
</tbody>
</table>
</details>
<p align="center">
EOF
sort -t '|' -k1,1n "$avatar_rows_file" | cut -d'|' -f2- | sed 's/^/ /' >> "$README_PATH"
cat >> "$README_PATH" <<-EOF
</p>
EOF
rm -f "$user_rows_file" "$avatar_rows_file"
- name: Configure Git
run: |
git config user.email "arlind@sulej.ch"
git config user.name "ci-bot"
git config lfs.https://${{ vars.CONTAINER_REGISTRY }}/arlind/skins.git/info/lfs.locksverify true
- name: Add and Commit changes
run: |
git config advice.addIgnoredFile false
git add "$README_PATH"
git commit -m "[ci skip] push back from pipeline" -q || echo "No changes to commit"
- name: Push changes and create tag
run: |
if [ "${GITHUB_REF}" = "refs/heads/main" ]; then
git push origin HEAD:main || echo "No changes to push"
else
git push origin HEAD:"${GITHUB_REF_NAME}" || echo "No changes to push"
fi