name: "Publish" on: push: branches: ["main"] paths: - 'modpacks/**/manifest.json' - 'datapacks/**/manifest.json' workflow_dispatch: jobs: detect: runs-on: technocality outputs: manifests: ${{ steps.find.outputs.manifests }} has_manifests: ${{ steps.find.outputs.has_manifests }} steps: - name: Checkout uses: actions/checkout@v5 with: fetch-depth: 2 filter: blob:none sparse-checkout: | modpacks datapacks - name: Find changed manifests id: find run: | set -eu MANIFESTS=$(git diff-tree --no-commit-id --name-only -r HEAD \ | grep -E '^(modpacks|datapacks)/.*/manifest\.json$' || true) if [ -z "$MANIFESTS" ]; then echo "has_manifests=false" >> "$GITHUB_OUTPUT" echo "manifests=[]" >> "$GITHUB_OUTPUT" echo "no changed manifests." exit 0 fi JSON="[" first=1 while IFS= read -r line; do [ -z "$line" ] && continue if [ "$first" -eq 1 ]; then first=0 else JSON="${JSON}," fi JSON="${JSON}\"${line}\"" done <<< "$MANIFESTS" JSON="${JSON}]" echo "has_manifests=true" >> "$GITHUB_OUTPUT" echo "manifests=${JSON}" >> "$GITHUB_OUTPUT" echo "manifests to publish: ${JSON}" publish: needs: detect if: always() runs-on: technocality strategy: fail-fast: false matrix: manifest: ${{ fromJson(needs.detect.outputs.manifests) }} steps: - name: Checkout uses: actions/checkout@v5 with: fetch-depth: 0 filter: blob:none sparse-checkout: | modpacks datapacks src/actions/publish src/actions/builder tools/changelog tools/manifest - name: Set up Node uses: actions/setup-node@v4 with: node-version: '20' - name: Validate Manifest run: npx tsx tools/manifest/validate.ts "${{ matrix.manifest }}" - name: Cache Publisher Binary id: cache-publisher uses: actions/cache@v4 with: path: ./publisher-bin key: publisher-v2-${{ runner.os }}-${{ hashFiles('src/actions/publish/**/*.rs', 'src/actions/publish/Cargo.toml', 'src/actions/publish/Cargo.lock') }} - name: Cache Minify-JSON Binary id: cache-minify uses: actions/cache@v4 with: path: ./builder-bin key: builder-v2-${{ runner.os }}-${{ hashFiles('src/actions/builder/**/*.rs', 'src/actions/builder/Cargo.toml', 'src/actions/builder/Cargo.lock') }} - name: Install Rust if: steps.cache-publisher.outputs.cache-hit != 'true' || steps.cache-minify.outputs.cache-hit != 'true' uses: https://github.com/dtolnay/rust-toolchain@stable - name: Rust Cache (publish) if: steps.cache-publisher.outputs.cache-hit != 'true' uses: https://github.com/Swatinem/rust-cache@v2 with: workspaces: "src/actions/publish -> target" - name: Rust Cache (builder) if: steps.cache-minify.outputs.cache-hit != 'true' uses: https://github.com/Swatinem/rust-cache@v2 with: workspaces: "src/actions/builder -> target" - name: Build Publisher if: steps.cache-publisher.outputs.cache-hit != 'true' run: | cargo build --release --manifest-path src/actions/publish/Cargo.toml --bin publish mkdir -p ./publisher-bin cp src/actions/publish/target/release/publish ./publisher-bin/publish - name: Build minify-json if: steps.cache-minify.outputs.cache-hit != 'true' run: | cargo build --release --manifest-path src/actions/builder/Cargo.toml --bin minify-json mkdir -p ./builder-bin cp src/actions/builder/target/release/minify-json ./builder-bin/minify-json - name: Generate Changelog id: changelog run: npx tsx tools/changelog/generate-changelog.ts "${{ matrix.manifest }}" - name: Cache Packwiz Binaries id: cache-go uses: actions/cache@v4 with: path: ~/go/bin key: go-bin-packwiz-v1-${{ runner.os }} - name: Setup Go if: steps.cache-go.outputs.cache-hit != 'true' uses: https://github.com/actions/setup-go@v5 with: go-version: 'stable' cache: true - name: Install Packwiz if: steps.cache-go.outputs.cache-hit != 'true' run: go install github.com/packwiz/packwiz@latest - name: Add Go bin to PATH run: echo "$HOME/go/bin" >> $GITHUB_PATH - name: Cache Packwiz Downloads uses: actions/cache@v4 with: path: ~/.cache/packwiz key: packwiz-cache-${{ runner.os }}-${{ github.run_id }} restore-keys: | packwiz-cache-${{ runner.os }}- - name: Minify JSON configs run: | set -eu chmod +x ./builder-bin/minify-json MANIFEST='${{ matrix.manifest }}' PACK_DIR="$(dirname "$MANIFEST")" if [[ "$MANIFEST" == datapacks/* ]]; then TARGET="${PACK_DIR}/content" if [ -d "$TARGET" ]; then cp -r "$TARGET" "${TARGET}.original" ./builder-bin/minify-json "$TARGET" fi elif [[ "$MANIFEST" == modpacks/* ]]; then for subdir in "$PACK_DIR"/*-mr "$PACK_DIR"/*-cf; do [ -d "$subdir" ] || continue CONFIG_DIR="$subdir/config" if [ -d "$CONFIG_DIR" ]; then cp -r "$CONFIG_DIR" "${CONFIG_DIR}.original" ./builder-bin/minify-json "$CONFIG_DIR" fi done fi - name: Run Publisher id: meta run: | chmod +x ./publisher-bin/publish ./publisher-bin/publish "${{ matrix.manifest }}" - name: Restore JSON sources if: always() run: | set -eu MANIFEST='${{ matrix.manifest }}' PACK_DIR="$(dirname "$MANIFEST")" if [[ "$MANIFEST" == datapacks/* ]]; then TARGET="${PACK_DIR}/content" if [ -d "${TARGET}.original" ]; then rm -rf "$TARGET" mv "${TARGET}.original" "$TARGET" fi elif [[ "$MANIFEST" == modpacks/* ]]; then for subdir in "$PACK_DIR"/*-mr "$PACK_DIR"/*-cf; do [ -d "$subdir" ] || continue CONFIG_DIR="$subdir/config" if [ -d "${CONFIG_DIR}.original" ]; then rm -rf "$CONFIG_DIR" mv "${CONFIG_DIR}.original" "$CONFIG_DIR" fi done fi - name: Upload to Modrinth if: steps.meta.outputs.mr_id != '' uses: https://github.com/Kir-Antipov/mc-publish@v3.3 with: modrinth-id: ${{ steps.meta.outputs.mr_id }} modrinth-token: ${{ secrets.MR }} files: "${{ github.workspace }}/${{ steps.meta.outputs.path }}/artifacts/*.mrpack" name: "${{ steps.meta.outputs.name }}" version: "${{ steps.meta.outputs.ver }}" version-type: ${{ steps.meta.outputs.release_type }} changelog: "${{ steps.changelog.outputs.notes }}" loaders: ${{ steps.meta.outputs.type == 'modpack' && steps.meta.outputs.loader || 'minecraft' }} game-versions: "${{ steps.meta.outputs.mc }}" - name: Upload to CurseForge if: steps.meta.outputs.cf_id != '' uses: https://github.com/Kir-Antipov/mc-publish@v3.3 with: curseforge-id: ${{ steps.meta.outputs.cf_id }} curseforge-token: ${{ secrets.CF }} files: "${{ github.workspace }}/${{ steps.meta.outputs.path }}/artifacts/*.zip" name: "${{ steps.meta.outputs.name }}" version: "${{ steps.meta.outputs.ver }}" version-type: ${{ steps.meta.outputs.release_type }} changelog: "${{ steps.changelog.outputs.notes }}" loaders: ${{ steps.meta.outputs.type == 'modpack' && steps.meta.outputs.loader || 'minecraft' }} game-versions: "${{ steps.meta.outputs.mc }}"