Skip to content

Commit 4eb436e

Browse files
authored
Merge branch 'main' into token-getter
2 parents 3d7a039 + c2039e4 commit 4eb436e

File tree

5 files changed

+192
-0
lines changed

5 files changed

+192
-0
lines changed

pkg/parser/schema_test.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,82 @@ func TestValidateMainWorkflowFrontmatterWithSchema(t *testing.T) {
10111011
wantErr: true,
10121012
errContains: "minItems",
10131013
},
1014+
{
1015+
name: "valid: workflow_dispatch with 25 inputs (max allowed)",
1016+
frontmatter: map[string]any{
1017+
"on": map[string]any{
1018+
"workflow_dispatch": map[string]any{
1019+
"inputs": map[string]any{
1020+
"input1": map[string]any{"description": "Input 1", "type": "string"},
1021+
"input2": map[string]any{"description": "Input 2", "type": "string"},
1022+
"input3": map[string]any{"description": "Input 3", "type": "string"},
1023+
"input4": map[string]any{"description": "Input 4", "type": "string"},
1024+
"input5": map[string]any{"description": "Input 5", "type": "string"},
1025+
"input6": map[string]any{"description": "Input 6", "type": "string"},
1026+
"input7": map[string]any{"description": "Input 7", "type": "string"},
1027+
"input8": map[string]any{"description": "Input 8", "type": "string"},
1028+
"input9": map[string]any{"description": "Input 9", "type": "string"},
1029+
"input10": map[string]any{"description": "Input 10", "type": "string"},
1030+
"input11": map[string]any{"description": "Input 11", "type": "string"},
1031+
"input12": map[string]any{"description": "Input 12", "type": "string"},
1032+
"input13": map[string]any{"description": "Input 13", "type": "string"},
1033+
"input14": map[string]any{"description": "Input 14", "type": "string"},
1034+
"input15": map[string]any{"description": "Input 15", "type": "string"},
1035+
"input16": map[string]any{"description": "Input 16", "type": "string"},
1036+
"input17": map[string]any{"description": "Input 17", "type": "string"},
1037+
"input18": map[string]any{"description": "Input 18", "type": "string"},
1038+
"input19": map[string]any{"description": "Input 19", "type": "string"},
1039+
"input20": map[string]any{"description": "Input 20", "type": "string"},
1040+
"input21": map[string]any{"description": "Input 21", "type": "string"},
1041+
"input22": map[string]any{"description": "Input 22", "type": "string"},
1042+
"input23": map[string]any{"description": "Input 23", "type": "string"},
1043+
"input24": map[string]any{"description": "Input 24", "type": "string"},
1044+
"input25": map[string]any{"description": "Input 25", "type": "string"},
1045+
},
1046+
},
1047+
},
1048+
},
1049+
wantErr: false,
1050+
},
1051+
{
1052+
name: "invalid: workflow_dispatch with 26 inputs (exceeds max)",
1053+
frontmatter: map[string]any{
1054+
"on": map[string]any{
1055+
"workflow_dispatch": map[string]any{
1056+
"inputs": map[string]any{
1057+
"input1": map[string]any{"description": "Input 1", "type": "string"},
1058+
"input2": map[string]any{"description": "Input 2", "type": "string"},
1059+
"input3": map[string]any{"description": "Input 3", "type": "string"},
1060+
"input4": map[string]any{"description": "Input 4", "type": "string"},
1061+
"input5": map[string]any{"description": "Input 5", "type": "string"},
1062+
"input6": map[string]any{"description": "Input 6", "type": "string"},
1063+
"input7": map[string]any{"description": "Input 7", "type": "string"},
1064+
"input8": map[string]any{"description": "Input 8", "type": "string"},
1065+
"input9": map[string]any{"description": "Input 9", "type": "string"},
1066+
"input10": map[string]any{"description": "Input 10", "type": "string"},
1067+
"input11": map[string]any{"description": "Input 11", "type": "string"},
1068+
"input12": map[string]any{"description": "Input 12", "type": "string"},
1069+
"input13": map[string]any{"description": "Input 13", "type": "string"},
1070+
"input14": map[string]any{"description": "Input 14", "type": "string"},
1071+
"input15": map[string]any{"description": "Input 15", "type": "string"},
1072+
"input16": map[string]any{"description": "Input 16", "type": "string"},
1073+
"input17": map[string]any{"description": "Input 17", "type": "string"},
1074+
"input18": map[string]any{"description": "Input 18", "type": "string"},
1075+
"input19": map[string]any{"description": "Input 19", "type": "string"},
1076+
"input20": map[string]any{"description": "Input 20", "type": "string"},
1077+
"input21": map[string]any{"description": "Input 21", "type": "string"},
1078+
"input22": map[string]any{"description": "Input 22", "type": "string"},
1079+
"input23": map[string]any{"description": "Input 23", "type": "string"},
1080+
"input24": map[string]any{"description": "Input 24", "type": "string"},
1081+
"input25": map[string]any{"description": "Input 25", "type": "string"},
1082+
"input26": map[string]any{"description": "Input 26", "type": "string"},
1083+
},
1084+
},
1085+
},
1086+
},
1087+
wantErr: true,
1088+
errContains: "maxProperties",
1089+
},
10141090
}
10151091

