Rename base package
This commit is contained in:
parent
7dadc66748
commit
16a0740679
14 changed files with 530 additions and 0 deletions
32
app/src/main/kotlin/de/rpr/githubreleases/App.kt
Normal file
32
app/src/main/kotlin/de/rpr/githubreleases/App.kt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val config = Config()
|
||||||
|
val publishers = Publishers(config)
|
||||||
|
val releaseRepository = ReleaseRepository()
|
||||||
|
val app = App(config, releaseRepository, OkHttpClient(), publishers)
|
||||||
|
app.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
class App(
|
||||||
|
private val config: Config,
|
||||||
|
private val releaseRepo: ReleaseRepository,
|
||||||
|
private val httpClient: OkHttpClient,
|
||||||
|
private val publishers: Publishers
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun execute() {
|
||||||
|
|
||||||
|
config.githubRepos.forEach { githubRepo ->
|
||||||
|
val existingReleases = releaseRepo.getExistingReleases(githubRepo)
|
||||||
|
val feedService = FeedService(githubRepo, httpClient)
|
||||||
|
val newReleases = feedService.getNewReleases(existingReleases)
|
||||||
|
val publisher = publishers.forName(githubRepo.name)
|
||||||
|
val publishedReleases = publisher.sendReleases(newReleases)
|
||||||
|
releaseRepo.save(publishedReleases)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
79
app/src/main/kotlin/de/rpr/githubreleases/Config.kt
Normal file
79
app/src/main/kotlin/de/rpr/githubreleases/Config.kt
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package de.rpr.githubreleases;
|
||||||
|
|
||||||
|
import de.rpr.githubreleases.LogLevel.ERROR
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
|
||||||
|
data class PublishingCredentials(
|
||||||
|
val instanceUrl: String?,
|
||||||
|
val accessToken: String?,
|
||||||
|
private val instanceUrlEnvName: String,
|
||||||
|
private val accessTokenEnvName: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
var valid: Boolean = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validate() {
|
||||||
|
if (instanceUrl.isNullOrBlank()) {
|
||||||
|
ERROR.log("No instance url available, please set the environment variable $instanceUrlEnvName")
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
if (accessToken.isNullOrBlank()) {
|
||||||
|
ERROR.log("No access token available, please set the environment variable $accessTokenEnvName")
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val githubRepos: List<GithubRepo>
|
||||||
|
val mastodonCredentials: Map<String, PublishingCredentials>
|
||||||
|
val schedulingDelay: Long = (System.getenv("SCHEDULING_DELAY")?.toLong() ?: 120) * 60
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
var valid = true
|
||||||
|
|
||||||
|
val githubReposString = System.getenv("GITHUB_REPOS")
|
||||||
|
if (githubReposString == null) {
|
||||||
|
ERROR.log("No github repos defined, please set repo urls in environment variable GITHUB_REPOS")
|
||||||
|
throw IllegalStateException("Invalid configuration")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
githubRepos = githubReposString.split(",").map {
|
||||||
|
GithubRepo(repoName(it), it)
|
||||||
|
}
|
||||||
|
|
||||||
|
mastodonCredentials = githubRepos.associate {
|
||||||
|
it.name to PublishingCredentials(
|
||||||
|
instanceUrlEnvName = "${it.name.uppercase()}_INSTANCE_URL",
|
||||||
|
instanceUrl = System.getenv("${it.name.uppercase()}_INSTANCE_URL"),
|
||||||
|
accessTokenEnvName = "${it.name.uppercase()}_ACCESS_TOKEN",
|
||||||
|
accessToken = System.getenv("${it.name.uppercase()}_ACCESS_TOKEN")
|
||||||
|
)
|
||||||
|
}.onEach { (_, credentials) ->
|
||||||
|
if (!credentials.valid) {
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedulingDelay < 300) {
|
||||||
|
ERROR.log("To avoid hammering the source webpage, scheduling delay has to be > 5 minutes")
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
throw IllegalStateException("Invalid configuration")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun repoName(url: String): String {
|
||||||
|
val usernameEnd = url.indexOf("/", startIndex = 20)
|
||||||
|
return url.substring(usernameEnd + 1).trimEnd { ch -> ch == '/' }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
app/src/main/kotlin/de/rpr/githubreleases/Extensions.kt
Normal file
7
app/src/main/kotlin/de/rpr/githubreleases/Extensions.kt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
fun String.toFile(): File = File(this)
|
||||||
|
fun String.toPath(): Path = this.toFile().toPath()
|
8
app/src/main/kotlin/de/rpr/githubreleases/FeedReader.kt
Normal file
8
app/src/main/kotlin/de/rpr/githubreleases/FeedReader.kt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import com.ouattararomuald.syndication.atom.AtomFeed
|
||||||
|
|
||||||
|
interface FeedReader {
|
||||||
|
|
||||||
|
fun readAtom(): AtomFeed
|
||||||
|
}
|
36
app/src/main/kotlin/de/rpr/githubreleases/FeedService.kt
Normal file
36
app/src/main/kotlin/de/rpr/githubreleases/FeedService.kt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import com.ouattararomuald.syndication.Syndication
|
||||||
|
import de.rpr.terminenbg.LocalDateTimeAdapter
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class FeedService(
|
||||||
|
private val githubRepo: GithubRepo,
|
||||||
|
httpClient: OkHttpClient
|
||||||
|
) {
|
||||||
|
private val syndication: Syndication = Syndication(
|
||||||
|
url = "${githubRepo.url}/releases.atom",
|
||||||
|
httpClient = httpClient
|
||||||
|
)
|
||||||
|
|
||||||
|
fun getNewReleases(existingReleases: Releases): Releases {
|
||||||
|
log("Consuming releases feed for ${githubRepo.url}")
|
||||||
|
|
||||||
|
val feedReader = syndication.create(FeedReader::class.java)
|
||||||
|
return feedReader.readAtom()
|
||||||
|
.items
|
||||||
|
?.map {
|
||||||
|
val created = LocalDateTime.parse(it.lastUpdatedTime, LocalDateTimeAdapter.formatter)
|
||||||
|
val link = it.links!!.first().href!!
|
||||||
|
Release(
|
||||||
|
id = it.title,
|
||||||
|
link = link,
|
||||||
|
created = created,
|
||||||
|
githubRepo = githubRepo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
?.filter { !existingReleases.contains(it) }
|
||||||
|
?.asCollection() ?: Releases()
|
||||||
|
}
|
||||||
|
}
|
6
app/src/main/kotlin/de/rpr/githubreleases/GithubRepo.kt
Normal file
6
app/src/main/kotlin/de/rpr/githubreleases/GithubRepo.kt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
data class GithubRepo(
|
||||||
|
val name: String,
|
||||||
|
val url: String
|
||||||
|
)
|
|
@ -0,0 +1,21 @@
|
||||||
|
package de.rpr.terminenbg
|
||||||
|
|
||||||
|
import com.google.gson.*
|
||||||
|
import java.lang.reflect.Type
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class LocalDateAdapter : JsonSerializer<LocalDate?>, JsonDeserializer<LocalDate?> {
|
||||||
|
|
||||||
|
private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||||
|
|
||||||
|
override fun serialize(src: LocalDate?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
|
||||||
|
return JsonPrimitive(src?.format(formatter))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): LocalDate? {
|
||||||
|
return LocalDate.parse(json?.asString, formatter)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package de.rpr.terminenbg
|
||||||
|
|
||||||
|
import com.google.gson.*
|
||||||
|
import java.lang.reflect.Type
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class LocalDateTimeAdapter : JsonSerializer<LocalDateTime?>, JsonDeserializer<LocalDateTime?> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(src: LocalDateTime?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
|
||||||
|
return JsonPrimitive(src?.format(formatter))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): LocalDateTime? {
|
||||||
|
return LocalDateTime.parse(json?.asString, formatter)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
app/src/main/kotlin/de/rpr/githubreleases/LogLevel.kt
Normal file
43
app/src/main/kotlin/de/rpr/githubreleases/LogLevel.kt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import java.io.PrintStream
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
fun log(message: String, logLevel: LogLevel = LogLevel.INFO) {
|
||||||
|
logLevel.log(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class LogLevel(val order: Int, val out: PrintStream) {
|
||||||
|
DEBUG(1, System.out),
|
||||||
|
INFO(2, System.out),
|
||||||
|
ERROR(3, System.err);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun log(message: String) {
|
||||||
|
val activeLogLevel = System.getenv("LOG_LEVEL")
|
||||||
|
?.let { LogLevel.valueOf(it.uppercase()) }
|
||||||
|
?: LogLevel.valueOf("INFO")
|
||||||
|
if (activeLogLevel.order <= this.order) {
|
||||||
|
out.println("${LocalDateTime.now().format(dateTimeFormatter)} $this - $message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val timeFormatter = java.time.format.DateTimeFormatterBuilder()
|
||||||
|
.appendValue(java.time.temporal.ChronoField.HOUR_OF_DAY, 2)
|
||||||
|
.appendLiteral(':')
|
||||||
|
.appendValue(java.time.temporal.ChronoField.MINUTE_OF_HOUR, 2)
|
||||||
|
.optionalStart()
|
||||||
|
.appendLiteral(':')
|
||||||
|
.appendValue(java.time.temporal.ChronoField.SECOND_OF_MINUTE, 2)
|
||||||
|
.appendLiteral(".")
|
||||||
|
.appendValue(java.time.temporal.ChronoField.MILLI_OF_SECOND, 3)
|
||||||
|
.toFormatter()
|
||||||
|
|
||||||
|
private val dateTimeFormatter = java.time.format.DateTimeFormatterBuilder()
|
||||||
|
.parseCaseInsensitive()
|
||||||
|
.append(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)
|
||||||
|
.appendLiteral('T')
|
||||||
|
.append(timeFormatter)
|
||||||
|
.toFormatter();
|
||||||
|
}
|
58
app/src/main/kotlin/de/rpr/githubreleases/Publisher.kt
Normal file
58
app/src/main/kotlin/de/rpr/githubreleases/Publisher.kt
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import social.bigbone.MastodonClient
|
||||||
|
import social.bigbone.api.entity.data.Visibility
|
||||||
|
import social.bigbone.api.exception.BigBoneRequestException
|
||||||
|
|
||||||
|
class Publisher(
|
||||||
|
val name: String,
|
||||||
|
private val client: MastodonClient,
|
||||||
|
private val dryRun: Boolean = System.getenv("PUBLISH_DRY_RUN").toBoolean()
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun sendReleases(releases: Releases): Releases {
|
||||||
|
val result = releases
|
||||||
|
.onEach { release -> log("Publishing release: ${release.title}") }
|
||||||
|
.mapNotNull { release ->
|
||||||
|
val request = client.statuses.postStatus(
|
||||||
|
status = release.text,
|
||||||
|
language = "en",
|
||||||
|
visibility = Visibility.PRIVATE
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
if (!dryRun) {
|
||||||
|
request.execute()
|
||||||
|
} else {
|
||||||
|
log("Dry-Run, skipping publishing of events...")
|
||||||
|
}
|
||||||
|
return@mapNotNull release
|
||||||
|
} catch (ex: BigBoneRequestException) {
|
||||||
|
log("ERROR: Event with id ${release.id} couldn't be published: " + ex.httpStatusCode)
|
||||||
|
LogLevel.ERROR.log("Cause: ${ex.message}")
|
||||||
|
LogLevel.ERROR.log("Root cause: ${ex.cause?.message}")
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Releases(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Publishers(private val config: Config) : Iterable<Publisher> {
|
||||||
|
|
||||||
|
private val instances: List<Publisher>
|
||||||
|
|
||||||
|
init {
|
||||||
|
val mastodonClients = config.githubRepos.associate {
|
||||||
|
val publishingCredentials = config.mastodonCredentials[it.name]!!
|
||||||
|
it.name to MastodonClient.Builder(publishingCredentials.instanceUrl!!)
|
||||||
|
.accessToken(publishingCredentials.accessToken!!).build()
|
||||||
|
}
|
||||||
|
instances = config.githubRepos.map { Publisher(it.name, mastodonClients[it.name]!!) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun forName(name: String) = instances.first() { it.name == name }
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<Publisher> {
|
||||||
|
return instances.iterator()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import de.rpr.terminenbg.LocalDateAdapter
|
||||||
|
import de.rpr.terminenbg.LocalDateTimeAdapter
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
import kotlin.io.path.name
|
||||||
|
|
||||||
|
class ReleaseRepository(private val basePath: String = System.getenv("REPO_PATH") ?: "releases/") {
|
||||||
|
|
||||||
|
init {
|
||||||
|
val basePath = basePath.toFile()
|
||||||
|
if (!basePath.exists()) {
|
||||||
|
basePath.mkdir()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val gson: Gson = GsonBuilder()
|
||||||
|
.registerTypeAdapter(LocalDate::class.java, LocalDateAdapter())
|
||||||
|
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter())
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.create()
|
||||||
|
|
||||||
|
fun save(releases: Releases) = releases.forEach { writeEvent(it) }
|
||||||
|
|
||||||
|
private fun writeEvent(release: Release) {
|
||||||
|
val file = File(basePath, "${LocalDate.now()}-${release.id}.${release.githubRepo.name.lowercase()}.json")
|
||||||
|
Files.writeString(file.toPath(), gson.toJson(release))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getExistingReleases(repository: GithubRepo): Releases {
|
||||||
|
return basePath.toPath()
|
||||||
|
.listDirectoryEntries()
|
||||||
|
.filter { it.fileName.name.endsWith(".${repository.name}.json") }
|
||||||
|
.map {
|
||||||
|
Files.readString(it).let { content ->
|
||||||
|
gson.fromJson(content, Release::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.asCollection()
|
||||||
|
}
|
||||||
|
}
|
69
app/src/main/kotlin/de/rpr/githubreleases/Releases.kt
Normal file
69
app/src/main/kotlin/de/rpr/githubreleases/Releases.kt
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
data class Release(
|
||||||
|
val id: String,
|
||||||
|
val link: String,
|
||||||
|
val created: LocalDateTime,
|
||||||
|
val githubRepo: GithubRepo
|
||||||
|
) {
|
||||||
|
val title: String get() = id
|
||||||
|
val text: String =
|
||||||
|
"\uD83C\uDF89 Navidrome $title has been published!\n\nRelease notes are available here: $link\n\n#Navidrome"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Release>.asCollection() = Releases(this)
|
||||||
|
|
||||||
|
class Releases(releases: List<Release>) : List<Release> {
|
||||||
|
|
||||||
|
constructor(vararg posts: Release) : this(posts.toList())
|
||||||
|
|
||||||
|
private val content: MutableList<Release> = mutableListOf()
|
||||||
|
|
||||||
|
init {
|
||||||
|
content.addAll(releases)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int get() = content.size
|
||||||
|
|
||||||
|
override fun get(index: Int): Release {
|
||||||
|
return content[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return content.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<Release> {
|
||||||
|
return content.iterator()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun listIterator(): ListIterator<Release> {
|
||||||
|
return content.listIterator()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun listIterator(index: Int): ListIterator<Release> {
|
||||||
|
return content.listIterator(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun subList(fromIndex: Int, toIndex: Int): List<Release> {
|
||||||
|
return content.subList(fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun lastIndexOf(element: Release): Int {
|
||||||
|
return content.lastIndexOf(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun indexOf(element: Release): Int {
|
||||||
|
return content.indexOf(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(elements: Collection<Release>): Boolean {
|
||||||
|
return content.containsAll(elements)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(element: Release): Boolean {
|
||||||
|
return content.map { it.id }.contains(element.id)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import assertk.assertThat
|
||||||
|
import assertk.assertions.contains
|
||||||
|
import assertk.assertions.isTrue
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
|
||||||
|
class ReleaseRepositoryTest : DescribeSpec({
|
||||||
|
|
||||||
|
val sampleReleaseContent = """{
|
||||||
|
"id": "v0.51.0",
|
||||||
|
"link": "https://github.com/navidrome/navidrome/releases/tag/v0.51.0",
|
||||||
|
"created": "2024-01-22T23:59:21Z",
|
||||||
|
"githubRepo": {
|
||||||
|
"name": "navidrome",
|
||||||
|
"url": "https://github.com/navidrome/navidrome/"
|
||||||
|
},
|
||||||
|
"text": "🎉 Navidrome v0.51.0 has been published!\n\nRelease notes are available here: https://github.com/navidrome/navidrome/releases/tag/v0.51.0\n\n#Navidrome"
|
||||||
|
}""".trimIndent()
|
||||||
|
|
||||||
|
val basePath = System.getProperty("java.io.tmpdir") + "/releases"
|
||||||
|
|
||||||
|
beforeSpec {
|
||||||
|
basePath.toFile().mkdir()
|
||||||
|
}
|
||||||
|
|
||||||
|
afterSpec {
|
||||||
|
basePath.toPath().listDirectoryEntries()
|
||||||
|
.forEach {
|
||||||
|
it.deleteExisting()
|
||||||
|
}
|
||||||
|
Files.deleteIfExists(basePath.toPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
afterTest {
|
||||||
|
basePath.toPath().listDirectoryEntries()
|
||||||
|
.forEach {
|
||||||
|
it.deleteExisting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("ReleaseRepository is created") {
|
||||||
|
|
||||||
|
it("should create the repository folder") {
|
||||||
|
ReleaseRepository(basePath)
|
||||||
|
assertThat(File(basePath).exists()).isTrue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("ReleaseRepository") {
|
||||||
|
|
||||||
|
it("should write events to repository folder") {
|
||||||
|
val eventRepository = ReleaseRepository(basePath)
|
||||||
|
eventRepository.save(
|
||||||
|
Releases(
|
||||||
|
Release(
|
||||||
|
id = "id",
|
||||||
|
link = "https://example.com",
|
||||||
|
created = LocalDateTime.now(),
|
||||||
|
githubRepo = testGithubRepo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertThat(basePath.toPath().listDirectoryEntries().map { it.fileName.toString() })
|
||||||
|
.contains("${LocalDate.now()}-id.example.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should read existing events from repository folder") {
|
||||||
|
|
||||||
|
val eventPath = Paths.get(basePath.toPath().toString(), "sample-post.${testGithubRepo.name}.json")
|
||||||
|
eventPath.toFile().createNewFile()
|
||||||
|
Files.writeString(eventPath, sampleReleaseContent)
|
||||||
|
|
||||||
|
val postRepository = ReleaseRepository(basePath)
|
||||||
|
val existingEvents = postRepository.getExistingReleases(testGithubRepo)
|
||||||
|
assertThat(existingEvents).contains(testRelease.copy(id="v0.51.0"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
12
app/src/test/kotlin/de/rpr/githubreleases/TestData.kt
Normal file
12
app/src/test/kotlin/de/rpr/githubreleases/TestData.kt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package de.rpr.githubreleases
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
val testGithubRepo = GithubRepo("example", "https://github.com/example/example")
|
||||||
|
|
||||||
|
val testRelease = Release(
|
||||||
|
id = "id",
|
||||||
|
link = "https://example.com",
|
||||||
|
created = LocalDateTime.of(2023, 11, 29, 12, 11),
|
||||||
|
githubRepo = testGithubRepo
|
||||||
|
)
|
Loading…
Reference in a new issue