Skip to content

Commit 5f5fffe

Browse files
authored
feat(dsl): allow specifying Kotlin step's condition in Kotlin (#1410)
It creates a synthetic step prior to running the actual step where the condition is specified. Lets the user avoid crafting complicated string-based GitHub expressions, in favor of a type-safe Kotlin code returning a boolean.
1 parent fc09300 commit 5f5fffe

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,9 +1885,9 @@ public final class io/github/typesafegithub/workflows/dsl/JobBuilder : io/github
18851885
public final fun getTimeoutMinutes ()Ljava/lang/Integer;
18861886
public fun get_customArguments ()Ljava/util/Map;
18871887
public final fun run ([Lkotlin/Unit;Ljava/lang/String;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;)Lio/github/typesafegithub/workflows/domain/CommandStep;
1888-
public final fun run ([Lkotlin/Unit;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Lio/github/typesafegithub/workflows/domain/KotlinLogicStep;
1888+
public final fun run ([Lkotlin/Unit;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Lio/github/typesafegithub/workflows/domain/KotlinLogicStep;
18891889
public static synthetic fun run$default (Lio/github/typesafegithub/workflows/dsl/JobBuilder;[Lkotlin/Unit;Ljava/lang/String;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/domain/CommandStep;
1890-
public static synthetic fun run$default (Lio/github/typesafegithub/workflows/dsl/JobBuilder;[Lkotlin/Unit;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/domain/KotlinLogicStep;
1890+
public static synthetic fun run$default (Lio/github/typesafegithub/workflows/dsl/JobBuilder;[Lkotlin/Unit;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/Boolean;Ljava/lang/Integer;Lio/github/typesafegithub/workflows/domain/Shell;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/domain/KotlinLogicStep;
18911891
public final fun uses ([Lkotlin/Unit;Lio/github/typesafegithub/workflows/domain/actions/Action;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Ljava/util/Map;)Lio/github/typesafegithub/workflows/domain/ActionStep;
18921892
public static synthetic fun uses$default (Lio/github/typesafegithub/workflows/dsl/JobBuilder;[Lkotlin/Unit;Lio/github/typesafegithub/workflows/domain/actions/Action;Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;Ljava/util/Map;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/domain/ActionStep;
18931893
}

github-workflows-kt/src/main/kotlin/io/github/typesafegithub/workflows/dsl/JobBuilder.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import io.github.typesafegithub.workflows.domain.RunnerType
1515
import io.github.typesafegithub.workflows.domain.Shell
1616
import io.github.typesafegithub.workflows.domain.actions.Action
1717
import io.github.typesafegithub.workflows.domain.contexts.Contexts
18+
import io.github.typesafegithub.workflows.dsl.expressions.expr
1819
import kotlinx.serialization.Contextual
1920
import kotlin.io.path.name
2021

@@ -104,6 +105,7 @@ public class JobBuilder<OUTPUT : JobOutputs>(
104105
@SuppressWarnings("FunctionParameterNaming")
105106
`if`: String? = null,
106107
condition: String? = null,
108+
ifKotlin: (Contexts.() -> Boolean)? = null,
107109
continueOnError: Boolean? = null,
108110
timeoutMinutes: Int? = null,
109111
shell: Shell? = null,
@@ -112,17 +114,25 @@ public class JobBuilder<OUTPUT : JobOutputs>(
112114
_customArguments: Map<String, @Contextual Any> = mapOf(),
113115
logic: Contexts.() -> Unit,
114116
): KotlinLogicStep {
115-
require(!(`if` != null && condition != null)) {
116-
"Either 'if' or 'condition' have to be set, not both!"
117+
require(listOfNotNull(`if`, condition, ifKotlin).size <= 1) {
118+
"Only one of 'if', 'condition' or `ifKotlin` can be set!"
117119
}
118120
require(job.steps.filterIsInstance<ActionStep<*>>().any { "/checkout@" in it.action.usesString }) {
119121
"Please check out the code prior to using Kotlin-based 'run' block!"
120122
}
121123
val sourceFile =
122124
workflowBuilder.workflow.sourceFile
123125
?: throw IllegalArgumentException("sourceFile needs to be set when using Kotlin-based 'run' block!")
124-
val id = "step-${job.steps.size}"
126+
val evaluationResultOutput = "evaluation-result"
125127

128+
val conditionCheckingStep =
129+
ifKotlin?.let {
130+
run {
131+
outputs[evaluationResultOutput] = ifKotlin().toString()
132+
}
133+
}
134+
135+
val id = "step-${job.steps.size}"
126136
val newStep =
127137
KotlinLogicStep(
128138
id = id,
@@ -133,7 +143,10 @@ public class JobBuilder<OUTPUT : JobOutputs>(
133143
command = "GHWKT_RUN_STEP='${this.id}:$id' '.github/workflows/${sourceFile.name}'",
134144
logic = logic,
135145
env = LinkedHashMap(env.toMap() + mapOf("GHWKT_GITHUB_CONTEXT_JSON" to "${'$'}{{ toJSON(github) }}")),
136-
condition = `if` ?: condition,
146+
condition =
147+
conditionCheckingStep?.let {
148+
expr { "steps.${conditionCheckingStep.id}.outputs.$evaluationResultOutput" }
149+
} ?: `if` ?: condition,
137150
continueOnError = continueOnError,
138151
timeoutMinutes = timeoutMinutes,
139152
shell = shell,

0 commit comments

Comments
 (0)