diff --git a/.github/scripts/update-version.sh b/.github/scripts/update-version.sh new file mode 100755 index 0000000..6ab1b17 --- /dev/null +++ b/.github/scripts/update-version.sh @@ -0,0 +1,10 @@ +if [ ! -z $(git diff --name-only HEAD HEAD~1 | grep build.gradle) ]; then + new_version="$(git log -n1 --format=format:"%H")" + sed --in-place "s!^//version:.*!//version: $new_version!g" build.gradle + git add build.gradle + git commit -m "[ci skip] update build script version to $new_version" + git push + echo "Updated buildscript version to $new_version"; +else + echo "Ignored buildscript version update: no changes detected" +fi diff --git a/.github/workflows/buildscript-maintenance.yml b/.github/workflows/buildscript-maintenance.yml new file mode 100644 index 0000000..f5128e3 --- /dev/null +++ b/.github/workflows/buildscript-maintenance.yml @@ -0,0 +1,24 @@ +# This workflow only meant for the source mod you shouldn't bring it into your own project + +name: Buildscript maintenance + +on: + push: + branches: [ master, main ] + +jobs: + buildscript-maintenance: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 2 + + - name: setup git config + run: | + git config user.name "GitHub CI Bot" + git config user.email "<>" + + - name: Ensure build script version is up to date + run: .github/scripts/update-version.sh diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml new file mode 100644 index 0000000..c720cfa --- /dev/null +++ b/.github/workflows/package-release.yml @@ -0,0 +1,71 @@ +# This workflow only meant for the source mod you shouldn't bring it into your own project + +name: Release packages + +on: + push: + branches: [ master, main ] + +jobs: + zip-packages: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Zip starter + uses: montudor/action-zip@v1 + with: + args: > + zip -r starter.zip . \ + \ + -x "*.git/*" \ + \ + -x ".github/scripts/update-version.sh" \ + -x ".github/workflows/buildscript-maintenance.yml" \ + -x ".github/workflows/package-release.yml" \ + \ + -x "*docs/*" \ + -x "README.md" \ + -x "LICENSE" \ + \ + -x "starter.zip" \ + -x "migration.zip" + + - name: Publish starter package + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "latest-starer" + prerelease: true + title: "Latest starter package" + files: "starter.zip" + + - name: Zip migration + uses: montudor/action-zip@v1 + with: + args: > + zip -r migration.zip . \ + \ + -x "*.git/*" \ + \ + -x ".github/scripts/update-version.sh" \ + -x ".github/workflows/buildscript-maintenance.yml" \ + -x ".github/workflows/package-release.yml" \ + \ + -x "*docs/*" \ + -x "*src/*" \ + -x "LICENSE" \ + -x "README.md" \ + \ + -x "starter.zip" \ + -x "migration.zip" + + - name: Publish migration package + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "latest-migration" + prerelease: true + title: "Latest migration package" + files: "migration.zip" diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..f4e30c1 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,32 @@ +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Build pull request + +on: + pull_request: + branches: [ master, main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Setup the workspace + run: ./gradlew setupCIWorkspace + + - name: Build the mod + run: ./gradlew build diff --git a/.github/workflows/gradle.yml b/.github/workflows/release.yml similarity index 93% rename from .github/workflows/gradle.yml rename to .github/workflows/release.yml index 7533889..6a64794 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,11 @@ # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle -name: Java CI with Gradle +name: Build and release main branch on: push: branches: [ master, main ] - pull_request: - branches: [ master, main ] jobs: build: diff --git a/LICENSE-template b/LICENSE-template new file mode 100644 index 0000000..242da62 --- /dev/null +++ b/LICENSE-template @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index f4d540a..2af11e0 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,13 @@ We all have been there! Check out our [FAQ](https://github.com/SinTh0r4s/Example ### Getting started Creating mod from scratch: -1. Fork this repository (you can keep the fork to simplify merging any build script updates in the future) -2. Clone repository -3. Replace placeholders (edit values in gradle.properties, change example package and class names, etc.) -4. Run `./gradlew setupDecompWorkspace` (if build fails with `Could not find :forgeBin:1.7.10-10.13.4.1614-1.7.10.` this should fix it) -5. Make sure to checkout the rest sections of this file. -6. You are good to go! +1. Unzip [project starter](https://github.com/SinTh0r4s/ExampleMod1.7.10/releases/download/latest-starer/starter.zip) into project directory. +2. Replace placeholders in LICENSE-template and rename it to LICENSE, or remove LICENSE-template and put any other license you like on your code. This is an permissive OSS project and we encourage you participate in OSS movement by having permissive license like one in template. You can find out pros and cons of OSS software in [this article](https://www.freecodecamp.org/news/what-is-great-about-developing-open-source-and-what-is-not/) +3. Ensure your project is under VCS. For example initialise git repository by running `git init; git commit --message "initialized repository"`. +4. Replace placeholders (edit values in gradle.properties, change example package and class names, etc.) +5. Run `./gradlew setupDecompWorkspace` (if build fails with `Could not find :forgeBin:1.7.10-10.13.4.1614-1.7.10.` this should fix it) +6. Make sure to check out the rest sections of this file. +7. You are good to go! We also have described guidelines for existing mod [migration](docs/migration.md) and [porting](docs/porting.md) diff --git a/build.gradle b/build.gradle index 09490ee..03a2929 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,4 @@ +//version: 04059a9fcbe502f677c7e2e757f97699da5f049f /* DO NOT CHANGE THIS FILE! @@ -7,6 +8,7 @@ Please check https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradl import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation + import java.util.concurrent.TimeUnit buildscript { @@ -25,7 +27,7 @@ buildscript { } } dependencies { - classpath 'com.github.GTNH2:ForgeGradle:FG_1.2-SNAPSHOT' + classpath 'com.github.TheElan:ForgeGradle:8816f1d388' } } @@ -46,37 +48,33 @@ idea { } } +checkPropertyExists("modName") +checkPropertyExists("modId") +checkPropertyExists("modGroup") +checkPropertyExists("autoUpdateBuildScript") +checkPropertyExists("minecraftVersion") +checkPropertyExists("forgeVersion") +checkPropertyExists("replaceGradleTokenInFile") +checkPropertyExists("gradleTokenModId") +checkPropertyExists("gradleTokenModName") +checkPropertyExists("gradleTokenVersion") +checkPropertyExists("gradleTokenGroupName") +checkPropertyExists("apiPackage") +checkPropertyExists("accessTransformersFile") +checkPropertyExists("usesMixins") +checkPropertyExists("mixinPlugin") +checkPropertyExists("mixinsPackage") +checkPropertyExists("coreModClass") +checkPropertyExists("containsMixinsAndOrCoreModOnly") +checkPropertyExists("usesShadowedDependencies") +checkPropertyExists("developmentEnvironmentUserName") -if(JavaVersion.current() != JavaVersion.VERSION_1_8) { - throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current()) -} - -def checkPropertyExsists(String propertyName) { +def checkPropertyExists(String propertyName) { if (project.hasProperty(propertyName) == false) { throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties") } } -checkPropertyExsists("modName") -checkPropertyExsists("modId") -checkPropertyExsists("modGroup") -checkPropertyExsists("minecraftVersion") -checkPropertyExsists("forgeVersion") -checkPropertyExsists("replaceGradleTokenInFile") -checkPropertyExsists("gradleTokenModId") -checkPropertyExsists("gradleTokenModName") -checkPropertyExsists("gradleTokenVersion") -checkPropertyExsists("gradleTokenGroupName") -checkPropertyExsists("apiPackage") -checkPropertyExsists("accessTransformersFile") -checkPropertyExsists("usesMixins") -checkPropertyExsists("mixinPlugin") -checkPropertyExsists("mixinsPackage") -checkPropertyExsists("coreModClass") -checkPropertyExsists("containsMixinsAndOrCoreModOnly") -checkPropertyExsists("usesShadowedDependencies") -checkPropertyExsists("developmentEnvironmentUserName") - String targetPackage = "src/main/java/" + modGroup.toString().replaceAll("\\.", "/") if(new File(targetPackage).exists() == false) { throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackage) @@ -441,7 +439,6 @@ task apiJar(type: Jar) { getArchiveClassifier().set('api') } - artifacts { archives sourcesJar archives devJar @@ -449,3 +446,59 @@ artifacts { archives apiJar } } + +// Updating +task updateBuildScript { + doLast { + if (updateBuildScript()) return + + print("Build script already up-to-date!") + } +} + +if (isNewBuildScriptVersionAvailable()) { + if (autoUpdateBuildScript.toBoolean()) { + updateBuildScript() + } else { + println("Build script update available! Run 'gradle updateBuildScript'") + } +} + +static URL availableBuildScriptUrl() { + new URL("https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle") +} + +static boolean updateBuildScript() { + if (isNewBuildScriptVersionAvailable()) { + def buildscriptFile = new File("build.gradle") + availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } + print("Build script updated. Please REIMPORT the project or RESTART your IDE!") + return true + } + return false +} + +static boolean isNewBuildScriptVersionAvailable() { + Map parameters = ["connectTimeout": 2000, "readTimeout": 2000] + + String currentBuildScript = new File("build.gradle").getText() + String currentBuildScriptHash = getVersionHash(currentBuildScript) + String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText() + String availableBuildScriptHash = getVersionHash(availableBuildScript) + + boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash + return !isUpToDate +} + +static String getVersionHash(String buildScriptContent) { + String versionLine = buildScriptContent.find("^//version: [a-z0-9]*") + if(versionLine != null) { + return versionLine.split(": ").last() + } + return "" +} + +configure(updateBuildScript) { + group = 'forgegradle' + description = 'Updates the build script to the latest version' +} diff --git a/docs/migration.md b/docs/migration.md index 4b92331..b01d544 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -5,15 +5,10 @@ Migration for the typical mod which doesn't use anything special but Minecraft f For core plugin, Mixins, shadowing, access transformers, ASM or etc. you'll need to do some extra steps. If they are missing in this document - we will gladly receive your suggestions/contribution. -1. Copy and replace all files from template to your repository, but: - 1. `build.gradle` - 2. `src` - 3. `LICENSE` - 4. `README.md` - 5. `build.gradle(.kts)` +1. Copy and replace all files from [template](https://github.com/SinTh0r4s/ExampleMod1.7.10/releases/download/latest-migration/migration.zip) to your repository, but `build.gradle` 2. Copy all repositories from your `build.gradle(.kts)` to `repositories.gradle` 3. Copy all dependencies from your `build.gradle(.kts)` to `dependecies.gradle` -4. replace your `build.gradle(.kts)` with `build.gradle` from template. In case you have written some custom tasks/configurations not present in the template - you'll best to move them to separate file and link it in this, like for example it does this with `dependencies.gradle` +4. replace your `build.gradle(.kts)` with `build.gradle` from template. In case you have written some custom tasks/configurations not present in the template - move them into `addon.gradle`. It will automatically be integrated if present. 5. Adapt `gradle.properties` to your mod 6. Ensure `src/main/resources/mcmod.info` contains `${modId}`, `${modName}`. `${modVersion}` and `${minecraftVersion}` 7. Re-import the project to your IDE (e.g. restart with clean caches in IntelliJ IDEA) diff --git a/gradle.properties b/gradle.properties index dd65ba2..ad54993 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,9 @@ modGroup = com.myname.mymodid # The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the # code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/ +# Will update your build.gradle automatically whenever an update is available +autoUpdateBuildScript = false + minecraftVersion = 1.7.10 forgeVersion = 10.13.4.1614 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5028f28..3ab0b72 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists