Skip to content

Commit 1146cb3

Browse files
Fix allow strings as bool in dotnet runner configs (#228)
* GitHub Api Breaking Change
1 parent 1636dd1 commit 1146cb3

2 files changed

Lines changed: 123 additions & 19 deletions

File tree

runnerconfiguration/compat/actions_runner_compat.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"math/big"
99
"strconv"
10+
"strings"
1011

1112
"github.com/ChristopherHX/github-act-runner/common"
1213
"github.com/ChristopherHX/github-act-runner/protocol"
@@ -24,19 +25,30 @@ type DotnetRsaParameters struct {
2425
Q []byte `json:"q"`
2526
}
2627

28+
type DotnetBoolean bool
29+
30+
func (b *DotnetBoolean) UnmarshalJSON(data []byte) error {
31+
var v bool
32+
if err := json.Unmarshal([]byte(strings.Trim(strings.ToLower(string(data)), "\"")), &v); err != nil {
33+
return err
34+
}
35+
*b = DotnetBoolean(v)
36+
return nil
37+
}
38+
2739
type DotnetAgent struct {
28-
AgentID string `json:"AgentId"`
29-
AgentName string `json:"AgentName"`
30-
DisableUpdate string `json:"DisableUpdate"`
31-
Ephemeral string `json:"Ephemeral"`
32-
PoolID string `json:"PoolId"`
33-
PoolName string `json:"PoolName,omitempty"`
34-
ServerURL string `json:"ServerUrl"`
35-
WorkFolder string `json:"WorkFolder"`
36-
GitHubURL string `json:"GitHubUrl"`
37-
UseV2Flow bool `json:"UseV2Flow"`
38-
ServerURLV2 string `json:"ServerUrlV2"`
39-
UseRunnerAdminFlow bool `json:"UseRunnerAdminFlow,omitempty"`
40+
AgentID string `json:"AgentId"`
41+
AgentName string `json:"AgentName"`
42+
DisableUpdate string `json:"DisableUpdate"`
43+
Ephemeral string `json:"Ephemeral"`
44+
PoolID string `json:"PoolId"`
45+
PoolName string `json:"PoolName,omitempty"`
46+
ServerURL string `json:"ServerUrl"`
47+
WorkFolder string `json:"WorkFolder"`
48+
GitHubURL string `json:"GitHubUrl"`
49+
UseV2Flow DotnetBoolean `json:"UseV2Flow"`
50+
ServerURLV2 string `json:"ServerUrlV2"`
51+
UseRunnerAdminFlow DotnetBoolean `json:"UseRunnerAdminFlow,omitempty"`
4052
}
4153

4254
type DotnetCredentials struct {
@@ -45,9 +57,9 @@ type DotnetCredentials struct {
4557
}
4658

4759
type DotnetCredentialsData struct {
48-
ClientID string `json:"ClientId"`
49-
AuthorizationURL string `json:"AuthorizationUrl"`
50-
RequireFipsCryptography bool `json:"RequireFipsCryptography"`
60+
ClientID string `json:"ClientId"`
61+
AuthorizationURL string `json:"AuthorizationUrl"`
62+
RequireFipsCryptography DotnetBoolean `json:"RequireFipsCryptography"`
5163
}
5264

5365
func BytesToBigInt(bytes []byte) *big.Int {
@@ -171,7 +183,7 @@ func ToRunnerInstance(fileAccess ConfigFileAccess) (*runnerconfiguration.RunnerI
171183
PoolID: poolID,
172184
Auth: &protocol.GitHubAuthResult{
173185
TenantURL: agent.ServerURL,
174-
UseV2FLow: agent.UseRunnerAdminFlow,
186+
UseV2FLow: bool(agent.UseRunnerAdminFlow),
175187
},
176188
PKey: FromRsaParameters(rsaParameters),
177189
Agent: &protocol.TaskAgent{
@@ -208,9 +220,9 @@ func FromRunnerInstance(instance *runnerconfiguration.RunnerInstance, fileAccess
208220
ServerURL: serverURL,
209221
WorkFolder: instance.WorkFolder,
210222
GitHubURL: instance.RegistrationURL,
211-
UseV2Flow: useV2Flow,
223+
UseV2Flow: DotnetBoolean(useV2Flow),
212224
ServerURLV2: serverV2URL,
213-
UseRunnerAdminFlow: instance.Auth.UseV2FLow,
225+
UseRunnerAdminFlow: DotnetBoolean(instance.Auth.UseV2FLow),
214226
}
215227
if agent.WorkFolder == "" {
216228
agent.WorkFolder = "_work"
@@ -223,7 +235,7 @@ func FromRunnerInstance(instance *runnerconfiguration.RunnerInstance, fileAccess
223235
AuthorizationURL: instance.Agent.Authorization.AuthorizationURL,
224236
// serverV2URL != "" means recent GitHub Server that requires recent actions/runner
225237
// that has received this bugfix https://github.com/actions/runner/pull/3789
226-
RequireFipsCryptography: requireFipsCryptography && hasRequireFipsCryptography || serverV2URL != "",
238+
RequireFipsCryptography: DotnetBoolean(requireFipsCryptography && hasRequireFipsCryptography || serverV2URL != ""),
227239
},
228240
}
229241
if err := fileAccess.Write(".runner", agent); err != nil {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package compat
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
)
7+
8+
func TestUnmarshalConfig(t *testing.T) {
9+
table := []struct {
10+
name string
11+
jsonData string
12+
expected DotnetAgent
13+
}{
14+
{
15+
name: "Boolean true without quotes",
16+
jsonData: `{"UseV2Flow": true}`,
17+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(true)},
18+
},
19+
{
20+
name: "Boolean false without quotes",
21+
jsonData: `{"UseV2Flow": false}`,
22+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(false)},
23+
},
24+
{
25+
name: "Boolean false without quotes no space",
26+
jsonData: `{"UseV2Flow":false}`,
27+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(false)},
28+
},
29+
{
30+
name: "Boolean True with quotes",
31+
jsonData: `{"UseV2Flow": "True"}`,
32+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(true)},
33+
},
34+
{
35+
name: "Boolean False with quotes",
36+
jsonData: `{"UseV2Flow": "False"}`,
37+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(false)},
38+
},
39+
{
40+
name: "Boolean true with quotes",
41+
jsonData: `{"UseV2Flow": "true"}`,
42+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(true)},
43+
},
44+
{
45+
name: "Boolean false with quotes",
46+
jsonData: `{"UseV2Flow": "false"}`,
47+
expected: DotnetAgent{UseV2Flow: DotnetBoolean(false)},
48+
},
49+
}
50+
for _, tt := range table {
51+
t.Run(tt.name, func(t *testing.T) {
52+
var agent DotnetAgent
53+
err := json.Unmarshal([]byte(tt.jsonData), &agent)
54+
if err != nil {
55+
t.Fatalf("Unexpected error during unmarshal: %v", err)
56+
}
57+
if agent.UseV2Flow != tt.expected.UseV2Flow {
58+
t.Errorf("Expected UseV2Flow to be %v, got %v", tt.expected.UseV2Flow, agent.UseV2Flow)
59+
}
60+
})
61+
}
62+
}
63+
64+
func TestMarshalDotnetBoolean(t *testing.T) {
65+
table := []struct {
66+
name string
67+
agent DotnetBoolean
68+
expectedJSON string
69+
}{
70+
{
71+
name: "Boolean true",
72+
agent: DotnetBoolean(true),
73+
expectedJSON: "true",
74+
},
75+
{
76+
name: "Boolean false",
77+
agent: DotnetBoolean(false),
78+
expectedJSON: "false",
79+
},
80+
}
81+
for _, tt := range table {
82+
t.Run(tt.name, func(t *testing.T) {
83+
data, err := json.Marshal(tt.agent)
84+
if err != nil {
85+
t.Fatalf("Unexpected error during marshal: %v", err)
86+
}
87+
if string(data) != tt.expectedJSON {
88+
t.Errorf("Expected JSON to be %s, got %s", tt.expectedJSON, string(data))
89+
}
90+
})
91+
}
92+
}

0 commit comments

Comments
 (0)