WorkflowKt is a Kotlin-first framework for building and running GitHub Actions workflows as executable Kotlin code inside your project.
Instead of maintaining brittle YAML files and shell scripts, WorkflowKt lets you express CI logic using real Kotlin, with direct access to your application modules, shared utilities, and the entire JVM ecosystem. Workflows become type-safe, testable, and versioned alongside your code.
GitHub Actions workflows often start simple but quickly grow into complex, hard-to-test YAML files that are disconnected from the actual application logic.
WorkflowKt is designed to close that gap by allowing you to:
- Implement workflows as strongly typed Kotlin code
- Share logic between CI and application modules
- Use existing Kotlin and JVM libraries without workarounds
- Run and debug workflows locally before pushing changes
With WorkflowKt, CI is no longer configuration. It is part of your software.
WorkflowKt is distributed as a Gradle plugin and a runtime library.
The plugin is responsible for discovering and registering workflow actions.
plugins {
id("ir.amirroid.workflowkt") version "0.0.1"
}The runtime provides core abstractions such as GithubAction, ActionContext, and ActionResult.
dependencies {
implementation("ir.amirroid:workflowkt-core:0.0.1")
}In WorkflowKt, every workflow is a Kotlin class that implements GithubAction.
A workflow defines:
- When it runs – by selecting an
ActionContextthat maps to a GitHub event - What it does – implemented as normal Kotlin code
- How it finishes – communicated through an
ActionResult
This model keeps workflows explicit, readable, and type-safe.
class RunTestsAndNotifyWithEmail : GithubAction<WorkflowDispatchContext> {
override fun run(
context: WorkflowDispatchContext,
environment: GithubEnvironment
): ActionResult {
// Execute tests, publish reports, send notifications, etc.
return ActionResult.Success()
}
}The returned ActionResult controls the outcome of the GitHub Actions step:
ActionResult.Successcompletes the step successfully and allows the workflow to continue.ActionResult.Failurefails the step and stops further workflow execution.
sealed interface ActionResult {
data class Success(val result: Map<String, String>? = null) : ActionResult
data class Failure(val reason: String? = null) : ActionResult
}WorkflowKt provides typed representations of common GitHub event payloads:
| Context | GitHub Event |
|---|---|
IssueContext |
issues |
PullRequestContext |
pull_request |
PushContext |
push |
ReleaseContext |
release |
ScheduleContext |
schedule |
WorkflowDispatchContext |
workflow_dispatch |
CreateContext |
create |
Each context provides typed access to the corresponding GitHub event payload.
Actions must be registered using the Gradle plugin so they can be executed by GitHub Actions or locally.
workflowkt {
registerAction(
key = "print_helloworld",
implementationClass = "ir.amirroid.workflowkt.samples.PrintHelloWorldGithubAction"
)
}- The first parameter is the action key used to reference the workflow.
- The second parameter is the fully qualified class name of the
GithubActionimplementation.
Once registered, an action can be executed by invoking the Gradle task:
./gradlew runWorkflowKt --key=run_testsThis task is typically called from a minimal GitHub Actions YAML file.
WorkflowKt supports executing workflows locally, without GitHub Actions, to simplify development and debugging.
Local execution relies on an environment properties file that mimics GitHub Actions variables.
Default location:
rootProject/workflowkt.properties
You can override this file in Gradle:
workflowkt {
testEnvironmentFile = rootProject.file("custom_env.properties")
}GITHUB_EVENT_PATH– path to the JSON file containing the GitHub event payloadGITHUB_EVENT_NAME– optional; inferred automatically if not provided
./gradlew testWorkflowKt --key=print_helloworldThis makes it possible to validate workflow behavior before pushing commits or opening pull requests.
WorkflowKt turns GitHub Actions from configuration files into real, testable Kotlin code.
It improves maintainability, enables local testing, and keeps CI logic close to the application it builds.
Licensed under the MIT License.