Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge development into main #67

Merged
merged 26 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
957f0bb
feat: add hello-world plugin example
rndquu Jun 5, 2024
403232c
fix: resolve conflicts
rndquu Jun 19, 2024
e5e5485
Merge pull request #50 from rndquu/feat/hello-world-example
rndquu Jun 19, 2024
e6fc6f4
ci: fix cspell
rndquu Jun 19, 2024
8ac7bba
ci: ignore msw in knip
rndquu Jun 19, 2024
3249656
Merge pull request #60 from rndquu/ci/fix-mswjs
gentlementlegen Jun 20, 2024
21d800a
feat!: bumped eslint to v9
gentlementlegen Jun 20, 2024
32ff5fd
chore: updated pattern to refuse underscore for file names
gentlementlegen Jun 20, 2024
ec91a92
chore: changed workflow to run all checks
gentlementlegen Jun 20, 2024
c8882f2
chore: renamed file to match kebab case
gentlementlegen Jun 20, 2024
ff44b69
chore: removed js allow and enabled interop
gentlementlegen Jun 20, 2024
fcfd3d6
chore: fixed knip run
gentlementlegen Jun 20, 2024
b474620
chore: added CLOUDFLARE_ACCOUNT_ID to env setup-kv build step
gentlementlegen Jun 20, 2024
80666ef
chore: added log for wrangler result
gentlementlegen Jun 20, 2024
b98cb0f
chore: added log for wrangler result
gentlementlegen Jun 20, 2024
ae53b6c
chore: update knip workflow configuration
gitcoindev Jun 21, 2024
1eac1f7
chore: remove superflous steps in knip-reporter workflow
gitcoindev Jun 21, 2024
fc65832
chore: remove unused binaries in ignoreBinaries knip configuration
gitcoindev Jun 21, 2024
5564c6e
chore: add setup-kv to knip ignoreBinaries list
gitcoindev Jun 21, 2024
9373a6d
chore: added cloudflare account id to wrangler step
gentlementlegen Jun 21, 2024
d93e839
chore: moved cloudflare ID to with instead of env
gentlementlegen Jun 21, 2024
e2517cc
Merge pull request #63 from gentlementlegen/fix/kv-namespace-deployment
whilefoo Jun 23, 2024
9a3a71d
chore: remove format:cspell and setup-kv from ignoreBinaries knip config
gitcoindev Jun 23, 2024
3a7066b
Merge pull request #65 from gitcoindev/correct-knip-workflow-configur…
gentlementlegen Jun 24, 2024
4abf7c5
chore: merged develop
gentlementlegen Jul 1, 2024
eda131b
Merge pull request #61 from gentlementlegen/fix/rename-file
gentlementlegen Jul 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log"],
"useGitignore": true,
"language": "en",
"words": ["dataurl", "devpool", "fkey", "outdir", "servedir", "supabase", "typebox", "ubiquibot", "smee", "tomlify"],
"words": ["dataurl", "devpool", "fkey", "mswjs", "outdir", "servedir", "supabase", "typebox", "ubiquibot", "smee", "tomlify"],
"dictionaries": ["typescript", "node", "software-terms"],
"import": ["@cspell/dict-typescript/cspell-ext.json", "@cspell/dict-node/cspell-ext.json", "@cspell/dict-software-terms"],
"ignoreRegExpList": ["[0-9a-fA-F]{6}"]
Expand Down
53 changes: 0 additions & 53 deletions .eslintrc

This file was deleted.

4 changes: 2 additions & 2 deletions .github/knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import type { KnipConfig } from "knip";
const config: KnipConfig = {
entry: ["src/worker.ts"],
project: ["src/**/*.ts"],
ignoreBinaries: ["build", "i", "format:cspell", "awk", "lsof"],
ignoreBinaries: ["i"],
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
ignoreExportsUsedInFile: true,
ignoreDependencies: ["@mswjs/data", "esbuild", "eslint-config-prettier", "eslint-plugin-prettier"],
ignoreDependencies: ["@mswjs/data", "esbuild", "eslint-config-prettier", "eslint-plugin-prettier", "msw"],
};

export default config;
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ jobs:
bun setup-kv
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

