0
# GitHub API Integration
1
2
ProbotOctokit is an enhanced Octokit client pre-configured with Probot-specific plugins for authentication, throttling, retries, and configuration management, providing seamless GitHub API access.
3
4
## Capabilities
5
6
### ProbotOctokit Class
7
8
Enhanced Octokit client with Probot-specific plugins and authentication strategies.
9
10
```typescript { .api }
11
/**
12
* Enhanced Octokit client with Probot plugins
13
* Extends the standard Octokit client with additional functionality
14
*/
15
class ProbotOctokit extends Octokit {
16
// Inherits all standard Octokit functionality
17
// Plus additional Probot-specific plugins and configuration
18
}
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { ProbotOctokit } from "probot";
25
26
// Create authenticated instance (usually done automatically by Probot)
27
const octokit = new ProbotOctokit({
28
auth: {
29
appId: process.env.APP_ID,
30
privateKey: process.env.PRIVATE_KEY,
31
installationId: 12345,
32
},
33
});
34
35
// Access GitHub API
36
const { data: user } = await octokit.users.getByUsername({
37
username: "octocat",
38
});
39
40
const { data: repos } = await octokit.repos.listForOrg({
41
org: "github",
42
type: "public",
43
});
44
```
45
46
## Pre-configured Plugins
47
48
### Authentication Plugin
49
50
Automatic GitHub App authentication with JWT and installation token management.
51
52
```typescript { .api }
53
// Uses octokit-auth-probot for GitHub App authentication
54
// Automatically handles:
55
// - JWT generation for app-level requests
56
// - Installation token acquisition and refresh
57
// - Token caching and expiration management
58
```
59
60
**Usage Examples:**
61
62
```typescript
63
// App-level authentication (in event handlers, authentication is automatic)
64
app.on("installation.created", async (context) => {
65
// context.octokit is automatically authenticated for the installation
66
const { data: repos } = await context.octokit.apps.listReposAccessibleToInstallation();
67
context.log.info(`Installation has access to ${repos.repositories.length} repositories`);
68
});
69
70
// Manual authentication (when creating Octokit instances outside event handlers)
71
const appOctokit = await app.auth(); // App-level auth
72
const installationOctokit = await app.auth(12345); // Installation-level auth
73
```
74
75
### Throttling Plugin
76
77
Automatic request throttling and rate limit handling with cluster support.
78
79
```typescript { .api }
80
// Default throttling configuration:
81
// - Primary rate limit: Automatic backoff when approaching limits
82
// - Secondary rate limit: Exponential backoff for abuse detection
83
// - Redis cluster support: Coordinate rate limiting across multiple instances
84
```
85
86
**Usage Examples:**
87
88
```typescript
89
// Throttling happens automatically, but can be customized
90
const octokit = new ProbotOctokit({
91
throttle: {
92
enabled: true,
93
// Custom rate limit handler
94
onRateLimit: (retryAfter, options, octokit) => {
95
octokit.log.warn(`Rate limit hit, retrying after ${retryAfter} seconds`);
96
return true; // Retry the request
97
},
98
// Custom secondary rate limit handler
99
onSecondaryRateLimit: (retryAfter, options, octokit) => {
100
octokit.log.warn(`Secondary rate limit hit, retrying after ${retryAfter} seconds`);
101
return true; // Retry the request
102
},
103
},
104
});
105
106
// Redis cluster support for distributed rate limiting
107
const clusteredOctokit = new ProbotOctokit({
108
throttle: {
109
enabled: true,
110
// Redis connection details from environment
111
connection: new Redis(process.env.REDIS_URL),
112
},
113
});
114
```
115
116
### Retry Plugin
117
118
Automatic request retries for network errors and temporary failures.
119
120
```typescript { .api }
121
// Default retry configuration:
122
// - Network errors: Exponential backoff with jitter
123
// - Server errors (5xx): Automatic retry with limits
124
// - Rate limit errors: Handled by throttling plugin
125
```
126
127
**Usage Examples:**
128
129
```typescript
130
// Retries happen automatically, but can be customized
131
const octokit = new ProbotOctokit({
132
retry: {
133
enabled: true,
134
retries: 3, // Maximum retry attempts
135
retryAfter: 2, // Base retry delay in seconds
136
// Custom retry condition
137
doNotRetry: ["400", "401", "403", "404", "422"],
138
},
139
});
140
141
// Disable retries for specific requests
142
const { data } = await octokit.request("GET /user", {
143
request: {
144
retries: 0,
145
},
146
});
147
```
148
149
### Pagination Plugin
150
151
Simplified pagination for GitHub API endpoints that return multiple pages.
152
153
```typescript { .api }
154
/**
155
* Paginate through all results of a GitHub API endpoint
156
* @param endpoint - GitHub API endpoint method
157
* @param parameters - Request parameters
158
* @returns AsyncIterator of all results
159
*/
160
paginate: {
161
(endpoint: string, parameters?: any): AsyncIterable<any>;
162
iterator: (endpoint: string, parameters?: any) => AsyncIterableIterator<any>;
163
};
164
```
165
166
**Usage Examples:**
167
168
```typescript
169
// Get all repositories for an organization
170
const allRepos = await octokit.paginate("GET /orgs/{org}/repos", {
171
org: "github",
172
type: "public",
173
});
174
175
console.log(`Found ${allRepos.length} repositories`);
176
177
// Iterate through results with custom processing
178
for await (const { data: repos } of octokit.paginate.iterator("GET /orgs/{org}/repos", {
179
org: "github",
180
})) {
181
for (const repo of repos) {
182
console.log(`Processing ${repo.name}`);
183
// Process each repository
184
}
185
}
186
187
// Paginate with additional parameters
188
const issues = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
189
owner: "octocat",
190
repo: "Hello-World",
191
state: "open",
192
labels: "bug",
193
per_page: 100,
194
});
195
```
196
197
### REST Endpoint Methods Plugin
198
199
Typed GitHub API methods with full parameter and response type safety.
200
201
```typescript { .api }
202
// Provides typed methods for all GitHub REST API endpoints
203
// - octokit.repos.* for repository operations
204
// - octokit.issues.* for issue operations
205
// - octokit.pulls.* for pull request operations
206
// - octokit.apps.* for GitHub App operations
207
// - And many more...
208
```
209
210
**Usage Examples:**
211
212
```typescript
213
// Typed repository operations
214
const { data: repo } = await octokit.repos.get({
215
owner: "octocat",
216
repo: "Hello-World",
217
});
218
219
const { data: contents } = await octokit.repos.getContent({
220
owner: "octocat",
221
repo: "Hello-World",
222
path: "README.md",
223
});
224
225
// Typed issue operations
226
const { data: issue } = await octokit.issues.create({
227
owner: "octocat",
228
repo: "Hello-World",
229
title: "Bug report",
230
body: "Something is broken",
231
labels: ["bug", "triage"],
232
assignees: ["maintainer1"],
233
});
234
235
const { data: comment } = await octokit.issues.createComment({
236
owner: "octocat",
237
repo: "Hello-World",
238
issue_number: 1,
239
body: "Thanks for reporting this!",
240
});
241
242
// Typed pull request operations
243
const { data: pr } = await octokit.pulls.create({
244
owner: "octocat",
245
repo: "Hello-World",
246
title: "Fix bug",
247
head: "fix-branch",
248
base: "main",
249
body: "This fixes the bug reported in #1",
250
});
251
```
252
253
### Enterprise Compatibility Plugin
254
255
Support for GitHub Enterprise Server with custom base URLs and configurations.
256
257
```typescript { .api }
258
// Automatic compatibility with GitHub Enterprise Server
259
// - Custom API base URLs
260
// - Enterprise-specific endpoints
261
// - Version compatibility handling
262
```
263
264
**Usage Examples:**
265
266
```typescript
267
// GitHub Enterprise Server configuration
268
const enterpriseOctokit = new ProbotOctokit({
269
baseUrl: "https://github.mycompany.com/api/v3",
270
auth: {
271
appId: process.env.APP_ID,
272
privateKey: process.env.PRIVATE_KEY,
273
installationId: 12345,
274
},
275
});
276
277
// Works with all standard GitHub API methods
278
const { data: user } = await enterpriseOctokit.users.getByUsername({
279
username: "employee",
280
});
281
```
282
283
### Configuration Plugin
284
285
Read YAML configuration files from repository `.github` directories.
286
287
```typescript { .api }
288
/**
289
* Read configuration file from .github directory
290
* @param options - Configuration options
291
* @returns Parsed configuration object
292
*/
293
config: {
294
get<T>(options: {
295
owner: string;
296
repo: string;
297
path: string;
298
defaults?: T;
299
}): Promise<T | null>;
300
};
301
```
302
303
**Usage Examples:**
304
305
```typescript
306
// Read .github/myapp.yml configuration
307
const config = await octokit.config.get({
308
owner: "octocat",
309
repo: "Hello-World",
310
path: "myapp.yml",
311
defaults: {
312
enabled: true,
313
threshold: 10,
314
},
315
});
316
317
if (config && config.enabled) {
318
// Use configuration
319
console.log(`Threshold: ${config.threshold}`);
320
}
321
```
322
323
### Request Logging Plugin
324
325
Automatic logging of GitHub API requests with correlation IDs.
326
327
```typescript { .api }
328
// Automatic request/response logging
329
// - Request details (method, URL, parameters)
330
// - Response details (status, timing)
331
// - GitHub delivery ID correlation
332
// - Rate limit information
333
```
334
335
**Usage Examples:**
336
337
```typescript
338
// Logging happens automatically with context
339
app.on("issues.opened", async (context) => {
340
// This request will be logged with the event delivery ID
341
await context.octokit.issues.createComment(
342
context.issue({ body: "Welcome!" })
343
);
344
345
// Logs will include:
346
// - Request: POST /repos/octocat/Hello-World/issues/1/comments
347
// - Response: 201 Created (timing information)
348
// - GitHub delivery ID: abc123-def456-ghi789
349
});
350
```
351
352
## Default Configuration
353
354
```typescript { .api }
355
// Default ProbotOctokit configuration
356
const defaultOptions = {
357
authStrategy: createProbotAuth,
358
throttle: {
359
enabled: true,
360
onSecondaryRateLimit: (retryAfter, options, octokit) => {
361
octokit.log.warn(`Secondary rate limit triggered, retrying after ${retryAfter} seconds`);
362
return true;
363
},
364
onRateLimit: (retryAfter, options, octokit) => {
365
octokit.log.warn(`Rate limit triggered, retrying after ${retryAfter} seconds`);
366
return true;
367
},
368
},
369
userAgent: `probot/${VERSION}`,
370
retry: {
371
enabled: true,
372
},
373
paginate: {
374
enabled: true,
375
},
376
restEndpointMethods: {
377
enabled: true,
378
},
379
enterpriseCompatibility: {
380
enabled: true,
381
},
382
};
383
```
384
385
## Authentication Types
386
387
```typescript { .api }
388
interface ProbotAuthOptions {
389
/** GitHub App ID */
390
appId: number | string;
391
/** GitHub App private key in PEM format */
392
privateKey: string;
393
/** Installation ID for installation-level auth */
394
installationId?: number;
395
/** GitHub API base URL (for Enterprise) */
396
baseUrl?: string;
397
/** Request options */
398
request?: RequestRequestOptions;
399
}
400
401
interface AuthResult {
402
/** Authentication type */
403
type: "app" | "installation";
404
/** Access token */
405
token: string;
406
/** Token expiration date */
407
expiresAt?: string;
408
/** Permissions granted to token */
409
permissions?: Record<string, string>;
410
/** Repository IDs accessible (for installation tokens) */
411
repositoryIds?: number[];
412
}
413
```
414
415
## Common API Patterns
416
417
### Repository Management
418
419
```typescript
420
// Get repository information
421
const { data: repo } = await octokit.repos.get({
422
owner: "octocat",
423
repo: "Hello-World",
424
});
425
426
// List repository contents
427
const { data: contents } = await octokit.repos.getContent({
428
owner: "octocat",
429
repo: "Hello-World",
430
path: "src",
431
});
432
433
// Create/update files
434
await octokit.repos.createOrUpdateFileContents({
435
owner: "octocat",
436
repo: "Hello-World",
437
path: "README.md",
438
message: "Update README",
439
content: Buffer.from("# Hello World").toString("base64"),
440
sha: existingFileSha, // Required for updates
441
});
442
```
443
444
### Issue and Pull Request Management
445
446
```typescript
447
// Create issue
448
const { data: issue } = await octokit.issues.create({
449
owner: "octocat",
450
repo: "Hello-World",
451
title: "Feature request",
452
body: "Please add this feature",
453
labels: ["enhancement"],
454
});
455
456
// Add labels
457
await octokit.issues.addLabels({
458
owner: "octocat",
459
repo: "Hello-World",
460
issue_number: issue.number,
461
labels: ["priority:high"],
462
});
463
464
// Create pull request
465
const { data: pr } = await octokit.pulls.create({
466
owner: "octocat",
467
repo: "Hello-World",
468
title: "Add new feature",
469
head: "feature-branch",
470
base: "main",
471
body: "Implements the requested feature from #123",
472
});
473
```
474
475
### GitHub App Management
476
477
```typescript
478
// List installations
479
const { data: installations } = await appOctokit.apps.listInstallations();
480
481
// Get installation repositories
482
const { data: repos } = await installationOctokit.apps.listReposAccessibleToInstallation();
483
484
// Create installation access token
485
const { data: token } = await appOctokit.apps.createInstallationAccessToken({
486
installation_id: 12345,
487
permissions: {
488
issues: "write",
489
contents: "read",
490
},
491
});
492
```