Merge branch 'main' into joshmgross/matrix-context-validation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@github/actions-languageservice",
|
||||
"version": "0.1.39",
|
||||
"version": "0.1.41",
|
||||
"description": "Language service for GitHub Actions",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import {data} from "@github/actions-expressions";
|
||||
import {complete, getExpressionInput} from "./complete";
|
||||
import {ContextProviderConfig} from "./context-providers/config";
|
||||
import {registerLogger} from "./log";
|
||||
import {getPositionFromCursor} from "./test-utils/cursor-position";
|
||||
import {TestLogger} from "./test-utils/logger";
|
||||
|
||||
const contextProviderConfig: ContextProviderConfig = {
|
||||
getContext: async (context: string) => {
|
||||
@@ -11,17 +13,14 @@ const contextProviderConfig: ContextProviderConfig = {
|
||||
key: "event",
|
||||
value: new data.StringData("push")
|
||||
});
|
||||
case "secrets":
|
||||
return new data.Dictionary({
|
||||
key: "DEPLOY_KEY",
|
||||
value: new data.StringData("DEPLOY_KEY")
|
||||
});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
registerLogger(new TestLogger());
|
||||
|
||||
describe("expressions", () => {
|
||||
it("input extraction", () => {
|
||||
const test = (input: string) => {
|
||||
@@ -146,7 +145,7 @@ jobs:
|
||||
`;
|
||||
const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig);
|
||||
|
||||
expect(result.map(x => x.label)).toEqual(["DEPLOY_KEY"]);
|
||||
expect(result.map(x => x.label)).toEqual(["GITHUB_TOKEN"]);
|
||||
});
|
||||
|
||||
it("needs context only includes referenced jobs", async () => {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import {TextEdit} from "vscode-languageserver-types";
|
||||
import {complete} from "./complete";
|
||||
import {WorkflowContext} from "./context/workflow-context";
|
||||
import {registerLogger} from "./log";
|
||||
import {getPositionFromCursor} from "./test-utils/cursor-position";
|
||||
import {TestLogger} from "./test-utils/logger";
|
||||
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
|
||||
|
||||
registerLogger(new TestLogger());
|
||||
|
||||
describe("completion", () => {
|
||||
it("runs-on", async () => {
|
||||
const input = "on: push\njobs:\n build:\n runs-on: |";
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Dictionary} from "@github/actions-expressions/data/dictionary";
|
||||
import {ExpressionData, Pair} from "@github/actions-expressions/data/expressiondata";
|
||||
|
||||
export type ContextProviderConfig = {
|
||||
getContext: (name: string) => Promise<data.Dictionary | undefined>;
|
||||
getContext: (name: string, defaultContext: data.Dictionary | undefined) => Promise<data.Dictionary | undefined>;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,17 +20,9 @@ export async function getContext(
|
||||
|
||||
const filteredNames = filterContextNames(names, workflowContext);
|
||||
for (const contextName of filteredNames) {
|
||||
let value: ContextValue | undefined;
|
||||
let value = (await getDefaultContext(contextName, workflowContext)) || new data.Dictionary();
|
||||
|
||||
value = await getDefaultContext(contextName, workflowContext);
|
||||
|
||||
if (!value) {
|
||||
value = await config?.getContext(contextName);
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
value = new data.Dictionary();
|
||||
}
|
||||
value = (await config?.getContext(contextName, value)) || value;
|
||||
|
||||
context.add(contextName, value);
|
||||
}
|
||||
@@ -55,6 +47,9 @@ async function getDefaultContext(name: string, workflowContext: WorkflowContext)
|
||||
case "inputs":
|
||||
return getInputsContext(workflowContext);
|
||||
|
||||
case "secrets":
|
||||
return objectToDictionary({GITHUB_TOKEN: "***"});
|
||||
|
||||
case "steps":
|
||||
return getStepsContext(workflowContext);
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import {Logger} from "../log";
|
||||
|
||||
export class TestLogger implements Logger {
|
||||
error(message: string): void {
|
||||
throw new Error(`Error: ${message}`);
|
||||
}
|
||||
|
||||
warn(message: string): void {
|
||||
console.warn(message);
|
||||
}
|
||||
|
||||
info(message: string): void {
|
||||
console.info(message);
|
||||
}
|
||||
|
||||
log(message: string): void {
|
||||
console.warn(message);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
import {DiagnosticSeverity} from "vscode-languageserver-types";
|
||||
import {registerLogger} from "./log";
|
||||
import {createDocument} from "./test-utils/document";
|
||||
import {TestLogger} from "./test-utils/logger";
|
||||
import {validate} from "./validate";
|
||||
|
||||
registerLogger(new TestLogger());
|
||||
|
||||
describe("expression validation", () => {
|
||||
it("access invalid context field", async () => {
|
||||
const result = await validate(
|
||||
|
||||
@@ -22,6 +22,7 @@ import {ContextProviderConfig} from "./context-providers/config";
|
||||
import {getContext} from "./context-providers/default";
|
||||
import {getWorkflowContext, WorkflowContext} from "./context/workflow-context";
|
||||
import {AccessError, wrapDictionary} from "./expression-validation/error-dictionary";
|
||||
import {error} from "./log";
|
||||
import {nullTrace} from "./nulltrace";
|
||||
import {getAllowedContext} from "./utils/allowed-context";
|
||||
import {findToken} from "./utils/find-token";
|
||||
@@ -75,8 +76,7 @@ export async function validate(
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO: Handle error here
|
||||
console.error(e);
|
||||
error(`Unhandled error while validating: ${e}`);
|
||||
}
|
||||
|
||||
return diagnostics;
|
||||
@@ -211,7 +211,7 @@ async function validateExpression(
|
||||
range: mapRange(expression.range)
|
||||
});
|
||||
} else {
|
||||
// Ignore error
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user