tech/github

GITHUB

GitHub platform skill. Use when:

production GitHub REST API v3, GraphQL API v4, Octokit v21 (TypeScript/JS), GitHub Actions, GitHub Apps
improves: tech

GitHub

GitHub is the primary platform for source control, CI/CD, and developer collaboration in the 2nth.ai stack. This skill covers the GitHub REST API, Octokit SDK, GitHub Actions automation, GitHub Apps, and the Copilot platform — including data policy obligations developers need to understand.

Stub — full skill pending. Core patterns documented below.

API areas

AreaREST base pathUse case
Repositories/repos/{owner}/{repo}CRUD, topics, activity, templates
Issues/repos/{owner}/{repo}/issuesCreate, list, comment, label, close
Pull Requests/repos/{owner}/{repo}/pullsOpen, review, merge, list checks
Actions/repos/{owner}/{repo}/actionsTrigger workflows, list runs, download artifacts
Code Search/search/codeFind files/symbols across repos
Code Scanning/repos/{owner}/{repo}/code-scanningUpload SARIF, list alerts
Copilot/orgs/{org}/copilotSeat assignment, usage metrics
Webhooks/repos/{owner}/{repo}/hooksSubscribe to push, PR, issue events
GitHub Apps/appJWT auth, installation tokens, org access

Authentication

Fine-grained PAT (recommended for personal/script use)

# Set as environment variable — never hardcode
export GITHUB_TOKEN="github_pat_xxxxxxxxxxxx"

# Use in requests
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
     -H "Accept: application/vnd.github+json" \
     https://api.github.com/repos/owner/repo

Fine-grained PATs scope to specific repositories and permissions. Prefer these over classic PATs for all new integrations.

GitHub Actions (built-in token)

# GITHUB_TOKEN is automatically injected — never create a PAT for this
jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write      # only request what you need
      pull-requests: read
    steps:
      - uses: actions/checkout@v4
      - name: Create release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release create v1.0.0 --generate-notes

GitHub App (for org-level / multi-repo automation)

import { createAppAuth } from '@octokit/auth-app';
import { Octokit } from '@octokit/rest';

// App authenticates with a JWT, then gets installation token per org/repo
const octokit = new Octokit({
  authStrategy: createAppAuth,
  auth: {
    appId: process.env.GITHUB_APP_ID,
    privateKey: process.env.GITHUB_APP_PRIVATE_KEY,
    installationId: process.env.GITHUB_INSTALLATION_ID,
  },
});

Octokit (TypeScript)

npm install @octokit/rest
import { Octokit } from '@octokit/rest';

const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN,
  userAgent: 'my-app/1.0.0',
});

// Get repo
const { data: repo } = await octokit.repos.get({ owner: '2nth-ai', repo: 'skills' });

// List open PRs
const { data: prs } = await octokit.pulls.list({
  owner: '2nth-ai',
  repo: 'skills',
  state: 'open',
  per_page: 50,
});

// Create an issue
const { data: issue } = await octokit.issues.create({
  owner: '2nth-ai',
  repo: 'skills',
  title: 'Add Python SDK skill',
  body: 'Stub needed for biz/accounting/python-sdk',
  labels: ['enhancement'],
});

// Merge a PR
await octokit.pulls.merge({
  owner: '2nth-ai',
  repo: 'skills',
  pull_number: 42,
  merge_method: 'squash',
  commit_title: 'feat: add python sdk skill (#42)',
});

Pagination

// Use paginate for large result sets
const allIssues = await octokit.paginate(octokit.issues.listForRepo, {
  owner: '2nth-ai',
  repo: 'skills',
  state: 'all',
  per_page: 100,
});

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:   # manual trigger

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build
      - run: npm run deploy
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}

  # Matrix build example
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ['18', '20', '22']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '${{ matrix.node }}' }
      - run: npm ci && npm test

Trigger a workflow via API

await octokit.actions.createWorkflowDispatch({
  owner: 'my-org',
  repo: 'my-repo',
  workflow_id: 'deploy.yml',
  ref: 'main',
  inputs: { environment: 'production' },
});

Webhooks (Cloudflare Worker)

import { createHmac } from 'crypto'; // not available in Workers — use Web Crypto

async function verifySignature(payload: string, signature: string, secret: string): Promise<boolean> {
  const encoder = new TextEncoder();
  const key = await crypto.subtle.importKey(
    'raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
  );
  const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(payload));
  const expected = 'sha256=' + Array.from(new Uint8Array(sig))
    .map(b => b.toString(16).padStart(2, '0')).join('');
  return expected === signature;
}

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const payload = await req.text();
    const sig = req.headers.get('x-hub-signature-256') ?? '';
    const event = req.headers.get('x-github-event') ?? '';

    if (!await verifySignature(payload, sig, env.GITHUB_WEBHOOK_SECRET)) {
      return new Response('Unauthorized', { status: 401 });
    }

    const body = JSON.parse(payload);

    if (event === 'push' && body.ref === 'refs/heads/main') {
      // trigger deploy, update cache, notify Slack, etc.
    }

    if (event === 'pull_request' && body.action === 'opened') {
      // auto-assign reviewer, post welcome comment, etc.
    }

    return new Response('OK');
  },
};

Rate limits

// Check rate limit before bulk operations
const { data } = await octokit.rateLimit.get();
const { remaining, reset, limit } = data.rate;
console.log(`${remaining}/${limit} requests left — resets ${new Date(reset * 1000)}`);

// Authenticated: 5,000 req/hr (PAT), 15,000 req/hr (GitHub App)
// Search API: 30 req/min authenticated
// Secondary rate limits apply to concurrent requests and content creation

Copilot data policy — what developers need to know

Effective date: 24 April 2026

GitHub updated its Copilot interaction data usage policy for Free, Pro, and Pro+ tiers. Business and Enterprise tiers are unaffected.

What changes

From 24 April 2026, GitHub will use interaction data from individual Copilot users to train and improve its AI models, unless the user opts out.

Data collected includes:

Data typeExamples
Code suggestions accepted or modifiedCompletions you tab-accept or partially edit
Inputs submittedPrompts, inline chat queries, code snippets you send
Surrounding code contextOpen files, imports, function signatures visible to Copilot
Comments and documentationDocstrings, inline comments in scope
Repository structureFile names, directory layout
Navigation patternsFiles visited, features used
Feature feedbackThumbs up/down ratings on suggestions

Data NOT collected:

Data sharing: Shared with GitHub affiliates (including Microsoft). Not shared with third-party providers.

How to opt out

  1. Go to github.com → Settings → Privacy
  2. Under "GitHub Copilot" → toggle off "Allow GitHub to use my data to improve GitHub Copilot"
  3. Previously opted-out preferences are automatically retained — no action needed if you opted out before
# Verify your current setting via API (requires user scope)
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
     -H "Accept: application/vnd.github+json" \
     https://api.github.com/user/copilot_interaction_data_policy

What this means for teams

TierImpactAction required
FreeData used to train models from 24 Apr 2026Opt out in Settings if unwilling
Pro / Pro+Same as FreeOpt out in Settings if unwilling
BusinessNo change — org data never used for trainingNone
EnterpriseNo change — org data never used for trainingNone

For consultants and contractors: If you use a personal Free/Pro Copilot account and write code for clients on personal hardware, client code snippets may be included in training data unless you opt out. Consider upgrading to Business or opting out via Settings.

For open source contributors: Contributions to public repos are already public. The policy extends to interaction patterns (what suggestions you accept), not just the code itself.


Gotchas

See also