Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/development' into feat/jest
Browse files Browse the repository at this point in the history
# Conflicts:
#	.gitignore
#	bun.lockb
#	package.json
#	src/github/types/env.ts
#	tests/__mocks__/db.ts
#	tests/main.test.ts
  • Loading branch information
gentlementlegen committed Mar 7, 2024
2 parents 97dd67a + 73ae1ad commit 3a88d8b
Show file tree
Hide file tree
Showing 24 changed files with 835 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"constructor-super": "error",
"no-invalid-this": "off",
"@typescript-eslint/no-invalid-this": ["error"],
"no-restricted-syntax": ["error", "ForInStatement"],
"no-restricted-syntax": ["error"],
"use-isnan": "error",
"@typescript-eslint/no-unused-vars": [
"error",
Expand Down
11 changes: 11 additions & 0 deletions .github/knip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { KnipConfig } from "knip";

const config: KnipConfig = {
entry: ["build/index.ts"],
project: ["src/**/*.ts"],
ignore: ["src/types/config.ts"],
ignoreExportsUsedInFile: true,
ignoreDependencies: [],
};

export default config;
33 changes: 33 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Build & Deploy

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-22.04

steps:
- name: Check out repository
uses: actions/checkout@v4
# with:
# submodules: "recursive" # Ensures submodules are checked out

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20.10.0

- name: Build
run: |
npm i -g bun
bun install
bun build src/worker.ts
# env: # Set environment variables for the build
# SUPABASE_URL: "https://wfzpewmlyiozupulbuur.supabase.co"
# SUPABASE_ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6IndmenBld21seWlvenVwdWxidXVyIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTU2NzQzMzksImV4cCI6MjAxMTI1MDMzOX0.SKIL3Q0NOBaMehH0ekFspwgcu3afp3Dl9EDzPqs1nKs"
31 changes: 0 additions & 31 deletions .github/workflows/cloudflare-deploy.yml

This file was deleted.

7 changes: 2 additions & 5 deletions .github/workflows/cspell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ jobs:
with:
node-version: "20.10.0"

- name: Install bun
run: npm i -g bun

- name: Install cspell
run: bun add cspell
- name: Install bun & CSpell
run: npm i -g bun cspell

- name: Run cspell
run: bun format:cspell
34 changes: 34 additions & 0 deletions .github/workflows/jest-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Run Jest testing suite
on:
workflow_dispatch:
pull_request_target:
types: [ opened, synchronize ]

env:
NODE_ENV: "test"

jobs:
testing:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: '20.10.0'
- uses: actions/checkout@master
with:
fetch-depth: 0
- name: Build & Run test suite
run: |
npm i -g bun
bun install
bun test | tee ./coverage.txt && exit ${PIPESTATUS[0]}
- name: Jest Coverage Comment
# Ensures this step is run even on previous step failure (e.g. test failed)
if: always()
uses: MishaKav/jest-coverage-comment@main
with:
coverage-summary-path: coverage/coverage-summary.json
junitxml-path: junit.xml
junitxml-title: JUnit
coverage-path: ./coverage.txt
33 changes: 33 additions & 0 deletions .github/workflows/knip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Knip

on:
pull_request_target:
workflow_dispatch:

permissions: write-all

jobs:
run-knip:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20.10.0

- name: Install toolchain
run: |
npm i -g bun
bun install
- name: Report knip results to pull request
uses: Codex-/knip-reporter@v2
with:
verbose: true
comment_id: ${{ github.workflow }}-reporter
command_script_name: knip-ci
annotations: true
ignore_results: false
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ node_modules
.yarn
.pnp.cjs
.pnp.loader.mjs
.env
static/dist
keys
coverage
junit.xml
99 changes: 85 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,106 @@

# @ubiquity/ubiquibot-kernel

The kernel is designed to:

- Interface with plugins (GitHub Actions) for longer running processes.
- Run on Cloudflare Workers.

## Environment variables
## Environment Variables

- **`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:

- `PRIVATE_KEY`
You need to obtain a private key from your GitHub App settings and convert it to Public-Key Cryptography Standards #8 (PKCS#8) format. You can 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.

###### Please 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.

- `WEBHOOK_SECRET`
This should be set in your GitHub App settings and also here.
- **`APP_ID`**
Retrieve this from your GitHub App settings.

- `APP_ID`
You can find this in your GitHub App settings.
- **`WEBHOOK_PROXY_URL` (only for development)**
Obtain a webhook URL at [smee.io](https://smee.io/) and set it in your GitHub App settings.

- `WEBHOOK_PROXY_URL` (only for development)
You need to obtain a webhook URL at <https://smee.io/> and set it in the GitHub App settings.

### Quick Start

```bash
git clone https://github.com/ubiquity/ubiquibot-kernel
cd ubiquibot-kernel
bun
bun install
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):

