feat: add auto script to deploy bot on mcsm
This commit is contained in:
6 files changed
+272
No files matched your search
@@ -0,0 +1,32 @@
|
|||||||
|
name: Build YeeeesMOTD
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java:
|
||||||
|
- 21
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Validate gradle wrapper
|
||||||
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
- name: Setup jdk ${{ matrix.java }}
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: Make Gradle wrapper executable
|
||||||
|
run: chmod +x ./gradlew
|
||||||
|
- name: Build
|
||||||
|
run: ./gradlew build
|
||||||
|
- name: Deploy Bot to MCSM
|
||||||
|
run: ./gradlew deployBot
|
||||||
|
env:
|
||||||
|
MCSM_API_KEY: ${{ secrets.MCSM_API_KEY }}
|
||||||
|
MCSM_API_URL: ${{ secrets.MCSM_API_URL }}
|
||||||
|
MCSM_DAEMON_ID: ${{ secrets.MCSM_DAEMON_ID }}
|
||||||
|
MCSM_INSTANCE_ID: ${{ secrets.MCSM_INSTANCE_ID }}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import buildsrc.MCSMDeploy
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -53,3 +54,11 @@ tasks.shadowJar {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register("deployBot") {
|
||||||
|
val apiKey = System.getenv("MCSM_API_KEY")
|
||||||
|
val apiUrl = System.getenv("MCSM_API_URL")
|
||||||
|
val daemonId = System.getenv("MCSM_DAEMON_ID")
|
||||||
|
val instanceId = System.getenv("MCSM_INSTANCE_ID")
|
||||||
|
MCSMDeploy(apiUrl, apiKey, daemonId, instanceId).deploy(file("build/libs/FancyBot-1.0.0-all.jar"))
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm") version "2.0.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.14")
|
||||||
|
implementation("com.google.code.gson:gson:2.11.0")
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/14
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package buildsrc
|
||||||
|
|
||||||
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
object Http {
|
||||||
|
|
||||||
|
val jsonMediaType = "application/json; charset=utf-8".toMediaType()
|
||||||
|
val jsonHeader = mapOf(
|
||||||
|
"Content-Type" to "application/json; charset=utf-8",
|
||||||
|
"Accept" to "application/json"
|
||||||
|
)
|
||||||
|
val okHttpClient = OkHttpClient()
|
||||||
|
|
||||||
|
fun buildParams(url: String, params: Map<String, Any>?): String {
|
||||||
|
val paramsUrl = StringBuilder("$url?")
|
||||||
|
params?.let {
|
||||||
|
it.forEach { (key, value) ->
|
||||||
|
paramsUrl.append("$key=$value&")
|
||||||
|
}
|
||||||
|
paramsUrl.setLength(paramsUrl.length - 1)
|
||||||
|
}
|
||||||
|
return if (params != null) paramsUrl.toString() else url
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addHeaders(request: Request.Builder, headers: Map<String, String>?): Request.Builder {
|
||||||
|
headers?.let {
|
||||||
|
it.forEach { (key, value) ->
|
||||||
|
request.addHeader(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun delete(
|
||||||
|
url: String,
|
||||||
|
jsonBody: String? = null,
|
||||||
|
params: Map<String, Any>? = null,
|
||||||
|
headers: Map<String, String>? = null
|
||||||
|
): String {
|
||||||
|
val paramsUrl = buildParams(url, params)
|
||||||
|
val requestBuilder = Request.Builder().url(paramsUrl)
|
||||||
|
jsonBody?.let {
|
||||||
|
val body = it.toRequestBody(jsonMediaType)
|
||||||
|
requestBuilder.delete(body)
|
||||||
|
} ?: requestBuilder.delete()
|
||||||
|
|
||||||
|
val headerRequest = addHeaders(requestBuilder, headers)
|
||||||
|
return executeRequest(headerRequest.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun postFile(
|
||||||
|
url: String,
|
||||||
|
file: File,
|
||||||
|
formBody: Map<String, Any>? = null,
|
||||||
|
headers: Map<String, String>? = null,
|
||||||
|
params: Map<String, Any>? = null
|
||||||
|
): String {
|
||||||
|
val multipartBody = MultipartBody.Builder().setType(MultipartBody.FORM)
|
||||||
|
formBody?.forEach { (key, value) ->
|
||||||
|
multipartBody.addFormDataPart(key, value.toString())
|
||||||
|
}
|
||||||
|
val fileMediaType = "application/octet-stream".toMediaType()
|
||||||
|
multipartBody.addFormDataPart("file", file.name, file.asRequestBody(fileMediaType))
|
||||||
|
|
||||||
|
val paramsUrl = buildParams(url, params)
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(paramsUrl)
|
||||||
|
.post(multipartBody.build())
|
||||||
|
val headerRequest = addHeaders(request, headers)
|
||||||
|
return executeRequest(headerRequest.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeRequest(request: Request): String {
|
||||||
|
return okHttpClient.newCall(request).execute().body.string()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun post(
|
||||||
|
url: String,
|
||||||
|
jsonBody: String,
|
||||||
|
headers: Map<String, String>? = null,
|
||||||
|
params: Map<String, Any>? = null
|
||||||
|
): String {
|
||||||
|
val body = jsonBody.toRequestBody(jsonMediaType)
|
||||||
|
val paramsUrl = buildParams(url, params)
|
||||||
|
val request = Request.Builder()
|
||||||
|
.post(body)
|
||||||
|
.url(paramsUrl)
|
||||||
|
this.addHeaders(request, jsonHeader)
|
||||||
|
val headerRequest = addHeaders(request, headers)
|
||||||
|
return this.executeRequest(headerRequest.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun get(
|
||||||
|
url: String,
|
||||||
|
params: Map<String, Any>? = null,
|
||||||
|
headers: Map<String, String>? = null
|
||||||
|
): String {
|
||||||
|
val paramsUrl = buildParams(url, params)
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(paramsUrl)
|
||||||
|
.get()
|
||||||
|
val headerRequest = addHeaders(request, headers)
|
||||||
|
return this.executeRequest(headerRequest.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/14
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package buildsrc
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
|
||||||
|
val gson: Gson = GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.disableHtmlEscaping()
|
||||||
|
.create()
|
||||||
|
|
||||||
|
|
||||||
|
fun Any.toJson(): String {
|
||||||
|
return gson.toJson(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> String.fromJson(): T {
|
||||||
|
return gson.fromJson(this, T::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> String.fromArrayJson(): T {
|
||||||
|
return gson.fromJson(this, object : TypeToken<T>() {}.type)
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 RTAkland
|
||||||
|
* Author: RTAkland
|
||||||
|
* Date: 2024/9/14
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package buildsrc
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class MCSMDeploy(
|
||||||
|
private val mcsmApiUrl: String,
|
||||||
|
private val apiKey: String,
|
||||||
|
private val daemonId: String,
|
||||||
|
private val instanceId: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
private fun deleteLastTimeJar() {
|
||||||
|
Http.delete(
|
||||||
|
"$mcsmApiUrl/api/files",
|
||||||
|
DeleteTarget(listOf("/FancyBot-1.0.0-all.jar")).toJson(),
|
||||||
|
mapOf(
|
||||||
|
"daemonId" to daemonId,
|
||||||
|
"uuid" to instanceId,
|
||||||
|
"apikey" to apiKey
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUploadConfig(): Pair<String, String> {
|
||||||
|
val result = Http.post(
|
||||||
|
"$mcsmApiUrl/api/files/upload?apikey=$apiKey&upload_dir=/&daemonId=$daemonId&uuid=$instanceId", ""
|
||||||
|
)
|
||||||
|
val config = result.fromJson<UploadConfig>().data
|
||||||
|
return config.password to config.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun uploadFile(file: File, password: String, addr: String) {
|
||||||
|
Http.postFile("${addr.replace("wss", "https")}/upload/$password", file)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun restartInstance() {
|
||||||
|
Http.get("$mcsmApiUrl/api/protected_instance/restart?apikey=$apiKey&daemonId=$daemonId&uuid=$instanceId")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deploy(file: File) {
|
||||||
|
this.deleteLastTimeJar()
|
||||||
|
val config = this.getUploadConfig()
|
||||||
|
this.uploadFile(file, config.first, config.second)
|
||||||
|
this.restartInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DeleteTarget(
|
||||||
|
val targets: List<String>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class UploadConfig(
|
||||||
|
val data: Data
|
||||||
|
) {
|
||||||
|
data class Data(
|
||||||
|
val password: String,
|
||||||
|
val addr: String
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user