ci: UTF-8 локаль + ASCII-дефис в именах тестов; release через общий publish action
ci / JVM build + tests (push) Failing after 2m44s

- ci.yml/release.yml: LANG/LC_ALL=C.UTF-8 — иначе Kotlin-компилятор падает
  с InvalidPathException на именах тестов с типографским тире (LANG=C → ASCII)
- имена тестов: типографское тире U+2014 заменено на ASCII-дефис (16 шт)
- release.yml переведён на общий composite-action subochev/devops/publish@main
  (как у asr-kmp/litert-kmp/embedder-kmp); версия = имя тега релиза
This commit is contained in:
2026-09-18 22:15:51 +03:00
parent 2634e0e204
commit 741ad8963d
6 changed files with 45 additions and 64 deletions
@@ -555,7 +555,7 @@ class ChatAgentTest {
}
@Test
fun `agentEvents — Created + Deleted flow`() = runTest {
fun `agentEvents - Created + Deleted flow`() = runTest {
val agent = newAgent()
val events = mutableListOf<AgentEvent>()
val job = launch(start = kotlinx.coroutines.CoroutineStart.UNDISPATCHED) {
@@ -17,7 +17,7 @@ class LlmConfigTest {
}
@Test
fun `fromEnv — happy path`() {
fun `fromEnv - happy path`() {
val cfg = AppConfig.fromEnv { name ->
when (name) {
"OPENAI_BASE_URL" -> "https://api.openai.com/v1"
@@ -32,13 +32,13 @@ class LlmConfigTest {
}
@Test
fun `fromEnv — falls back to default system prompt`() {
fun `fromEnv - falls back to default system prompt`() {
val cfg = AppConfig.fromEnv(openAiEnv()).llm
assertEquals(LlmConfig.DEFAULT_SYSTEM_PROMPT, cfg.systemPrompt)
}
@Test
fun `fromEnv — missing base url throws`() {
fun `fromEnv - missing base url throws`() {
assertFailsWith<IllegalStateException> {
AppConfig.fromEnv { name ->
when (name) {
@@ -51,7 +51,7 @@ class LlmConfigTest {
}
@Test
fun `fromEnv — missing api key throws`() {
fun `fromEnv - missing api key throws`() {
assertFailsWith<IllegalStateException> {
AppConfig.fromEnv { name ->
when (name) {
@@ -64,7 +64,7 @@ class LlmConfigTest {
}
@Test
fun `fromEnv — missing model throws`() {
fun `fromEnv - missing model throws`() {
assertFailsWith<IllegalStateException> {
AppConfig.fromEnv { name ->
when (name) {
@@ -91,7 +91,7 @@ class LlmConfigTest {
}
@Test
fun `fromEnv — OPENAI_CONTEXT_WINDOW parsed into OpenAiConfig`() {
fun `fromEnv - OPENAI_CONTEXT_WINDOW parsed into OpenAiConfig`() {
val cfg = AppConfig.fromEnv { name ->
when (name) {
"OPENAI_BASE_URL" -> "https://api.openai.com/v1"
@@ -105,7 +105,7 @@ class LlmConfigTest {
}
@Test
fun `contextWindow — env parsed once and exposed via derived prop`() {
fun `contextWindow - env parsed once and exposed via derived prop`() {
// Старый resolveContextWindow проверял "env wins over config" — но в новой
// модели env и config это одно и то же значение (env читается один раз в
// AppConfig.fromEnv и сохраняется в OpenAiConfig.contextWindow). Поэтому
@@ -124,13 +124,13 @@ class LlmConfigTest {
}
@Test
fun `contextWindow — returns null when nothing set`() {
fun `contextWindow - returns null when nothing set`() {
val cfg = AppConfig.fromEnv(openAiEnv()).llm
assertEquals(null, cfg.contextWindow)
}
@Test
fun `fromEnv — OPENAI_CONTEXT_WINDOW garbage falls back to null`() {
fun `fromEnv - OPENAI_CONTEXT_WINDOW garbage falls back to null`() {
val cfg = AppConfig.fromEnv { name ->
when (name) {
"OPENAI_BASE_URL" -> "https://api.openai.com/v1"
@@ -28,7 +28,7 @@ class PersistenceTest {
}
@Test
fun `upsert + get conversation — roundtrip`() = runTest {
fun `upsert + get conversation - roundtrip`() = runTest {
val now = Instant.fromEpochMilliseconds(1_700_000_000_000)
val rec = ConversationRecord(
id = "c1",
@@ -114,7 +114,7 @@ class PersistenceTest {
}
@Test
fun `message audit log — append and read back`() = runTest {
fun `message audit log - append and read back`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
stores.messages.append(
MessageRecord.UserMessage("m1", "c1", listOf(Content.Text("hi")), t0),
@@ -147,7 +147,7 @@ class PersistenceTest {
}
@Test
fun `working memory — append + list preserves order`() = runTest {
fun `working memory - append + list preserves order`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
val t1 = Instant.fromEpochMilliseconds(1_700_000_001_000)
stores.workingMemory.append(
@@ -167,7 +167,7 @@ class PersistenceTest {
}
@Test
fun `working memory — compact without summary just drops tail`() = runTest {
fun `working memory - compact without summary just drops tail`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
stores.workingMemory.append("c1", WorkingMemoryEntry.User("m1", listOf(Content.Text("u1"))), t0)
stores.workingMemory.append("c1", WorkingMemoryEntry.Assistant("m2", listOf(Content.Text("a1"))), t0)
@@ -182,7 +182,7 @@ class PersistenceTest {
}
@Test
fun `working memory — compact with summary inserts Summary entry`() = runTest {
fun `working memory - compact with summary inserts Summary entry`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
stores.workingMemory.append("c1", WorkingMemoryEntry.User("m1", listOf(Content.Text("u1"))), t0)
stores.workingMemory.append("c1", WorkingMemoryEntry.Assistant("m2", listOf(Content.Text("a1"))), t0)
@@ -203,7 +203,7 @@ class PersistenceTest {
}
@Test
fun `working memory — compact with blank summaryText behaves as drop`() = runTest {
fun `working memory - compact with blank summaryText behaves as drop`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
stores.workingMemory.append("c1", WorkingMemoryEntry.User("m1", listOf(Content.Text("u1"))), t0)
val rows = stores.workingMemory.list("c1")
@@ -214,7 +214,7 @@ class PersistenceTest {
}
@Test
fun `working memory — compact is atomic on other conversations`() = runTest {
fun `working memory - compact is atomic on other conversations`() = runTest {
val t0 = Instant.fromEpochMilliseconds(1_700_000_000_000)
stores.workingMemory.append("c1", WorkingMemoryEntry.User("m1", listOf(Content.Text("u1"))), t0)
stores.workingMemory.append("c1", WorkingMemoryEntry.Assistant("m2", listOf(Content.Text("a1"))), t0)