name: Validate Minecraft Packs description: Validate and build datapack/resourcepack inputs: pack_zip: description: Datapack zip output path required: true pack_type: description: Pack type - auto, datapack, resourcepack, or both required: false default: "auto" run_build: description: Run build.sh before validation required: false default: "true" run_mecha: description: Run Mecha datapack validation required: false default: "true" minecraft_version: description: Minecraft version for mecha required: false default: "26.1" mecha_stats: description: Output mecha stat required: false default: "false" mecha_log: description: Mecha log level required: false default: "" runs: using: composite steps: - name: Build packs if: ${{ inputs.run_build == 'true' }} shell: bash run: | sh build.sh - name: Check JSON files shell: bash run: | python - <<'PY' import json from pathlib import Path failed = False for path in Path(".").rglob("*.json"): if ".git" in path.parts: continue if ".pack-check" in path.parts: continue if "node_modules" in path.parts: continue try: json.loads(path.read_text(encoding="utf-8")) except Exception as e: print(f"Invalid JSON: {path}") print(e) failed = True if failed: raise SystemExit(1) print("All JSON files are valid") PY - name: Check pack.mcmeta files shell: bash run: | python - <<'PY' import json from pathlib import Path failed = False found = False for path in Path(".").rglob("pack.mcmeta"): if ".git" in path.parts: continue if ".pack-check" in path.parts: continue found = True try: data = json.loads(path.read_text(encoding="utf-8")) pack = data.get("pack", {}) if "pack_format" not in pack: raise ValueError("Missing pack.pack_format") if "description" not in pack: raise ValueError("Missing pack.description") if not isinstance(pack["pack_format"], int): raise ValueError("pack.pack_format must be an integer") print(f"OK: {path}") except Exception as e: print(f"Invalid pack.mcmeta: {path}") print(e) failed = True if not found: print("No pack.mcmeta files found") failed = True if failed: raise SystemExit(1) PY - name: Validate zip files shell: bash run: | test -f "${{ inputs.pack_zip }}" unzip -t "${{ inputs.pack_zip }}" - name: Validate pack structure shell: bash env: PACK_TYPE: ${{ inputs.pack_type }} run: | set -euo pipefail rm -rf .pack-check mkdir -p .pack-check unzip -q "${{ inputs.pack_zip }}" -d .pack-check test -f .pack-check/pack.mcmeta has_data="false" has_assets="false" if [ -d .pack-check/data ]; then has_data="true" fi if [ -d .pack-check/assets ]; then has_assets="true" fi detected_type="" if [ "$has_data" = "true" ] && [ "$has_assets" = "true" ]; then detected_type="both" elif [ "$has_data" = "true" ]; then detected_type="datapack" elif [ "$has_assets" = "true" ]; then detected_type="resourcepack" else echo "Pack must contain data/ or assets/" exit 1 fi if [ "$PACK_TYPE" = "auto" ]; then PACK_TYPE="$detected_type" fi case "$PACK_TYPE" in datapack) test "$has_data" = "true" ;; resourcepack) test "$has_assets" = "true" ;; both) test "$has_data" = "true" test "$has_assets" = "true" ;; *) echo "Unknown pack_type: $PACK_TYPE" echo "Expected: auto, datapack, resourcepack, or both" exit 1 ;; esac echo "Detected pack type: $detected_type" echo "Validated pack type: $PACK_TYPE" echo "$PACK_TYPE" > .pack-check/type if [ -n "${GITHUB_ENV:-}" ]; then echo "PACK_TYPE=$PACK_TYPE" >> "$GITHUB_ENV" echo "DETECTED_PACK_TYPE=$detected_type" >> "$GITHUB_ENV" fi if [ -n "${GITEA_ENV:-}" ]; then echo "PACK_TYPE=$PACK_TYPE" >> "$GITEA_ENV" echo "DETECTED_PACK_TYPE=$detected_type" >> "$GITEA_ENV" fi - name: Install Mecha if: ${{ inputs.run_mecha == 'true' }} shell: bash run: | set -euo pipefail if [ "${PACK_TYPE:-}" = "resourcepack" ]; then echo "Resourcepack detected, skipping Mecha install" exit 0 fi uv tool install mecha || uv tool upgrade mecha mecha --version - name: Run Mecha on built datapack if: ${{ inputs.run_mecha == 'true' }} shell: bash env: MINECRAFT_VERSION: ${{ inputs.minecraft_version }} MECHA_STATS: ${{ inputs.mecha_stats }} MECHA_LOG: ${{ inputs.mecha_log }} run: | set -euo pipefail if [ "${PACK_TYPE:-}" = "resourcepack" ]; then echo "Resourcepack detected, skipping Mecha" exit 0 fi if [ ! -d .pack-check/data ]; then echo "No data/ directory found, skipping Mecha" exit 0 fi mecha_args=() if [ -n "${MECHA_LOG:-}" ]; then mecha_args+=("-l" "$MECHA_LOG") fi if [ -n "${MINECRAFT_VERSION:-}" ]; then mecha_args+=("-m" "$MINECRAFT_VERSION") fi if [ "${MECHA_STATS:-false}" = "true" ]; then mecha_args+=("-s") fi mecha "${mecha_args[@]}" .pack-check