Skip to content

Commit fc43ce6

Browse files
authored
feat(server): allow pinning action to commit hash (#2102)
Part of #1691 DD: https://github.com/typesafegithub/design-docs/blob/main/2025-04-27%20Enhancements%20to%20referring%20to%20actions%20by%20commit%20hash.md This change implements the `commit_lenient` variant which doesn't provide any validation on the commit hash (if the commit hash corresponds to the tag referred to by the version). It just blindly uses the given commit hash in `uses:` attribute, and the given full version in the comment.
1 parent ebe6791 commit fc43ce6

5 files changed

Lines changed: 52 additions & 9 deletions

File tree

.github/workflows/test-script-consuming-jit-bindings.main.do-not-compile.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@
2424
// Always untyped action.
2525
@file:DependsOn("typesafegithub:always-untyped-action-for-tests:v1")
2626

27+
// Action version pinned to a commit.
28+
@file:DependsOn("actions:setup-python___commit_lenient:v6.0.0__e797f83bcb11b83ae66e0230d6156d7c80228e7c")
29+
2730
import io.github.typesafegithub.workflows.actions.actions.Cache
2831
import io.github.typesafegithub.workflows.actions.actions.Checkout
2932
import io.github.typesafegithub.workflows.actions.actions.SetupNode
33+
import io.github.typesafegithub.workflows.actions.actions.SetupPython
3034
import io.github.typesafegithub.workflows.actions.actions.Checkout_Untyped
3135
import io.github.typesafegithub.workflows.actions.gradle.ActionsSetupGradle
3236
import io.github.typesafegithub.workflows.actions.gradle.ActionsDependencySubmission_Untyped
@@ -47,3 +51,5 @@ ActionsWrapperValidation().actionVersion shouldBe "v4.2"
4751

4852
// Ensure that 'copy(...)' method is exposed.
4953
Checkout(fetchTags = false).copy(fetchTags = true)
54+
55+
SetupPython().actionVersion shouldBe "e797f83bcb11b83ae66e0230d6156d7c80228e7c"

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
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;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
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;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;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;
99
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;
10+
public final fun component7 ()Ljava/lang/String;
11+
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;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;Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/ActionCoords;
1213
public fun equals (Ljava/lang/Object;)Z
1314
public final fun getComment ()Ljava/lang/String;
1415
public final fun getName ()Ljava/lang/String;
1516
public final fun getOwner ()Ljava/lang/String;
1617
public final fun getPath ()Ljava/lang/String;
1718
public final fun getSignificantVersion ()Lio/github/typesafegithub/workflows/actionbindinggenerator/domain/SignificantVersion;
1819
public final fun getVersion ()Ljava/lang/String;
20+
public final fun getVersionForTypings ()Ljava/lang/String;
1921
public fun hashCode ()I
2022
public fun toString ()Ljava/lang/String;
2123
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ public data class ActionCoords(
1616
val significantVersion: SignificantVersion = FULL,
1717
val path: String? = null,
1818
val comment: String? = null,
19+
/**
20+
* Contrary to [version] which is used in the YAML to call the action,
21+
* [versionForTypings] is used internally to check the typings, where
22+
* using [version] wouldn't provide desired typings (e.g. when it's
23+
* a commit hash), then we can provide [versionForTypings] for which
24+
* the typings are defined.
25+
*/
26+
val versionForTypings: String = version,
1927
)
2028

2129
/**

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private suspend fun ActionCoords.fetchTypingMetadata(
6060
val gitRef =
6161
when (metadataRevision) {
6262
is CommitHash -> metadataRevision.value
63-
NewestForVersion -> this.version
63+
NewestForVersion -> this.versionForTypings
6464
}
6565
val list = listOf(actionTypesYmlUrl(gitRef), actionTypesYamlUrl(gitRef))
6666
val typesMetadataYaml =
@@ -105,7 +105,7 @@ private suspend fun ActionCoords.fetchTypingsForOlderVersionFromCatalog(httpClie
105105
else -> throw IOException("Failed fetching from $metadataUrl")
106106
}
107107
val metadata = yaml.decodeFromString<CatalogMetadata>(metadataYml)
108-
val requestedVersionAsInt = this.version.versionToIntOrNull() ?: return null
108+
val requestedVersionAsInt = this.versionForTypings.versionToIntOrNull() ?: return null
109109
val fallbackVersion =
110110
metadata.versionsWithTypings
111111
.filter { it.versionToInt() < requestedVersionAsInt }
@@ -151,7 +151,8 @@ internal fun ActionTypes.toTypesMap(): Map<String, Typing> =
151151
value.toTyping(key)
152152
} ?: emptyMap()
153153

154-
private fun ActionCoords.toMajorVersion(): ActionCoords = this.copy(version = this.version.substringBefore("."))
154+
private fun ActionCoords.toMajorVersion(): ActionCoords =
155+
this.copy(version = this.versionForTypings.substringBefore("."))
155156

156157
private fun ActionType.toTyping(fieldName: String): Typing =
157158
when (this.type) {

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,44 @@ fun Parameters.parseRequest(extractVersion: Boolean): BindingsServerRequest {
2020
.entries
2121
.find { "$it" == significantVersionString }
2222
} ?: FULL
23+
val pinToCommit =
24+
nameAndPathAndSignificantVersionParts
25+
.drop(1)
26+
.takeIf { it.isNotEmpty() }
27+
?.single() == "commit_lenient"
2328
val nameAndPathParts = nameAndPath.split("__")
2429
val name = nameAndPathParts.first()
2530
val path =
2631
nameAndPathParts
2732
.drop(1)
2833
.joinToString("/")
2934
.takeUnless { it.isBlank() }
30-
val version = if (extractVersion) this["version"]!! else "irrelevant"
35+
val version =
36+
if (extractVersion) {
37+
val versionPart = this["version"]!!
38+
if (pinToCommit) {
39+
versionPart.split("__")[1]
40+
} else {
41+
versionPart
42+
}
43+
} else {
44+
"irrelevant"
45+
}
46+
val comment = if (pinToCommit && extractVersion) this["version"]!!.split("__")[0] else null
47+
val versionForTypings = if (extractVersion) this["version"]!!.split("__")[0] else "irrelevant"
3148

3249
return BindingsServerRequest(
3350
rawName = this["name"]!!,
3451
rawVersion = this["version"],
35-
actionCoords = ActionCoords(owner, name, version, significantVersion, path),
52+
actionCoords =
53+
ActionCoords(
54+
owner = owner,
55+
name = name,
56+
version = version,
57+
versionForTypings = versionForTypings,
58+
significantVersion = significantVersion,
59+
path = path,
60+
comment = comment,
61+
),
3662
)
3763
}

0 commit comments

Comments
 (0)