5 Commits
Author SHA1 Message Date
flecomte 7291419c9f chore: fix postgresql.secret in ci
Tests / build (push) Successful in 6m17s
Tests / test (push) Failing after 11m40s
Tests / lint (push) Successful in 14m20s
2026-07-31 21:51:27 +02:00
flecomte b2b8fcf92f refactor: fix cast warning 2026-07-31 21:36:21 +02:00
flecomte 4e4b307275 chore: fix cache for copyEnv gradle task
Tests / build (push) Successful in 9m51s
Tests / test (push) Failing after 11m0s
Tests / lint (push) Successful in 18m7s
2026-07-31 00:58:27 +02:00
flecomte e87a36caa5 chore: update CI actions versions 2026-07-31 00:24:17 +02:00
flecomte e2d7942c7e refactoring: Masive refactor to build the V2
Tests / build (push) Successful in 7m14s
Tests / lint (push) Successful in 8m35s
Tests / test (push) Failing after 11m0s
2026-07-30 23:01:50 +02:00
11 changed files with 78 additions and 74 deletions
+14 -14
View File
@@ -18,10 +18,10 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '21'
@@ -31,7 +31,7 @@ jobs:
run: echo "key=gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}" >> $GITHUB_OUTPUT run: echo "key=gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}" >> $GITHUB_OUTPUT
- name: Cache Gradle dependencies - name: Cache Gradle dependencies
uses: actions/cache@v3 uses: actions/cache@v6
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
@@ -48,16 +48,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '21'
- name: Restore Gradle cache - name: Restore Gradle cache
uses: actions/cache@v3 uses: actions/cache@v6
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
@@ -73,7 +73,7 @@ jobs:
run: ./gradlew ktlintCheck run: ./gradlew ktlintCheck
- name: Publish ktlint report - name: Publish ktlint report
uses: yutailang0119/action-ktlint@v4 uses: yutailang0119/action-ktlint@v5
if: always() if: always()
with: with:
report-path: build/reports/ktlint/**/*.xml report-path: build/reports/ktlint/**/*.xml
@@ -84,16 +84,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '21'
- name: Restore Gradle cache - name: Restore Gradle cache
uses: actions/cache@v3 uses: actions/cache@v6
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
@@ -106,20 +106,20 @@ jobs:
run: chmod +x gradlew run: chmod +x gradlew
- name: Start CI Docker Compose services - name: Start CI Docker Compose services
run: ./gradlew composeUp -Pci run: ./gradlew ciComposeUp -Pci
- name: Run tests - name: Run tests
run: ./gradlew test -x composeUp --no-daemon run: ./gradlew test -x ciComposeUp -Pci --no-daemon
- name: Upload test reports - name: Upload test reports
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: test-results name: test-results
path: build/reports/tests/test path: build/reports/tests/test
- name: Publish Test Report - name: Publish Test Report
uses: dorny/test-reporter@v1 uses: dorny/test-reporter@v3
if: always() if: always()
with: with:
name: JUnit Tests name: JUnit Tests
+40 -27
View File
@@ -1,3 +1,4 @@
import com.avast.gradle.dockercompose.ComposeExtension
import org.jlleitschuh.gradle.ktlint.KtlintExtension import org.jlleitschuh.gradle.ktlint.KtlintExtension
val ktorVersion: Provider<String> = providers.gradleProperty("ktor_version") val ktorVersion: Provider<String> = providers.gradleProperty("ktor_version")
@@ -49,29 +50,42 @@ tasks.withType<Test>().configureEach {
useJUnitPlatform() useJUnitPlatform()
} }
dockerCompose { configure<ComposeExtension> {
val composeFile = createNested("test").apply {
if (project.hasProperty("ci")) { useComposeFiles.set(listOf("docker/docker-compose-test.yaml"))
// Use docker-compose-ci.yaml for the CI setProjectName("event-demo-test")
"docker/docker-compose-ci.yaml" }
} else { createNested("dev").apply {
// Use docker-compose-test.yaml for local tests useComposeFiles.set(listOf("docker/docker-compose-dev.yaml"))
"docker/docker-compose-test.yaml" setProjectName("event-demo-dev")
} }
useComposeFiles.set(listOf(composeFile)) createNested("ci").apply {
setProjectName("event-demo-test") useComposeFiles.set(listOf("docker/docker-compose-ci.yaml"))
setProjectName("event-demo-ci")
}
} }
tasks.test { tasks.test {
dependsOn("composeUp") if (project.hasProperty("ci")) {
dockerCompose.useComposeFiles.set(listOf("docker/docker-compose-test.yaml")) dependsOn("ciComposeUp")
dockerCompose.setProjectName("event-demo-test") } else {
dependsOn("testComposeUp")
}
} }
tasks.named("run") { tasks.named("run") {
dependsOn("composeUp") dependsOn("devComposeUp")
dockerCompose.useComposeFiles.set(listOf("docker/docker-compose-test.yaml")) }
dockerCompose.setProjectName("event-demo-dev") tasks.composeUp {
dependsOn("copyEnv")
}
tasks.named("devComposeUp") {
dependsOn("copyEnv")
}
tasks.named("testComposeUp") {
dependsOn("copyEnv")
}
tasks.named("ciComposeUp") {
dependsOn("copyEnv")
} }
tasks.register<Copy>("copyEnv") { tasks.register<Copy>("copyEnv") {
@@ -88,13 +102,15 @@ tasks.register<Copy>("copyEnv") {
exclude() exclude()
} }
} }
val files =
buildList {
add(File("docker/postgresql.secret"))
if (!project.hasProperty("ci")) {
add(File("docker/pgadmin.secret"))
}
}
outputs.files(*files.toTypedArray())
doLast { doLast {
val files =
listOf(
File("docker/pgadmin.secret"),
File("docker/postgresql.secret"),
)
files.forEach { files.forEach {
if (!it.exists()) { if (!it.exists()) {
it.writeText("changeit") it.writeText("changeit")
@@ -102,9 +118,6 @@ tasks.register<Copy>("copyEnv") {
} }
} }
} }
tasks.composeUp {
dependsOn("copyEnv")
}
dependencies { dependencies {
implementation("io.ktor:ktor-server-core-jvm") implementation("io.ktor:ktor-server-core-jvm")
+2 -3
View File
@@ -1,6 +1,5 @@
name: event-demo-test name: event-demo-ci
include: include:
- path: - path:
- parts/docker-compose-databases.yaml - parts/docker-compose-databases.yaml
- parts/docker-compose-databases-expose.yaml - parts/docker-compose-databases-expose.yaml
- parts/docker-compose-traefik.yaml
+4
View File
@@ -0,0 +1,4 @@
name: event-demo-test
include:
- path:
- docker-compose-test.yaml
+1 -6
View File
@@ -24,8 +24,6 @@ services:
environment: environment:
POSTGRES_PASSWORD_FILE: /run/secrets/postgresql_password POSTGRES_PASSWORD_FILE: /run/secrets/postgresql_password
POSTGRES_USER: event-demo POSTGRES_USER: event-demo
secrets:
- postgresql_password
healthcheck: healthcheck:
test: ["CMD-SHELL", "sh -c 'pg_isready -U event-demo'"] test: ["CMD-SHELL", "sh -c 'pg_isready -U event-demo'"]
interval: 1s interval: 1s
@@ -33,6 +31,7 @@ services:
retries: 10 retries: 10
volumes: volumes:
- postgresql_data:/var/lib/postgresql - postgresql_data:/var/lib/postgresql
- ../postgresql.secret:/run/secrets/postgresql_password:ro
rabbitmq: rabbitmq:
image: rabbitmq:4-management-alpine image: rabbitmq:4-management-alpine
@@ -47,10 +46,6 @@ services:
volumes: volumes:
- rabbitmq_data:/var/lib/rabbitmq/ - rabbitmq_data:/var/lib/rabbitmq/
secrets:
postgresql_password:
file: ../postgresql.secret
volumes: volumes:
redis_data: redis_data:
redisinsight_data: redisinsight_data:
@@ -37,16 +37,8 @@ abstract class GameEventManager(
return this return this
} }
protected fun <G : Game> Game.isStatusOrFail( protected inline fun <reified G : Game> Game.isStatusOrFail(message: String): G =
kClass: KClass<G>, this as? G ?: throw CommandException(message)
message: String,
): G {
if (kClass.isInstance(this)) {
return this as G
} else {
throw CommandException(message)
}
}
protected fun <T> retry( protected fun <T> retry(
mapAttempts: Int = 5, mapAttempts: Int = 5,
@@ -20,7 +20,7 @@ class JoinTheGameHandler(
retry { retry {
command command
.getGame() .getGame()
.isStatusOrFail(GameCreated::class, "The game is started") .isStatusOrFail<GameCreated>("The game is started")
.userJoinTheGame( .userJoinTheGame(
userId = command.userId, userId = command.userId,
name = user.username, name = user.username,
@@ -16,7 +16,7 @@ class PlayCardHandler(
override fun handle(command: PlayCardCommand) { override fun handle(command: PlayCardCommand) {
command command
.getGame() .getGame()
.isStatusOrFail(GameStarted::class, "The game is not started") .isStatusOrFail<GameStarted>("The game is not started")
.playTheCard( .playTheCard(
card = command.payload.card, card = command.payload.card,
playerId = command.payload.playerId, playerId = command.payload.playerId,
@@ -16,7 +16,7 @@ class ReadyToPlayHandler(
override fun handle(command: ReadyToPlayCommand) { override fun handle(command: ReadyToPlayCommand) {
command command
.getGame() .getGame()
.isStatusOrFail(GameCreated::class, "The game is started") .isStatusOrFail<GameCreated>("The game is started")
.setReadyPlayer(command.payload.playerId) .setReadyPlayer(command.payload.playerId)
.saveEvents() .saveEvents()
.publishEvents() .publishEvents()
@@ -18,7 +18,7 @@ class TakeCartFromDrawPileHandler(
override fun handle(command: TakeCartFromDrawPileCommand) { override fun handle(command: TakeCartFromDrawPileCommand) {
command command
.getGame() .getGame()
.isStatusOrFail(GameStarted::class, "The game is not started") .isStatusOrFail<GameStarted>("The game is not started")
.playerTakeCartFromDrawPile(command.payload.playerId, 1) .playerTakeCartFromDrawPile(command.payload.playerId, 1)
.saveEvents() .saveEvents()
.publishEvents() .publishEvents()
@@ -33,16 +33,17 @@ class EventStreamTest :
block(aggregateId) block(aggregateId)
} }
fun Koin.eventStreams(): List<EventStream<EventXTest, IdTest>> = fun Koin.eventStreams(): Map<String, EventStream<EventXTest, IdTest>> =
listOf( mapOf(
EventStreamInMemory(IdTest()), EventStreamInMemory::class.simpleName.toString() to EventStreamInMemory(IdTest()),
EventStreamInPostgresql( EventStreamInPostgresql::class.simpleName.toString() to
IdTest(), EventStreamInPostgresql(
dataSource = get(), IdTest(),
objectToString = { Json.encodeToString(it) }, dataSource = get(),
stringToObject = { Json.decodeFromString(it) }, objectToString = { Json.encodeToString(it) },
"game.game_event_stream", stringToObject = { Json.decodeFromString(it) },
), "game.game_event_stream",
),
) )
context("readVersionBetween should only return the event of aggregate") { context("readVersionBetween should only return the event of aggregate") {