User Tools

Site Tools


tutorial:publishing_mods_using_github_actions

Publishing mods on CurseForge, Modrinth & GitHub with MC-Publish

MC-Publish is a GitHub Action by Kir-Antipov that communicates with GitHub, CurseForge and Modrinth APIs to upload your mod files. This page only goes through the basics of the set-up and you should check out its Github documentation for further information.

What are GitHub Actions?

Github Actions are essentially commands that get executed on GitHub servers. They are free to use as long as your GitHub repository is public and come with a limit, that should not hinder you, if it isn't. In Software Development Github Actions and similar workflow automation systems are standard place and help tremendously with making deployments (such as releasing a new version of your mod) as seamless as possible.

If you dread the manual process of uploading your mod to multiple platforms, this is the solution.

Before we start

You should have already done the following:

  1. create a repository of your mod on GitHub
  2. upload a version of your mod to CurseForge and Modrinth and have it approved

Setup

If we want Github to do something for us, we need to tell their servers what exactly we want. To do that we need to add a .yml file in /.github/workflows. You can think of this .yml file as the config file of your Github Action. It does not matter how it is named, you should however pick a relevant name. YAML is generally similar to JSON in concept, but has a very different syntax. Just like Python you don't use curly braces {} and instead only use indention to declare your structure.

The general structure of your .yml file should look like this:

name: Publish on GitHub, CurseForge & Modrinth    #The name of your GitHub Action on github.com
 
on: [ pull_request, workflow_dispatch ]           #When your GitHub Action will be executed ('pull_request' -> on every Merge(/Pull) Request; 'workflow_dispatch' -> allows manual execution through github.com

env:                                              #Environment variables that can later be referenced using ${{ env.MINECRAFT_VERSION }}. These are useful for repeating information and allow for quick changes for new mod updates
  MINECRAFT_VERSION: 1.19.2                        
  JAVA_VERSION: 17                   

permissions:
  contents: write

jobs:                                             #The place where you actually tell the GitHub server what to do. 
  build:                                          #To publish your mod you only need one 'job', here it is called 'build'.
    runs-on: ubuntu-latest                        #'runs-on' specifies the operation system (linux).
    steps:                                        #Under 'steps' you will list all the individual commands, such as MC-Publish by Kir-Antipov.
      ...

I recommend to keep on: [ pull_request, workflow_dispatch ] and adapt your usage of git branches accordingly. This means developing every update on its own branch and only merging into main when its ready to be released. If this absolutely does not fit your needs you can check for different triggers or just use workflow_dispatch. Remember that you dont want to accidently start your GitHub Action while setting up.

Basic environments variables should include:

  • Minecraft version
  • Java version
  • Your mod version
  • Your mod release name
  • publishing tokens (will come later)

Publishing steps

The arguably most important part of your .yml file!

First we will look at the syntax of a step, prepare all prerequisite steps and then finally go over MC-Publish.

Syntax

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Example step
        if: ${{ condition is met }}
        uses: actions/common-action
        with: 
          variable1: Some Value
          variable2: Another Value
        run: ls -a
        
      - name: Another Example step
 
        ...
  • name The name of the step, should accurrately describe the step.
  • if A condition that needs to return true in order for the step to execute.
  • uses Here you can specify additional GitHub Actions. You could program everything yourself, but where is the point in that if someone already did that for you? MC-Publish by Kir-Antipov is an example of that.
  • with If you specified a GitHub Action with uses you can input predefined variables with your own values.
  • run Execute a command on the command line.

Prerequisite steps

The following steps mirror the steps you needed to take before you could develop mods on your pc, just imagine you are a simple linux server and suddenly someone wants you to upload their minecraft mod. You wouldn't even know what Java is.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check Environment Variables
        run: env

      - name: Checkout Repository
        uses: actions/checkout@v3
        with:
          submodules: true

      - name: Setup Java
        uses: actions/setup-java@v2
        with:
          distribution: "temurin"
          java-version: 17

      - name: Make Gradle Wrapper Executable
        if: ${{ runner.os != 'Windows' }}
        run: chmod +x ./gradlew

      - name: Build
        run: ./gradlew clean build
 
        ...

While the steps above are necessary you dont need to understand them fully. If you are interested and want to fully understand them I recommend taking a beginner linux course.

During execution the 'Build' step will take by far the longest (~3min.), so dont worry if something goes wrong it will tell you.

MC-Publish

This section will by its nature not be complete, to get a full overview you can check the official GitHub Documentation of MC-Publish.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      ...
      
      - name: Publish (CurseForge/Modrinth/GitHub)
        uses: Kir-Antipov/mc-publish@v3.2                                   #The specified MC-Publish GitHub Action in the version 3.2
        with:
          curseforge-id: 123456                                             #The id of your CurseForge project
          curseforge-token: "${{env.CURSEFORGE_TOKEN}}"
          
          modrinth-id: 1q2w3e4r                                             #The id of your modrinth project
          modrinth-token: "${{env.MODRINTH_TOKEN}}"
          
          github-tag: "v${{env.VERSION}}"
          github-token: "${{env.GITHUB_TOKEN}}"

          name: "${{env.RELEASE_NAME}}"                             
          version: "${{env.VERSION}}"
          version-type: release
          changelog-file: CHANGELOG.md                                      #The file in which the changes of your new update are specified (the path starts at your project root)

          loaders: fabric
          game-versions: "${{env.MINECRAFT_VERSION}}"
          java: "${{env.JAVA_VERSION}}"

