import com.google.gson.Gson import org.apache.commons.codec.Charsets import org.apache.http.HttpResponse import org.apache.http.client.HttpClient import org.apache.http.client.config.CookieSpecs import org.apache.http.client.config.RequestConfig import org.apache.http.client.methods.HttpGet import org.apache.http.client.methods.HttpPost import org.apache.http.entity.ContentType import org.apache.http.entity.mime.MultipartEntityBuilder import org.apache.http.impl.client.HttpClientBuilder buildscript { repositories { mavenCentral() } dependencies { classpath "org.apache.httpcomponents:httpmime:4.5.13" classpath "com.google.code.gson:gson:2.8.6" classpath "org.apache.httpcomponents:httpclient:4.5.13" } } apply from: 'env-variables.gradle' static String getValueFromCurseAPI(apiKey, endpoint) { String API_BASE_URL = 'https://minecraft.curseforge.com' HttpClient client = HttpClientBuilder.create() .setDefaultRequestConfig(RequestConfig.custom() .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build()).build() HttpGet get = new HttpGet(API_BASE_URL + endpoint) get.setHeader('X-Api-Token', apiKey) HttpResponse response = client.execute(get) int statusCode = response.statusLine.statusCode if (statusCode == 200) { byte[] data = response.entity.content.bytes return new String(data, Charsets.UTF_8) } else { if (response.getFirstHeader('content-type').value.contains('json')) { InputStreamReader reader = new InputStreamReader(response.entity.content) reader.close() throw new RuntimeException("[CurseForge] Error") } else { throw new RuntimeException("[CurseForge] HTTP Error Code $response.statusLine.statusCode: $response.statusLine.reasonPhrase") } } } /** * Upload a single file (in case you also want to upload the other files like source n stuff) * @param json * @param file * @return * @throws IOException * @throws URISyntaxException */ UploadResponse uploadFile(Metadata metadata, File file, String apiKey, Gson gson) throws IOException, URISyntaxException { String API_BASE_URL = 'https://minecraft.curseforge.com' String UPLOAD_URL = "/api/projects/%s/upload-file" // Upload // Important info String uploadUrl = String.format(API_BASE_URL + UPLOAD_URL, project.curse_project_id) HttpClient client = HttpClientBuilder.create() .setDefaultRequestConfig(RequestConfig.custom() .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build()).build() HttpPost post = new HttpPost(uploadUrl) post.setHeader('X-Api-Token', apiKey) // https://support.curseforge.com/en/support/solutions/articles/9000197321-curseforge-api post.setEntity(MultipartEntityBuilder.create() .addTextBody('metadata', gson.toJson(metadata), ContentType.APPLICATION_JSON) .addBinaryBody('file', file) .build()) HttpResponse response = client.execute(post) InputStreamReader reader = new InputStreamReader(response.entity.content) UploadResponse uploadResponse = gson.fromJson(reader, UploadResponse) reader.close() return uploadResponse } class GameVersion { int id int gameVersionTypeID String name String slug } /** * As described here https://support.curseforge.com/en/support/solutions/articles/9000197321-curseforge-api */ class Metadata { String changelog String changelogType int[] gameVersions String releaseType } class UploadResponse { int id } // Based on https://github.com/matthewprenger/CurseGradle as it didnt support Bukkit uploads at the time. task curseforge { dependsOn(jar) doLast { String apiKey = System.getenv("CURSE_API") if(apiKey != null) { Gson gson = new Gson() //String VERSION_TYPES_URL = "/api/game/version-types" int gameVersionTypeID = 1 String VERSION_URL = "/api/game/versions" println("Uploading to CurseForge") // Get game versions String gameVersionsString = getValueFromCurseAPI(apiKey, VERSION_URL) GameVersion[] gameVersions = gson.fromJson(gameVersionsString, GameVersion[].class) def versions = gameVersions.findAll {it.gameVersionTypeID == gameVersionTypeID} String[] supportedVersions = [ "1.21", "1.20.6", "1.20.5", "1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.19.3", "1.19.2", "1.19.1", "1.19", "1.18.2", "1.18.1", "1.18", "1.17", "1.16", "1.15", "1.14", "1.13" ] def supportedGameVersions = versions.findAll {supportedVersions.contains(it.name)} int[] supportedGameVersionIds = supportedGameVersions.collect {it.id}.toArray() println("Supported Version Id's ${supportedGameVersionIds}") Metadata uploadMetadata = new Metadata() uploadMetadata.changelog = "${project.github}/blob/${ext.githubSha}/docs/changelogs/CHANGELOG.md" uploadMetadata.changelogType = "markdown" uploadMetadata.releaseType = ext.isDevBranch ? "beta" : "release" uploadMetadata.gameVersions = supportedGameVersionIds def uploadId = uploadFile(uploadMetadata, file(jar.archiveFile), apiKey, gson) println("Uploaded with ID: ${uploadId.id}") println("Published build") } else { println("Curse token unspecified") } } // id = project.curse_project_id // // TODO add code to reference this but also cut the latest change logs in for the files // changelog = "${project.github}/blob/${sha}/CHANGELOG.md" // changelogType = 'markdown' // releaseType = 'release' }