```sh
echo $(openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in YOUR_PRIVATE_KEY.PEM) | npx wrangler secret put PRIVATE_KEY --env dev
```

6. **Deploy the Kernel:**
- Execute `bun run deploy-dev` to deploy the kernel.

### Plugin Input and Output

#### Input

Inputs are received within the workflow, triggered by the `workflow_dispatch` event. The plugin is designed to handle the following inputs:

- `stateId`: An identifier used to track the state of plugin chain execution in Cloudflare KV. It is crucial to pass this identifier back in the output.
- `eventName`: The complete name of the event (e.g., `issue_comment.created`).
- `eventPayload`: The payload associated with the event.
- `settings`: A string containing JSON with settings specific to your plugin. The plugin itself defines these settings.
- `authToken`: A JWT token for accessing GitHub's API to the repository where the event occurred.
- `ref`: A reference (branch, tag, commit SHA) indicating the version of the plugin to be utilized.
#### Output
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`.

- `state_id`: The state ID passed in the inputs must be included here.
- `output`: A string containing JSON with custom output, defined by the plugin itself.

## Testing

### Jest

To start Jest tests, run

```shell
bun test
```
53 changes: 27 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
"format:prettier": "prettier --write .",
"format:cspell": "cspell **/*",
"prepare": "husky install",
"deploy": "wrangler deploy",
"worker": "wrangler dev --port 8787",
"proxy": "tsx src/proxy.ts"
"deploy-dev": "wrangler deploy --env dev",
"deploy-production": "wrangler deploy --env production",
"worker": "wrangler dev --env dev --port 8787",
"proxy": "tsx src/proxy.ts",
"knip": "knip --config .github/knip.ts",
"knip-ci": "knip --no-exit-code --reporter json --config .github/knip.ts",
"test": "jest --setupFiles dotenv/config --coverage"
},
"keywords": [
"typescript",
Expand All @@ -35,38 +39,35 @@
"create-cloudflare": "^2.8.3",
"octokit": "^3.1.2",
"smee-client": "^2.0.0",
"universal-github-app-jwt": "^2.0.5"
"universal-github-app-jwt": "^2.0.5",
"dotenv": "^16.4.4"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240117.0",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@commitlint/cli": "^18.6.1",
"@commitlint/config-conventional": "^18.6.2",
"@cspell/dict-node": "^4.0.3",
"@cspell/dict-software-terms": "^3.3.17",
"@cspell/dict-software-terms": "^3.3.18",
"@cspell/dict-typescript": "^3.1.2",
"@mswjs/data": "0.16.1",
"@types/bun": "1.0.8",
"@types/jest": "29.5.12",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"cspell": "^8.3.2",
"dotenv": "^16.3.1",
"esbuild": "^0.19.10",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-sonarjs": "^0.23.0",
"husky": "^8.0.3",
"jest": "29.7.0",
"jest-junit": "16.0.0",
"knip": "^3.3.0",
"lint-staged": "^15.1.0",
"@types/node": "^20.11.19",
"@typescript-eslint/eslint-plugin": "^7.0.1",
"@typescript-eslint/parser": "^7.0.1",
"cspell": "^8.4.0",
"esbuild": "^0.20.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-sonarjs": "^0.24.0",
"husky": "^9.0.11",
"knip": "^5.0.1",
"lint-staged": "^15.2.2",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.4",
"ts-jest": "29.1.2",
"prettier": "^3.2.5",
"ts-node": "10.9.2",
"tsx": "^4.6.2",
"typescript": "^5.0.4",
"tsx": "^4.7.1",
"typescript": "^5.3.3",
"wrangler": "^3.23.0"
},
"lint-staged": {
Expand Down
5 changes: 4 additions & 1 deletion src/github/github-context.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { EmitterWebhookEvent as WebhookEvent, EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks";
import { customOctokit } from "./github-client";
import { GitHubEventHandler } from "./github-event-handler";

export class GitHubContext<T extends WebhookEventName = WebhookEventName> {
public key: WebhookEventName;
public name: WebhookEventName;
public id: string;
public payload: WebhookEvent<T>["payload"];
public octokit: InstanceType<typeof customOctokit>;
public eventHandler: InstanceType<typeof GitHubEventHandler>;

constructor(event: WebhookEvent<T>, octokit: InstanceType<typeof customOctokit>) {
constructor(eventHandler: InstanceType<typeof GitHubEventHandler>, event: WebhookEvent<T>, octokit: InstanceType<typeof customOctokit>) {
this.eventHandler = eventHandler;
this.name = event.name;
this.id = event.id;
this.payload = event.payload;
Expand Down
Loading

0 comments on commit 3a88d8b

Please sign in to comment.