AgentStack
SKILL verified MIT Self-run

Minecraft Ci Release

skill-jahrome907-minecraft-agent-skills-minecraft-ci-release · by Jahrome907

Set up CI/CD pipelines, automated publishing, and release workflows for Minecraft mods and plugins for 1.21.x. Covers GitHub Actions matrix builds for NeoForge and Fabric, automated publishing to Modrinth (via minotaur Gradle plugin) and CurseForge (via curseforgegradle), GitHub Releases with JAR artifacts, semantic versioning conventions for Minecraft mods, CHANGELOG generation, Dependabot for G…

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-jahrome907-minecraft-agent-skills-minecraft-ci-release

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Minecraft Ci Release? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Minecraft CI / Release Skill

Workflow Overview

PR opened → build + test checks
main branch push → build artifacts
Tag push (v*) → build + publish to Modrinth + CurseForge + GitHub Releases

Routing Boundaries

  • Use when: the task is CI/CD pipelines, release automation, artifact publishing, versioning, or release governance.
  • Do not use when: the task is implementing gameplay/plugin/mod features (minecraft-modding, minecraft-plugin-dev, minecraft-datapack).
  • Do not use when: the task is server runtime operations and infrastructure tuning (minecraft-server-admin).

Versioning Convention

Minecraft mod versions follow: {mod_version}+{mc_version}

1.0.0+1.21.11  ← mod 1.0.0 for MC 1.21.11
1.2.3+1.21.11
2.0.0+1.21.11

Git tag format: v1.0.0 (mod version only, not MC version in the tag).


Core CI Workflow (NeoForge + Fabric)

.github/workflows/build.yml

name: Build

on:
  push:
    branches: ["main", "develop"]
  pull_request:
    branches: ["main"]

permissions:
  contents: read