10161092
for _, tt := range tests {
@@ -1256,6 +1332,74 @@ func TestValidateIncludedFileFrontmatterWithSchema(t *testing.T) {
12561332
wantErr: true,
12571333
errContains: "additional properties 'invalid_option' not allowed",
12581334
},
1335+
{
1336+
name: "valid: included file with 25 inputs (max allowed)",
1337+
frontmatter: map[string]any{
1338+
"inputs": map[string]any{
1339+
"input1": map[string]any{"description": "Input 1", "type": "string"},
1340+
"input2": map[string]any{"description": "Input 2", "type": "string"},
1341+
"input3": map[string]any{"description": "Input 3", "type": "string"},
1342+
"input4": map[string]any{"description": "Input 4", "type": "string"},
1343+
"input5": map[string]any{"description": "Input 5", "type": "string"},
1344+
"input6": map[string]any{"description": "Input 6", "type": "string"},
1345+
"input7": map[string]any{"description": "Input 7", "type": "string"},
1346+
"input8": map[string]any{"description": "Input 8", "type": "string"},
1347+
"input9": map[string]any{"description": "Input 9", "type": "string"},
1348+
"input10": map[string]any{"description": "Input 10", "type": "string"},
1349+
"input11": map[string]any{"description": "Input 11", "type": "string"},
1350+
"input12": map[string]any{"description": "Input 12", "type": "string"},
1351+
"input13": map[string]any{"description": "Input 13", "type": "string"},
1352+
"input14": map[string]any{"description": "Input 14", "type": "string"},
1353+
"input15": map[string]any{"description": "Input 15", "type": "string"},
1354+
"input16": map[string]any{"description": "Input 16", "type": "string"},
1355+
"input17": map[string]any{"description": "Input 17", "type": "string"},
1356+
"input18": map[string]any{"description": "Input 18", "type": "string"},
1357+
"input19": map[string]any{"description": "Input 19", "type": "string"},
1358+
"input20": map[string]any{"description": "Input 20", "type": "string"},
1359+
"input21": map[string]any{"description": "Input 21", "type": "string"},
1360+
"input22": map[string]any{"description": "Input 22", "type": "string"},
1361+
"input23": map[string]any{"description": "Input 23", "type": "string"},
1362+
"input24": map[string]any{"description": "Input 24", "type": "string"},
1363+
"input25": map[string]any{"description": "Input 25", "type": "string"},
1364+
},
1365+
},
1366+
wantErr: false,
1367+
},
1368+
{
1369+
name: "invalid: included file with 26 inputs (exceeds max)",
1370+
frontmatter: map[string]any{
1371+
"inputs": map[string]any{
1372+
"input1": map[string]any{"description": "Input 1", "type": "string"},
1373+
"input2": map[string]any{"description": "Input 2", "type": "string"},
1374+
"input3": map[string]any{"description": "Input 3", "type": "string"},
1375+
"input4": map[string]any{"description": "Input 4", "type": "string"},
1376+
"input5": map[string]any{"description": "Input 5", "type": "string"},
1377+
"input6": map[string]any{"description": "Input 6", "type": "string"},
1378+
"input7": map[string]any{"description": "Input 7", "type": "string"},
1379+
"input8": map[string]any{"description": "Input 8", "type": "string"},
1380+
"input9": map[string]any{"description": "Input 9", "type": "string"},
1381+
"input10": map[string]any{"description": "Input 10", "type": "string"},
1382+
"input11": map[string]any{"description": "Input 11", "type": "string"},
1383+
"input12": map[string]any{"description": "Input 12", "type": "string"},
1384+
"input13": map[string]any{"description": "Input 13", "type": "string"},
1385+
"input14": map[string]any{"description": "Input 14", "type": "string"},
1386+
"input15": map[string]any{"description": "Input 15", "type": "string"},
1387+
"input16": map[string]any{"description": "Input 16", "type": "string"},
1388+
"input17": map[string]any{"description": "Input 17", "type": "string"},
1389+
"input18": map[string]any{"description": "Input 18", "type": "string"},
1390+
"input19": map[string]any{"description": "Input 19", "type": "string"},
1391+
"input20": map[string]any{"description": "Input 20", "type": "string"},
1392+
"input21": map[string]any{"description": "Input 21", "type": "string"},
1393+
"input22": map[string]any{"description": "Input 22", "type": "string"},
1394+
"input23": map[string]any{"description": "Input 23", "type": "string"},
1395+
"input24": map[string]any{"description": "Input 24", "type": "string"},
1396+
"input25": map[string]any{"description": "Input 25", "type": "string"},
1397+
"input26": map[string]any{"description": "Input 26", "type": "string"},
1398+
},
1399+
},
1400+
wantErr: true,
1401+
errContains: "maxProperties",
1402+
},
12591403
}
12601404

