Skip to content

Commit 0bdacb8

Browse files
authored
Extract business logic to separate function (#218)
Part of #204. Thanks to this change, we're able to unit-test the business logic. It's a piece of preparation before introducing scanning of the whole action's repo to also validate typings for sub-actions (actions that are not the top-level action, exisitng in the repo root).
1 parent 9808cf1 commit 0bdacb8

File tree

13 files changed

+185
-18
lines changed

13 files changed

+185
-18
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package it.krzeminski.githubactionstyping
2+
3+
import it.krzeminski.githubactionstyping.parsing.readYamlFile
4+
import java.nio.file.Path
5+
6+
/**
7+
* Runs validation for a given action, with its manifest files present in the current directory.
8+
*
9+
* @param repoRoot: Allows customizing which path should be taken as repo root for action(-types).y(a)ml file discovery.
10+
*
11+
* @return a pair where:
12+
* - the boolean means if the typings are valid
13+
* - the string is a printable report, with details about all inputs and outputs
14+
*/
15+
fun validateTypings(repoRoot: Path = Path.of(".")): Pair<Boolean, String> {
16+
val manifest = repoRoot.readYamlFile("action") ?:
17+
return Pair(false, "No action manifest (action.yml or action.yaml) found!")
18+
19+
val typesManifest = repoRoot.readYamlFile("action-types") ?:
20+
return Pair(false, "No types manifest (action-types.yml or action-types.yaml) found!")
21+
22+
return manifestsToReport(manifest, typesManifest)
23+
}

src/main/kotlin/it/krzeminski/githubactionstyping/Main.kt

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
package it.krzeminski.githubactionstyping
22

3-
import it.krzeminski.githubactionstyping.parsing.readYamlFile
43
import kotlin.system.exitProcess
54

65
fun main() {
7-
val typesManifest = readYamlFile("action-types") ?: run {
8-
println("No types manifest (action-types.yml or action-types.yaml) found!")
9-
exitProcess(1)
10-
throw IllegalStateException()
11-
}
12-
13-
val manifest = readYamlFile("action") ?: run {
14-
println("No action manifest (action.yml or action.yaml) found!")
15-
exitProcess(1)
16-
throw IllegalStateException()
17-
}
18-
19-
val (isValid, report) = manifestsToReport(manifest, typesManifest)
6+
val (isValid, report) = validateTypings()
207
println(report)
218

229
if (!isValid) {
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package it.krzeminski.githubactionstyping.parsing
22

3-
import java.io.File
3+
import java.nio.file.Path
4+
import kotlin.io.path.exists
5+
import kotlin.io.path.readText
46

5-
fun readYamlFile(nameWithoutExtension: String): String? =
7+
fun Path.readYamlFile(nameWithoutExtension: String): String? =
68
listOf("yaml", "yml")
79
.map { "$nameWithoutExtension.$it" }
8-
.firstOrNull { File(it).exists() }
9-
?.let { File(it).readText() }
10+
.firstOrNull { this.resolve(it).exists() }
11+
?.let { this.resolve(it).readText() }
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package it.krzeminski.githubactionstyping
2+
3+
import io.kotest.assertions.assertSoftly
4+
import io.kotest.core.spec.style.FunSpec
5+
import io.kotest.matchers.shouldBe
6+
import java.io.File
7+
import java.nio.file.Path
8+
9+
class LogicTest : FunSpec({
10+
val testRepos: Path = javaClass.classLoader.getResource("test-repos").let {
11+
File(it.toURI()).toPath()
12+
}
13+
14+
test("repo with only top-level action and valid typings") {
15+
// When
16+
val (isValid, report) = validateTypings(
17+
repoRoot = testRepos.resolve("repo-with-only-top-level-action-and-valid-typings"),
18+
)
19+
20+
// Then
21+
assertSoftly {
22+
isValid shouldBe true
23+
report shouldBe """
24+
Overall result:
25+
${'\u001b'}[32m✔ VALID${'\u001b'}[0m
26+
27+
Inputs:
28+
• verbose:
29+
${'\u001b'}[32m✔ VALID${'\u001b'}[0m
30+
• someEnum:
31+
${'\u001b'}[32m✔ VALID${'\u001b'}[0m
32+
33+
Outputs:
34+
None.
35+
36+
37+
""".trimIndent()
38+
}
39+
}
40+
41+
test("repo with only top-level action and invalid typings") {
42+
// When
43+
val (isValid, report) = validateTypings(
44+
repoRoot = testRepos.resolve("repo-with-only-top-level-action-and-invalid-typings"),
45+
)
46+
47+
// Then
48+
assertSoftly {
49+
isValid shouldBe false
50+
report shouldBe """
51+
Overall result:
52+
${'\u001b'}[31m❌ INVALID: Some typing is invalid.${'\u001b'}[0m
53+
54+
Inputs:
55+
• verbose:
56+
${'\u001b'}[32m✔ VALID${'\u001b'}[0m
57+
• someEnum:
58+
${'\u001b'}[31m❌ INVALID: 'allowed-values' is not allowed for this type.${'\u001b'}[0m
59+
60+
Outputs:
61+
None.
62+
63+
64+
""".trimIndent()
65+
}
66+
}
67+
68+
test("repo with only top-level action and no typings") {
69+
// When
70+
val (isValid, report) = validateTypings(
71+
repoRoot = testRepos.resolve("repo-with-only-top-level-action-and-no-typings"),
72+
)
73+
74+
// Then
75+
assertSoftly {
76+
isValid shouldBe false
77+
report shouldBe "No types manifest (action-types.yml or action-types.yaml) found!"
78+
}
79+
}
80+
81+
test("repo with only top-level action and top-level manifest") {
82+
// When
83+
val (isValid, report) = validateTypings(
84+
repoRoot = testRepos.resolve("repo-with-only-top-level-action-and-no-top-level-manifest"),
85+
)
86+
87+
// Then
88+
assertSoftly {
89+
isValid shouldBe false
90+
report shouldBe "No action manifest (action.yml or action.yaml) found!"
91+
}
92+
}
93+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm an action with just a single top-level "action.yml" and its associated typings that are invalid.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
inputs:
2+
verbose:
3+
type: boolean
4+
someEnum:
5+
type: string
6+
allowed-values:
7+
- foo
8+
- bar
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: GitHub Actions Typing
2+
description: Bring type-safety to your GitHub actions' API!
3+
author: Piotr Krzemiński
4+
inputs:
5+
verbose:
6+
description: 'Set to true to display debug information helpful when troubleshooting issues with this action.'
7+
required: false
8+
default: 'false'
9+
someEnum:
10+
description: 'Testing enum'
11+
required: false
12+
runs:
13+
using: 'docker'
14+
image: 'Dockerfile'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm an action with just a single top-level "action.yml" and no associated typings.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: GitHub Actions Typing
2+
description: Bring type-safety to your GitHub actions' API!
3+
author: Piotr Krzemiński
4+
inputs:
5+
verbose:
6+
description: 'Set to true to display debug information helpful when troubleshooting issues with this action.'
7+
required: false
8+
default: 'false'
9+
someEnum:
10+
description: 'Testing enum'
11+
required: false
12+
runs:
13+
using: 'docker'
14+
image: 'Dockerfile'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm an action with just a single top-level "action.yml" and no associated typings.

0 commit comments

Comments
 (0)