- uses: cloudflare/wrangler-action@v3
with:
wranglerVersion: '3.57.0'
wranglerVersion: "3.57.0"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
secrets: |
WEBHOOK_PROXY_URL
WEBHOOK_SECRET
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/bun-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Run Bun testing suite
on:
workflow_dispatch:
pull_request:
types: [ opened, synchronize ]
types: [opened, synchronize]

env:
NODE_ENV: "test"
Expand All @@ -18,7 +18,7 @@ jobs:
- uses: oven-sh/setup-bun@v1
- uses: actions/setup-node@v4
with:
node-version: '20.10.0'
node-version: "20.10.0"
- uses: actions/checkout@master
with:
fetch-depth: 0
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/cspell.yml → .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Spell Check
name: Format Checks

on:
push:

jobs:
spellcheck:
name: Check for spelling errors
formatCheck:
name: Check for formatting issues
runs-on: ubuntu-latest

steps:
Expand All @@ -17,8 +17,10 @@ jobs:
with:
node-version: "20.10.0"

- name: Install bun & CSpell
run: npm i -g bun cspell
- uses: oven-sh/setup-bun@v1

- name: Run cspell
run: bun format:cspell
- name: Install deps
run: bun i

- name: Run checks
run: bun format
38 changes: 38 additions & 0 deletions .github/workflows/knip-reporter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Knip-reporter

on:
workflow_run:
workflows: ["Knip"]
types:
- completed

jobs:
knip-reporter:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion != 'success' }}
steps:
- uses: actions/download-artifact@v4
with:
name: knip-results
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Read pr number
id: pr-number
uses: juliangruber/read-file-action@v1
with:
path: ./pr-number.txt
trim: true

- name: Report knip results to pull request
uses: gitcoindev/knip-reporter@main
with:
verbose: true
comment_id: ${{ github.workflow }}-reporter
command_script_name: knip-ci
annotations: true
ignore_results: false
json_input: true
json_input_file_name: knip-results.json
pull_request_number: ${{ steps.pr-number.outputs.content }}
token: ${{ secrets.GITHUB_TOKEN }}
25 changes: 14 additions & 11 deletions .github/workflows/knip.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
name: Knip

on:
pull_request_target:
workflow_dispatch:

permissions: write-all
pull_request:

jobs:
run-knip:
Expand All @@ -23,11 +20,17 @@ jobs:
npm i -g bun
bun install

- name: Report knip results to pull request
uses: Codex-/knip-reporter@v2
- name: Store PR number
run: echo ${{ github.event.number }} > pr-number.txt

- name: Run Knip
run: bun knip || bun knip --reporter json > knip-results.json

- name: Upload knip result
if: failure()
uses: actions/upload-artifact@v4
with:
verbose: true
comment_id: ${{ github.workflow }}-reporter
command_script_name: knip-ci
annotations: true
ignore_results: false
name: knip-results
path: |
knip-results.json
pr-number.txt
60 changes: 53 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# @ubiquity/ubiquibot-kernel

The kernel is designed to:
Expand All @@ -11,11 +10,11 @@ The kernel is designed to:
- **`PRIVATE_KEY`**
Obtain a private key from your GitHub App settings and convert it to the Public-Key Cryptography Standards #8 (PKCS#8) format. Use the following command to perform this conversion and append the result to your `.dev.vars` file:

```sh
echo "PRIVATE_KEY=\"$(openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in YOUR_PRIVATE_KEY.PEM | awk 'BEGIN{ORS="\\n"} 1')\"" >> .dev.vars
```
```sh
echo "PRIVATE_KEY=\"$(openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in YOUR_PRIVATE_KEY.PEM | awk 'BEGIN{ORS="\\n"} 1')\"" >> .dev.vars
```

**Note:** Replace `YOUR_PRIVATE_KEY.PEM` with the path to your actual PEM file when running the command.
**Note:** Replace `YOUR_PRIVATE_KEY.PEM` with the path to your actual PEM file when running the command.

