# GitHub

> Support for querying GitHub

The `github` module provides several helper functions to query GitHub, along with the connection information for more advanced usage.

## Configuration

[Section titled “Configuration”](#configuration)

The `github` configuration is automatically detected from the environment and git.

* The GitHub token is read from the `GITHUB_TOKEN` environment variable. Some queries might work without authentication for public repositories.
* The current issue or pull request number is automatically detected from the `GITHUB_ISSUE` environment variable. It is set in a pull request action, but otherwise you can set it manually.

### GitHub CodeSpaces

[Section titled “GitHub CodeSpaces”](#github-codespaces)

In a GitHub CodeSpace, the `GITHUB_TOKEN` is automatically provisioned.

### GitHub Actions

[Section titled “GitHub Actions”](#github-actions)

In GitHub Actions, you might need to add permissions to the workspace to access workflow logs, pull requests and or Marketplace Models. Additionally, you need to pass the `secret.GITHUB_TOKEN` to the GenAIScript script run.

Read the [guide on GitHub Actions](/genaiscript/reference/github-actions) for more details.

genai.yml

```yml
permissions:
    contents: read
    actions: read
    pull-requests: read # or write if you plan to create comments
    models: read # access to GitHub Marketplace Models
...
    - run: npx --yes genaiscript ...
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        ...
```

## Functions

[Section titled “Functions”](#functions)

### Issues

[Section titled “Issues”](#issues)

You can query issues and issue comments using `listIssues` and `listIssueComments`.

```js
const issues = await github.listIssues({ per_page: 5 });
console.log(issues.map((i) => i.title));


// Use issue number!
const issueComments = await github.listIssueComments(
  issues[0].number,
);
console.log(issueComments);
```

* update issue:

```js
await github.updateIssue(issues[0].number, {
  title: "New title",
  body: "New body",
});
```

* create issues:

```js
// Create a simple issue
const issue = await github.createIssue("Bug: Something is broken", "Description of the bug", {
  labels: ["bug", "priority-high"]
});


// Create a sub-issue (child issue linked to a parent)
const subIssue = await github.createIssue("Sub-task: Fix login form", "Fix the specific login form issue", {
  labels: ["bug", "sub-task"],
  parentIssue: 123 // Link to parent issue #123
});
```

* create issue comments:

```js
// Use issue number!
await github.createIssueComment(issueNumber, "Hello, world!");
```

* list issue labels

```js
const labels = await github.listIssueLabels(issueNumber);
console.log(labels.map((i) => i.name));
```

* list issue labels for the repository

```js
const labels = await github.listIssueLabels();
```

### Pull Requests

[Section titled “Pull Requests”](#pull-requests)

Query pull requests and pull request review comments using `listPullRequests` and `listPullRequestReviewComments`.

```js
const prs = await github.listPullRequests({ per_page: 5 });
console.log(prs.map((i) => i.title));


// Use pull request number!
const prcs = await github.listPullRequestReviewComments(
  prs[0].number,
);
console.log(prcs.map((i) => i.body));
```

In GitHub Actions, ensure the `pull-request: read` permission is granted.

### Workflow Runs

[Section titled “Workflow Runs”](#workflow-runs)

Access the log of workflow runs to analyze failures with `listWorkflowRuns`.

```js
// List runs
const runs = await github.listWorkflowRuns("build.yml", {
  per_page: 5,
});
console.log(runs.map((i) => i.status));


const jobs = await github.listWorkflowJobs(runs[0].id);
// Redacted job log
console.log(jobs[0].content);
```

In GitHub Actions, grant the `actions: read` permission.

### Bots

[Section titled “Bots”](#bots)

You can assign a bot to an existing issue or pull request using `assignIssueToBot`.

```js
// Test assigning issue to bot (default copilot-swe-agent)
const result = await github.assignIssueToBot(issueNumber);
```

### Artifacts

[Section titled “Artifacts”](#artifacts)

Workflows can create and attach artifacts to the workflow run. You can list and download these artifacts using `listWorkflowArtifacts` and `downloadArtifact`.

```js
const artifacts = await github.listWorkflowArtifacts(
  runs[0].id,
);
console.log(artifacts);


const artifact = artifacts[0];
// genaiscript automatically unzips the artifact
const files = await github.downloadArtifact(artifact.id);
console.log(files);
```

### Assets

[Section titled “Assets”](#assets)

Image or video assets urls uploaded through the GitHub UI can be resolved using `resolveAssetUrl`. They are typically of the form `https://github.com/.../assets/<uuid>`. The function returns a short lived URL with an embedded access token to download the asset.

```js
const url = await github.resolveAssetUrl(
  "https://github.com/user-attachments/assets/a6e1935a-868e-4cca-9531-ad0ccdb9eace",
);
console.log(url);
```

### Search Code

[Section titled “Search Code”](#search-code)

Use `searchCode` for a code search on the default branch in the same repository.

```js
const res = await github.searchCode("HTMLToText");
console.log(res);
```

### Get File Content

[Section titled “Get File Content”](#get-file-content)

Retrieve file content for a given ref, tag, or commit SHA using `getFile`.

```js
const pkg = await github.getFile("package.json", "main");
console.log(pkg.content.slice(0, 50) + "...");
```

### Get Repository Content

[Section titled “Get Repository Content”](#get-repository-content)

List files or directories at a path in a remote repository. By default, file contents from a directory are not loaded. Use `downloadContent: true`.

```js
// Get top-level markdown files
const files = await github.getRepositoryContent("", {
  type: "file",
  glob: "*.md",
  downloadContent: true,
  maxDownloadSize: 2_000,
});
```

### Upload asset

[Section titled “Upload asset”](#upload-asset)

This API requires `contents: write` permission in GitHub Actions. It uploads data into an orphaned branch in the Repository and returns the URL to the uploaded asset.

```js
const url = await github.uploadAsset(file);
console.log(url);
```

The URL can be used in markdown in comments or issues.

Note

It takes a few minutes for the asset to be available at this URL.

### Languages

[Section titled “Languages”](#languages)

Query the list of programming languages that GitHub computed for the repository using `listRepositoryLanguages`.

```js
const languages = await github.listRepositoryLanguages();
```

### Branches

[Section titled “Branches”](#branches)

List the branches on the repository using `listBranches`.

```js
const branches = await github.listBranches();
console.log(branches);
```

### Releases

[Section titled “Releases”](#releases)

List the releases on the repository using `listReleases`.

```js
const releases = await github.listReleases();
console.log(releases);
```

## Octokit access

[Section titled “Octokit access”](#octokit-access)

Utilize [octokit](https://www.npmjs.com/package/octokit) to access the full GitHub APIs.

```js
import { Octokit } from "@octokit/core"


const { client }: { client: Octokit } = await github.api()
...
```

Install octokit in your list of packages:

* npm

  ```sh
  npm i -D octokit
  ```

* pnpm

  ```sh
  pnpm add -D octokit
  ```

* yarn

  ```sh
  yarn add -D octokit
  ```

## Working on a different repository

[Section titled “Working on a different repository”](#working-on-a-different-repository)

Use `client` to open a github client on a different repository using the same secrets.

```js
const client = github.client("owner", "repo");
```