CURSEFORGE_TOKEN, MODRINTH_TOKEN or GITHUB_TOKEN are essentially passwords that are used to authenticate you as a person, that means these are specific to your account and not to your mod. This makes sure that only you can push updates through the API. When uploading normally you authenticate yourself when you log in. Where do you find these authentication tokens? It's different for every platform:

GitHub Settings > Developer Settings > Personal access tokens > Tokens (classic) ⇒ press “Generate new token” and choose classic ⇒ select the 'repo' scope (write a descriptive note, 90 days expiration is recommended, you will need to generate a new token afterwards) ⇒ press “Generate token”

Modrinth Settings ⇒ Authorization token

CurseForge Settings > My API Tokens ⇒ choose a descriptive name and press “Generate Token”

It is strongly recommended that you save the authentication tokens somewhere safe, e.g. a password manager. GitHub won't let you access your token after you have generated it!

Now that you have all the tokens you need, you have to make them accessible to your GitHub Action. Go to the settings page of your mod repository on github.com and navigate to Secrets > Actions. Add all your authentication tokens as secrets. You will need to reference the name you give them here in your .yml file. A secret named PUBLISH_CURSEFORGE_TOKEN can be referenced using

${{ secrets.PUBLISH_CURSEFORGE_TOKEN }}

Full .yml example

name: Publish on GitHub, CurseForge & Modrinth    
 
on: [ pull_request, workflow_dispatch ]           

env:                                              
  MINECRAFT_VERSION: 1.19.2                        
  JAVA_VERSION: 17      
  VERSION: 1.1.0+1.19.2  
  RELEASE_NAME: Example Mod 1.1.0 for Minecraft 1.19.2
  MODRINTH_TOKEN: ${{ secrets.PUBLISH_MODRINTH_TOKEN }}
  CURSEFORGE_TOKEN: ${{ secrets.PUBLISH_CURSEFORGE_TOKEN }}
  GITHUB_TOKEN: ${{ secrets.PUBLISH_GITHUB_TOKEN }}           

permissions:
  contents: write

jobs:                                             
  build:                                          
    runs-on: ubuntu-latest                        
    steps:                                        
      - name: Check Environment Variables
        run: env

      - name: Checkout Repository
        uses: actions/checkout@v3
        with:
          submodules: true

      - name: Setup Java
        uses: actions/setup-java@v2
        with:
          distribution: "temurin"
          java-version: 17

      - name: Make Gradle Wrapper Executable
        if: ${{ runner.os != 'Windows' }}
        run: chmod +x ./gradlew

      - name: Build
        run: ./gradlew clean build
        
      - name: Publish (CurseForge/Modrinth/GitHub)
        uses: Kir-Antipov/mc-publish@v3.2                                   
        with:
          curseforge-id: 123456                                             
          curseforge-token: "${{env.CURSEFORGE_TOKEN}}"
          
          modrinth-id: 1q2w3e4r                                             
          modrinth-token: "${{env.MODRINTH_TOKEN}}"
          
          github-tag: "v${{env.VERSION}}"
          github-token: "${{env.GITHUB_TOKEN}}"

          name: "${{env.RELEASE_NAME}}"                             
          version: "${{env.VERSION}}"
          version-type: release
          changelog-file: CHANGELOG.md                                      

          loaders: fabric
          game-versions: "${{env.MINECRAFT_VERSION}}"
          java: "${{env.JAVA_VERSION}}"

Setup Complete

To recap, here is what you should have by now:

  • Newly generated authentication tokens for every platform
  • Authentication tokens stored as secrets in your GitHub repository
  • a .yml file in /.github/workflows pushed to your github repository
  • a empty CHANGELOG.md file in your project root

If you have all these you are finished! You can now use your newly created GitHub Action to deploy updates for your mod!

Additional tips

Here is a list of useful resources that didn't fit into the general tutorial.

Update Checklist

When updating your mod you now have a few places you need to look at.

  • update the version number
    • in src/fabric.mod.json under “version”: “1.1.0+1.19.2”
    • in gradle.properties (typically) under mod_version = 1.1.0+1.19.2
    • in .github/workflows/publish.yml under VERSION: 1.1.0+1.19.2 and RELEASE_NAME: Example Mod 1.1.0 for Minecraft 1.19.2
  • update the changelog in CHANGELOG.md
  • (if you use the recommended workflow) Merge the update branch into the current default branch

Handling dependencies

Check out the official documentation. I recommend using the fabric.mod.json approach.

Errors when uploading to Modrinth

Since Modrinth updated its API some people have problems uploading through the API. If that happens to you, try separating the Modrinth portion from GitHub and CurseForge. You can do this easily by copying the MC-Publish step and trimming out the now unnecessary input in with. You should now have two separate steps.

Change the version in the step that publishes to modrinth to 2.1 → uses: Kir-Antipov/mc-publish@v2.1

tutorial/publishing_mods_using_github_actions.txt · Last modified: 2024/11/19 22:35 by kkiris