Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.typesafegithub.workflows

import com.google.devtools.ksp.processing.CodeGenerator
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ksp.writeTo

fun generateVersionInfo(
codeGenerator: CodeGenerator,
libraryVersion: String,
) {
val funSpec =
FunSpec
.builder(name = "getLibraryVersion")
.addModifiers(KModifier.INTERNAL)
.returns(String::class)
.addCode(CodeBlock.of("return \"$libraryVersion\""))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the best I could do to pass the version known in build time to the library. I tried with JAR metadata, with no success.

.build()

val fileSpec =
FileSpec
.builder(packageName = "io.github.typesafegithub.workflows.internal", fileName = "VersionInfo.kt")
.addFunction(funSpec)
.build()

fileSpec.writeTo(codeGenerator = codeGenerator, aggregating = false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import io.github.typesafegithub.workflows.dsl.expressions.generateEventPayloads
import io.github.typesafegithub.workflows.generateVersionInfo

class KspGenerator(
private val codeGenerator: CodeGenerator,
private val libraryVersion: String,
) : SymbolProcessor {
private var wasRun = false

override fun process(resolver: Resolver): List<KSAnnotated> {
if (!wasRun) {
generateEventPayloads(codeGenerator = codeGenerator)
generateVersionInfo(codeGenerator = codeGenerator, libraryVersion = libraryVersion)
wasRun = true
}
return emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ class KspGeneratorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
KspGenerator(
codeGenerator = environment.codeGenerator,
libraryVersion = environment.options["library-version"] ?: error("No library version specified"),
)
}
1 change: 1 addition & 0 deletions github-workflows-kt/api/github-workflows-kt.api
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ public abstract class io/github/typesafegithub/workflows/domain/actions/Action {
public abstract fun buildOutputObject (Ljava/lang/String;)Lio/github/typesafegithub/workflows/domain/actions/Action$Outputs;
public abstract fun getUsesString ()Ljava/lang/String;
public final fun getYamlArgumentsString ()Ljava/lang/String;
public fun isCompatibleWithLibraryVersion (Ljava/lang/String;)Z
public abstract fun toYamlArguments ()Ljava/util/LinkedHashMap;
}

Expand Down
4 changes: 4 additions & 0 deletions github-workflows-kt/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ kotlin {
explicitApi()
}

ksp {
arg("library-version", project.version.toString())
}

fun ConfigurableKtLintTask.kotlinterConfig() {
exclude { it.file.invariantSeparatorsPath.contains("/generated/") }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.github.typesafegithub.workflows.domain.actions.Action
import io.github.typesafegithub.workflows.domain.actions.Action.Outputs
import io.github.typesafegithub.workflows.domain.contexts.Contexts
import io.github.typesafegithub.workflows.dsl.HasCustomArguments
import io.github.typesafegithub.workflows.internal.getLibraryVersion
import kotlinx.serialization.Contextual

@Suppress("LongParameterList")
Expand Down Expand Up @@ -88,4 +89,10 @@ public open class ActionStep<out OUTPUTS : Outputs>(
) {
override val outputs: OUTPUTS
get() = super.outputs

init {
assert(action.isCompatibleWithLibraryVersion(getLibraryVersion())) {
"This version of the library is not compatible with the provided action binding!"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public abstract class Action<out OUTPUTS : Outputs> {

public abstract val usesString: String

public open fun isCompatibleWithLibraryVersion(libraryVersion: String): Boolean = true
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll be able to override it in the future releases of the server, so that it runs different logic depending on the version of the server routes.


public open class Outputs(
private val stepId: String,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package io.github.typesafegithub.workflows.domain

import io.github.typesafegithub.workflows.actions.actions.Checkout
import io.github.typesafegithub.workflows.domain.AbstractResult.Status
import io.github.typesafegithub.workflows.domain.actions.Action
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

Expand Down Expand Up @@ -31,4 +33,30 @@ class StepTest :
val step0: Step<*> = CommandStep(id = "step-0", command = "ls")
step0.outputs["foo"] shouldBe "steps.step-0.outputs.foo"
}

test("incompatible library version with the binding") {
// Given
val incompatibleAction =
object : Action<Action.Outputs>() {
override fun isCompatibleWithLibraryVersion(libraryVersion: String): Boolean = false

override fun toYamlArguments(): LinkedHashMap<String, String> =
throw NotImplementedError("Irrelevant for this test")

override fun buildOutputObject(stepId: String): Outputs = Outputs(stepId)

override val usesString: String
get() = throw NotImplementedError("Irrelevant for this test")
}

// When
shouldThrow<AssertionError> {
ActionStep(
id = "whatever",
action = incompatibleAction,
)
}.also {
it.message shouldBe "This version of the library is not compatible with the provided action binding!"
}
}
})
Loading