Compare commits

..

18 Commits

Author SHA1 Message Date
4636768184 Merge pull request '1.2.0 release' (#2) from develop into main
All checks were successful
/ publish (push) Successful in 1m15s
Reviewed-on: Infendro/migration-ktor#2
2026-02-19 13:17:15 +00:00
d26f0a1310 Upgrade dependencies 2026-02-19 14:16:50 +01:00
e3931e3e8f improve ci 2026-01-13 18:16:01 +01:00
3380f50cc7 update README
All checks were successful
/ publish (push) Successful in 1m2s
2025-12-13 23:11:46 +01:00
b777eadd13 bump version to 1.1.1 2025-12-13 23:09:13 +01:00
bba1f2d63d update dependencies 2025-12-13 23:09:05 +01:00
27b335a0af fix workflow
All checks were successful
/ publish (push) Successful in 48s
2025-12-13 01:31:56 +01:00
21ed1c40b5 refactor build.gradle.kts 2025-12-13 01:04:46 +01:00
d0c130cb61 use common plugin 2025-12-13 00:49:46 +01:00
1fbff53dbd refactor 2025-12-12 21:59:18 +01:00
a759d19466 update README 2025-10-03 11:44:09 +02:00
8d2efa65df update README
All checks were successful
/ publish (push) Successful in 49s
2025-10-02 11:28:26 +02:00
0cc1f208ff bump version to 1.1.0 2025-10-02 11:26:01 +02:00
53d857186d suppress unused warnings 2025-10-02 11:23:19 +02:00
e74d0cdc60 add README 2025-10-02 11:18:36 +02:00
dcd23f0283 fix config
All checks were successful
/ publish (push) Successful in 46s
2025-08-31 11:19:59 +02:00
8b8614b4de use migration library
All checks were successful
/ publish (push) Successful in 1m7s
2025-08-31 10:58:00 +02:00
9f32143b60 refactor package 2025-08-21 15:03:20 +02:00
10 changed files with 112 additions and 165 deletions

View File

@@ -1,34 +0,0 @@
on:
push:
branches:
- main
env:
GIT__TOKEN: ${{ secrets.TOKEN }}
jobs:
publish:
runs-on: linux
steps:
- uses: actions/checkout@v4
- uses: actions/cache/restore@v4
with:
key: gradle
path: |
~/.gradle/caches/
~/.gradle/wrapper/
- uses: actions/setup-java@v4
with:
java-version: '24'
distribution: 'temurin'
- run: ./gradlew publish
- uses: actions/cache/save@v4
with:
key: gradle
path: |
~/.gradle/caches/
~/.gradle/wrapper/

View File

@@ -0,0 +1,30 @@
on:
push:
branches: [ main ]
jobs:
publish:
runs-on: linux
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
java-version: '24'
distribution: 'temurin'
- name: Cache Gradle
uses: actions/cache@v4
with:
key: gradle-${{ hashFiles('**/libs.versions.toml') }}
restore-keys: gradle
path: |
~/.gradle/caches/
~/.gradle/wrapper/
- name: Publish
run: ./gradlew publish
env:
INFENDRO__TOKEN: ${{ secrets.TOKEN }}

34
README.md Normal file
View File

@@ -0,0 +1,34 @@
# migration-ktor
`migration-ktor` is a Kotlin library that enables code-based migrations in Ktor.
## Installation
Add the following to your `build.gradle.kts`.
```kotlin
repositories {
maven("https://git.infendro.com/api/packages/Infendro/maven")
}
dependencies {
implementation("com.infendro:ktor-migration:1.2.0")
}
```
## Usage
```kotlin
fun Application.configureDatabase() {
// connect to a database
Database.connect(/* parameters */)
// install the plugin
install(Migration) {
// create a migration
migration("initial") {
// execute code to migrate the database
}
}
}
```

View File

@@ -1,54 +1,37 @@
group = "com.infendro"
version = "1.0.0"
import com.infendro.plugin.infendro
import com.infendro.plugin.token
repositories {
mavenCentral()
}
group = "com.infendro"
version = "1.2.0"
plugins {
alias(libs.plugins.infendro)
alias(libs.plugins.kotlin)
id("maven-publish")
}
repositories {
infendro()
mavenCentral()
}
dependencies {
implementation(libs.ktor.server)
implementation(libs.migration)
implementation(libs.exposed)
implementation(libs.exposed.dao)
implementation(libs.exposed.jdbc)
}
publishing {
publications {
create<MavenPublication>("JVM") {
from(components["java"])
groupId = group as String
groupId = project.group as String
artifactId = project.name
version = version
version = project.version as String
}
}
repositories {
maven {
url = uri("https://git.infendro.com/api/packages/Infendro/maven")
authentication.create("header", HttpHeaderAuthentication::class)
credentials(HttpHeaderCredentials::class) {
val token = secret("git.token") ?: throw GradleException()
name = "Authorization"
value = "token $token"
}
}
infendro(token)
}
}
fun secret(
key: String,
): String? {
val property = key
val environment = key
.uppercase()
.replace(".", "__")
val prop = properties[property] as String?
val env = System.getenv(environment)
return prop ?: env
}

View File

@@ -1,13 +1,16 @@
[versions]
kotlin = "2.2.10"
ktor = "3.2.3"
exposed = "0.60.0"
infendro = "1.1.0"
kotlin = "2.3.0"
ktor = "3.4.0"
migration = "1.2.0"
exposed = "1.0.0"
[plugins]
infendro = { id = "com.infendro.plugin", version.ref = "infendro" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
[libraries]
ktor-server = { module = "io.ktor:ktor-server-core-jvm", version.ref = "ktor" }
migration = { module = "com.infendro:migration", version.ref = "migration" }
exposed = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" }
exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" }

View File

@@ -1 +1,6 @@
rootProject.name = "ktor-migration"
rootProject.name = "migration-ktor"
pluginManagement.repositories {
maven("https://git.infendro.com/api/packages/Infendro/maven")
mavenCentral()
}

View File

@@ -0,0 +1,19 @@
package com.infendro.ktor.migration
import com.infendro.migration.migrate
import io.ktor.server.application.*
import org.jetbrains.exposed.v1.jdbc.JdbcTransaction
val Migration = createApplicationPlugin("Migration", MigrationConfig::new) {
migrate(pluginConfig.config)
}
class MigrationConfig {
internal val config = com.infendro.migration.MigrationConfig()
fun migration(name: String, migrate: JdbcTransaction.() -> Unit) = config.migration(name, migrate)
companion object {
fun new() = MigrationConfig()
}
}

View File

@@ -1,55 +0,0 @@
package com.infendro.migration
import com.infendro.migration.model.MigrationRepository
import com.infendro.migration.model.MigrationTable
import io.ktor.server.application.*
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.transactions.transaction
import org.slf4j.Logger
import org.slf4j.LoggerFactory
internal val logger: Logger = LoggerFactory.getLogger("Database")
val Migration = createApplicationPlugin(
name = "Migration",
createConfiguration = { MigrationConfig() },
) {
transaction {
SchemaUtils.create(MigrationTable)
}
val (migrations) = pluginConfig
for ((name, body) in migrations) {
if (MigrationRepository.exists(name))
continue
transaction {
try {
body()
logger.info("""Migration "$name" successful""")
} catch (e: Exception) {
logger.error("""Migration "$name" failed""")
throw e
}
}
MigrationRepository.insert(name)
}
}
data class MigrationConfig(
internal val migrations: MutableList<Migration> = mutableListOf()
) {
fun migration(
name: String,
block: Transaction.() -> Unit,
) {
migrations += Migration(name, block)
}
data class Migration(
val name: String,
val body: Transaction.() -> Unit
)
}

View File

@@ -1,16 +0,0 @@
package com.infendro.migration.model
import org.jetbrains.exposed.dao.LongEntity
import org.jetbrains.exposed.dao.LongEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.LongIdTable
object MigrationTable : LongIdTable("migration", "id") {
val name = text("name")
}
class MigrationEntity(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<MigrationEntity>(MigrationTable)
var name by MigrationTable.name
}

View File

@@ -1,22 +0,0 @@
package com.infendro.migration.model
import org.jetbrains.exposed.sql.transactions.transaction
object MigrationRepository {
fun exists(
name: String,
): Boolean = transaction {
MigrationEntity
.find { MigrationTable.name eq name }
.any()
}
fun insert(
name: String,
): Unit = transaction {
MigrationEntity
.new {
this.name = name
}
}
}