diff --git a/plugin/src/main/kotlin/io/github/pshevche/act/ActExec.kt b/plugin/src/main/kotlin/io/github/pshevche/act/ActExec.kt index 1c38c39..6d77a27 100644 --- a/plugin/src/main/kotlin/io/github/pshevche/act/ActExec.kt +++ b/plugin/src/main/kotlin/io/github/pshevche/act/ActExec.kt @@ -43,6 +43,20 @@ open class ActExec : DefaultTask() { */ fun env(action: Action) = action.execute(env) + /** + * Inputs to make available to actions. + * Can be specified in a separate file (default .input) or as a map of values. + */ + @get:Nested + @get:Optional + val actionInputs: GithubActionInput = DefaultGithubActionInput(objects, projectDir.file(".input").asFile) + + /** + * Inputs to make available to actions. + * Can be specified in a separate file (default .input) or as a map of values. + */ + fun actionInputs(action: Action) = action.execute(actionInputs) + /** * Secrets to make available to actions. * Can be specified in a separate file (default .secrets) or as a map of values. @@ -84,6 +98,8 @@ open class ActExec : DefaultTask() { runner.workflows(workflows.get()) .envFile(env.file.orNull) .envValues(env.values.get()) + .inputsFile(actionInputs.file.orNull) + .inputValues(actionInputs.values.get()) .secretsFile(secrets.file.orNull) .secretValues(secrets.values.get()) .variablesFile(variables.file.orNull) diff --git a/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActConfigBuilder.kt b/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActConfigBuilder.kt index 2113e1b..71e9e27 100644 --- a/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActConfigBuilder.kt +++ b/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActConfigBuilder.kt @@ -14,6 +14,8 @@ abstract class ActConfigBuilder { var secretValues: Map = emptyMap() var variablesFile: File? = null var variableValues: Map = emptyMap() + var inputsFile: File? = null + var inputValues: Map = emptyMap() fun workflows(workflows: File): ActConfigBuilder { this.workflows = workflows @@ -78,4 +80,19 @@ abstract class ActConfigBuilder { this.variableValues = mapOf(*values) return this } + + fun inputsFile(file: File?): ActConfigBuilder { + this.inputsFile = file + return this + } + + fun inputValues(values: Map): ActConfigBuilder { + this.inputValues = values + return this + } + + fun inputValues(vararg values: Pair): ActConfigBuilder { + this.inputValues = mapOf(*values) + return this + } } diff --git a/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActRunner.kt b/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActRunner.kt index e9efba0..490b552 100644 --- a/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActRunner.kt +++ b/plugin/src/main/kotlin/io/github/pshevche/act/internal/ActRunner.kt @@ -44,6 +44,12 @@ class ActRunner : ActConfigBuilder() { } addAll(envValues.flatMap { listOf("--env", "${it.key}=${it.value}") }) + inputsFile?.let { + add("--input-file") + add(it.path) + } + addAll(inputValues.flatMap { listOf("--input", "${it.key}=${it.value}") }) + secretsFile?.let { add("--secret-file") add(it.path) diff --git a/plugin/src/test/kotlin/io/github/pshevche/act/ActExecFuncTest.kt b/plugin/src/test/kotlin/io/github/pshevche/act/ActExecFuncTest.kt index 45e2f47..824ba8c 100644 --- a/plugin/src/test/kotlin/io/github/pshevche/act/ActExecFuncTest.kt +++ b/plugin/src/test/kotlin/io/github/pshevche/act/ActExecFuncTest.kt @@ -344,4 +344,76 @@ class ActExecFuncTest : FreeSpec({ result.output shouldContain "Hallo, Welt!" } } + + "configures inputs" - { + "as values" { + workspace.addWorkflows(".github/workflows/", "hello_inputs") + workspace.execTask("actInputValues") { + inputValues( + "GREETING" to "Hallo", + "NAME" to "Welt" + ) + } + + val result = runner.build("actInputValues") + + result.shouldSucceed(":actInputValues") + result.shouldHaveSuccessfulJobs("print_greeting_with_inputs") + result.output shouldContain "Hallo, Welt!" + } + + "from default file" { + workspace.addWorkflows(".github/workflows/", "hello_inputs") + workspace.dir.resolve(".input").apply { + createNewFile() + appendText("GREETING=Hallo\n") + appendText("NAME=Welt\n") + } + workspace.execTask("actInputFile") + + val result = runner.build("actInputFile") + + result.shouldSucceed(":actInputFile") + result.shouldHaveSuccessfulJobs("print_greeting_with_inputs") + result.output shouldContain "Hallo, Welt!" + } + + "from custom file" { + workspace.addWorkflows(".github/workflows/", "hello_inputs") + val customInputs = workspace.dir.resolve(".customInput") + customInputs.apply { + createNewFile() + appendText("GREETING=Hallo\n") + appendText("NAME=Welt\n") + } + workspace.execTask("actInputFile") { + inputsFile = customInputs + } + + val result = runner.build("actInputFile") + + result.shouldSucceed(":actInputFile") + result.shouldHaveSuccessfulJobs("print_greeting_with_inputs") + result.output shouldContain "Hallo, Welt!" + } + + "both from file and as values" { + workspace.addWorkflows(".github/workflows/", "hello_inputs") + val customInputs = workspace.dir.resolve(".customInput") + customInputs.apply { + createNewFile() + appendText("GREETING=Hallo\n") + } + workspace.execTask("actInputFileAndValues") { + inputsFile = customInputs + inputValues("NAME" to "Welt") + } + + val result = runner.build("actInputFileAndValues") + + result.shouldSucceed(":actInputFileAndValues") + result.shouldHaveSuccessfulJobs("print_greeting_with_inputs") + result.output shouldContain "Hallo, Welt!" + } + } }) diff --git a/plugin/src/test/kotlin/io/github/pshevche/act/fixtures/ActExecTaskBuilder.kt b/plugin/src/test/kotlin/io/github/pshevche/act/fixtures/ActExecTaskBuilder.kt index 488e059..72f8505 100644 --- a/plugin/src/test/kotlin/io/github/pshevche/act/fixtures/ActExecTaskBuilder.kt +++ b/plugin/src/test/kotlin/io/github/pshevche/act/fixtures/ActExecTaskBuilder.kt @@ -11,17 +11,6 @@ class ActExecTaskBuilder : ActConfigBuilder() { taskConfigBuilder.append("workflows = file('${it.path}')\n") } - if (additionalArgs.isNotEmpty()) { - taskConfigBuilder.append( - "additionalArgs = [${ - additionalArgs.joinToString( - separator = ", ", - transform = { "'$it'" } - ) - }]\n" - ) - } - timeout?.let { taskConfigBuilder.append("timeout = java.time.Duration.ofMillis(${it.toMillis()})\n") } @@ -29,7 +18,6 @@ class ActExecTaskBuilder : ActConfigBuilder() { envFile?.let { taskConfigBuilder.append("env.file.set(file('${it.path}'))\n") } - if (envValues.isNotEmpty()) { val valuesAsString = envValues.map { e -> "\"${e.key}\": \"${e.value}\"" }.joinToString(", ") taskConfigBuilder.append("env { values.set([$valuesAsString]) }\n") @@ -38,7 +26,6 @@ class ActExecTaskBuilder : ActConfigBuilder() { secretsFile?.let { taskConfigBuilder.append("secrets.file.set(file('${it.path}'))\n") } - if (secretValues.isNotEmpty()) { val valuesAsString = secretValues.map { e -> "\"${e.key}\": \"${e.value}\"" }.joinToString(", ") taskConfigBuilder.append("secrets { values.set([$valuesAsString]) }\n") @@ -47,12 +34,30 @@ class ActExecTaskBuilder : ActConfigBuilder() { variablesFile?.let { taskConfigBuilder.append("variables.file.set(file('${it.path}'))\n") } - if (variableValues.isNotEmpty()) { val valuesAsString = variableValues.map { e -> "\"${e.key}\": \"${e.value}\"" }.joinToString(", ") taskConfigBuilder.append("variables { values.set([$valuesAsString]) }\n") } + inputsFile?.let { + taskConfigBuilder.append("actionInputs.file.set(file('${it.path}'))\n") + } + if (inputValues.isNotEmpty()) { + val valuesAsString = inputValues.map { e -> "\"${e.key}\": \"${e.value}\"" }.joinToString(", ") + taskConfigBuilder.append("actionInputs { values.set([$valuesAsString]) }\n") + } + + if (additionalArgs.isNotEmpty()) { + taskConfigBuilder.append( + "additionalArgs = [${ + additionalArgs.joinToString( + separator = ", ", + transform = { "'$it'" } + ) + }]\n" + ) + } + return taskConfigBuilder.toString() } } diff --git a/plugin/src/test/resources/workflows/hello_inputs.yml b/plugin/src/test/resources/workflows/hello_inputs.yml new file mode 100644 index 0000000..6d7a672 --- /dev/null +++ b/plugin/src/test/resources/workflows/hello_inputs.yml @@ -0,0 +1,17 @@ +name: Hello World +on: + workflow_dispatch: + inputs: + GREETING: + required: true + type: string + NAME: + required: true + type: string + +jobs: + print_greeting_with_inputs: + runs-on: ubuntu-latest + steps: + - name: Greet someone + run: echo "${{ inputs.GREETING }}, ${{ inputs.NAME }}!"