Merge pull request #191 from github/cschleiden/events-without-default-types
Support events without default `types`
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import {data, DescriptionDictionary} from "@github/actions-expressions";
|
||||
|
||||
import webhooks from "./webhooks.json";
|
||||
import webhookObjects from "./objects.json";
|
||||
import webhooks from "./webhooks.json";
|
||||
|
||||
import schedule from "./schedule.json" assert {type: "json"};
|
||||
import workflow_call from "./workflow_call.json" assert {type: "json"};
|
||||
@@ -73,9 +73,12 @@ type DeduplicatedWebhooks = {
|
||||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const dedupedWebhookPayloads: DeduplicatedWebhooks = webhooks as any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const objects: Param[] = webhookObjects as any;
|
||||
|
||||
// Hydrated webhook payloads
|
||||
const webhookPayloads: Webhooks = {};
|
||||
|
||||
// Hydrate the workflow dispatch payload if it exists
|
||||
@@ -89,7 +92,18 @@ if (inputs) {
|
||||
delete inputs.childParamsGroups;
|
||||
}
|
||||
|
||||
export function getEventPayload(event: string, action: string = "default"): DescriptionDictionary | undefined {
|
||||
export function getSupportedEventTypes(event: string): string[] {
|
||||
const payloads = dedupedWebhookPayloads?.[event];
|
||||
if (!payloads) {
|
||||
if (customEventPayloads[event]) {
|
||||
return ["default"];
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(payloads || {});
|
||||
}
|
||||
|
||||
export function getEventPayload(event: string, action: string): DescriptionDictionary | undefined {
|
||||
const payload = getWebhookPayload(event, action);
|
||||
if (!payload) {
|
||||
// Not all events are real webhooks. Check if there is a custom payload for this event
|
||||
@@ -117,7 +131,7 @@ function mergeParam(target: DescriptionDictionary, param: Param) {
|
||||
// auto-completion. Possible existence and the description are enough.
|
||||
//
|
||||
// As a special case, if the param is already set, do not overwrite it.
|
||||
if (!!target.get(param.name)) {
|
||||
if (target.get(param.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,16 +139,16 @@ function mergeParam(target: DescriptionDictionary, param: Param) {
|
||||
}
|
||||
}
|
||||
|
||||
function mergeObject(d: DescriptionDictionary, toAdd: Object): DescriptionDictionary {
|
||||
function mergeObject(d: DescriptionDictionary, toAdd: object): DescriptionDictionary {
|
||||
for (const [key, value] of Object.entries(toAdd)) {
|
||||
if (value && typeof value === "object" && !d.get(key)) {
|
||||
if (!Array.isArray(value) && Object.entries(value).length === 0) {
|
||||
if (!Array.isArray(value) && Object.entries(value as object).length === 0) {
|
||||
// Allow an empty object to be any value
|
||||
d.add(key, new data.Null());
|
||||
continue;
|
||||
}
|
||||
|
||||
d.add(key, mergeObject(new DescriptionDictionary(), value));
|
||||
d.add(key, mergeObject(new DescriptionDictionary(), value as object));
|
||||
} else {
|
||||
d.add(key, new data.Null());
|
||||
}
|
||||
@@ -144,16 +158,17 @@ function mergeObject(d: DescriptionDictionary, toAdd: Object): DescriptionDictio
|
||||
}
|
||||
|
||||
function getWebhookPayload(event: string, action: string): WebhookPayload | undefined {
|
||||
const deduplicatedPayload = dedupedWebhookPayloads?.[event]?.[action];
|
||||
if (!deduplicatedPayload) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Is the payload already hydrated?
|
||||
const existingPayload = webhookPayloads?.[event]?.[action];
|
||||
if (existingPayload) {
|
||||
return existingPayload;
|
||||
}
|
||||
|
||||
const deduplicatedPayload = dedupedWebhookPayloads?.[event]?.[action];
|
||||
if (!deduplicatedPayload) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Recreate the full payload and store it for reuse
|
||||
const params = deduplicatedPayload.bodyParameters.map(p => fullParam(p));
|
||||
const payload = {
|
||||
|
||||
@@ -74,6 +74,59 @@ jobs:
|
||||
]);
|
||||
});
|
||||
|
||||
it("single event - no default types", async () => {
|
||||
const workflowContext = await testGetWorkflowContext(`
|
||||
on:
|
||||
issues:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: ec|ho`);
|
||||
|
||||
const g = getGithubContext(workflowContext, Mode.Completion);
|
||||
if (!isDescriptionDictionary(g)) {
|
||||
fail();
|
||||
}
|
||||
|
||||
const e = g.get("event") as DescriptionDictionary;
|
||||
const i = e.get("issue") as DescriptionDictionary;
|
||||
|
||||
expect(i.pairs().map(p => p.key)).toEqual([
|
||||
"active_lock_reason",
|
||||
"assignee",
|
||||
"assignees",
|
||||
"author_association",
|
||||
"body",
|
||||
"closed_at",
|
||||
"comments",
|
||||
"comments_url",
|
||||
"created_at",
|
||||
"draft",
|
||||
"events_url",
|
||||
"html_url",
|
||||
"id",
|
||||
"labels",
|
||||
"labels_url",
|
||||
"locked",
|
||||
"milestone",
|
||||
"node_id",
|
||||
"number",
|
||||
"performed_via_github_app",
|
||||
"pull_request",
|
||||
"reactions",
|
||||
"repository_url",
|
||||
"state",
|
||||
"state_reason",
|
||||
"timeline_url",
|
||||
"title",
|
||||
"updated_at",
|
||||
"url",
|
||||
"user"
|
||||
]);
|
||||
});
|
||||
|
||||
it("multiple events - multiple types", async () => {
|
||||
const workflowContext = await testGetWorkflowContext(`
|
||||
on:
|
||||
|
||||
@@ -4,7 +4,7 @@ import {TypesFilterConfig} from "@github/actions-workflow-parser/model/workflow-
|
||||
import {WorkflowContext} from "../context/workflow-context";
|
||||
import {Mode} from "./default";
|
||||
import {getDescription} from "./descriptions";
|
||||
import {getEventPayload} from "./events/eventPayloads";
|
||||
import {getEventPayload, getSupportedEventTypes} from "./events/eventPayloads";
|
||||
import {getInputsContext} from "./inputs";
|
||||
|
||||
export function getGithubContext(workflowContext: WorkflowContext, mode: Mode): DescriptionDictionary {
|
||||
@@ -98,10 +98,14 @@ function getEventContext(workflowContext: WorkflowContext, mode: Mode): Expressi
|
||||
for (const eventName of events) {
|
||||
const event = eventsConfig[eventName] as TypesFilterConfig;
|
||||
|
||||
const types = getTypes(eventName, event.types);
|
||||
let types = getTypes(eventName, event.types);
|
||||
const payloadEventName = getPayloadEventName(eventName);
|
||||
|
||||
if (types.length === 1 && types[0] === "default") {
|
||||
types = getSupportedEventTypes(eventName);
|
||||
}
|
||||
|
||||
for (const type of types) {
|
||||
const payloadEventName = getPayloadEventName(eventName);
|
||||
const eventPayload = getEventPayload(payloadEventName, type);
|
||||
|
||||
if (!eventPayload) {
|
||||
|
||||
Reference in New Issue
Block a user