-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Build native image
- Loading branch information
Showing
14 changed files
with
271 additions
and
268 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM alpine:latest | ||
LABEL authors="offz" | ||
|
||
RUN apk add gcompat | ||
|
||
COPY build/native/nativeCompile/discord-role-picker / | ||
ENTRYPOINT ["/discord-role-picker"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,52 @@ | ||
plugins { | ||
alias(libs.plugins.kotlinJvm) | ||
alias(libs.plugins.kotlinx.serialization) | ||
alias(libs.plugins.graalvm.nativeimage) | ||
application | ||
id("com.google.cloud.tools.jib") version "3.4.3" | ||
id("com.ryandens.jlink-application") version "0.4.0" | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
maven("https://oss.sonatype.org/content/repositories/snapshots") | ||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots") | ||
} | ||
|
||
dependencies { | ||
implementation(libs.kordExtensions) | ||
implementation(libs.kord) | ||
implementation(libs.kotlinx.serialization.json) | ||
implementation(libs.kaml) | ||
implementation(libs.clikt) | ||
implementation(libs.slf4j) | ||
} | ||
|
||
kotlin { | ||
jvmToolchain(21) | ||
jvmToolchain(23) // want this for graalvm 23 despite kotlin not supporting yet | ||
} | ||
|
||
application { | ||
mainClass = "com.mineinabyss.discord.bot.MainKt" | ||
java { | ||
sourceCompatibility = JavaVersion.VERSION_22 | ||
targetCompatibility = JavaVersion.VERSION_22 | ||
} | ||
|
||
tasks { | ||
jibDockerBuild { | ||
dependsOn("jlinkJre") | ||
} | ||
this.jib { | ||
dependsOn("jlinkJre") | ||
sourceSets { | ||
main { | ||
kotlin.srcDir("src") | ||
} | ||
} | ||
|
||
jlinkJre { | ||
modules.set(setOf("java.logging", "java.management", "jdk.crypto.ec", "java.naming")) // defaults to only java.base | ||
application { | ||
mainClass = "MainKt" | ||
} | ||
|
||
jib { | ||
from.image = "gcr.io/distroless/java-base-debian11:nonroot-amd64" | ||
to.image = "ghcr.io/mineinabyss/discord-role-picker" | ||
extraDirectories { | ||
paths { | ||
path { | ||
setFrom(file("build/jlink-jre/jre")) | ||
into = "/usr/local" | ||
} | ||
} | ||
permissions = mapOf("/usr/local/bin/java" to "755") | ||
} | ||
container { | ||
environment = mapOf("BOT_CONFIG" to "/app/config.yml") | ||
creationTime = "USE_CURRENT_TIMESTAMP" | ||
ports = listOf("8080") | ||
graalvmNative { | ||
binaries { | ||
named("main") { | ||
fallback.set(false) | ||
verbose.set(false) | ||
|
||
// good defauls intended for Java 8 (>= 8u191) containers | ||
jvmFlags = listOf( | ||
"-server", | ||
"-Djava.awt.headless=true", | ||
"-XX:InitialRAMFraction=2", | ||
"-XX:MinRAMFraction=2", | ||
"-XX:MaxRAMFraction=2", | ||
"-XX:+UseG1GC", | ||
"-XX:MaxGCPauseMillis=100", | ||
"-XX:+UseStringDeduplication" | ||
) | ||
buildArgs.addAll( | ||
"--initialize-at-build-time", | ||
"-Os" | ||
) | ||
imageName.set("discord-role-picker") | ||
// runtimeArgs.add("-Xmx10m") | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,20 @@ | ||
[versions] | ||
clikt = "4.2.2" | ||
kaml = "0.60.0" | ||
kordExtensions = "1.8.1-SNAPSHOT" | ||
kotlin = "2.0.0" | ||
kotlinx-serialization = "1.7.0" | ||
slf4j = "2.0.9" | ||
|
||
[libraries] | ||
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" } | ||
kaml = { module = "com.charleskorn.kaml:kaml", version.ref = "kaml" } | ||
kordExtensions = { module = "com.kotlindiscord.kord.extensions:kord-extensions", version.ref = "kordExtensions" } | ||
#kordExtensions = "dev.kordex:kord-extensions:2.3.1-SNAPSHOT" | ||
discord4j = "com.discord4j:discord4j-core:3.2.7" | ||
kord = "dev.kord:kord-core:0.15.0" | ||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } | ||
slf4j = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } | ||
|
||
[plugins] | ||
kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } | ||
kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } | ||
graalvm-nativeimage = "org.graalvm.buildtools.native:0.10.3" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
package com.mineinabyss.discord.bot | ||
import bot.StartCommand | ||
|
||
|
||
fun main(args: Array<String>) = StartCommand().main(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package bot | ||
|
||
import config.Config | ||
import config.RoleGroup | ||
import dev.kord.common.entity.Permission | ||
import dev.kord.common.entity.Permissions | ||
import dev.kord.common.entity.Snowflake | ||
import dev.kord.core.Kord | ||
import dev.kord.core.behavior.edit | ||
import dev.kord.core.behavior.interaction.respondEphemeral | ||
import dev.kord.core.behavior.interaction.response.MessageInteractionResponseBehavior | ||
import dev.kord.core.behavior.interaction.response.edit | ||
import dev.kord.core.behavior.interaction.response.respond | ||
import dev.kord.core.cache.data.toData | ||
import dev.kord.core.entity.Message | ||
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent | ||
import dev.kord.core.event.interaction.GuildChatInputCommandInteractionCreateEvent | ||
import dev.kord.core.event.interaction.SelectMenuInteractionCreateEvent | ||
import dev.kord.core.on | ||
import dev.kord.rest.builder.component.ActionRowBuilder | ||
import dev.kord.rest.builder.component.option | ||
import dev.kord.rest.builder.message.actionRow | ||
import java.util.concurrent.ConcurrentHashMap | ||
|
||
class CreateButtons( | ||
val kord: Kord, | ||
val config: Config, | ||
) { | ||
private val pastResponses = ConcurrentHashMap<Snowflake, MessageInteractionResponseBehavior>() | ||
|
||
suspend fun updateRolesMessage() { | ||
if (config.rolesMessageReference == null) return | ||
val message = Message( | ||
kord.rest.channel.getMessage( | ||
config.rolesMessageReference.channel, | ||
config.rolesMessageReference.message | ||
).toData(), kord | ||
) | ||
message.edit { | ||
actionRow { | ||
config.groups.forEach { | ||
interactionButton(it.style, "roles/${it.id}") { | ||
label = it.name | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
suspend fun init() { | ||
val roleMessageCommand = | ||
kord.createGuildChatInputCommand(config.guildId, "rolesmessage", "Create roles message") { | ||
defaultMemberPermissions = Permissions(Permission.Administrator) | ||
} | ||
|
||
val rolesUpdateCommand = | ||
kord.createGuildChatInputCommand(config.guildId, "rolesupdate", "Update roles message") { | ||
defaultMemberPermissions = Permissions(Permission.Administrator) | ||
} | ||
|
||
kord.on<GuildChatInputCommandInteractionCreateEvent> { | ||
println(interaction) | ||
when (interaction.invokedCommandId) { | ||
roleMessageCommand.id -> { | ||
val response = interaction.deferEphemeralResponse() | ||
interaction.channel.createMessage("Place this message's id into the config") | ||
response.respond { | ||
content = "Created roles message" | ||
} | ||
} | ||
|
||
rolesUpdateCommand.id -> { | ||
val response = interaction.deferEphemeralResponse() | ||
updateRolesMessage() | ||
response.respond { content = "Updated roles message" } | ||
} | ||
} | ||
} | ||
|
||
kord.on<SelectMenuInteractionCreateEvent> { | ||
val comp = interaction.componentId | ||
when { | ||
comp.startsWith("select/") -> { | ||
val response = interaction.deferEphemeralMessageUpdate() | ||
val options = config.findByName(comp.removePrefix("select/"))?.options ?: return@on | ||
val guild = kord.getGuild(config.guildId) | ||
val member = guild.getMember(interaction.user.id) | ||
val selectedRoles = interaction.values.filter { it != "unknown" }.map { Snowflake(it) }.toSet() | ||
val (add, remove) = options.partition { | ||
it.role in selectedRoles | ||
} | ||
add.forEach { member.addRole(it.role ?: return@forEach) } | ||
remove.forEach { member.removeRole(it.role ?: return@forEach) } | ||
response.edit {} | ||
} | ||
} | ||
} | ||
|
||
kord.on<ButtonInteractionCreateEvent> { | ||
val comp = interaction.componentId | ||
when { | ||
comp.startsWith("roles/") -> { | ||
val response = interaction.respondEphemeral { | ||
pastResponses[interaction.user.id]?.delete() | ||
actionRow { | ||
createComponents( | ||
this@on, config.findByName(comp.removePrefix("roles/")) ?: return@actionRow | ||
) | ||
} | ||
} | ||
pastResponses[interaction.user.id] = response | ||
} | ||
} | ||
} | ||
updateRolesMessage() | ||
} | ||
|
||
suspend inline fun ActionRowBuilder.createComponents( | ||
event: ButtonInteractionCreateEvent, | ||
group: RoleGroup, | ||
) = stringSelect("select/${group.id}") { | ||
val guild = kord.getGuild(config.guildId) | ||
val member = guild.getMember(event.interaction.user.id) | ||
val optionCount = group.options.count { option -> | ||
val role = option.role?.let { guild.getRole(it) } | ||
option(option.name ?: role?.name ?: "", role?.id?.toString() ?: return@count false) { | ||
emoji = option.emoji | ||
description = option.desc | ||
default = member.roleIds.contains(role.id) | ||
} | ||
true | ||
} | ||
allowedValues = 0..optionCount | ||
} | ||
} | ||
|
Oops, something went wrong.