diff --git a/.gitea/actions/create-osk/action.yml b/.gitea/actions/create-osk/action.yml new file mode 100644 index 0000000..80260cb --- /dev/null +++ b/.gitea/actions/create-osk/action.yml @@ -0,0 +1,128 @@ +name: "Create OSK Files" +description: "Create .osk archives for changed skins (safe handling of input JSON path)" + +inputs: + changed_skins_file: + description: "Path to file containing JSON array (changed skins)" + required: false + default: "" + +runs: + using: "composite" + steps: + - name: Create OSK Files + shell: bash + run: | + set -euo pipefail + echo "[OSK Creation Job Started]" + + # Determine the changed skins file path from input or environment + CHANGED_SKINS_FILE="${{ inputs.changed_skins_file }}" + if [ -z "${CHANGED_SKINS_FILE:-}" ]; then + CHANGED_SKINS_FILE="${CHANGED_SKINS_FILE:-${CHANGED_SKINS_FILE_ENV:-}}" + fi + + # Allow workflow to pass CHANGED_SKINS_FILE via environment too + if [ -z "${CHANGED_SKINS_FILE:-}" ] && [ -n "${CHANGED_SKINS_FILE:-}" ]; then + CHANGED_SKINS_FILE="${CHANGED_SKINS_FILE}" + fi + + # Fallback to common temp path if caller wrote there + if [ -z "${CHANGED_SKINS_FILE:-}" ]; then + if [ -f "/tmp/changed_skins.json" ]; then + CHANGED_SKINS_FILE="/tmp/changed_skins.json" + elif [ -f "/tmp/changed_skins.txt" ]; then + CHANGED_SKINS_FILE="/tmp/changed_skins.txt" + fi + fi + + if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then + echo "No skins changed or changed-skins file missing at: ${CHANGED_SKINS_FILE:-}". + echo "Skipping OSK creation." + exit 0 + fi + + # Create a safe list file to avoid any template expansion / parsing surprises + temp_list_file="/tmp/osk_skins_list_$RANDOM.txt" + # If file is JSON array, extract with jq; if it's plain newline list, copy as-is + if jq -e . >/dev/null 2>&1 < "$CHANGED_SKINS_FILE"; then + jq -r '.[]' "$CHANGED_SKINS_FILE" > "$temp_list_file" + else + # treat as newline-separated + cp "$CHANGED_SKINS_FILE" "$temp_list_file" + fi + + # read into array + mapfile -t skin_dirs < "$temp_list_file" + rm -f "$temp_list_file" + + if [ "${#skin_dirs[@]}" -eq 0 ]; then + echo "No skins to process. Exiting."; + exit 0; + fi + + sanitize_filename() { + echo "$1" | \ + tr -d '\000-\037' | \ + sed -e 's#[\\/:\*\?"<>|]#-#g' | \ + sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' + } + + FIXED_TIMESTAMP="2025-01-01 00:00:00" + SKIN_COUNT=${#skin_dirs[@]} + INDEX=1 + + for skin_path in "${skin_dirs[@]}"; do + # skip empty lines + [ -z "${skin_path}" ] && { ((INDEX++)); continue; } + + SKIN_DIR="${DANSER_SKINS_DIR:-$DANSER_SKINS_DIR}/${skin_path}" + if [ ! -d "$SKIN_DIR" ]; then + # try without prefix if caller passed full path + if [ -d "$skin_path" ]; then + SKIN_DIR="$skin_path" + else + echo "Skipping missing skin directory: $SKIN_DIR" + ((INDEX++)) + continue + fi + fi + + OUTPUT_DIR="${OSK_PATH:-/tmp/osk_out}/$skin_path" + mkdir -p "$OUTPUT_DIR" + + skin_header="$skin_path" + ini_file=$(find "$SKIN_DIR" -maxdepth 1 -type f -iname "skin.ini" -print -quit || true) + if [ -f "$ini_file" ]; then + name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n1 || true) + if [ -n "$name_line" ]; then + val="${name_line#*:}" + val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" + if [ -n "$val" ]; then + sanitized="$(sanitize_filename "$val")" + [ -n "$sanitized" ] && skin_header="$sanitized" + fi + fi + fi + + echo "" + echo "[$INDEX/$SKIN_COUNT] Processing skin: $skin_header" + + # normalize timestamps to make builds deterministic + (cd "$SKIN_DIR" && find . -type f -print0 | xargs -0 -I '{}' touch -d "$FIXED_TIMESTAMP" '{}') || true + + # Create a sorted file list to feed to zip (filenames may contain spaces/parentheses) + filelist_tmp="/tmp/osk_files_$RANDOM.txt" + (cd "$SKIN_DIR" && find . -type f -print0 | while IFS= read -r -d '' f; do printf '%s\n' "$f"; done | sort) > "$filelist_tmp" + + # Use zip reading names from file (-@) - convert to newline separated safe list + # zip reads stdin; we provide list via input redirection + (cd "$SKIN_DIR" && cat "$filelist_tmp" | zip -q -X -@ "$OUTPUT_DIR/${skin_header}.osk") + rm -f "$filelist_tmp" + + echo " ✓ OSK file created at $OUTPUT_DIR/${skin_header}.osk" + INDEX=$((INDEX + 1)) + done + + echo "" + echo "[OSK Creation Job Finished — processed $SKIN_COUNT skins]"