Skip to content

Commit

Permalink
fix: the user now has its own octokit instance
Browse files Browse the repository at this point in the history
  • Loading branch information
gentlementlegen committed Feb 12, 2025
1 parent e15ca55 commit 52d7b12
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .dev.vars.example
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MY_SECRET="MY_SECRET"
USER_GITHUB_TOKEN="ghp_"
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# `@ubiquity-os/plugin-template`
# `@ubiquity-os/plugin-demo`

## Prerequisites

Expand All @@ -25,14 +25,12 @@

```yml
plugins:
- name: hello-world
id: hello-world
- name: plugin-demo
id: plugin-demo
uses:
- plugin: http://localhost:4000
- plugin: https://ubiquity-os-plugin-demo-main.ubiquity.workers.dev
with:
# Define configurable items here and the kernel will pass these to the plugin.
configurableResponse: "Hello, is it me you are looking for?"
customStringsUrl: "https://raw.githubusercontent.com/ubiquibot/plugin-template/development/strings.json"
userName: "ubiquity-os-simulant"
```
###### At this stage, your plugin will fire on your defined events with the required settings passed in from the kernel. You can now start writing your plugin's logic.
Expand Down
4 changes: 2 additions & 2 deletions src/action.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createActionsPlugin } from "@ubiquity-os/plugin-sdk";
import { LOG_LEVEL, LogLevel } from "@ubiquity-os/ubiquity-os-logger";
import { runPlugin } from "./index";
import { Env, envSchema, PluginSettings, pluginSettingsSchema, SupportedEvents } from "./types";
import { Context, Env, envSchema, PluginSettings, pluginSettingsSchema, SupportedEvents } from "./types";