jobs:
  build:
    name: Build (${{ matrix.platform }})
    runs-on: ubuntu-latest
    strategy:
      matrix:
        platform: [neoforge, fabric]
      fail-fast: false

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Java 21
        uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/main' }}

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build (${{ matrix.platform }})
        run: ./gradlew :${{ matrix.platform }}:build --no-daemon

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: mod-${{ matrix.platform }}-${{ github.sha }}
          path: ${{ matrix.platform }}/build/libs/*.jar
          if-no-files-found: error

Release Workflow (with Publishing)

.github/workflows/release.yml

name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write      # for creating GitHub releases

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Java 21
        uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Extract version from tag
        id: version
        run: echo "MOD_VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT

      - name: Build all platforms
        run: ./gradlew build --no-daemon

      - name: Publish to Modrinth & CurseForge
        run: ./gradlew publishMods --no-daemon
        env:
          MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
          CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          files: |
            fabric/build/libs/*.jar
            neoforge/build/libs/*.jar
          generate_release_notes: true
          draft: false
          prerelease: ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }}

Paper Plugin CI

.github/workflows/build.yml (plugin)

name: Build

on:
  push:
    branches: ["main"]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"
      - uses: gradle/actions/setup-gradle@v4
      - run: chmod +x gradlew
      - run: ./gradlew shadowJar --no-daemon
      - uses: actions/upload-artifact@v4
        with:
          name: plugin-${{ github.sha }}
          path: build/libs/*.jar

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew test --no-daemon

Modrinth Publishing (minotaur)

build.gradle.kts (root or platform-specific)

plugins {
    id("com.modrinth.minotaur") version "2.8.7"
}

// === Fabric subproject ===
modrinth {
    token.set(System.getenv("MODRINTH_TOKEN") ?: "")
    projectId.set("YOUR-PROJECT-ID")    // from modrinth.com project slug or ID

    versionNumber.set("${project.version}")
    versionType.set("release")          // release | beta | alpha

    uploadFile.set(tasks.remapJar)      // the JAR to upload

    gameVersions.addAll("1.21.11")
    loaders.addAll("fabric")

    changelog.set(
        rootProject.file("CHANGELOG.md").readText()
            .substringAfter("## [${project.version}]")
            .substringBefore("\n## [")
            .trim()
    )

    dependencies {
        required.project("fabric-api")
        // optional.project("some-optional-mod")
    }
}

Combined Fabric + NeoForge publish task (root-level)

// root build.gradle.kts
tasks.register("publishMods") {
    dependsOn(":fabric:modrinth", ":neoforge:modrinth")
    dependsOn(":fabric:curseforge", ":neoforge:curseforge")
    group = "publishing"
    description = "Publish all platforms to Modrinth and CurseForge"
}

CurseForge Publishing

build.gradle.kts

plugins {
    id("net.darkhax.curseforgegradle") version "1.1.25"
}

tasks.register("curseforge") {
    apiToken = System.getenv("CURSEFORGE_TOKEN") ?: ""

    val cf = upload(PROJECT_ID, tasks.named("remapJar"))  // or shadowJar
    cf.changelogType = "markdown"
    cf.changelog = rootProject.file("CHANGELOG.md").readText()
        .substringAfter("## [${project.version}]")
        .substringBefore("\n## [")
        .trim()

    cf.releaseType = "release"
    cf.addGameVersion("1.21.11")
    cf.addModLoader("Fabric")     // "NeoForge" for NeoForge subproject
    cf.addRequirement("fabric-api")
    // cf.addJavaVersion("Java 21")

    // Replace PROJECT_ID with your numeric CurseForge project ID
}

> Replace PROJECT_ID with your actual numeric CurseForge project ID (found in project settings).


gradle.properties Secrets Pattern

Never hardcode tokens. Read them from environment:

# gradle.properties (committed)
mod_id=mymod
mod_version=1.0.0
minecraft_version=1.21.11
modrinth_project_id=AABBCCDD
curseforge_project_id=123456

# DO NOT commit tokens
# Set these as GitHub repo secrets:
# MODRINTH_TOKEN, CURSEFORGE_TOKEN

Semantic Versioning for Mods

| Change | Version bump | |--------|-------------| | New features, no breaking changes | Minor: 1.1.0 | | Bug fixes only | Patch: 1.0.1 | | API/config breaking changes | Major: 2.0.0 | | Minecraft version update | Keep mod version, change +1.21.11 suffix | | Pre-release | 1.0.0-beta.1, 1.0.0-rc.1 |


CHANGELOG.md Convention

# Changelog

## [1.1.0] — 2025-06-01
### Added
- New `/kit` command
- PDC-based kill tracker

### Fixed
- Death message not appearing on Paper 1.21.11

## [1.0.0] — 2025-05-01
### Added
- Initial release

Automate CHANGELOG parsing in Gradle (as shown above in modrinth block) by extracting the section between version headers.


Dependabot Configuration

.github/dependabot.yml

version: 2
updates:
  - package-ecosystem: "gradle"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      gradle-plugins:
        patterns:
          - "com.gradleup.shadow"
          - "dev.architectury.loom"
          - "com.modrinth.minotaur"
          - "net.darkhax.curseforgegradle"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

Build Caching Best Practices

# In all workflow jobs:
- name: Setup Gradle
  uses: gradle/actions/setup-gradle@v4
  with:
    # Read-only cache on PRs, read-write on main
    cache-read-only: ${{ github.event_name == 'pull_request' }}
    # Cache Minecraft assets (speeds up loom tasks by minutes)
    gradle-home-cache-includes: |
      caches
      notifications
      .gradle/loom-cache

Branch Protection + Required Checks

Recommended GitHub branch protection for main:

  • Require status checks: build (fabric), build (neoforge), test
  • Require linear history (squash/rebase merges)
  • Require signed commits (optional but recommended for release workflows)

Tag and Release Script

#!/usr/bin/env bash
# scripts/release.sh 
# Usage: ./scripts/release.sh 1.1.0
set -euo pipefail

VERSION="${1:?Usage: release.sh }"

# Update gradle.properties
sed -i "s/^mod_version=.*/mod_version=${VERSION}/" gradle.properties

# Stage and commit
git add gradle.properties
git commit -m "chore: release v${VERSION}"

# Tag
git tag "v${VERSION}"

echo "Created commit and tag v${VERSION}"
echo "Push with: git push && git push --tags"

Workflow Snippet Validator

Use the bundled validator script to keep SKILL.md workflow snippets copy-paste safe:

# Run from the installed skill directory:
./scripts/validate-workflow-snippets.sh --root .

# Strict mode treats warnings as failures:
./scripts/validate-workflow-snippets.sh --root . --strict

The validator is bundled and self-contained. Run it from a copied .agents/, .codex/, or .claude/ minecraft-ci-release skill directory without relying on repo-root node_modules.

What it checks:

  • YAML snippet structure for workflow-like blocks (name, on, jobs)
  • Unresolved placeholder tokens and suspicious glob patterns
  • ${{ secrets.* }} usage stays consistent with secrets documented in this file

References

  • GitHub Actions: https://docs.github.com/en/actions
  • minotaur (Modrinth): https://github.com/modrinth/minotaur
  • curseforgegradle: https://github.com/Darkhax-Minecraft/CurseForgeGradle
  • softprops/action-gh-release: https://github.com/softprops/action-gh-release
  • gradle/actions: https://github.com/gradle/actions
  • Modrinth API docs: https://docs.modrinth.com/

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.