Skip to content

Commit

Permalink
fix(sdk): add postComment function for structured metadata
Browse files Browse the repository at this point in the history
Introduce postComment function to embed structured metadata in comments.
  • Loading branch information
gentlementlegen committed Oct 25, 2024
1 parent ebf9635 commit b87f4ca
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
54 changes: 50 additions & 4 deletions src/sdk/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as core from "@actions/core";
import * as github from "@actions/github";
import { EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks";
import { Type as T, TAnySchema } from "@sinclair/typebox";
import { TAnySchema, Type as T } from "@sinclair/typebox";
import { Value } from "@sinclair/typebox/value";
import { LOG_LEVEL, LogLevel, LogReturn, Logs } from "@ubiquity-os/ubiquity-os-logger";
import { config } from "dotenv";
Expand Down Expand Up @@ -31,6 +31,8 @@ const inputSchema = T.Object({
signature: T.String(),
});

const HEADER_NAME = "Ubiquity";

export async function createActionsPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends WebhookEventName = WebhookEventName>(
handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>,
options?: Options
Expand Down Expand Up @@ -96,12 +98,12 @@ export async function createActionsPlugin<TConfig = unknown, TEnv = unknown, TSu
}

if (pluginOptions.postCommentOnError && loggerError) {
await postComment(context, loggerError);
await postErrorComment(context, loggerError);
}
}
}

async function postComment(context: Context, error: LogReturn) {
async function postErrorComment(context: Context, error: LogReturn) {
if ("issue" in context.payload && context.payload.repository?.owner?.login) {
await context.octokit.rest.issues.createComment({
owner: context.payload.repository.owner.login,
Expand All @@ -110,7 +112,7 @@ async function postComment(context: Context, error: LogReturn) {
body: `${error.logMessage.diff}\n<!--\n${getGithubWorkflowRunUrl()}\n${sanitizeMetadata(error.metadata)}\n-->`,
});
} else {
context.logger.info("Cannot post comment because issue is not found in the payload");
context.logger.info("Cannot post error comment because issue is not found in the payload");
}
}

Expand All @@ -130,3 +132,47 @@ async function returnDataToKernel(repoToken: string, stateId: string, output: ob
},
});
}

function createStructuredMetadata(className: string | undefined, logReturn: LogReturn) {
let logMessage, metadata;
if (logReturn) {
logMessage = logReturn.logMessage;
metadata = logReturn.metadata;
}

const jsonPretty = sanitizeMetadata(metadata);
const stackLine = new Error().stack?.split("\n")[2] ?? "";
const caller = stackLine.match(/at (\S+)/)?.[1] ?? "";
const ubiquityMetadataHeader = `<!-- ${HEADER_NAME} - ${className} - ${caller} - ${metadata?.revision}`;

let metadataSerialized: string;
const metadataSerializedVisible = ["```json", jsonPretty, "```"].join("\n");
const metadataSerializedHidden = [ubiquityMetadataHeader, jsonPretty, "-->"].join("\n");

if (logMessage?.type === "fatal") {
// if the log message is fatal, then we want to show the metadata
metadataSerialized = [metadataSerializedVisible, metadataSerializedHidden].join("\n");
} else {
// otherwise we want to hide it
metadataSerialized = metadataSerializedHidden;
}

return metadataSerialized;
}

/**
* Posts a comment on a GitHub issue if the issue exists in the context payload, embedding structured metadata to it.
*/
export async function postComment(context: Context, message: LogReturn) {
if ("issue" in context.payload && context.payload.repository?.owner?.login) {
const metadata = createStructuredMetadata(message.metadata?.name, message);
await context.octokit.rest.issues.createComment({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.issue.number,
body: [message.logMessage.raw, metadata].join("\n"),
});
} else {
context.logger.info("Cannot post comment because issue is not found in the payload");
}
}
2 changes: 1 addition & 1 deletion src/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { createPlugin } from "./server";
export { createActionsPlugin } from "./actions";
export { createActionsPlugin, postComment } from "./actions";
export type { Context } from "./context";
export * from "./constants";

0 comments on commit b87f4ca

Please sign in to comment.