# GitHub OAuth

Connect GitHub repositories, issues, pull requests, and notifications.

JsWorkflows provides a platform-managed GitHub OAuth app. You do not need to create a GitHub OAuth app or provide credentials.

## Available scopes

| Resource | Operation | Scope |
| --- | --- | --- |
| Repositories | Read public repositories | `public_repo` |
| Repositories | Read/write all repositories (including private) | `repo` |
| Issues & Pull Requests | Create/update issues & PRs | `repo` |
| GitHub Actions | Manage workflow files | `workflow` |
| User Profile | Read user profile | `read:user` |
| User Profile | Read user email | `user:email` |
| Notifications | Read & manage notifications | `notifications` |

## Connecting

1. Go to **OAuth Connections → Add Connection → GitHub**.
2. Select the resources and operations your workflow needs.
3. Sign in with your GitHub account and grant the requested permissions.
4. Give the connection a handle (e.g., `my-github`).

Use lowercase letters, numbers, and hyphens only for the handle.

GitHub OAuth tokens do not expire and are not automatically refreshed.

## Example: create an issue

```js
export class Workflow {
  async start(data, _headers, api) {
    const { token, error } = await api.getOAuthToken('my-github');
    if (error || !token) throw new Error(error || 'Missing GitHub token');

    const response = await fetch('https://api.github.com/repos/OWNER/REPO/issues', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        Authorization: `Bearer ${token}`,
        Accept: 'application/vnd.github+json',
        'X-GitHub-Api-Version': '2026-03-10',
      },
      body: JSON.stringify({
        title: `Order ${data.name} requires attention`,
        body: `Order total: ${data.total_price} ${data.currency}\nCustomer: ${data.email}`,
        labels: ['orders', 'needs-review'],
      }),
    });

    if (!response.ok) {
      throw new Error(`GitHub API ${response.status}: ${await response.text()}`);
    }

    const issue = await response.json();
    console.log(`Created issue #${issue.number}`);
  }
}
```

`labels`, `assignees`, and `milestone` are optional when creating an issue. If you use them, send normal JSON arrays or values in the same request body.

## Example: trigger a GitHub Actions workflow

```js
const { token, error } = await api.getOAuthToken('my-github');
if (error || !token) throw new Error(error || 'Missing GitHub token');

const response = await fetch('https://api.github.com/repos/OWNER/REPO/actions/workflows/deploy.yml/dispatches', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json; charset=utf-8',
    Authorization: `Bearer ${token}`,
    Accept: 'application/vnd.github+json',
    'X-GitHub-Api-Version': '2026-03-10',
  },
  body: JSON.stringify({
    ref: 'main',
    inputs: {
      shop: 'nice-sale-demo',
      environment: 'production',
    },
  }),
});

if (!response.ok) {
  throw new Error(`GitHub API ${response.status}: ${await response.text()}`);
}
```

For workflow dispatch, `ref` is required. `inputs` is optional and the keys must match the workflow's declared `workflow_dispatch` inputs.