name: "Generate Documentation" description: "Generate README index and per-skin markdown pages" inputs: new_tag: description: "The new tag for this build" required: true readme_path: description: "Path to write README.md" required: true doc_dir: description: "Directory to write per-skin markdown pages" required: true runs: using: "composite" steps: - name: Generate README shell: bash run: | echo "Generating README index…" sanitize_filename() { echo "$1" | \ tr -d '\000-\037' | \ sed -e 's#[\\/:\*\?"<>|]#-#g' | \ sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' } url_encode_path() { local IFS='/' local parts=($1) local encoded="" for part in "${parts[@]}"; do [ -n "$encoded" ] && encoded+="/" encoded+=$(printf '%s' "$part" | jq -sRr @uri) done echo "$encoded" } SKINS_JSON_FILE="${{ github.workspace }}/.gitea/workflows/skins.json" DESC_FILE=$(mktemp) echo "---" > "${{ inputs.readme_path }}" echo "gitea: none" >> "${{ inputs.readme_path }}" echo "include_toc: true" >> "${{ inputs.readme_path }}" echo "---" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "# Skins" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "**Go back to [osc/skins]($REGISTRY_URL/osc/skins)**" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "**Click on the Skin name to download it, or click on the thumbnail to see more about the skin, including a video preview, screenshots, and mod icons.**" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" jq -r '.descriptions | to_entries[] | "\(.key)=\(.value)"' "$SKINS_JSON_FILE" > "$DESC_FILE" jq -r '.order[]?' "$SKINS_JSON_FILE" > order.txt get_desc() { grep -F -m1 -- "$1=" "$DESC_FILE" 2>/dev/null | cut -d '=' -f2- || true } declare -A ordered while IFS= read -r skin; do [ "$skin" = "default-skin" ] && continue ordered["$skin"]=1 dir="$DANSER_SKINS_DIR/$skin" [ ! -d "$dir" ] && continue ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true) skin_header="$skin" if [ -f "$ini_file" ]; then name_line=$(grep -a -i -m1 'Name[[:space:]]*:' "$ini_file" || true) if [ -n "$name_line" ]; then val="${name_line#*:}" val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" [ -n "$val" ] && skin_header=$(sanitize_filename "$val") fi else continue fi raw_path="$(printf "%s/%s" "$skin" "$skin_header" | sed 's/^ *//;s/ *$//')" base_path=$(url_encode_path "$raw_path") echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/${{ inputs.new_tag }}/export/${base_path}.osk)" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" desc=$(get_desc "$skin") [ -n "$desc" ] && { echo "$desc" >> "${{ inputs.readme_path }}"; echo "" >> "${{ inputs.readme_path }}"; } if [ -f "$ini_file" ]; then author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true) if [ -n "$author_line" ]; then author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') [ -n "$author" ] && { echo "**Author:** $author" >> "${{ inputs.readme_path }}"; echo "" >> "${{ inputs.readme_path }}"; } fi fi echo "[![$skin_header Thumbnail](media/thumbnail/${base_path}.webp)](/docs/${base_path}.md)" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" done < order.txt for dir in "$DANSER_SKINS_DIR"/*; do [ -d "$dir" ] || continue skin="$(basename "$dir")" [ "$skin" = "default-skin" ] && continue [[ -n "${ordered[$skin]}" ]] && continue ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true) skin_header="$skin" if [ -f "$ini_file" ]; then name_line=$(grep -a -i -m1 'Name[[:space:]]*:' "$ini_file" || true) if [ -n "$name_line" ]; then val="${name_line#*:}" val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" [ -n "$val" ] && skin_header=$(sanitize_filename "$val") fi else continue fi raw_path="$(printf "%s/%s" "$skin" "$skin_header" | sed 's/^ *//;s/ *$//')" base_path=$(url_encode_path "$raw_path") echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/${{ inputs.new_tag }}/export/${base_path}.osk)" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" if [ -f "$ini_file" ]; then author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true) if [ -n "$author_line" ]; then author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') [ -n "$author" ] && { echo "**Author:** $author" >> "${{ inputs.readme_path }}"; echo "" >> "${{ inputs.readme_path }}"; } fi fi echo "[![$skin_header Thumbnail](media/thumbnail/${base_path}.webp)](/docs/${base_path}.md)" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" done echo "# Build History" >> "${{ inputs.readme_path }}" echo "" >> "${{ inputs.readme_path }}" echo "| Version | Date |" >> "${{ inputs.readme_path }}" echo "| ------- | ---- |" >> "${{ inputs.readme_path }}" current_commit_date=$(TZ="Europe/Zurich" date -d "$(git log -1 --format=%cI)" "+%d.%m.%Y %H:%M:%S") echo "| [\`${{ inputs.new_tag }} (Current)\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/${{ inputs.new_tag }}/README.md) | $current_commit_date |" >> "${{ inputs.readme_path }}" old_tags=$(git tag --sort=-v:refname | grep -v "^${{ inputs.new_tag }}$" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true) if [ -n "$old_tags" ]; then echo "$old_tags" | while read -r tag; do tag_date=$(git log -1 --format=%ci "$tag") formatted_date=$(TZ="Europe/Zurich" date -d "$tag_date" "+%d.%m.%Y %H:%M:%S") echo "| [\`$tag\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$tag/README.md) | $formatted_date |" >> "${{ inputs.readme_path }}" done fi echo "README index generated successfully." - name: Generate Per-Skin Pages shell: bash run: | echo "Generating detailed per-skin markdown pages…" sanitize_filename() { echo "$1" | \ tr -d '\000-\037' | \ sed -e 's#[\\/:\*\?"<>|]#-#g' | \ sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' } url_encode_path() { local IFS='/' local parts=($1) local encoded="" for part in "${parts[@]}"; do [ -n "$encoded" ] && encoded+="/" encoded+=$(printf '%s' "$part" | jq -sRr @uri) done echo "$encoded" } mkdir -p "${{ inputs.doc_dir }}" for dir in "$DANSER_SKINS_DIR"/*; do [ -d "$dir" ] || continue skin=$(basename "$dir") [ "$skin" = "default-skin" ] && continue ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true) skin_header="$skin" if [ -f "$ini_file" ]; then line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true) if [ -n "$line" ]; then val="${line#*:}" val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" if [ -n "$val" ]; then skin_header=$(sanitize_filename "$val") fi fi fi raw_path="${skin}/${skin_header}" base_path=$(url_encode_path "$raw_path") osk_url="$REGISTRY_URL/$USER_REPOSITORY/media/tag/${{ inputs.new_tag }}/export/${base_path}.osk" md_file_path="${{ inputs.doc_dir }}/${raw_path}.md" mkdir -p "$(dirname "$md_file_path")" video_url="$REGISTRY_URL/$USER_REPOSITORY/media/tag/${{ inputs.new_tag }}/media/gameplay/${base_path}.mp4" author="" if [ -f "$ini_file" ]; then author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true) if [ -n "$author_line" ]; then author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') fi fi { echo "# [$skin_header]($osk_url)" echo "" [ -n "$author" ] && echo "**Author:** $author" [ -n "$author" ] && echo "" echo "## Hitsounds" echo "" echo "" echo "## Ranking Panel" echo "![](/media/panel/${base_path}.webp)" echo "" echo "## Mod Icons" echo "![](/media/icons/${base_path}-mod-icons.webp)" echo "" echo "## Build History" echo "" echo "| Version | Date |" echo "| ------- | ---- |" current_commit_date=$(TZ="Europe/Zurich" date -d "$(git log -1 --format=%cI)" "+%d.%m.%Y %H:%M:%S") echo "| [\`${{ inputs.new_tag }} (Current)\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/${{ inputs.new_tag }}/docs/${base_path}.md) | $current_commit_date |" old_tags=$(git tag --sort=-v:refname | grep -v "^${{ inputs.new_tag }}$" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true) if [ -n "$old_tags" ]; then echo "$old_tags" | while read -r tag; do raw_osk_path="export/${skin}/${skin_header}.osk" if git ls-tree -r --name-only "$tag" | grep -Fx -- "$raw_osk_path" >/dev/null; then tag_date=$(git log -1 --format=%ci "$tag") formatted_date=$(TZ="Europe/Zurich" date -d "$tag_date" "+%d.%m.%Y %H:%M:%S") echo "| [\`$tag\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$tag/docs/${base_path}.md) | $formatted_date |" fi done fi } > "$md_file_path" echo " → Wrote $md_file_path" done echo "Per-skin markdown pages complete."