Skip to content

Commit 3804a2a

Browse files
committed
feat(server): make it possible to POST custom typings for testing during typing creation
1 parent 90c28ef commit 3804a2a

File tree

17 files changed

+271
-28
lines changed

17 files changed

+271
-28
lines changed

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
public final class io/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords {
2-
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;)V
3-
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
2+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;Ljava/lang/String;)V
3+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
44
public final fun component1 ()Ljava/lang/String;
55
public final fun component2 ()Ljava/lang/String;
66
public final fun component3 ()Ljava/lang/String;
77
public final fun component4 ()Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;
88
public final fun component5 ()Ljava/lang/String;
9-
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;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;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
9+
public final fun component6 ()Ljava/lang/String;
10+
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;Ljava/lang/String;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
11+
public static synthetic fun copy$default (Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
1112
public fun equals (Ljava/lang/Object;)Z
1213
public final fun getName ()Ljava/lang/String;
1314
public final fun getOwner ()Ljava/lang/String;
1415
public final fun getPath ()Ljava/lang/String;
1516
public final fun getSignificantVersion ()Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;
17+
public final fun getTypesUuid ()Ljava/lang/String;
1618
public final fun getVersion ()Ljava/lang/String;
1719
public fun hashCode ()I
1820
public fun toString ()Ljava/lang/String;
@@ -59,6 +61,7 @@ public final class io/github/typesafegithub/workflows/actionbindinggenerator/dom
5961

6062
public final class io/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource : java/lang/Enum {
6163
public static final field ACTION Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
64+
public static final field CUSTOM Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
6265
public static final field TYPING_CATALOG Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
6366
public static fun getEntries ()Lkotlin/enums/EnumEntries;
6467
public static fun valueOf (Ljava/lang/String;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/TypingActualSource;
@@ -85,8 +88,8 @@ public final class io/github/typesafegithub/workflows/actionbindinggenerator/gen
8588
}
8689

8790
public final class io/github/typesafegithub/workflows/actionbindinggenerator/generation/GenerationKt {
88-
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;
89-
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;
91+
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;
92+
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;
9093
}
9194

9295
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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public data class ActionCoords(
1515
*/
1616
val significantVersion: SignificantVersion = FULL,
1717
val path: String? = null,
18+
val typesUuid: String? = null,
1819
)
1920

2021
/**
@@ -23,9 +24,11 @@ public data class ActionCoords(
2324
*/
2425
public val ActionCoords.isTopLevel: Boolean get() = path == null
2526

26-
public val ActionCoords.prettyPrint: String get() = "$prettyPrintWithoutVersion@$version"
27+
public val ActionCoords.prettyPrint: String get() = "$prettyPrintBase@$version${typesUuid?.let { " (types: $it)" } ?: ""}"
2728

28-
public val ActionCoords.prettyPrintWithoutVersion: String get() = "$owner/$fullName${
29+
public val ActionCoords.prettyPrintWithoutVersion: String get() = "$prettyPrintBase${typesUuid?.let { " (types: $it)" } ?: ""}"
30+
31+
private val ActionCoords.prettyPrintBase: String get() = "$owner/$fullName${
2932
significantVersion.takeUnless { it == FULL }?.let { " with $it version" } ?: ""
3033
}"
3134

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
@@ -64,11 +64,13 @@ public fun ActionCoords.generateBinding(
6464
metadataRevision: MetadataRevision,
6565
metadata: Metadata? = null,
6666
inputTypings: Pair<Map<String, Typing>, TypingActualSource?>? = null,
67+
types: String? = null,
6768
): List<ActionBinding> {
6869
val metadataResolved = metadata ?: this.fetchMetadata(metadataRevision) ?: return emptyList()
6970
val metadataProcessed = metadataResolved.removeDeprecatedInputsIfNameClash()
7071

71-
val inputTypingsResolved = inputTypings ?: this.provideTypes(metadataRevision)
72+
val (inputTypingsResolved, typingActualSource) =
73+
inputTypings ?: this.provideTypes(metadataRevision, types = types)
7274

7375
val packageName = owner.toKotlinPackageName()
7476
val className = this.buildActionClassName()
@@ -81,7 +83,7 @@ public fun ActionCoords.generateBinding(
8183
emptyMap(),
8284
classNameUntyped,
8385
untypedClass = true,
84-
replaceWith = inputTypingsResolved.second?.let { CodeBlock.of("ReplaceWith(%S)", className) },
86+
replaceWith = typingActualSource?.let { CodeBlock.of("ReplaceWith(%S)", className) },
8587
)
8688

8789
return listOfNotNull(
@@ -92,12 +94,12 @@ public fun ActionCoords.generateBinding(
9294
packageName = packageName,
9395
typingActualSource = null,
9496
),
95-
inputTypingsResolved.second?.let {
97+
typingActualSource?.let {
9698
val actionBindingSourceCode =
9799
generateActionBindingSourceCode(
98100
metadata = metadataProcessed,
99101
coords = this,
100-
inputTypings = inputTypingsResolved.first,
102+
inputTypings = inputTypingsResolved,
101103
className = className,
102104
)
103105
ActionBinding(

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
@@ -10,6 +10,7 @@ import io.github.typesafegithub.workflows.actionbindinggenerator.domain.Metadata
1010
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.NewestForVersion
1111
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource
1212
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.ACTION
13+
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.CUSTOM
1314
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.TypingActualSource.TYPING_CATALOG
1415
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.subName
1516
import io.github.typesafegithub.workflows.actionbindinggenerator.metadata.fetchUri
@@ -24,10 +25,12 @@ private val logger = logger { }
2425
internal fun ActionCoords.provideTypes(
2526
metadataRevision: MetadataRevision,
2627
fetchUri: (URI) -> String = ::fetchUri,
28+
types: String? = null,
2729
): Pair<Map<String, Typing>, TypingActualSource?> =
2830
(
29-
this.fetchTypingMetadata(metadataRevision, fetchUri)
30-
?: this.toMajorVersion().fetchFromTypingsFromCatalog(fetchUri)
31+
customTypingMetadata(types)
32+
?: this.fetchTypingMetadata(metadataRevision, fetchUri)
33+
?: this.toMajorVersion().fetchTypingsFromCatalog(fetchUri)
3134
)?.let { Pair(it.first.toTypesMap(), it.second) }
3235
?: Pair(emptyMap(), null)
3336

@@ -45,6 +48,9 @@ private fun ActionCoords.catalogMetadata() =
4548
private fun ActionCoords.actionTypesYamlUrl(gitRef: String) =
4649
"https://raw.githubusercontent.com/$owner/$name/$gitRef$subName/action-types.yaml"
4750

51+
private fun customTypingMetadata(types: String? = null) =
52+
types?.let { Pair(yaml.decodeFromStringOrDefaultIfEmpty(it, ActionTypes()), CUSTOM) }
53+
4854
private fun ActionCoords.fetchTypingMetadata(
4955
metadataRevision: MetadataRevision,
5056
fetchUri: (URI) -> String = ::fetchUri,
@@ -68,7 +74,7 @@ private fun ActionCoords.fetchTypingMetadata(
6874
return Pair(yaml.decodeFromStringOrDefaultIfEmpty(typesMetadataYaml, ActionTypes()), ACTION)
6975
}
7076

71-
private fun ActionCoords.fetchFromTypingsFromCatalog(fetchUri: (URI) -> String = ::fetchUri): Pair<ActionTypes, TypingActualSource>? =
77+
private fun ActionCoords.fetchTypingsFromCatalog(fetchUri: (URI) -> String = ::fetchUri): Pair<ActionTypes, TypingActualSource>? =
7278
(
7379
fetchTypingsFromUrl(url = actionTypesFromCatalog(), fetchUri = fetchUri)
7480
?: fetchTypingsForOlderVersionFromCatalog(fetchUri = fetchUri)

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

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ class TypesProvidingTest :
152152
stored-in-typing-catalog:
153153
type: string
154154
""".trimIndent()
155+
val custom =
156+
"""
157+
inputs:
158+
custom:
159+
type: string
160+
""".trimIndent()
155161
val metadata =
156162
"""
157163
"versionsWithTypings":
@@ -376,6 +382,134 @@ class TypesProvidingTest :
376382
types shouldBe Pair(mapOf("hosted-by-action-yml" to StringTyping), TypingActualSource.ACTION)
377383
}
378384

385+
test("only custom") {
386+
// Given
387+
val fetchUri: (URI) -> String = { throw IOException() }
388+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
389+
390+
// When
391+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
392+
393+
// Then
394+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
395+
}
396+
397+
test("only custom for subaction") {
398+
// Given
399+
val fetchUri: (URI) -> String = { throw IOException() }
400+
val actionCoord = ActionCoords("some-owner", "some-name", "v3", FULL, "some-sub")
401+
402+
// When
403+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
404+
405+
// Then
406+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
407+
}
408+
409+
test("hosted by action, stored in typing catalog, and custom") {
410+
// Given
411+
val fetchUri: (URI) -> String = {
412+
when (it) {
413+
URI(
414+
"https://raw.githubusercontent.com/some-owner/some-name/" +
415+
"some-hash/action-types.yml",
416+
),
417+
-> hostedByActionYml
418+
URI(
419+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
420+
"main/typings/some-owner/some-name/v3/action-types.yml",
421+
),
422+
-> storedInTypingCatalog
423+
else -> throw IOException()
424+
}
425+
}
426+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
427+
428+
// When
429+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
430+
431+
// Then
432+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
433+
}
434+
435+
test("hosted by subaction, stored in typing catalog, and custom") {
436+
// Given
437+
val fetchUri: (URI) -> String = {
438+
when (it) {
439+
URI(
440+
"https://raw.githubusercontent.com/some-owner/some-name/" +
441+
"some-hash/some-sub/action-types.yml",
442+
),
443+
-> hostedByActionYml
444+
URI(
445+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
446+
"main/typings/some-owner/some-name/v3/some-sub/action-types.yml",
447+
),
448+
-> storedInTypingCatalog
449+
else -> throw IOException()
450+
}
451+
}
452+
val actionCoord = ActionCoords("some-owner", "some-name", "v3", FULL, "some-sub")
453+
454+
// When
455+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = custom)
456+
457+
// Then
458+
types shouldBe Pair(mapOf("custom" to StringTyping), TypingActualSource.CUSTOM)
459+
}
460+
461+
test("hosted by action, stored in typing catalog, and empty custom") {
462+
// Given
463+
val fetchUri: (URI) -> String = {
464+
when (it) {
465+
URI(
466+
"https://raw.githubusercontent.com/some-owner/some-name/" +
467+
"some-hash/action-types.yml",
468+
),
469+
-> hostedByActionYml
470+
URI(
471+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
472+
"main/typings/some-owner/some-name/v3/action-types.yml",
473+
),
474+
-> storedInTypingCatalog
475+
else -> throw IOException()
476+
}
477+
}
478+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
479+
480+
// When
481+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = "")
482+
483+
// Then
484+
types shouldBe Pair(emptyMap(), TypingActualSource.CUSTOM)
485+
}
486+
487+
test("hosted by subaction, stored in typing catalog, and empty custom") {
488+
// Given
489+
val fetchUri: (URI) -> String = {
490+
when (it) {
491+
URI(
492+
"https://raw.githubusercontent.com/some-owner/some-name/" +
493+
"some-hash/some-sub/action-types.yml",
494+
),
495+
-> hostedByActionYml
496+
URI(
497+
"https://raw.githubusercontent.com/typesafegithub/github-actions-typing-catalog/" +
498+
"main/typings/some-owner/some-name/v3/some-sub/action-types.yml",
499+
),
500+
-> storedInTypingCatalog
501+
else -> throw IOException()
502+
}
503+
}
504+
val actionCoord = ActionCoords("some-owner", "some-name", "v3", FULL, "some-sub")
505+
506+
// When
507+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = "")
508+
509+
// Then
510+
types shouldBe Pair(emptyMap(), TypingActualSource.CUSTOM)
511+
}
512+
379513
test("only stored in typing catalog for older version") {
380514
// Given
381515
val fetchUri: (URI) -> String = {
@@ -576,6 +710,26 @@ class TypesProvidingTest :
576710
)
577711
}
578712

713+
test("only custom") {
714+
// Given
715+
val fetchUri: (URI) -> String = { throw IOException() }
716+
val actionCoord = ActionCoords("some-owner", "some-name", "v3")
717+
718+
// When
719+
val types = actionCoord.provideTypes(metadataRevision = CommitHash("some-hash"), fetchUri = fetchUri, types = typingYml)
720+
721+
// Then
722+
types shouldBe
723+
Pair(
724+
mapOf(
725+
"granted-scopes" to ListOfTypings(",", EnumTyping("GrantedScopes", listOf("read", "write"))),
726+
"granted-scopes2" to ListOfTypings(",", EnumTyping("GrantedScopes", listOf("read", "write"))),
727+
"granted-scopes3" to ListOfTypings("""\n""", EnumTyping("GrantedScopes", listOf("read", "write"))),
728+
),
729+
TypingActualSource.CUSTOM,
730+
)
731+
}
732+
579733
test("billion laughs attack is prevented") {
580734
// Given
581735
val billionLaughsAttack =

0 commit comments

Comments
 (0)