Support needs for reusable jobs

This commit is contained in:
Christopher Schleiden
2023-02-07 14:52:12 -08:00
parent 05605c80c7
commit cd38b2fe76
5 changed files with 110 additions and 31 deletions
@@ -0,0 +1,75 @@
import {DescriptionDictionary} from "@github/actions-expressions/.";
import {WorkflowContext} from "../context/workflow-context";
import {testGetWorkflowContext} from "../test-utils/test-workflow-context";
import {getNeedsContext} from "./needs";
describe("needs context", () => {
describe("invalid workflow context", () => {
it("jobs not defined", () => {
const workflowContext = {} as WorkflowContext;
expect(workflowContext.job).toBeUndefined();
expect(workflowContext.reusableWorkflowJob).toBeUndefined();
const context = getNeedsContext(workflowContext);
expect(context).toEqual(new DescriptionDictionary());
});
});
it("job without needs", async () => {
const workflowContext = await testGetWorkflowContext(`on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: ec|ho`);
const context = getNeedsContext(workflowContext);
expect(context).toEqual(new DescriptionDictionary());
});
it("job with needs", async () => {
const workflowContext = await testGetWorkflowContext(`on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo
build:
runs-on: ubuntu-latest
needs: [test]
steps:
- run: ec|ho`);
const context = getNeedsContext(workflowContext);
expect(context.pairs().map(x => x.key)).toEqual(["test"]);
});
it("reusable job without needs", async () => {
const workflowContext = await testGetWorkflowContext(`on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo
build:
uses: ./.github/workflows/some-reusable-wor|kflow.yml`);
const context = getNeedsContext(workflowContext);
expect(context).toEqual(new DescriptionDictionary());
});
it("reusable job with needs", async () => {
const workflowContext = await testGetWorkflowContext(`on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo
build:
uses: ./.github/workflows/some-reusable-wor|kflow.yml
needs: [test]`);
const context = getNeedsContext(workflowContext);
expect(context.pairs().map(x => x.key)).toEqual(["test"]);
});
});
@@ -6,11 +6,14 @@ import {WorkflowContext} from "../context/workflow-context";
export function getNeedsContext(workflowContext: WorkflowContext): DescriptionDictionary {
const d = new DescriptionDictionary();
if (!workflowContext.job || !workflowContext.job.needs) {
const job = workflowContext.job || workflowContext.reusableWorkflowJob;
if (!job?.needs) {
return d;
}
for (const jobID of workflowContext.job.needs) {
for (const jobID of job.needs) {
const job = workflowContext.template?.jobs.find(job => job.id.value === jobID.value);
d.add(jobID.value, needsJobContext(job));
}
@@ -1,30 +1,5 @@
import {convertWorkflowTemplate, parseWorkflow, WorkflowTemplate} from "@github/actions-workflow-parser";
import {ActionStep, RunStep} from "@github/actions-workflow-parser/model/workflow-template";
import {nullTrace} from "../nulltrace";
import {getPositionFromCursor} from "../test-utils/cursor-position";
import {findToken} from "../utils/find-token";
import {getWorkflowContext, WorkflowContext} from "./workflow-context";
async function testGetWorkflowContext(input: string): Promise<WorkflowContext> {
const [textDocument, pos] = getPositionFromCursor(input);
const result = parseWorkflow(
{
content: textDocument.getText(),
name: "wf.yaml"
},
nullTrace
);
let template: WorkflowTemplate | undefined;
if (result.value) {
template = await convertWorkflowTemplate(result.context, result.value);
}
const {path} = findToken(pos, result.value);
return getWorkflowContext(textDocument.uri, template, path);
}
import {testGetWorkflowContext} from "../test-utils/test-workflow-context";
describe("getWorkflowContext", () => {
it("context for workflow", async () => {
@@ -0,0 +1,26 @@
import {convertWorkflowTemplate, parseWorkflow, WorkflowTemplate} from "@github/actions-workflow-parser";
import {getWorkflowContext, WorkflowContext} from "../context/workflow-context";
import {nullTrace} from "../nulltrace";
import {findToken} from "../utils/find-token";
import {getPositionFromCursor} from "./cursor-position";
export async function testGetWorkflowContext(input: string): Promise<WorkflowContext> {
const [textDocument, pos] = getPositionFromCursor(input);
const result = parseWorkflow(
{
content: textDocument.getText(),
name: "wf.yaml"
},
nullTrace
);
let template: WorkflowTemplate | undefined;
if (result.value) {
template = await convertWorkflowTemplate(result.context, result.value);
}
const {path} = findToken(pos, result.value);
return getWorkflowContext(textDocument.uri, template, path);
}