octokit.js

repository·main·Indexed 27 days ago

https://github.com/octokit/octokit.js

An all-in-one GitHub SDK for Browsers, Node.js, and Deno. It provides a unified interface for interacting with GitHub's REST and GraphQL APIs, managing GitHub Apps (including webhooks and OAuth), and handling repository-specific actions.

Tokens
6K
Snippets
13
Records
29
Agent score
93%

What's inside octokit.js

  1. Authenticate as a GitHub App Installation

    main

    To authenticate as a GitHub App Installation, use the createAppAuth strategy from @octokit/auth-app. You must provide the appId, privateKey, and installationId within the auth option.

    import { createAppAuth } from "@octokit/auth-app";
    const octokit = new Octokit({
      authStrategy: createAppAuth,
      auth: {
        appId: 1,
        privateKey: "-----BEGIN PRIVATE KEY-----\n...",
        installationId: 123,
      },
    });
    
    // authenticates as app based on request URLs
    const {
      data: { slug },
    } = await octokit.rest.apps.getAuthenticated();
    
    // creates an installation access token as needed
    await octokit.rest.issues.create({
      owner: "octocat",
      repo: "hello-world",
      title: "Hello world from " + slug,
    });
  2. Implement OAuth for browser-based apps

    main

    Because you cannot expose a clientSecret in a browser, you must use a backend server running the App client to handle the OAuth flow.

    1. The browser app initiates the flow and redirects the user to your server's /api/github/oauth/login.
    2. After authorization, GitHub redirects to your server's /api/github/oauth/callback.
    3. Your browser app must then capture the code and state from the URL parameters.
    4. The browser app sends a POST request to your server's /api/github/oauth/token to exchange the code for an access token.
    5. Use the resulting token to instantiate @octokit/core.
    const code = new URL(location.href).searchParams.get("code");
    if (code) {
      // remove ?code=... from URL
      const path =
        location.pathname +
        location.search.replace(/\b(code|state)=\\w+/g, "").replace(/[?&]+$/, "");
      history.replaceState({}, "", path);
    
      // exchange the code for a token with your backend.
      const response = await fetch("/api/github/oauth/token", {
        method: "POST",
        headers: {
          "content-type": "application/json",
        },
        body: JSON.stringify({ code }),
      });
      const { token } = await response.json();
      // `token` is the OAuth Access Token that can be use
    
      const { Octokit } = await import("https://esm.sh/@octokit/core");
      const octokit = new Octokit({ auth: token });
    
      const {
        data: {
          login,
        },
      } = await octokit.request("GET /user");
      alert("Hi there, " + login);
    }
  3. Install and use octokit.js

    main
    The octokit package is a universal SDK that works in Browsers, Node.js, and Deno. It integrates the API client (REST/GraphQL), App client (GitHub Apps/Webhooks/OAuth), and Action client (single repository access).
  4. Handle Webhooks with the App client

    main

    The App client provides app.webhooks.* APIs to receive, verify, and handle webhook events. You can define event listeners using app.webhooks.on(event_name, callback).

    For Node.js servers, use createNodeMiddleware(app) to expose a webhook endpoint. For serverless environments, use app.webhooks.verifyAndReceive() to manually verify and process the event using headers and the request body.

    import { createServer } from "node:http";
    import { App, createNodeMiddleware } from "octokit";
    
    const app = new App({
      appId,
      privateKey,
      webhooks: { secret },
    });
    
    // Handle a specific event
    app.webhooks.on("issues.opened", ({ octokit, payload }) => {
      return octokit.rest.issues.createComment({
        owner: payload.repository.owner.login,
        repo: payload.repository.name,
        issue_number: payload.issue.number,
        body: "Hello, World!",
      });
    });
    
    // Expose the webhook endpoint via Node.js http server
    createServer(createNodeMiddleware(app)).listen(3000);
    
    // --- Serverless usage ---
    // await app.webhooks.verifyAndReceive({
    //   id: request.headers["x-github-delivery"],
    //   name: request.headers["x-github-event"],
    //   signature: request.headers["x-hub-signature-256"],
    //   payload: request.body,
    // });
  5. Configure TypeScript for octokit.js

    main

    Because octokit uses conditional exports, you must configure your tsconfig.json to support them. Set your module resolution and module settings to node16 (or higher).

    {
      "compilerOptions": {
        "moduleResolution": "node16",
        "module": "node16"
      }
    }
  6. Use the App client for GitHub Apps

    main

    The App client simplifies working with GitHub Apps by managing authentication (JWT and installation access tokens), webhooks, and OAuth. You can use it to iterate through all repositories an app is installed on or to get an octokit instance authenticated as a specific installation.

    To use it, provide your appId and privateKey to the App constructor.

    import { App } from "octokit";
    
    const app = new App({ appId, privateKey });
    
    // Example: Iterate through every repository the app is installed on
    for await (const { octokit, repository } of app.eachRepository.iterator()) {
      await octokit.rest.repos.createDispatchEvent({
        owner: repository.owner.login,
        repo: repository.name,
        event_type: "my_event",
        client_payload: {
          foo: "bar",
        },
      });
      console.log("Event dispatched for %s", repository.full_name);
    }
    
    // Example: Get an octokit instance authenticated as a specific installation
    const octokit = await app.getInstallationOctokit(123);
  7. Handle breaking changes via the beta branch

    main

    Breaking changes must be merged into a beta branch for testing before being released to main.

    Workflow for breaking changes:

    1. Create a beta branch based on main.
    2. Land changes in the beta branch.
    3. Create a draft Pull Request from beta to main with the title vX (where X is the next major version).
    4. Once tested and reviewed, merge the beta branch into main.

    Merge Order for dependent repositories: If a change affects multiple repositories, merge from the leaf nodes up to the higher-level nodes in this order:

    1. octokit/types
    2. endpoint
    3. request
    4. plugins
    5. auth strategies
    6. core
    7. *-methods
    8. oauth-app
    9. webhooks
    10. app
    11. octokit/octokit.js
    12. octokit/rest.js
  8. Initialize the Octokit API Client

    main

    The Octokit client allows you to interact with GitHub's REST and GraphQL APIs. You can initialize it with a personal access token for authentication.

    To get started, create a personal access token at GitHub settings and pass it to the constructor.

    // Create a personal access token at https://github.com/settings/tokens/new?scopes=repo
    const octokit = new Octokit({ auth: `personal-access-token123` });
    
    // Compare: https://docs.github.com/en/rest/reference/users#get-the-authenticated-user
    const {
      data: { login },
    } = await octokit.rest.users.getAuthenticated();
    console.log("Hello, %s", login);
  9. Implement OAuth with the App client

    main

    The App client supports OAuth for GitHub Apps. You can handle the OAuth web flow by providing clientId and clientSecret in the oauth configuration.

    Key tasks include:

    • Listening for token.created events.
    • Exchanging a code for a token using app.oauth.createToken({ code }) (useful for serverless).
    • Using the device flow with app.oauth.createToken({ async onVerification(verification) { ... } }).

    Note: If you are building an OAuth App (not a GitHub App), use the @octokit/oauth-app package instead.

    import { createServer } from "node:http";
    import { App, createNodeMiddleware } from "octokit";
    
    const app = new App({
      oauth: { clientId, clientSecret },
    });
    
    // Listen for successful token creation
    app.oauth.on("token.created", async ({ token, octokit }) => {
      await octokit.rest.activity.setRepoSubscription({
        owner: "octocat",
        repo: "hello-world",
        subscribed: true,
      });
    });
    
    // Serverless: Exchange code for token
    // const { token } = await app.oauth.createToken({ code: request.query.code });
    
    createServer(createNodeMiddleware(app)).listen(3000);
  10. Create and manage maintenance releases

    main

    Maintenance releases are used for older major versions (e.g., 2.x). Note that maintenance releases only support fix: ... and feat: ... commits; breaking changes are not supported in maintenance branches.

    Steps to initialize a maintenance branch:

    1. Identify the latest tag for the version you want to maintain (e.g., v2.10.9).
    2. Create and push the maintenance branch:
    git checkout -b 2.x v2.10.9
    git push -u origin HEAD

    Steps to apply a fix to a maintenance branch:

    1. Create a feature branch based on the maintenance branch:
    git checkout -b 2.x-my-fix 2.x
    1. Commit changes, push, and create a Pull Request with the maintenance branch (e.g., 2.x) as the base.
    2. Upon merging, semantic-release will publish the update to npm using a @release-*.x tag instead of @latest.
  11. Configure Proxy Servers in Node.js

    main

    Octokit does not use standard proxy environment variables by default. To use a proxy in Node.js, provide a custom fetch implementation that uses a proxy agent (like undici.ProxyAgent).

    You can set this globally in the constructor or on a per-request basis.

    import { fetch as undiciFetch, ProxyAgent } from 'undici';
    
    const myFetch = (url, options) => {
      return undiciFetch(url, {
        ...options,
        dispatcher: new ProxyAgent(<your_proxy_url>)
      })
    }
    
    const octokit = new Octokit({
      request: {
         fetch: myFetch
      },
    });
    
    // Or per-request:
    // octokit.rest.repos.get({ owner, repo, request: { fetch: myFetch } });
  12. Configure Octokit constructor options

    main

    When instantiating Octokit, you can provide several configuration options:

    Common Options

    • userAgent (String): Recommended to set your own user agent. It will be prepended to the default Octokit user agent.
    • authStrategy (Function): The strategy used for authentication. Defaults to @octokit/auth-token.
    • auth (String | Object): The authentication credentials (e.g., a personal access token) unless a custom authStrategy is used.
    • baseUrl (String): Use this when connecting to GitHub Enterprise Server (e.g., https://github.acme-inc.com/api/v3).

    Advanced Options

    • request (Object):
      • request.signal: An AbortController instance to cancel requests.
      • request.fetch: A replacement for the built-in fetch method.
      • request.timeout (Node.js only): Sets a request timeout in milliseconds (defaults to 0).
    • timeZone (String): Sets the Time-Zone header (using Olson database names) for generating commit timestamps.
    • throttle (Object): Configures request throttling via @octokit/plugin-throttling. You can provide onRateLimit and onSecondaryRateLimit handlers. Set enabled: false to opt-out.
    • retry (Object): Configures request retries via @octokit/plugin-retry. Set enabled: false to opt-out.