export default createActionsPlugin<PluginSettings, Env, null, SupportedEvents>(
(context) => {
return runPlugin(context);
return runPlugin(context as Context);
},
{
logLevel: (process.env.LOG_LEVEL as LogLevel) || LOG_LEVEL.INFO,
Expand Down
78 changes: 47 additions & 31 deletions src/handlers/hello-world.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { customOctokit } from "@ubiquity-os/plugin-sdk/octokit";
import { Context } from "../types";

async function setLabels({ payload, octokit }: Context) {
Expand All @@ -18,55 +17,72 @@ async function setLabels({ payload, octokit }: Context) {
});
}

async function createPullRequest({ payload, octokit }: Context) {
const userOctokit = new customOctokit({
auth: "",
async function createPullRequest({ payload, logger, userOctokit }: Context) {
const sourceRepo = payload.repository.name;
const sourceIssueNumber = "issue" in payload ? payload.issue.number : payload.pull_request.number;
const sourceOwner = payload.repository.owner.login;

const { data: user } = await userOctokit.rest.users.getAuthenticated();
logger.info(`Creating fork for user: ${user.login}`);

await userOctokit.rest.repos.createFork({
owner: sourceOwner,
repo: sourceRepo,
});
const repo = payload.repository.name;
const issueNumber = "issue" in payload ? payload.issue.number : payload.pull_request.number;
const owner = payload.repository.owner.login;

const { data: repoData } = await octokit.rest.repos.get({
owner,
repo,
logger.debug("Waiting for the fork to be ready...");
await new Promise((resolve) => setTimeout(resolve, 5000));

const { data: repoData } = await userOctokit.rest.repos.get({
owner: sourceOwner,
repo: sourceRepo,
});
const defaultBranch = repoData.default_branch;
const { data: refData } = await octokit.rest.git.getRef({
owner,
repo,
logger.debug("Repository data", { defaultBranch, repoUrl: repoData.html_url });
const { data: refData } = await userOctokit.rest.git.getRef({
owner: sourceOwner,
repo: sourceRepo,
ref: `heads/${defaultBranch}`,
});
const ref = `fix/${crypto.randomUUID()}`;

await octokit.rest.git.createRef({
owner,
repo,
await userOctokit.rest.git.createRef({
owner: user.login,
repo: sourceRepo,
ref: `refs/heads/${ref}`,
sha: refData.object.sha,
});
await octokit.rest.repos.createOrUpdateFileContents({
owner,
repo,
path: "test.txt",
message: "chore: update test.txt file",
content: Buffer.from(crypto.randomUUID()).toString("base64"),
branch: ref,
const { data: commit } = await userOctokit.rest.git.getCommit({
owner: user.login,
repo: sourceRepo,
commit_sha: refData.object.sha,
});
const { data: newCommit } = await userOctokit.rest.git.createCommit({
owner: user.login,
repo: sourceRepo,
message: "chore: empty commit",
tree: commit.tree.sha,
parents: [refData.object.sha],
});
await userOctokit.rest.git.updateRef({
owner: user.login,
repo: sourceRepo,
ref: `heads/${ref}`,
sha: newCommit.sha,
});
await userOctokit.rest.pulls.create({
owner,
repo,
head: ref,
owner: sourceOwner,
repo: sourceRepo,
head: `${user.login}:${ref}`,
base: defaultBranch,
body: `Resolves #${issueNumber}`,
body: `Resolves #${sourceIssueNumber}`,
title: ref,
});
}

export async function handleComment(context: Context) {
const { payload } = context;
const { payload, userOctokit } = context;

const userOctokit = new customOctokit({
auth: "",
});
const repo = payload.repository.name;
const issueNumber = "issue" in payload ? payload.issue.number : payload.pull_request.number;
const owner = payload.repository.owner.login;
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { customOctokit } from "@ubiquity-os/plugin-sdk/octokit";
import { handleComment } from "./handlers/hello-world";
import { Context } from "./types";
import { isCommentEvent } from "./types/typeguards";

export async function runPlugin(context: Context) {
const { logger, eventName } = context;

context.userOctokit = new customOctokit({
auth: context.env.USER_GITHUB_TOKEN,
});

if (isCommentEvent(context)) {
return await handleComment(context);
}
Expand Down
5 changes: 4 additions & 1 deletion src/types/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Context as PluginContext } from "@ubiquity-os/plugin-sdk";
import { customOctokit } from "@ubiquity-os/plugin-sdk/octokit";
import { Env } from "./env";
import { PluginSettings } from "./plugin-input";

Expand All @@ -9,4 +10,6 @@ import { PluginSettings } from "./plugin-input";
*/
export type SupportedEvents = "issue_comment.created" | "pull_request_review_comment.created";

export type Context<T extends SupportedEvents = SupportedEvents> = PluginContext<PluginSettings, Env, null, T>;
export type Context<T extends SupportedEvents = SupportedEvents> = PluginContext<PluginSettings, Env, null, T> & {
userOctokit: InstanceType<typeof customOctokit>;
};
1 change: 1 addition & 0 deletions src/types/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { LOG_LEVEL } from "@ubiquity-os/ubiquity-os-logger";
export const envSchema = T.Object({
LOG_LEVEL: T.Optional(T.Enum(LOG_LEVEL, { default: LOG_LEVEL.INFO })),
KERNEL_PUBLIC_KEY: T.Optional(T.String()),
USER_GITHUB_TOKEN: T.String(),
});

export type Env = StaticDecode<typeof envSchema>;
9 changes: 1 addition & 8 deletions src/types/plugin-input.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import { StaticDecode, Type as T } from "@sinclair/typebox";

/**
* This should contain the properties of the bot config
* that are required for the plugin to function.
*
* The kernel will extract those and pass them to the plugin,
* which are built into the context object from setup().
*/
export const pluginSettingsSchema = T.Object(
{
userName: T.String({ default: "ubiquity-os-simulant" }),
userName: T.String({ default: "ubiquity-os-simulant", description: "The name of the user for the simulation of a real user" }),
},
{ default: {} }
);
Expand Down
4 changes: 2 additions & 2 deletions src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { Manifest } from "@ubiquity-os/plugin-sdk/manifest";
import { ExecutionContext } from "hono";
import manifest from "../manifest.json";
import { runPlugin } from "./index";
import { Env, envSchema, PluginSettings, pluginSettingsSchema, SupportedEvents } from "./types";
import { Context, Env, envSchema, PluginSettings, pluginSettingsSchema, SupportedEvents } from "./types";

export default {
async fetch(request: Request, env: Env, executionCtx?: ExecutionContext) {
return createPlugin<PluginSettings, Env, null, SupportedEvents>(
(context) => {
return runPlugin(context);
return runPlugin(context as Context);
},
manifest as Manifest,
{
Expand Down

0 comments on commit 52d7b12

Please sign in to comment.