- **`WEBHOOK_SECRET`**
Set this value in both your GitHub App settings and here.
Expand All @@ -26,7 +25,6 @@ The kernel is designed to:
- **`WEBHOOK_PROXY_URL` (only for development)**
Obtain a webhook URL at [smee.io](https://smee.io/) and set it in your GitHub App settings.


### Quick Start

```bash
Expand All @@ -39,31 +37,38 @@ bun dev
### Deploying to Cloudflare Workers

1. **Install Dependencies:**

- Execute `bun install` to install the required dependencies.

2. **Create a Github App:**

- Generate a Github App and configure its settings.
- Navigate to app settings and click `Permissions & events`.
- Ensure the app is subscribed to all events with the following permissions:

Repository permissions:

- Actions: Read & Write
- Contents: Read & Write
- Issues: Read & Write
- Pull Requests: Read & Write

Organization permissions:

- Members: Read only

3. **Cloudflare Account Setup:**

- If not done already, create a Cloudflare account.
- Run `npx wrangler login` to log in.

4. **Create a KV Namespace:**

- Generate a KV namespace using `npx wrangler kv:namespace create PLUGIN_CHAIN_STATE`.
- Copy the generated ID and paste it under `[env.dev]` in `wrangler.toml`.

5. **Manage Secrets:**

- Add (env) secrets using `npx wrangler secret put <KEY> --env dev`.
- For the private key, execute the following (replace `YOUR_PRIVATE_KEY.PEM` with the actual PEM file path):

Expand Down Expand Up @@ -97,7 +102,9 @@ Example usage:
const input: PluginInput = {
stateId: "abc123",
eventName: "issue_comment.created",
eventPayload: { /* ... */ },
eventPayload: {
/* ... */
},
settings: '{ "key": "value" }',
authToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
ref: "refs/heads/main",
Expand Down Expand Up @@ -126,6 +133,45 @@ const output: PluginOutput = {
};
```

## Plugin Quick Start

The kernel supports 2 types of plugins:

1. Github actions ([wiki](https://github.com/ubiquity/ubiquibot-kernel/wiki/How-it-works))
2. Cloudflare Workers (which are simple backend servers with a single API route)

How to run a "hello-world" plugin the Cloudflare way:

1. Run `bun dev` to spin up the kernel
2. Run `bun plugin:hello-world` to spin up a local server for the "hello-world" plugin
3. Update the bot's config file in the repository where you use the bot (`OWNER/REPOSITORY/.github/.ubiquibot-config.yml`):

```
plugins:
'issue_comment.created':
- name: "hello-world-plugin name"
description: "hello-world-plugin description"
command: "/hello"
example: "/hello example"
skipBotEvents: true
uses:
# hello-world-plugin
- plugin: http://127.0.0.1:9090
type: github
with:
response: world
```

4. Post a `/hello` comment in any issue
5. The bot should respond with the `world` message ([example](https://github.com/rndquu-org/test-repo/issues/54#issuecomment-2149313139))

How it works:

1. When you post the `/hello` command the kernel receives the `issue_comment.created` event
2. The kernel matches the `/hello` command to the plugin that should be executed (i.e. the API method that should be called)
3. The kernel passes github event payload, bot's access token and plugin settings (from `.ubiquibot-config.yml`) to the plugin endpoint
4. The plugin performs all of the required actions and returns the result

## Testing

### Jest
Expand Down
Binary file modified bun.lockb
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ async function main() {
let namespaceId: string;
try {
const res = execSync(`wrangler kv:namespace create ${NAMESPACE_TITLE}`).toString();
console.log(res);
const newId = res.match(/id = \s*"([^"]+)"/)?.[1];
if (!newId) {
throw new Error(`The new ID could not be found.`);
}
namespaceId = newId;
console.log(`Namespace created with ID: ${namespaceId}`);
} catch (error) {
console.error(error);
const listOutput = JSON.parse(execSync(`wrangler kv:namespace list`).toString()) as Namespace[];
const existingNamespace = listOutput.find((o) => o.title === NAMESPACE_TITLE_WITH_PREFIX);
if (!existingNamespace) {
Expand All @@ -99,6 +101,6 @@ async function main() {
main()
.then(() => console.log("Successfully bound namespace."))
.catch((e) => {
console.error("Error checking or creating namespace:", e);
console.error("Error checking or creating namespace:\n", e);
process.exit(1);
});
Loading
Loading