Skip to content

Commit

Permalink
Github integration (#10)
Browse files Browse the repository at this point in the history
* github integration

* adding readme
  • Loading branch information
justrdk authored Oct 15, 2024
1 parent b3b989d commit ca4ec4d
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 0 deletions.
121 changes: 121 additions & 0 deletions github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# @restackio/integrations-github

This package provides integration with Github, allowing you to create and publish releases programmatically using the Github API.

## Installation

To install the package, use npm or yarn:

```bash
npm install @restackio/integrations-github
```

## Usage

Make sure to create an access token on your github account and set the token as environment variabled named `GITHUB_AUTH_TOKEN`

### Setting up the Github service

To use the Github integration, you need to set up the Github service:

```typescript
// services.ts
import Restack from "@restackio/ai";
import { githubService } from "@restackio/integrations-github";

export async function services() {
const client = new Restack();
githubService({ client }).catch((err) => {
console.error("Error starting Github service:", err);
});
}

services().catch((err) => {
console.error("Error running services:", err);
});
```

### Creating a release

To create a release for a provided repository on Github:

```typescript
/// workflows/createRelease.ts

import { log, step } from "@restackio/ai/workflow";
import { githubTaskQueue } from "@restackio/integrations-github/taskQueue";
import * as githubFunctions from "@restackio/integrations-github/functions";

import * as functions from "../functions";

export async function createReleaseWorkflow({
owner,
repo,
tagName,
releaseName,
releaseBody,
branch,
}: {
owner: string;
repo: string;
tagName: string;
releaseName: string;
releaseBody: string;
branch?: string;
}) {
const createdRelease = await step<typeof githubFunctions>({
taskQueue: githubTaskQueue,
}).createRelease({
owner,
repo,
tagName,
releaseName,
releaseBody,
branch,
});

return createdRelease;
}
```

### Publishing a release

To mark the release as published on Github:

```typescript
/// workflows/publishRelease.ts

import { log, step } from "@restackio/ai/workflow";
import { githubTaskQueue } from "@restackio/integrations-github/taskQueue";
import * as githubFunctions from "@restackio/integrations-github/functions";

import * as functions from "../functions";

export async function publishReleaseWorkflow({
owner,
repo,
id,
}: {
owner: string;
repo: string;
id: number;
}) {
const publishedRelease = await step<typeof githubFunctions>({
taskQueue: githubTaskQueue,
}).publishRelease({
owner,
repo,
id.
});

return publishedRelease;
}
```

## Configuration

The Github client is configured using an access token. You can either pass the API key directly to the functions or set it as an environment variable:

```bash
GITHUB_AUTH_TOKEN=your-access-token
```
44 changes: 44 additions & 0 deletions github/functions/createRelease.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { githubClient } from "../utils/client.js";

export async function createRelease({
owner,
repo,
tagName,
releaseName,
releaseBody,
branch,
isDraft = false,
}: {
owner: string;
repo: string;
tagName: string;
releaseName: string;
releaseBody: string;
branch?: string;
isDraft?: boolean;
}) {
try {
const { octokit } = await githubClient();
const { data } = await octokit.rest.repos.createRelease({
owner,
repo,
tag_name: tagName,
name: releaseName,
body: releaseBody,
draft: isDraft,
generate_release_notes: true,
...(branch && { target_commitish: branch }),
});

return {
name: data.name,
tag_name: data.tag_name,
draft: data.draft,
published_at: data.published_at,
html_url: data.html_url,
id: data.id,
};
} catch (error) {
throw new Error(`Error while creating release: ${error}`);
}
}
21 changes: 21 additions & 0 deletions github/functions/getReleases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { githubClient } from "../utils/client.js";

export async function getReleases({
owner,
repo,
}: {
owner: string;
repo: string;
}) {
try {
const { octokit } = await githubClient();
const { data } = await octokit.rest.repos.listReleases({
owner,
repo,
});

return data;
} catch (error) {
throw new Error(`Error while fetching releases: ${error}`);
}
}
3 changes: 3 additions & 0 deletions github/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./createRelease.js";
export * from "./getReleases.js";
export * from "./publishRelease.js";
32 changes: 32 additions & 0 deletions github/functions/publishRelease.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { githubClient } from "../utils/client.js";

export async function publishRelease({
owner,
repo,
id,
}: {
owner: string;
repo: string;
id: number;
}) {
try {
const { octokit } = await githubClient();
const { data } = await octokit.rest.repos.updateRelease({
owner,
repo,
release_id: id,
draft: false,
});

return {
name: data.name,
tag_name: data.tag_name,
draft: data.draft,
published_at: data.published_at,
html_url: data.html_url,
id: data.id,
};
} catch (error) {
throw new Error(`Error while updating release: ${error}`);
}
}
45 changes: 45 additions & 0 deletions github/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@restackio/integrations-github",
"version": "1.0.0",
"main": "dist/service.js",
"types": "dist/service.d.ts",
"scripts": {
"start.watch": "nodemon ./service.ts",
"dev": "pnpm start.watch",
"clean": "rm -rf dist",
"build": "npm run clean && tsc"
},
"dependencies": {
"@octokit/auth-token": "^5.1.1",
"octokit": "^4.0.2"
},
"files": [
"dist"
],
"type": "module",
"exports": {
".": {
"import": "./dist/service.js",
"require": "./dist/service.js",
"types": "./dist/service.d.ts"
},
"./taskQueue": {
"import": "./dist/taskQueue.js",
"require": "./dist/taskQueue.js",
"types": "./dist/taskQueue.d.ts"
},
"./functions": {
"import": "./dist/functions/index.js",
"require": "./dist/functions/index.js",
"types": "./dist/functions/index.ts"
},
"./workflows": {
"import": "./dist/workflows/index.js",
"require": "./dist/workflows/index.js",
"types": "./dist/workflows/index.ts"
}
},
"devDependencies": {
"@types/node": "^22.7.5"
}
}
28 changes: 28 additions & 0 deletions github/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Restack, { ServiceInput } from "@restackio/ai";

import { githubTaskQueue } from "./taskQueue.js";
import {
createRelease,
getReleases,
publishRelease,
} from "./functions/index.js";

export async function githubService({
client,
options = {
rateLimit: 100,
},
}: {
client: Restack.default;
options?: ServiceInput["options"];
}) {
await client.startService({
taskQueue: githubTaskQueue,
functions: { createRelease, getReleases, publishRelease },
options,
});
}

githubService({ client: new Restack.default() }).catch((err) => {
console.error("Error service:", err);
});
1 change: 1 addition & 0 deletions github/taskQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const githubTaskQueue = "github";
8 changes: 8 additions & 0 deletions github/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./"
},
"include": ["**/*"]
}
17 changes: 17 additions & 0 deletions github/utils/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Octokit } from "octokit";
import { createTokenAuth } from "@octokit/auth-token";

import "dotenv/config";

export async function githubClient(
accessToken?: string
): Promise<{ octokit: Octokit }> {
const auth = createTokenAuth(accessToken ?? process.env.GITHUB_AUTH_TOKEN!);
const { token } = await auth();

const octokit = new Octokit({
auth: token,
});

return { octokit };
}

0 comments on commit ca4ec4d

Please sign in to comment.