Skip to content

Commit 984db40

Browse files
authored
feat(library): allow fallback to local bindings server in consistency check job (#1767)
Part of #1765. If enabled, mitigates availability issues with the bindings server in the consistency check job.
1 parent 30546e6 commit 984db40

File tree

4 files changed

+130
-7
lines changed

4 files changed

+130
-7
lines changed

github-workflows-kt/api/github-workflows-kt.api

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,16 +3092,18 @@ public abstract interface class io/github/typesafegithub/workflows/yaml/Consiste
30923092
}
30933093

30943094
public final class io/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration : io/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig {
3095-
public fun <init> (Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;)V
3095+
public fun <init> (Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;Z)V
30963096
public final fun component1 ()Ljava/lang/String;
30973097
public final fun component2 ()Ljava/util/Map;
30983098
public final fun component3 ()Lkotlin/jvm/functions/Function1;
3099-
public final fun copy (Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;
3100-
public static synthetic fun copy$default (Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;
3099+
public final fun component4 ()Z
3100+
public final fun copy (Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;Z)Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;
3101+
public static synthetic fun copy$default (Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;ZILjava/lang/Object;)Lio/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig$Configuration;
31013102
public fun equals (Ljava/lang/Object;)Z
31023103
public final fun getAdditionalSteps ()Lkotlin/jvm/functions/Function1;
31033104
public final fun getCondition ()Ljava/lang/String;
31043105
public final fun getEnv ()Ljava/util/Map;
3106+
public final fun getUseLocalBindingsServerAsFallback ()Z
31053107
public fun hashCode ()I
31063108
public fun toString ()Ljava/lang/String;
31073109
}

github-workflows-kt/src/main/kotlin/io/github/typesafegithub/workflows/yaml/ConsistencyCheckJob.kt

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package io.github.typesafegithub.workflows.yaml
22

3+
import io.github.typesafegithub.workflows.domain.AbstractResult.Status
34
import io.github.typesafegithub.workflows.domain.Job
45
import io.github.typesafegithub.workflows.domain.JobOutputs
56
import io.github.typesafegithub.workflows.domain.RunnerType.UbuntuLatest
67
import io.github.typesafegithub.workflows.domain.actions.CustomAction
78
import io.github.typesafegithub.workflows.dsl.WorkflowBuilder
9+
import io.github.typesafegithub.workflows.dsl.expressions.expr
810
import io.github.typesafegithub.workflows.internal.relativeToAbsolute
911
import java.nio.file.Path
1012
import kotlin.io.path.invariantSeparatorsPathString
1113

14+
@Suppress("LongMethod")
1215
internal fun WorkflowBuilder.consistencyCheckJob(
1316
sourceFilePath: String?,
1417
targetFileName: String?,
@@ -51,10 +54,45 @@ internal fun WorkflowBuilder.consistencyCheckJob(
5154
block()
5255
}
5356

54-
run(
55-
name = "Execute script",
56-
command = "rm '$targetFilePath' && '$sourceFilePath'",
57-
)
57+
if (consistencyCheckJobConfig.useLocalBindingsServerAsFallback) {
58+
val firstCompilationStep =
59+
run(
60+
name = "Execute script",
61+
command = "rm '$targetFilePath' && '$sourceFilePath'",
62+
continueOnError = true,
63+
)
64+
val ifFirstCompilationFails = expr { firstCompilationStep.outcome.neq(Status.Success) }
65+
run(
66+
name = "Start the local server",
67+
command = "docker run -p 8080:8080 krzema12/github-workflows-kt-jit-binding-server &",
68+
condition = ifFirstCompilationFails,
69+
)
70+
run(
71+
name = "Wait for the server",
72+
command =
73+
"curl --head -X GET --retry 60 --retry-all-errors --retry-delay 1 " +
74+
"http://localhost:8080/status",
75+
condition = ifFirstCompilationFails,
76+
)
77+
run(
78+
name = "Replace server URL in script",
79+
command =
80+
"sed -i -e 's/https:\\/\\/bindings.krzeminski.it/http:\\/\\/localhost:8080/g' " +
81+
sourceFilePath,
82+
condition = ifFirstCompilationFails,
83+
)
84+
run(
85+
name = "Execute script again",
86+
command = "rm -f '$targetFilePath' && '$sourceFilePath'",
87+
condition = ifFirstCompilationFails,
88+
)
89+
} else {
90+
run(
91+
name = "Execute script",
92+
command = "rm '$targetFilePath' && '$sourceFilePath'",
93+
)
94+
}
95+
5896
run(
5997
name = "Consistency check",
6098
command = "git diff --exit-code '$targetFilePath'",

github-workflows-kt/src/main/kotlin/io/github/typesafegithub/workflows/yaml/ConsistencyCheckJobConfig.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public val DEFAULT_CONSISTENCY_CHECK_JOB_CONFIG: ConsistencyCheckJobConfig.Confi
88
condition = null,
99
env = emptyMap(),
1010
additionalSteps = null,
11+
useLocalBindingsServerAsFallback = false,
1112
)
1213

1314
public sealed interface ConsistencyCheckJobConfig {
@@ -17,5 +18,12 @@ public sealed interface ConsistencyCheckJobConfig {
1718
val condition: String?,
1819
val env: Map<String, String>,
1920
val additionalSteps: (JobBuilder<JobOutputs.EMPTY>.() -> Unit)?,
21+
/**
22+
* If the script execution step in the consistency check job fails, another attempt to execute is made with a
23+
* local bindings server running.
24+
* An assumption is made that the bindings server is under `https://bindings.krzeminski.it`. It's currently not
25+
* configurable.
26+
*/
27+
val useLocalBindingsServerAsFallback: Boolean,
2028
) : ConsistencyCheckJobConfig
2129
}

github-workflows-kt/src/test/kotlin/io/github/typesafegithub/workflows/IntegrationTest.kt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,81 @@ class IntegrationTest :
240240
""".trimIndent()
241241
}
242242

243+
test("fallback for bindings server") {
244+
// when
245+
workflow(
246+
name = "Test workflow",
247+
on = listOf(Push()),
248+
sourceFile = sourceTempFile,
249+
consistencyCheckJobConfig =
250+
DEFAULT_CONSISTENCY_CHECK_JOB_CONFIG.copy(
251+
useLocalBindingsServerAsFallback = true,
252+
),
253+
) {
254+
job(
255+
id = "test_job",
256+
runsOn = RunnerType.UbuntuLatest,
257+
) {
258+
run(
259+
name = "Hello world!",
260+
command = "echo 'hello!'",
261+
)
262+
}
263+
}
264+
265+
// then
266+
targetTempFile.readText() shouldBe
267+
"""
268+
# This file was generated using Kotlin DSL (.github/workflows/some_workflow.main.kts).
269+
# If you want to modify the workflow, please change the Kotlin file and regenerate this YAML file.
270+
# Generated with https://github.com/typesafegithub/github-workflows-kt
271+
272+
name: 'Test workflow'
273+
on:
274+
push: {}
275+
jobs:
276+
check_yaml_consistency:
277+
name: 'Check YAML consistency'
278+
runs-on: 'ubuntu-latest'
279+
steps:
280+
- id: 'step-0'
281+
name: 'Check out'
282+
uses: 'actions/checkout@v4'
283+
- id: 'step-1'
284+
name: 'Execute script'
285+
continue-on-error: true
286+
run: 'rm ''.github/workflows/some_workflow.yaml'' && ''.github/workflows/some_workflow.main.kts'''
287+
- id: 'step-2'
288+
name: 'Start the local server'
289+
run: 'docker run -p 8080:8080 krzema12/github-workflows-kt-jit-binding-server &'
290+
if: '${'$'}{{ steps.step-1.outcome != ''success'' }}'
291+
- id: 'step-3'
292+
name: 'Wait for the server'
293+
run: 'curl --head -X GET --retry 60 --retry-all-errors --retry-delay 1 http://localhost:8080/status'
294+
if: '${'$'}{{ steps.step-1.outcome != ''success'' }}'
295+
- id: 'step-4'
296+
name: 'Replace server URL in script'
297+
run: 'sed -i -e ''s/https:\/\/bindings.krzeminski.it/http:\/\/localhost:8080/g'' .github/workflows/some_workflow.main.kts'
298+
if: '${'$'}{{ steps.step-1.outcome != ''success'' }}'
299+
- id: 'step-5'
300+
name: 'Execute script again'
301+
run: 'rm -f ''.github/workflows/some_workflow.yaml'' && ''.github/workflows/some_workflow.main.kts'''
302+
if: '${'$'}{{ steps.step-1.outcome != ''success'' }}'
303+
- id: 'step-6'
304+
name: 'Consistency check'
305+
run: 'git diff --exit-code ''.github/workflows/some_workflow.yaml'''
306+
test_job:
307+
runs-on: 'ubuntu-latest'
308+
needs:
309+
- 'check_yaml_consistency'
310+
steps:
311+
- id: 'step-0'
312+
name: 'Hello world!'
313+
run: 'echo ''hello!'''
314+
315+
""".trimIndent()
316+
}
317+
243318
test("with concurrency, default behavior") {
244319
// when
245320
workflow(

0 commit comments

Comments
 (0)