Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
y9san9 committed Nov 25, 2023
0 parents commit 2bbeb78
Show file tree
Hide file tree
Showing 27 changed files with 895 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Production Deploy

on:
push:
branches: [ "dev" ]
workflow_dispatch:

jobs:
production-deploy:
runs-on: ubuntu-latest
env:
GITHUB_USERNAME: "meetacy-robot"
GITHUB_TOKEN: ${{ secrets.ROBOT_TOKEN }}
IS_RUNNER: "true"
DEPLOY_DESTINATION: ${{ secrets.DEPLOY_DESTINATION }}
DEPLOY_SERVICE_NAME: ${{ secrets.DEPLOY_SERVICE_NAME }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_PASSWORD: ${{ secrets.SSH_PASSWORD }}
SSH_PORT: ${{ secrets.SSH_PORT }}
SSH_USER: ${{ secrets.SSH_USER }}
steps:
- uses: actions/checkout@v3
- name: Gradle Cache Setup
uses: gradle/gradle-build-action@v2
- run: ./gradlew productionDeploy
17 changes: 17 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Test

on:
pull_request:
branches: [ "dev" ]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
env:
GITHUB_USERNAME: "meetacy-robot"
GITHUB_TOKEN: ${{ secrets.ROBOT_TOKEN }}
steps:
- uses: actions/checkout@v3
- name: Gradle Cache Setup
uses: gradle/gradle-build-action@v2
- run: ./gradlew test
42 changes: 42 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
`kotlin-dsl`
}

repositories {
mavenCentral()
gradlePluginPortal()
}

dependencies {
api(libs.gradle.kotlin)
api(libs.gradle.kotlinx.serialization)
api(libs.gradle.ssh)
api(libs.gradle.shadow)
}
11 changes: 11 additions & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
dependencyResolutionManagement {
repositories {
mavenCentral()
}

versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
65 changes: 65 additions & 0 deletions build-logic/src/main/kotlin/deploy-convention.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import deploy.DeployExtension
import deploy.SshSessionExtension
import org.hidetake.groovy.ssh.connection.AllowAnyHosts
import org.hidetake.groovy.ssh.core.Remote
import org.jetbrains.kotlin.konan.properties.loadProperties
import java.io.File
import java.util.*

plugins {
application
id("com.github.johnrengelman.shadow")
id("org.hidetake.ssh")
}

val extension = project.extensions.create<DeployExtension>(name = "deploy")

project.afterEvaluate {
val default = extension.targets["default"]
extension.targets.filter { it.key != "default" }.forEach { configuration ->
configuration.value.apply {
host ?: default?.host ?: error("`host` should be defined in `deploy`")
destination ?: default?.destination ?: error("`destination` should be defined in `deploy`")
mainClass ?: default?.mainClass ?: error("`mainClass` should be defined in `deploy`")
serviceName ?: default?.serviceName ?: error("`service name` should be defined in `deploy`")
}

val shadowJar = tasks.named<ShadowJar>("shadowJar") {
archiveFileName.set(configuration.value.archiveName ?: default?.archiveName)
mergeServiceFiles()
manifest {
attributes(mapOf("Main-Class" to (configuration.value.mainClass ?: default?.mainClass)))
}
}

val webServer = Remote(
mapOf(
"host" to (configuration.value.host ?: default?.host),
"user" to (configuration.value.user ?: default?.user),
"password" to (configuration.value.password ?: default?.password),
"knownHosts" to ((configuration.value.knownHostsFile ?: default?.knownHostsFile)?.let(::File)
?: AllowAnyHosts.instance)
)
)

project.extensions.create<SshSessionExtension>("${configuration.key}SshSession", project, webServer)

project.task("${configuration.key}Deploy") {
group = "deploy"
dependsOn(shadowJar)

doLast {
project.extensions.getByName<SshSessionExtension>("${configuration.key}SshSession").invoke {
put(
hashMapOf(
"from" to shadowJar.get().archiveFile.get().asFile,
"into" to configuration.value.destination
)
)
execute("systemctl restart ${configuration.value.serviceName ?: default?.serviceName}")
}
}
}
}
}
16 changes: 16 additions & 0 deletions build-logic/src/main/kotlin/deploy/DeployExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package deploy

open class DeployExtension {
internal val targets: MutableMap<String, TargetConfiguration> = mutableMapOf()

fun target(name: String, block: TargetConfiguration.() -> Unit) {
val configuration = TargetConfiguration().apply(block)
targets[name] = configuration
}
}

/**
* Default configuration that used as fallback when some value wasn't specified.
* Use it to avoid code-repeating.
*/
fun DeployExtension.default(block: TargetConfiguration.() -> Unit) = target("default", block)
19 changes: 19 additions & 0 deletions build-logic/src/main/kotlin/deploy/SshSessionExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package deploy

import org.gradle.api.Project
import org.gradle.kotlin.dsl.delegateClosureOf
import org.gradle.kotlin.dsl.the
import org.hidetake.groovy.ssh.core.Remote
import org.hidetake.groovy.ssh.core.RunHandler
import org.hidetake.groovy.ssh.core.Service
import org.hidetake.groovy.ssh.session.SessionHandler


open class SshSessionExtension(
private val project: Project,
private val remote: Remote
) {
operator fun invoke(handler: SessionHandler.() -> Unit) = project.the<Service>().apply {
run(delegateClosureOf<RunHandler> { session(remote, delegateClosureOf(handler)) })
}
}
19 changes: 19 additions & 0 deletions build-logic/src/main/kotlin/deploy/TargetConfiguration.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package deploy

open class TargetConfiguration {
var mainClass: String? = null

/**
* Jar-file destination on remote server (directory).
* Example: `/opt/prod/foo`
*/
var destination: String? = null
var archiveName: String? = null

var host: String? = null
var user: String? = null
var password: String? = null
var knownHostsFile: String? = null
var implementationTitle: String? = mainClass
var serviceName: String? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugins {
kotlin("plugin.serialization")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
kotlin("jvm")
}

kotlin {
jvmToolchain(17)
}
40 changes: 40 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import deploy.default
import org.jetbrains.kotlin.konan.properties.loadProperties

plugins {
application
id("telegram-bot-convention")
id("deploy-convention")
}

application {
mainClass = "app.meetacy.backend.MainKt"
}

dependencies {
implementation(libs.ktgbotapi)
implementation(libs.meetacy.sdk.api.ktor)
}

val propertiesFile: File = rootProject.file("deploy.properties")

deploy {
val isRunner = System.getenv("IS_RUNNER")?.toBoolean() == true
val properties = if (propertiesFile.exists()) loadProperties(propertiesFile.absolutePath) else null

if (!isRunner && properties == null) return@deploy

default {
host = properties?.getProperty("host") ?: System.getenv("SSH_HOST")
user = properties?.getProperty("user") ?: System.getenv("SSH_USER")
password = properties?.getProperty("password") ?: System.getenv("SSH_PASSWORD")
knownHostsFile = properties?.getProperty("knownHosts") ?: System.getenv("SSH_KNOWN_HOST_FILE")
archiveName = "app.jar"
mainClass = "app.meetacy.telegram.bot.MainKt"
}

target("production") {
destination = properties?.getProperty("prod.destination") ?: System.getenv("DEPLOY_DESTINATION")
serviceName = properties?.getProperty("prod.serviceName") ?: System.getenv("DEPLOY_SERVICE_NAME")
}
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
kotlin.code.style=official
Loading

0 comments on commit 2bbeb78

Please sign in to comment.