From c4160c6d095a0354f59666c5f8e90cfceaab1a4c Mon Sep 17 00:00:00 2001 From: whilefoo Date: Thu, 29 Aug 2024 23:18:43 +0200 Subject: [PATCH 01/10] feat: actions sdk --- bun.lockb | Bin 427506 -> 434290 bytes package.json | 2 + src/sdk/actions.ts | 115 +++++++++++++++++++++++++++++++++++++++++++ src/sdk/constants.ts | 1 + src/sdk/index.ts | 2 + src/sdk/server.ts | 65 ++++++++++++++++++++---- 6 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 src/sdk/actions.ts diff --git a/bun.lockb b/bun.lockb index a35e00b7514e314a1fe188b122a7bf1b74083f1c..4d6ba3fa512f6764746aaa28ed263a9e2fc8f667 100755 GIT binary patch delta 98170 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 AVgLXD delta 94670 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 folj$0w+d>xX3x~1?>;g6TL-( + handler: (context: Context) => Promise | undefined>, + options?: Options +) { + const pluginOptions = { + logLevel: options?.logLevel || LOG_LEVEL.INFO, + postCommentOnError: options?.postCommentOnError || true, + settingsSchema: options?.settingsSchema, + envSchema: options?.envSchema, + }; + + const inputs = Value.Decode(inputSchema, github.context.payload.inputs); + + let config: TConfig; + if (pluginOptions.settingsSchema) { + config = Value.Decode(pluginOptions.settingsSchema, JSON.parse(inputs.settings)); + } else { + config = JSON.parse(inputs.settings) as TConfig; + } + + let env: TEnv; + if (pluginOptions.envSchema) { + env = Value.Decode(pluginOptions.envSchema, process.env); + } else { + env = process.env as TEnv; + } + + const context: Context = { + eventName: inputs.eventName as TSupportedEvents, + payload: JSON.parse(inputs.eventPayload), + octokit: new customOctokit({ auth: inputs.authToken }), + config: config, + env: env, + logger: new Logs(pluginOptions.logLevel), + }; + + try { + const result = await handler(context); + core.setOutput("result", result); + await returnDataToKernel(inputs.authToken, inputs.stateId, result); + } catch (error) { + console.error(error); + + let loggerError: LogReturn | null; + if (error instanceof Error) { + core.setFailed(error); + loggerError = context.logger.error(`Error: ${error}`, { error: error }); + } else if (error instanceof LogReturn) { + core.setFailed(error.logMessage.raw); + loggerError = error; + } else { + core.setFailed(`Error: ${error}`); + loggerError = context.logger.error(`Error: ${error}`); + } + + if (pluginOptions.postCommentOnError && loggerError) { + await postComment(context, loggerError); + } + } +} + +async function postComment(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, + repo: context.payload.repository.name, + issue_number: context.payload.issue.number, + body: `${error.logMessage.diff}\n`, + }); + } +} + +function getGithubWorkflowRunUrl() { + return `${github.context.payload.repository?.html_url}/actions/runs/${github.context.runId}`; +} + +async function returnDataToKernel(repoToken: string, stateId: string, output: object | undefined) { + const octokit = new customOctokit({ auth: repoToken }); + await octokit.rest.repos.createDispatchEvent({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + event_type: "return_data_to_ubiquibot_kernel", + client_payload: { + state_id: stateId, + output: output ? JSON.stringify(output) : null, + }, + }); +} diff --git a/src/sdk/constants.ts b/src/sdk/constants.ts index bd46b8d..57d618d 100644 --- a/src/sdk/constants.ts +++ b/src/sdk/constants.ts @@ -8,3 +8,4 @@ dkRj2Je2kag9b3FMxskv1npNSrPVcSc5lGNYlnZnfxIAnCknOC118JjitlrpT6wd 8wIDAQAB -----END PUBLIC KEY----- `; +export const KERNEL_APP_ID = 0; diff --git a/src/sdk/index.ts b/src/sdk/index.ts index 7cadb41..4911055 100644 --- a/src/sdk/index.ts +++ b/src/sdk/index.ts @@ -1,2 +1,4 @@ export { createPlugin } from "./server"; +export { createActionsPlugin } from "./actions"; export type { Context } from "./context"; +export { KERNEL_APP_ID, KERNEL_PUBLIC_KEY } from "./constants"; diff --git a/src/sdk/server.ts b/src/sdk/server.ts index 6285d1e..52257b8 100644 --- a/src/sdk/server.ts +++ b/src/sdk/server.ts @@ -5,12 +5,17 @@ import { customOctokit } from "./octokit"; import { EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks"; import { verifySignature } from "./signature"; import { KERNEL_PUBLIC_KEY } from "./constants"; -import { Logs, LogLevel, LOG_LEVEL } from "@ubiquity-dao/ubiquibot-logger"; +import { Logs, LogLevel, LOG_LEVEL, LogReturn } from "@ubiquity-dao/ubiquibot-logger"; import { Manifest } from "../types/manifest"; +import { TAnySchema } from "@sinclair/typebox"; +import { Value } from "@sinclair/typebox/value"; interface Options { kernelPublicKey?: string; logLevel?: LogLevel; + postCommentOnError?: boolean; + settingsSchema?: TAnySchema; + envSchema?: TAnySchema; } export async function createPlugin( @@ -18,6 +23,14 @@ export async function createPlugin { @@ -32,24 +45,31 @@ export async function createPlugin = { eventName: payload.eventName, payload: payload.payload, octokit: new customOctokit({ auth: payload.authToken }), - config: payload.settings as TConfig, - env: ctx.env as TEnv, - logger: new Logs(options?.logLevel || LOG_LEVEL.INFO), + config: config, + env: env, + logger: new Logs(pluginOptions.logLevel), }; try { @@ -57,9 +77,34 @@ export async function createPlugin`, + }); + } +} From 2be91f648bb2c98e73549e5a7ed7fd5c5025098d Mon Sep 17 00:00:00 2001 From: whilefoo Date: Wed, 4 Sep 2024 09:46:32 +0200 Subject: [PATCH 02/10] feat: add tests --- src/sdk/actions.ts | 3 +- src/sdk/server.ts | 3 +- src/sdk/util.ts | 5 ++++ tests/sdk.test.ts | 74 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 src/sdk/util.ts diff --git a/src/sdk/actions.ts b/src/sdk/actions.ts index 53fa065..68f6305 100644 --- a/src/sdk/actions.ts +++ b/src/sdk/actions.ts @@ -7,6 +7,7 @@ import { Logs, LogLevel, LOG_LEVEL, LogReturn } from "@ubiquity-dao/ubiquibot-lo import { config } from "dotenv"; import { Type as T, TAnySchema } from "@sinclair/typebox"; import { Value } from "@sinclair/typebox/value"; +import { sanitizeMetadata } from "./util"; config(); interface Options { @@ -92,7 +93,7 @@ async function postComment(context: Context, error: LogReturn) { owner: context.payload.repository.owner.login, repo: context.payload.repository.name, issue_number: context.payload.issue.number, - body: `${error.logMessage.diff}\n`, + body: `${error.logMessage.diff}\n`, }); } } diff --git a/src/sdk/server.ts b/src/sdk/server.ts index 52257b8..6993ea5 100644 --- a/src/sdk/server.ts +++ b/src/sdk/server.ts @@ -9,6 +9,7 @@ import { Logs, LogLevel, LOG_LEVEL, LogReturn } from "@ubiquity-dao/ubiquibot-lo import { Manifest } from "../types/manifest"; import { TAnySchema } from "@sinclair/typebox"; import { Value } from "@sinclair/typebox/value"; +import { sanitizeMetadata } from "./util"; interface Options { kernelPublicKey?: string; @@ -104,7 +105,7 @@ async function postComment(context: Context, error: LogReturn) { owner: context.payload.repository.owner.login, repo: context.payload.repository.name, issue_number: context.payload.issue.number, - body: `${error.logMessage.diff}\n`, + body: `${error.logMessage.diff}\n`, }); } } diff --git a/src/sdk/util.ts b/src/sdk/util.ts new file mode 100644 index 0000000..d518b91 --- /dev/null +++ b/src/sdk/util.ts @@ -0,0 +1,5 @@ +import { LogReturn } from "@ubiquity-dao/ubiquibot-logger"; + +export function sanitizeMetadata(obj: LogReturn["metadata"]): string { + return JSON.stringify(obj, null, 2).replace(//g, ">").replace(/--/g, "--"); +} diff --git a/tests/sdk.test.ts b/tests/sdk.test.ts index 5679245..20fe0aa 100644 --- a/tests/sdk.test.ts +++ b/tests/sdk.test.ts @@ -1,6 +1,6 @@ import { server } from "./__mocks__/node"; import issueCommented from "./__mocks__/requests/issue-comment-post.json"; -import { expect, describe, beforeAll, afterAll, afterEach, it } from "@jest/globals"; +import { expect, describe, beforeAll, afterAll, afterEach, it, jest } from "@jest/globals"; import * as crypto from "crypto"; import { createPlugin } from "../src/sdk/server"; @@ -37,10 +37,14 @@ beforeAll(async () => { ); server.listen(); }); -afterEach(() => server.resetHandlers()); +afterEach(() => { + server.resetHandlers(); + jest.resetModules(); + jest.restoreAllMocks(); +}); afterAll(() => server.close()); -describe("SDK tests", () => { +describe("SDK worker tests", () => { it("Should serve manifest", async () => { const res = await app.request("/manifest.json", { method: "GET", @@ -129,6 +133,68 @@ describe("SDK tests", () => { }); expect(res.status).toEqual(200); const result = await res.json(); - expect(result).toEqual({ stateId: "stateId", output: { success: true, event: "issue_comment.created" } }); + expect(result).toEqual({ stateId: "stateId", output: { success: true, event: issueCommented.eventName } }); + }); +}); + +describe("SDK actions tests", () => { + it("Should accept correct request", async () => { + jest.mock("@actions/github", () => ({ + context: { + runId: "1", + payload: { + inputs: { + stateId: "stateId", + eventName: issueCommented.eventName, + settings: "{}", + eventPayload: JSON.stringify(issueCommented.eventPayload), + authToken: "test", + ref: "", + }, + }, + repo: { + owner: "ubiquity", + repo: "ubiquibot-kernel", + }, + }, + })); + const setOutput = jest.fn(); + const setFailed = jest.fn(); + jest.mock("@actions/core", () => ({ + setOutput, + setFailed, + })); + const createDispatchEvent = jest.fn(); + jest.mock("../src/sdk/octokit", () => ({ + customOctokit: class MockOctokit { + constructor() { + return { + rest: { + repos: { + createDispatchEvent: createDispatchEvent, + }, + }, + }; + } + }, + })); + const { createActionsPlugin } = await import("../src/sdk/actions"); + + await createActionsPlugin(async (context: Context) => { + return { + event: context.eventName, + }; + }); + expect(setOutput).toHaveBeenCalledWith("result", { event: issueCommented.eventName }); + expect(setFailed).not.toHaveBeenCalled(); + expect(createDispatchEvent).toHaveBeenCalledWith({ + event_type: "return_data_to_ubiquibot_kernel", + owner: "ubiquity", + repo: "ubiquibot-kernel", + client_payload: { + state_id: "stateId", + output: JSON.stringify({ event: issueCommented.eventName }), + }, + }); }); }); From e32602a1f357d093a2a7471796fbe54ae49176e5 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Wed, 4 Sep 2024 13:18:09 +0200 Subject: [PATCH 03/10] fix: tests --- bun.lockb | Bin 434290 -> 434290 bytes package.json | 2 +- src/sdk/server.ts | 2 +- tests/configuration.test.ts | 43 +++++++++++++---- tests/main.test.ts | 93 ++++++++++++++++++------------------ tests/sdk.test.ts | 43 +++++++++++++++++ 6 files changed, 126 insertions(+), 57 deletions(-) diff --git a/bun.lockb b/bun.lockb index 4d6ba3fa512f6764746aaa28ed263a9e2fc8f667..0193fd3154c251785c36242dc151ddc9d49ee798 100755 GIT binary patch delta 160 zcmV;R0AK&|z#8(v8jvm^08{^{0Z3H0v@jfwpv8zFy{cUoM$7Es8pN~J6v|bH1pdrO&@)A-NwFeBdu}+Fh zlh{l!g9uEw2uuN8RX~aP9qsUTIK = { eventName: payload.eventName, - payload: payload.payload, + payload: payload.eventPayload, octokit: new customOctokit({ auth: payload.authToken }), config: config, env: env, diff --git a/tests/configuration.test.ts b/tests/configuration.test.ts index 582872b..f238fc2 100644 --- a/tests/configuration.test.ts +++ b/tests/configuration.test.ts @@ -6,6 +6,7 @@ import { getConfig } from "../src/github/utils/config"; import { GitHubContext } from "../src/github/github-context"; import { GitHubEventHandler } from "../src/github/github-event-handler"; import { getManifest } from "../src/github/utils/plugins"; +import { RestEndpointMethodTypes } from "@octokit/plugin-rest-endpoint-methods"; config({ path: ".dev.vars" }); @@ -23,16 +24,40 @@ afterAll(() => { describe("Configuration tests", () => { it("Should properly parse the Action path if a branch and workflow are specified", async () => { - function getContent() { - return { - data: ` -plugins: - - uses: - - plugin: ubiquity/user-activity-watcher:compute.yml@fork/pull/1 - with: - settings1: 'enabled'`, - }; + function getContent(args: RestEndpointMethodTypes["repos"]["getContent"]["parameters"]) { + let data: string; + if (args.path === "manifest.json") { + data = ` + { + "name": "plugin", + "commands": { + "command": { + "description": "description", + "ubiquity:example": "example" + } + } + } + `; + } else { + data = ` + plugins: + - uses: + - plugin: ubiquity/user-activity-watcher:compute.yml@fork/pull/1 + with: + settings1: 'enabled'`; + } + + if (args.mediaType === undefined || args.mediaType?.format === "base64") { + return { + data: { + content: Buffer.from(data).toString("base64"), + }, + }; + } else if (args.mediaType?.format === "raw") { + return { data }; + } } + const cfg = await getConfig({ key: issueOpened, name: issueOpened, diff --git a/tests/main.test.ts b/tests/main.test.ts index fa5ad59..85ab398 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -165,36 +165,56 @@ describe("Worker tests", () => { it("Should merge organization and repository configuration", async () => { const workflowId = "compute.yml"; function getContent(args: RestEndpointMethodTypes["repos"]["getContent"]["parameters"]) { - if (args.repo !== "ubiquibot-config") { + let data: string; + if (args.path === "manifest.json") { + data = ` + { + "name": "plugin", + "commands": { + "command": { + "description": "description", + "ubiquity:example": "example" + } + } + } + `; + } else if (args.repo !== "ubiquibot-config") { + data = ` + plugins: + - uses: + - plugin: repo-3/plugin-3 + with: + setting1: false + - uses: + - plugin: repo-1/plugin-1 + with: + setting2: true`; + } else { + data = ` + plugins: + - uses: + - plugin: uses-1/plugin-1 + with: + settings1: 'enabled' + - uses: + - plugin: repo-1/plugin-1 + with: + setting1: false + - uses: + - plugin: repo-2/plugin-2 + with: + setting2: true`; + } + + if (args.mediaType === undefined || args.mediaType?.format === "base64") { return { - data: ` -plugins: - - uses: - - plugin: repo-3/plugin-3 - with: - setting1: false - - uses: - - plugin: repo-1/plugin-1 - with: - setting2: true`, + data: { + content: Buffer.from(data).toString("base64"), + }, }; + } else if (args.mediaType?.format === "raw") { + return { data }; } - return { - data: ` -plugins: - - uses: - - plugin: uses-1/plugin-1 - with: - settings1: 'enabled' - - uses: - - plugin: repo-1/plugin-1 - with: - setting1: false - - uses: - - plugin: repo-2/plugin-2 - with: - setting2: true`, - }; } const cfg = await getConfig({ key: issueOpened, @@ -207,25 +227,6 @@ plugins: }, } as unknown as GitHubContext<"issues.closed">["payload"], octokit: { - repos: { - getContent() { - return { - data: { - content: Buffer.from( - JSON.stringify({ - name: "plugin", - commands: { - command: { - description: "description", - "ubiquity:example": "example", - }, - }, - }) - ).toString("base64"), - }, - }; - }, - }, rest: { repos: { getContent, diff --git a/tests/sdk.test.ts b/tests/sdk.test.ts index 20fe0aa..8cc7df5 100644 --- a/tests/sdk.test.ts +++ b/tests/sdk.test.ts @@ -86,6 +86,36 @@ describe("SDK worker tests", () => { expect(res.status).toEqual(400); }); it("Should handle thrown errors", async () => { + const createComment = jest.fn(); + jest.mock("../src/sdk/octokit", () => ({ + customOctokit: class MockOctokit { + constructor() { + return { + rest: { + issues: { + createComment, + }, + }, + }; + } + }, + })); + + const { createPlugin } = await import("../src/sdk/server"); + const app = await createPlugin( + async (context: Context<{ shouldFail: boolean }>) => { + if (context.config.shouldFail) { + throw context.logger.error("test error"); + } + return { + success: true, + event: context.eventName, + }; + }, + { name: "test" }, + { kernelPublicKey: publicKey } + ); + const data = { ...issueCommented, stateId: "stateId", @@ -108,6 +138,19 @@ describe("SDK worker tests", () => { method: "POST", }); expect(res.status).toEqual(500); + expect(createComment).toHaveBeenCalledWith({ + issue_number: 5, + owner: "ubiquibot", + repo: "bot", + body: `\`\`\`diff +! test error +\`\`\` +`, + }); }); it("Should accept correct request", async () => { const data = { From 654e3839b6e2e70c7c23dd3736a9263dfdda2426 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Thu, 5 Sep 2024 19:56:33 +0200 Subject: [PATCH 04/10] chore: small fixes --- package.json | 4 ++-- src/sdk/actions.ts | 1 + tests/configuration.test.ts | 19 ------------------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 95f01f9..cce7761 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "open-source" ], "dependencies": { - "@actions/core": "^1.10.1", - "@actions/github": "^6.0.0", + "@actions/core": "1.10.1", + "@actions/github": "6.0.0", "@octokit/auth-app": "7.1.0", "@octokit/core": "6.1.2", "@octokit/plugin-paginate-rest": "11.3.3", diff --git a/src/sdk/actions.ts b/src/sdk/actions.ts index 68f6305..cd85900 100644 --- a/src/sdk/actions.ts +++ b/src/sdk/actions.ts @@ -8,6 +8,7 @@ import { config } from "dotenv"; import { Type as T, TAnySchema } from "@sinclair/typebox"; import { Value } from "@sinclair/typebox/value"; import { sanitizeMetadata } from "./util"; + config(); interface Options { diff --git a/tests/configuration.test.ts b/tests/configuration.test.ts index f238fc2..6d2334e 100644 --- a/tests/configuration.test.ts +++ b/tests/configuration.test.ts @@ -69,25 +69,6 @@ describe("Configuration tests", () => { }, } as unknown as GitHubContext<"issues.closed">["payload"], octokit: { - repos: { - getContent() { - return { - data: { - content: Buffer.from( - JSON.stringify({ - name: "plugin", - commands: { - command: { - description: "description", - "ubiquity:example": "example", - }, - }, - }) - ).toString("base64"), - }, - }; - }, - }, rest: { repos: { getContent, From 7bcdef99eaaea9efd3b4811f376bd77baa94e14a Mon Sep 17 00:00:00 2001 From: zyrafal Date: Sun, 8 Sep 2024 21:57:08 +0200 Subject: [PATCH 05/10] Add sync-template.yml workflow --- .github/workflows/sync-template.yml | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/sync-template.yml diff --git a/.github/workflows/sync-template.yml b/.github/workflows/sync-template.yml new file mode 100644 index 0000000..dc92ad5 --- /dev/null +++ b/.github/workflows/sync-template.yml @@ -0,0 +1,49 @@ +name: Sync branch to template + +on: + workflow_dispatch: + schedule: + - cron: '14 0 1 * *' + +jobs: + sync: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get GitHub App token + uses: tibdex/github-app-token@v1.7.0 + id: get_installation_token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Sync branch to template + env: + GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} + IGNORE_FILES: "README.md another-file.txt" + run: | + branch_name=$(git rev-parse --abbrev-ref HEAD) + original_remote=$(git remote get-url origin) + pr_branch="sync-template/${branch_name}" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git checkout -b "$pr_branch" + git clone https://github.com/ubiquity/ts-template + for file in $IGNORE_FILES; do + rm -rf "ts-template/$file" + done + cp -rf ts-template/* . + rm -rf ts-template/ + git add . + git commit -m "chore: sync template" + git push "$original_remote" "$pr_branch" + gh pr create --title "Sync branch to template" --body "This pull request merges changes from the template repository." --head "$pr_branch" --base "$branch_name" + + From d292f5abf93301aaee0d508a0166d891ac36fd18 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Tue, 10 Sep 2024 13:02:36 +0200 Subject: [PATCH 06/10] feat: add app id and bot user id --- src/github/handlers/index.ts | 6 +++--- src/sdk/constants.ts | 3 ++- src/sdk/index.ts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/github/handlers/index.ts b/src/github/handlers/index.ts index d3f91a4..c95d6af 100644 --- a/src/github/handlers/index.ts +++ b/src/github/handlers/index.ts @@ -25,8 +25,8 @@ export function bindHandlers(eventHandler: GitHubEventHandler) { eventHandler.onAny(tryCatchWrapper((event) => handleEvent(event, eventHandler))); // onAny should also receive GithubContext but the types in octokit/webhooks are weird } -async function shouldSkipPlugin(event: EmitterWebhookEvent, context: GitHubContext, pluginChain: PluginConfiguration["plugins"][0]) { - if (pluginChain.skipBotEvents && "sender" in event.payload && event.payload.sender?.type === "Bot") { +export async function shouldSkipPlugin(context: GitHubContext, pluginChain: PluginConfiguration["plugins"][0]) { + if (pluginChain.skipBotEvents && "sender" in context.payload && context.payload.sender?.type === "Bot") { console.log("Skipping plugin chain because sender is a bot"); return true; } @@ -68,7 +68,7 @@ async function handleEvent(event: EmitterWebhookEvent, eventHandler: InstanceTyp } for (const pluginChain of pluginChains) { - if (await shouldSkipPlugin(event, context, pluginChain)) { + if (await shouldSkipPlugin(context, pluginChain)) { continue; } diff --git a/src/sdk/constants.ts b/src/sdk/constants.ts index 57d618d..f394a86 100644 --- a/src/sdk/constants.ts +++ b/src/sdk/constants.ts @@ -8,4 +8,5 @@ dkRj2Je2kag9b3FMxskv1npNSrPVcSc5lGNYlnZnfxIAnCknOC118JjitlrpT6wd 8wIDAQAB -----END PUBLIC KEY----- `; -export const KERNEL_APP_ID = 0; +export const KERNEL_APP_ID = 975031; +export const BOT_USER_ID = 178941584; diff --git a/src/sdk/index.ts b/src/sdk/index.ts index 4911055..4339ddf 100644 --- a/src/sdk/index.ts +++ b/src/sdk/index.ts @@ -1,4 +1,4 @@ export { createPlugin } from "./server"; export { createActionsPlugin } from "./actions"; export type { Context } from "./context"; -export { KERNEL_APP_ID, KERNEL_PUBLIC_KEY } from "./constants"; +export * from "./constants"; From 128e93efc9a28533834d009d582f62894a2a4927 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Tue, 10 Sep 2024 13:03:04 +0200 Subject: [PATCH 07/10] feat: test for skipBotEvents --- tests/configuration.test.ts | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/tests/configuration.test.ts b/tests/configuration.test.ts index 6d2334e..a5eaeed 100644 --- a/tests/configuration.test.ts +++ b/tests/configuration.test.ts @@ -7,6 +7,7 @@ import { GitHubContext } from "../src/github/github-context"; import { GitHubEventHandler } from "../src/github/github-event-handler"; import { getManifest } from "../src/github/utils/plugins"; import { RestEndpointMethodTypes } from "@octokit/plugin-rest-endpoint-methods"; +import { shouldSkipPlugin } from "../src/github/handlers"; config({ path: ".dev.vars" }); @@ -44,7 +45,8 @@ describe("Configuration tests", () => { - uses: - plugin: ubiquity/user-activity-watcher:compute.yml@fork/pull/1 with: - settings1: 'enabled'`; + settings1: 'enabled' + skipBotEvents: false`; } if (args.mediaType === undefined || args.mediaType?.format === "base64") { @@ -92,7 +94,7 @@ describe("Configuration tests", () => { }, }, ], - skipBotEvents: true, + skipBotEvents: false, }); }); it("Should retrieve the configuration manifest from the proper branch if specified", async () => { @@ -160,4 +162,67 @@ describe("Configuration tests", () => { ); expect(manifest).toEqual(content["withoutRef"]); }); + it("should not skip bot event if skipBotEvents is set to false", async () => { + function getContent(args: RestEndpointMethodTypes["repos"]["getContent"]["parameters"]) { + let data: string; + if (args.path === "manifest.json") { + data = ` + { + "name": "plugin", + "commands": { + "command": { + "description": "description", + "ubiquity:example": "example" + } + } + } + `; + } else { + data = ` + plugins: + - uses: + - plugin: ubiquity/test-plugin + with: + settings1: 'enabled' + skipBotEvents: false`; + } + + if (args.mediaType === undefined || args.mediaType?.format === "base64") { + return { + data: { + content: Buffer.from(data).toString("base64"), + }, + }; + } else if (args.mediaType?.format === "raw") { + return { data }; + } + } + + const context = { + key: issueOpened, + name: issueOpened, + id: "", + payload: { + repository: { + owner: { login: "ubiquity" }, + name: "conversation-rewards", + }, + sender: { + type: "Bot", + }, + } as unknown as GitHubContext<"issues.closed">["payload"], + octokit: { + rest: { + repos: { + getContent, + }, + }, + }, + eventHandler: {} as GitHubEventHandler, + } as unknown as GitHubContext; + + const cfg = await getConfig(context); + expect(cfg.plugins[0].skipBotEvents).toEqual(false); + await expect(shouldSkipPlugin(context, cfg.plugins[0])).resolves.toEqual(false); + }); }); From 41ee9e1c32336c33a96263e206940bdca4a9ce6e Mon Sep 17 00:00:00 2001 From: whilefoo Date: Thu, 12 Sep 2024 14:34:39 +0200 Subject: [PATCH 08/10] chore: unpin logger version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cce7761..4b94720 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@octokit/webhooks": "13.2.8", "@octokit/webhooks-types": "7.5.1", "@sinclair/typebox": "0.32.35", - "@ubiquity-dao/ubiquibot-logger": "1.3.1", + "@ubiquity-dao/ubiquibot-logger": "^1.3.1", "dotenv": "16.4.5", "hono": "4.4.13", "smee-client": "2.0.1", From ba98cb691e168b5d563ac45611cd10cc08216f93 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Thu, 12 Sep 2024 18:12:11 +0200 Subject: [PATCH 09/10] fix: log if comment can't be created --- src/sdk/actions.ts | 2 ++ src/sdk/server.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/sdk/actions.ts b/src/sdk/actions.ts index cd85900..9479c4a 100644 --- a/src/sdk/actions.ts +++ b/src/sdk/actions.ts @@ -96,6 +96,8 @@ async function postComment(context: Context, error: LogReturn) { issue_number: context.payload.issue.number, body: `${error.logMessage.diff}\n`, }); + } else { + context.logger.info("Cannot post comment because issue is not found in the payload"); } } diff --git a/src/sdk/server.ts b/src/sdk/server.ts index 8e5a5e3..5e17035 100644 --- a/src/sdk/server.ts +++ b/src/sdk/server.ts @@ -107,5 +107,7 @@ async function postComment(context: Context, error: LogReturn) { issue_number: context.payload.issue.number, body: `${error.logMessage.diff}\n`, }); + } else { + context.logger.info("Cannot post comment because issue is not found in the payload"); } } From 1c42c47fd1f8916d71b90cd5cbff846e029e16ef Mon Sep 17 00:00:00 2001 From: Mentlegen <9807008+gentlementlegen@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:10:44 +0900 Subject: [PATCH 10/10] chore!: renamed kernel toml --- wrangler.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrangler.toml b/wrangler.toml index c78f2a6..228d0db 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,4 +1,4 @@ -name = "ubiquityos-kernel" +name = "ubiquity-os-kernel" main = "src/worker.ts" compatibility_date = "2023-12-06" compatibility_flags = [ "nodejs_compat" ]