Skip to content

Commit 0c9d817

Browse files
committed
feat: add job.workflow_* context properties
Add workflow_ref, workflow_sha, workflow_repository, and workflow_file_path to the job context for reusable workflow jobs. These fields provide direct access to the workflow file information without needing to parse github.workflow_ref. - Add 4 new fields to getJobContext() in job.ts - Add descriptions in descriptions.json - Update autocomplete test expectations - Add validation and unit tests
1 parent cc316ab commit 0c9d817

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

languageservice/src/complete.expressions.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,16 @@ jobs:
11641164
`;
11651165

11661166
const result = await complete(...getPositionFromCursor(input), {contextProviderConfig});
1167-
expect(result.map(x => x.label)).toEqual(["check_run_id", "container", "services", "status"]);
1167+
expect(result.map(x => x.label)).toEqual([
1168+
"check_run_id",
1169+
"container",
1170+
"services",
1171+
"status",
1172+
"workflow_file_path",
1173+
"workflow_ref",
1174+
"workflow_repository",
1175+
"workflow_sha"
1176+
]);
11681177
});
11691178

11701179
it("job context is suggested within a job output", async () => {

languageservice/src/context-providers/descriptions.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,18 @@
218218
},
219219
"check_run_id": {
220220
"description": "The unique identifier of the check run for this job."
221+
},
222+
"workflow_file_path": {
223+
"description": "The path of the workflow file that contains the job. For example, `.github/workflows/my-workflow.yml`."
224+
},
225+
"workflow_ref": {
226+
"description": "The ref of the workflow file that contains the job. For example, `octocat/hello-world/.github/workflows/my-workflow.yml@refs/heads/my_branch`."
227+
},
228+
"workflow_repository": {
229+
"description": "The owner and repository name of the workflow file that contains the job. For example, `octocat/Hello-World`."
230+
},
231+
"workflow_sha": {
232+
"description": "The commit SHA of the workflow file that contains the job."
221233
}
222234
},
223235
"secrets": {

languageservice/src/context-providers/job.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ describe("job context", () => {
2424

2525
expect(context.get("status")).toBeDefined();
2626
expect(context.get("check_run_id")).toBeDefined();
27+
expect(context.get("workflow_ref")).toBeDefined();
28+
expect(context.get("workflow_sha")).toBeDefined();
29+
expect(context.get("workflow_repository")).toBeDefined();
30+
expect(context.get("workflow_file_path")).toBeDefined();
2731
expect(context.get("container")).toBeUndefined();
2832
expect(context.get("services")).toBeUndefined();
2933
});
@@ -173,4 +177,21 @@ describe("job context", () => {
173177
expect(redis.getDescription("ports")).toBeDefined();
174178
});
175179
});
180+
181+
describe("workflow context fields", () => {
182+
it("includes workflow context fields with descriptions", () => {
183+
const workflowContext = {job: {}} as WorkflowContext;
184+
const context = getJobContext(workflowContext);
185+
186+
expect(context.get("workflow_ref")).toBeDefined();
187+
expect(context.get("workflow_sha")).toBeDefined();
188+
expect(context.get("workflow_repository")).toBeDefined();
189+
expect(context.get("workflow_file_path")).toBeDefined();
190+
191+
expect(context.getDescription("workflow_ref")).toBeDefined();
192+
expect(context.getDescription("workflow_sha")).toBeDefined();
193+
expect(context.getDescription("workflow_repository")).toBeDefined();
194+
expect(context.getDescription("workflow_file_path")).toBeDefined();
195+
});
196+
});
176197
});

languageservice/src/context-providers/job.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ export function getJobContext(workflowContext: WorkflowContext): DescriptionDict
4242
// Check run ID
4343
jobContext.add("check_run_id", new data.StringData(""), getDescription("job", "check_run_id"));
4444

45+
// Workflow context fields (populated at runtime for reusable workflow jobs)
46+
jobContext.add("workflow_file_path", new data.StringData(""), getDescription("job", "workflow_file_path"));
47+
jobContext.add("workflow_ref", new data.StringData(""), getDescription("job", "workflow_ref"));
48+
jobContext.add("workflow_repository", new data.StringData(""), getDescription("job", "workflow_repository"));
49+
jobContext.add("workflow_sha", new data.StringData(""), getDescription("job", "workflow_sha"));
50+
4551
return jobContext;
4652
}
4753

languageservice/src/validate.expressions.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,24 @@ jobs:
432432
expect(result).toEqual([]);
433433
});
434434

435+
it("job.workflow_ref", async () => {
436+
const input = `
437+
on: push
438+
439+
jobs:
440+
test:
441+
runs-on: ubuntu-latest
442+
steps:
443+
- run: echo \${{ job.workflow_ref }}
444+
- run: echo \${{ job.workflow_sha }}
445+
- run: echo \${{ job.workflow_repository }}
446+
- run: echo \${{ job.workflow_file_path }}
447+
`;
448+
const result = await validate(createDocument("wf.yaml", input));
449+
450+
expect(result).toEqual([]);
451+
});
452+
435453
it("job.services.<service_id>", async () => {
436454
const input = `
437455
on: push

0 commit comments

Comments
 (0)