Skip to content

Commit 2d36b76

Browse files
committed
feat(server): make it possible to POST custom typings for testing during typing creation
1 parent d7c77ab commit 2d36b76

File tree

9 files changed

+135
-26
lines changed

9 files changed

+135
-26
lines changed

action-binding-generator/api/action-binding-generator.api

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ public abstract interface annotation class io/github/typesafegithub/workflows/ac
22
}
33

44
public final class io/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords {
5-
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
5+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
6+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
67
public final fun component1 ()Ljava/lang/String;
78
public final fun component2 ()Ljava/lang/String;
89
public final fun component3 ()Ljava/lang/String;
9-
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
10-
public static synthetic fun copy$default (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
10+
public final fun component4 ()Ljava/lang/String;
11+
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
12+
public static synthetic fun copy$default (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
1113
public fun equals (Ljava/lang/Object;)Z
1214
public final fun getName ()Ljava/lang/String;
1315
public final fun getOwner ()Ljava/lang/String;
16+
public final fun getTypesUuid ()Ljava/lang/String;
1417
public final fun getVersion ()Ljava/lang/String;
1518
public fun hashCode ()I
1619
public fun toString ()Ljava/lang/String;
@@ -46,6 +49,7 @@ public final class io/github/typesafegithub/workflows/actionbindinggenerator/dom
4649

4750
public final class io/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource : java/lang/Enum {
4851
public static final field ACTION Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
52+
public static final field CUSTOM Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
4953
public static final field TYPING_CATALOG Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
5054
public static fun getEntries ()Lkotlin/enums/EnumEntries;
5155
public static fun valueOf (Ljava/lang/String;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
@@ -72,8 +76,8 @@ public final class io/github/typesafegithub/workflows/actionbindinggenerator/gen
7276
}
7377

7478
public final class io/github/typesafegithub/workflows/actionbindinggenerator/generation/GenerationKt {
75-
public static final fun generateBinding (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/MetadataRevision;Lio/github/typesafegithub/workflows/actionbindinggenerator/metadata/Metadata;Lkotlin/Pair;)Ljava/util/List;
76-
public static synthetic fun generateBinding$default (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/MetadataRevision;Lio/github/typesafegithub/workflows/actionbindinggenerator/metadata/Metadata;Lkotlin/Pair;ILjava/lang/Object;)Ljava/util/List;
79+
public static final fun generateBinding (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/MetadataRevision;Lio/github/typesafegithub/workflows/actionbindinggenerator/metadata/Metadata;Lkotlin/Pair;Ljava/lang/String;)Ljava/util/List;
80+
public static synthetic fun generateBinding$default (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/MetadataRevision;Lio/github/typesafegithub/workflows/actionbindinggenerator/metadata/Metadata;Lkotlin/Pair;Ljava/lang/String;ILjava/lang/Object;)Ljava/util/List;
7781
}
7882

7983
public final class io/github/typesafegithub/workflows/actionbindinggenerator/metadata/Input {

action-binding-generator/src/main/kotlin/io/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public data class ActionCoords(
44
val owner: String,
55
val name: String,
66
val version: String,
7+
val typesUuid: String? = null,
78
)
89

910
/**
@@ -12,7 +13,7 @@ public data class ActionCoords(
1213
*/
1314
public val ActionCoords.isTopLevel: Boolean get() = "/" !in name
1415

15-
public val ActionCoords.prettyPrint: String get() = "$owner/$name@$version"
16+
public val ActionCoords.prettyPrint: String get() = "$owner/$name@$version${typesUuid?.let { " (types: $it)" } ?: ""}"
1617

1718
/**
1819
* For most actions, it's the same as [ActionCoords.name].

action-binding-generator/src/main/kotlin/io/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ package io.github.typesafegithub.workflows.actionbindinggenerator.domain
33
public enum class TypingActualSource {
44
ACTION,
55
TYPING_CATALOG,
6+
CUSTOM,
67
}

action-binding-generator/src/main/kotlin/io/github/typesafegithub/workflows/actionbindinggenerator/generation/Generation.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,26 @@ public fun ActionCoords.generateBinding(
5757
metadataRevision: MetadataRevision,
5858
metadata: Metadata? = null,
5959
inputTypings: Pair<Map<String, Typing>, TypingActualSource?>? = null,
60+
types: String? = null,
6061
): List<ActionBinding> {
6162
val metadataResolved = metadata ?: this.fetchMetadata(metadataRevision) ?: return emptyList()
6263
val metadataProcessed = metadataResolved.removeDeprecatedInputsIfNameClash()
6364

64-
val inputTypingsResolved = inputTypings ?: this.provideTypes(metadataRevision)
65+
val (inputTypingsResolved, typingActualSource) =
66+
inputTypings ?: this.provideTypes(metadataRevision, types = types)
6567

6668
val classNameUntyped = this.buildActionClassName() + "_Untyped"
6769
val actionBindingSourceCodeUntyped =
6870
generateActionBindingSourceCode(metadataProcessed, this, emptyMap(), classNameUntyped, untyped = true)
6971

7072
val classNameAndSourceCodeTyped =
71-
if (inputTypingsResolved.second != null) {
73+
if (typingActualSource != null) {
7274
val className = this.buildActionClassName()
7375
val actionBindingSourceCode =
7476
generateActionBindingSourceCode(
7577
metadataProcessed,
7678
this,
77-
inputTypingsResolved.first,
79+
inputTypingsResolved,
7880
className,
7981
untyped = false,
8082
)
@@ -99,7 +101,7 @@ public fun ActionCoords.generateBinding(
99101
filePath = "io/github/typesafegithub/workflows/actions/$packageName/$className.kt",
100102
className = className,
101103
packageName = packageName,
102-
typingActualSource = inputTypingsResolved.second,
104+
typingActualSource = typingActualSource,
103105
)
104106
},
105107
)

action-binding-generator/src/main/kotlin/io/github/typesafegithub/workflows/actionbindinggenerator/typing/TypesProviding.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.github.typesafegithub.workflows.actionbindinggenerator.domain.Metadata
77
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.NewestForVersion
88
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource
99
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.ACTION
10+
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.CUSTOM
1011
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.TYPING_CATALOG
1112
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.repoName
1213
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.subName
@@ -21,10 +22,12 @@ import java.net.URI
2122
internal fun ActionCoords.provideTypes(
2223
metadataRevision: MetadataRevision,
2324
fetchUri: (URI) -> String = ::fetchUri,
25+
types: String? = null,
2426
): Pair<Map<String, Typing>, TypingActualSource?> =
2527
(
26-
this.fetchTypingMetadata(metadataRevision, fetchUri)
27-
?: this.toMajorVersion().fetchFromTypingsFromCatalog(fetchUri)
28+
customTypingMetadata(types)
29+
?: this.fetchTypingMetadata(metadataRevision, fetchUri)
30+
?: this.toMajorVersion().fetchTypingsFromCatalog(fetchUri)
2831
)?.let { Pair(it.first.toTypesMap(), it.second) }
2932
?: Pair(emptyMap(), null)
3033

@@ -42,6 +45,9 @@ private fun ActionCoords.catalogMetadata() =
4245
private fun ActionCoords.actionTypesYamlUrl(gitRef: String) =
4346
"https://raw.githubusercontent.com/$owner/$repoName/$gitRef$subName/action-types.yaml"
4447

48+
private fun customTypingMetadata(types: String? = null) =
49+
types?.let { Pair(myYaml.decodeFromStringOrDefaultIfEmpty(it, ActionTypes()), CUSTOM) }
50+
4551
private fun ActionCoords.fetchTypingMetadata(
4652
metadataRevision: MetadataRevision,
4753
fetchUri: (URI) -> String = ::fetchUri,
@@ -65,7 +71,7 @@ private fun ActionCoords.fetchTypingMetadata(
6571
return Pair(myYaml.decodeFromStringOrDefaultIfEmpty(typesMetadataYaml, ActionTypes()), ACTION)
6672
}
6773

68-
private fun ActionCoords.fetchFromTypingsFromCatalog(fetchUri: (URI) -> String = ::fetchUri): Pair<ActionTypes, TypingActualSource>? =
74+
private fun ActionCoords.fetchTypingsFromCatalog(fetchUri: (URI) -> String = ::fetchUri): Pair<ActionTypes, TypingActualSource>? =
6975
(
7076
fetchTypingsFromUrl(url = actionTypesFromCatalog(), fetchUri = fetchUri)
7177
?: fetchTypingsForOlderVersionFromCatalog(fetchUri = fetchUri)

action-binding-generator/src/test/kotlin/io/github/typesafegithub/workflows/actionbindinggenerator/typing/TypesProvidingTest.kt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ class TypesProvidingTest :
8585
stored-in-typing-catalog:
8686
type: string
8787
""".trimIndent()
88+
val custom =
89+
"""
90+
inputs:
91+
custom:
92+
type: string
93+
""".trimIndent()
8894
val metadata =
8995
"""
9096
"versionsWithTypings":
@@ -198,6 +204,70 @@ class TypesProvidingTest :
198204
types shouldBe Pair(mapOf("hosted-by-action-yml" to StringTyping), TypingActualSource.ACTION)
199205
}
200206

207+
test("only custom") {
208+
// Given
209+
val fetchUri: (URI) -> String = { throw IOException() }
210+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
211+
212+
// When
213+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
214+
215+
// Then
216+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
217+
}
218+
219+
test("hosted by action, stored in typing catalog, and custom") {
220+
// Given
221+
val fetchUri: (URI) -> String = {
222+
when (it) {
223+
URI(
224+
"https://raw.githubusercontent.com/some-owner/some-name/" +
225+
"some-hash/action-types.yml",
226+
),
227+
-> hostedByActionYml
228+
URI(
229+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
230+
"main/typings/some-owner/some-name/v3/action-types.yml",
231+
),
232+
-> storedInTypingCatalog
233+
else -> throw IOException()
234+
}
235+
}
236+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
237+
238+
// When
239+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
240+
241+
// Then
242+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
243+
}
244+
245+
test("hosted by action, stored in typing catalog, and empty custom") {
246+
// Given
247+
val fetchUri: (URI) -> String = {
248+
when (it) {
249+
URI(
250+
"https://raw.githubusercontent.com/some-owner/some-name/" +
251+
"some-hash/action-types.yml",
252+
),
253+
-> hostedByActionYml
254+
URI(
255+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
256+
"main/typings/some-owner/some-name/v3/action-types.yml",
257+
),
258+
-> storedInTypingCatalog
259+
else -> throw IOException()
260+
}
261+
}
262+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
263+
264+
// When
265+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = "")
266+
267+
// Then
268+
types shouldBe Pair(emptyMap(), TypingActualSource.CUSTOM)
269+
}
270+
201271
test("only stored in typing catalog for older version") {
202272
// Given
203273
val fetchUri: (URI) -> String = {

jit-binding-server/src/main/kotlin/io/github/typesafegithub/workflows/jitbindingserver/Main.kt

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ import io.ktor.server.application.call
1616
import io.ktor.server.application.install
1717
import io.ktor.server.engine.embeddedServer
1818
import io.ktor.server.netty.Netty
19+
import io.ktor.server.request.receiveText
1920
import io.ktor.server.response.respondBytes
2021
import io.ktor.server.response.respondText
2122
import io.ktor.server.routing.Route
2223
import io.ktor.server.routing.get
2324
import io.ktor.server.routing.head
25+
import io.ktor.server.routing.post
2426
import io.ktor.server.routing.route
2527
import io.ktor.server.routing.routing
2628
import io.opentelemetry.instrumentation.ktor.v2_0.server.KtorServerTracing
29+
import java.util.UUID.randomUUID
2730
import kotlin.time.Duration.Companion.hours
2831

2932
fun main() {
@@ -66,7 +69,7 @@ fun main() {
6669
}
6770

6871
get("/status") {
69-
call.respondText("OK")
72+
call.respondText(text = "OK")
7073
}
7174
}
7275
}.start(wait = true)
@@ -86,7 +89,7 @@ private fun Route.metadata() {
8689
val bindingArtifacts = actionCoords.buildPackageArtifacts(githubToken = getGithubToken())
8790
if (file in bindingArtifacts) {
8891
when (val artifact = bindingArtifacts[file]) {
89-
is String -> call.respondText(artifact)
92+
is String -> call.respondText(text = artifact)
9093
else -> call.respondText(text = "Not found", status = HttpStatusCode.NotFound)
9194
}
9295
} else {
@@ -102,14 +105,14 @@ private fun Route.artifact(
102105
get {
103106
val bindingArtifacts = call.toBindingArtifacts(bindingsCache, refresh)
104107
if (bindingArtifacts == null) {
105-
call.respondText("Not found", status = HttpStatusCode.NotFound)
108+
call.respondText(text = "Not found", status = HttpStatusCode.NotFound)
106109
return@get
107110
}
108111

109112
val file = call.parameters["file"]!!
110113
if (file in bindingArtifacts) {
111114
when (val artifact = bindingArtifacts[file]) {
112-
is TextArtifact -> call.respondText(artifact.data)
115+
is TextArtifact -> call.respondText(text = artifact.data)
113116
is JarArtifact ->
114117
call.respondBytes(
115118
bytes = artifact.data,
@@ -127,39 +130,58 @@ private fun Route.artifact(
127130
val bindingArtifacts = call.toBindingArtifacts(bindingsCache, refresh)
128131
val file = call.parameters["file"]!!
129132
if (bindingArtifacts == null) {
130-
call.respondText("Not found", status = HttpStatusCode.NotFound)
133+
call.respondText(text = "Not found", status = HttpStatusCode.NotFound)
131134
return@head
132135
}
133136
if (file in bindingArtifacts) {
134-
call.respondText("Exists", status = HttpStatusCode.OK)
137+
call.respondText(text = "Exists", status = HttpStatusCode.OK)
135138
} else {
136139
call.respondText(text = "Not found", status = HttpStatusCode.NotFound)
137140
}
138141
}
142+
143+
post {
144+
val owner = "${call.parameters["owner"]}__types__${randomUUID()}"
145+
val name = call.parameters["name"]!!
146+
val version = call.parameters["version"]!!
147+
val types = call.receiveText()
148+
call.toBindingArtifacts(bindingsCache, refresh = true, owner = owner, types = types)
149+
call.respondText(text = "$owner:$name:$version")
150+
}
139151
}
140152

141153
private suspend fun ApplicationCall.toBindingArtifacts(
142154
bindingsCache: Cache<ActionCoords, Result<Map<String, Artifact>>>,
143155
refresh: Boolean,
156+
owner: String = parameters["owner"]!!,
157+
types: String? = null,
144158
): Map<String, Artifact>? {
145-
val owner = parameters["owner"]!!
146159
val name = parameters["name"]!!
147160
val version = parameters["version"]!!
161+
val (ownerPlain, typesUuid) =
162+
if (owner.contains("__types__")) {
163+
owner
164+
.split("__types__", limit = 2)
165+
.let { it.first() to it[1] }
166+
} else {
167+
owner to null
168+
}
148169
val actionCoords =
149170
ActionCoords(
150-
owner = owner,
171+
owner = ownerPlain,
151172
name = name,
152173
version = version,
174+
typesUuid = typesUuid,
153175
)
154176
println("➡️ Requesting ${actionCoords.prettyPrint}")
155177
val bindingArtifacts =
156178
if (refresh) {
157-
actionCoords.buildVersionArtifacts().also {
179+
actionCoords.buildVersionArtifacts(types ?: typesUuid?.let { "" }).also {
158180
bindingsCache.put(actionCoords, Result.of(it))
159181
}
160182
} else {
161183
bindingsCache
162-
.get(actionCoords) { Result.of(actionCoords.buildVersionArtifacts()) }
184+
.get(actionCoords) { Result.of(actionCoords.buildVersionArtifacts(types ?: typesUuid?.let { "" })) }
163185
.getOrNull()
164186
}
165187
return bindingArtifacts

maven-binding-builder/src/main/kotlin/io/github/typesafegithub/workflows/mavenbinding/JarBuilding.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ internal fun buildJars(
3030
owner: String,
3131
name: String,
3232
version: String,
33+
types: String?,
3334
): Jars? {
3435
val binding =
35-
generateBinding(owner = owner, name = name, version = version).also {
36+
generateBinding(owner = owner, name = name, version = version, types = types).also {
3637
if (it.isEmpty()) return null
3738
}
3839
val (sourceFilePaths, compilationInputDir) = binding.prepareDirectoryWithSources()
@@ -54,6 +55,7 @@ private fun generateBinding(
5455
owner: String,
5556
name: String,
5657
version: String,
58+
types: String?,
5759
): List<ActionBinding> {
5860
val actionCoords =
5961
ActionCoords(
@@ -63,6 +65,7 @@ private fun generateBinding(
6365
)
6466
return actionCoords.generateBinding(
6567
metadataRevision = NewestForVersion,
68+
types = types,
6669
)
6770
}
6871

maven-binding-builder/src/main/kotlin/io/github/typesafegithub/workflows/mavenbinding/VersionArtifactsBuilding.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ data class JarArtifact(
1313
val data: ByteArray,
1414
) : Artifact
1515

16-
fun ActionCoords.buildVersionArtifacts(): Map<String, Artifact>? {
17-
val jars = buildJars(owner = owner, name = name.replace("__", "/"), version = version) ?: return null
16+
fun ActionCoords.buildVersionArtifacts(types: String? = null): Map<String, Artifact>? {
17+
val jars = buildJars(owner = owner, name = name.replace("__", "/"), version = version, types = types) ?: return null
1818
val pom = buildPomFile(owner = owner, name = name.replace("__", "/"), version = version)
1919
val module = buildModuleFile(owner = owner, name = name.replace("__", "/"), version = version)
2020
return mapOf(

0 commit comments

Comments
 (0)