12611405
for _, tt := range tests {

pkg/parser/schemas/included_file_schema.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"inputs": {
1111
"type": "object",
1212
"description": "Input parameters for the shared workflow. Uses the same schema as workflow_dispatch inputs. Values can be referenced in the workflow using ${{ github.aw.inputs.<key> }} expressions.",
13+
"maxProperties": 25,
1314
"additionalProperties": {
1415
"type": "object",
1516
"additionalProperties": false,
@@ -515,6 +516,7 @@
515516
"inputs": {
516517
"type": "object",
517518
"description": "Input parameters for the tool, using workflow_dispatch input syntax",
519+
"maxProperties": 25,
518520
"additionalProperties": {
519521
"type": "object",
520522
"properties": {

pkg/parser/schemas/main_workflow_schema.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@
487487
"inputs": {
488488
"type": "object",
489489
"description": "Input parameters for manual dispatch",
490+
"maxProperties": 25,
490491
"additionalProperties": {
491492
"type": "object",
492493
"additionalProperties": false,
@@ -4408,6 +4409,7 @@
44084409
"type": "object",
44094410
"description": "Input parameters for the safe job (workflow_dispatch syntax) - REQUIRED: at least one input must be defined",
44104411
"minProperties": 1,
4412+
"maxProperties": 25,
44114413
"patternProperties": {
44124414
"^[a-zA-Z_][a-zA-Z0-9_-]*$": {
44134415
"type": "object",

pkg/workflow/js.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ var loadAgentOutputScript string
115115
//go:embed js/lock-issue.cjs
116116
var lockIssueScript string
117117

118+
//go:embed js/unlock-issue.cjs
119+
var unlockIssueScript string
120+
118121
//go:embed js/staged_preview.cjs
119122
var stagedPreviewScript string
120123

@@ -282,6 +285,7 @@ func GetJavaScriptSources() map[string]string {
282285
"sanitize_workflow_name.cjs": sanitizeWorkflowNameScript,
283286
"load_agent_output.cjs": loadAgentOutputScript,
284287
"lock-issue.cjs": lockIssueScript,
288+
"unlock-issue.cjs": unlockIssueScript,
285289
"staged_preview.cjs": stagedPreviewScript,
286290
"assign_agent_helpers.cjs": assignAgentHelpersScript,
287291
"safe_output_helpers.cjs": safeOutputHelpersScript,

pkg/workflow/js/unlock-issue.cjs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// @ts-check
2+
/// <reference types="@actions/github-script" />
3+
4+
/**
5+
* Unlock a GitHub issue
6+
* This script is used in the conclusion job to ensure the issue is unlocked
7+
* after agent workflow execution completes or fails
8+
*/
9+
10+
async function main() {
11+
// Get issue number from context
12+
const issueNumber = context.issue.number;
13+
14+
if (!issueNumber) {
15+
core.setFailed("Issue number not found in context");
16+
return;
17+
}
18+
19+
const owner = context.repo.owner;
20+
const repo = context.repo.repo;
21+
22+
core.info(`Unlocking issue #${issueNumber} after agent workflow execution`);
23+
24+
try {
25+
// Unlock the issue
26+
await github.rest.issues.unlock({
27+
owner,
28+
repo,
29+
issue_number: issueNumber,
30+
});
31+
32+
core.info(`✅ Successfully unlocked issue #${issueNumber}`);
33+
} catch (error) {
34+
const errorMessage = error instanceof Error ? error.message : String(error);
35+
core.error(`Failed to unlock issue: ${errorMessage}`);
36+
core.setFailed(`Failed to unlock issue #${issueNumber}: ${errorMessage}`);
37+
}
38+
}
39+
40+
await main();

0 commit comments

Comments
 (0)