The kernel is designed to:
APP_PRIVATE_KEY
Obtain a private key from your GitHub App settings and convert it to the Public-Key Cryptography Standards #8 (PKCS#8) format. A new private key in PEM format can be generated and downloaded from https://github.com/organizations/{your-organization-name}/settings/apps/{your-github-app-name}. Use the following command to perform PEM to PKCS#8 conversion and append the result to your .dev.vars
file:
echo "APP_PRIVATE_KEY=\"$(openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in YOUR_APP_PRIVATE_KEY.PEM | awk 'BEGIN{ORS="\\n"} 1')\"" >> .dev.vars
Note: Replace YOUR_APP_PRIVATE_KEY.PEM
with the path to your actual PEM file when running the command.
APP_WEBHOOK_SECRET
Set this value in both your GitHub App settings and here.
APP_ID
Retrieve this from your GitHub App settings.
WEBHOOK_PROXY_URL
(only for development)
Obtain a webhook URL at smee.io and set it in your GitHub App settings.
git clone https://github.com/ubiquity/ubiquibot-kernel
cd ubiquibot-kernel
bun install
bun dev
Install Dependencies:
bun install
to install the required dependencies.Create a GitHub App:
Permissions & events
.Ensure the app is subscribed to all events with the following permissions:
Repository permissions:
Organization permissions:
Cloudflare Account Setup:
npx wrangler login
to log in.Create a KV Namespace:
npx wrangler kv:namespace create PLUGIN_CHAIN_STATE
.[env.dev]
in wrangler.toml
.Manage Secrets:
npx wrangler secret put <KEY> --env dev
.For the private key, execute the following (replace YOUR_APP_PRIVATE_KEY.PEM
with the actual PEM file path):
echo $(openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in YOUR_APP_PRIVATE_KEY.PEM) | npx wrangler secret put APP_PRIVATE_KEY --env dev
Deploy the Kernel:
bun run deploy-dev
to deploy the kernel.Inputs are received within the workflow, triggered by the workflow_dispatch
event. The plugin is designed to handle the following inputs:
interface PluginInput {
stateId: string; // An identifier used to track the state of plugin chain execution in Cloudflare KV
eventName: string; // The complete name of the event (e.g., `issue_comment.created`)
eventPayload: any; // The payload associated with the event
settings: string; // A string containing JSON with settings specific to your plugin
authToken: string; // A JWT token for accessing GitHub's API to the repository where the event occurred
ref: string; // A reference (branch, tag, commit SHA) indicating the version of the plugin to be utilized
}
Example usage:
const input: PluginInput = {
stateId: "abc123",
eventName: "issue_comment.created",
eventPayload: {
/* ... */
},
settings: '{ "key": "value" }',
authToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
ref: "refs/heads/main",
};
Data is returned using the repository_dispatch
event on the plugin's repository, and the output is structured within the client_payload
.
The event_type
must be set to return_data_to_ubiquibot_kernel
.
interface PluginOutput {
state_id: string; // The state ID passed in the inputs must be included here
output: string; // A string containing JSON with custom output, defined by the plugin itself
}
Example usage:
const output: PluginOutput = {
state_id: "abc123",
output: '{ "result": "success", "message": "Plugin executed successfully" }',
};
The kernel supports 2 types of plugins:
How to run a "hello-world" plugin the Cloudflare way:
bun dev
to spin up the kernelbun plugin:hello-world
to spin up a local server for the "hello-world" pluginOWNER/REPOSITORY/.github/.ubiquibot-config.yml
):plugins:
- skipBotEvents: true
uses:
# hello-world-plugin
- plugin: http://127.0.0.1:9090
runsOn: [ "issue_comment.created" ]
with:
response: world
/hello
comment in any issueworld
message (example)How it works:
/hello
command the kernel receives the issue_comment.created
event/hello
command to the plugin that should be executed (i.e. the API method that should be called).ubiquibot-config.yml
) to the plugin endpointA screencast tutorial on how to set up and run a hello world plugin is available at wiki.
To start Jest tests, run
bun test