Octokit.js 정보
JavaScript를 사용하여 GitHub의 REST API와 상호 작용하는 스크립트를 작성하려면 GitHub에서 Octokit.js SDK를 사용하는 것이 좋습니다. Octokit.js GitHub에 의해 유지 관리됩니다. SDK는 모범 사례를 구현하고 JavaScript를 통해 REST API와 더 쉽게 상호 작용할 수 있도록 합니다. Octokit.js 모든 최신 브라우저, Node.js 및 Deno에서 작동합니다. Octokit.js 대한 자세한 내용은 Octokit.js 추가 정보를 참조하세요.
사전 요구 사항
이 가이드에서는 JavaScript 및 GitHub REST API에 익숙하다고 가정합니다. REST API에 대한 자세한 내용은 "REST API 시작.
Octokit.js 라이브러리를 사용하려면 를 설치하고 가져와 octokit
야 합니다. 이 가이드에서는 ES6에 따라 import 문을 사용합니다. 다양한 설치 및 가져오기 방법에 대한 자세한 내용은 Octokit.js 추가 정보 사용 섹션을 참조하세요.
인스턴스화 및 인증
경고: 인증 자격 증명을 암호처럼 처리합니다.
자격 증명을 안전하게 유지하려면 자격 증명을 비밀로 저장하고 GitHub Actions을 통해 스크립트를 실행할 수 있습니다. 자세한 내용은 "암호화된 비밀"을 참조하세요.
이(가) 불가능합니다, 1Password CLI 와 같은 다른 서비스를 사용하여 자격 증명을 안전하게 저장하는 것이 좋습니다.
personal access token을(를) 사용하여 인증
개인 용도로 GitHub REST API를 사용하려는 경우 personal access token을(를) 만들 수 있습니다. personal access token을(를) 만드는 방법에 대한 자세한 내용은 "개인용 액세스 토큰 만들기.
먼저 에서 octokit
가져옵니다Octokit
. 그런 다음 인스턴스를 만들 때 personal access token를 Octokit
전달합니다. 다음 예제에서 를 personal access token에 대한 참조로 바꿉 YOUR-TOKEN
있습니다.{ % ifversion ghes or ghae %} 을 GitHub.com의 이름으로 바꿉 [hostname]
니다.{ % endif %}
import { Octokit } from "octokit";
const octokit = new Octokit({
auth: 'YOUR-TOKEN',
});
GitHub App을(를) 사용하여 인증
조직 또는 다른 사용자를 대신하여 API를 사용하려는 경우 GitHub에서 GitHub App을(를) 사용하는 것이 좋습니다. GitHub Apps에 엔드포인트를 사용할 수 있는 경우 해당 엔드포인트에 대한 REST 참조 설명서에 "GitHub Apps에서 작동"이 표시됩니다. 자세한 내용은 "GitHub 앱 만들기", "GitHub 앱 인증 정보" 및 "사용자를 대신하여 GitHub 앱으로 인증.
에서 octokit
가져오는 Octokit
대신 를 가져옵니다App
. 다음 예제에서 를 앱 ID에 대한 참조로 바꿉 APP_ID
니다. 를 앱의 프라이빗 키에 대한 참조로 대체 PRIVATE_KEY
합니다. 를 대신 인증하려는 앱 설치의 ID로 바꿉 INSTALLATION_ID
니다. 앱의 ID를 찾고 앱의 설정 페이지에서 프라이빗 키를 생성할 수 있습니다. 자세한 내용은 "GitHub 앱에 대한 프라이빗 키 관리"을 참조하세요. , GET /repos/{owner}/{repo}/installation
또는 GET /orgs/{org}/installation
엔드포인트를 사용하여 설치 ID를 GET /users/{username}/installation
가져올 수 있습니다. 자세한 내용은 REST 참조 설명서의 "GitHub 앱"을 참조하세요.
import { App } from "octokit";
const app = new App({
appId: APP_ID,
privateKey: PRIVATE_KEY,
});
const octokit = await app.getInstallationOctokit(INSTALLATION_ID);
GitHub Actions에서 인증
GitHub Actions 워크플로에서 API를 사용하려면 GitHub에서 토큰을 만드는 대신 기본 제공 GITHUB_TOKEN
으로 인증하는 것이 좋습니다. permissions
키를 사용하여 GITHUB_TOKEN
에 대한 사용 권한을 부여할 수 있습니다. 에 대한 GITHUB_TOKEN
자세한 내용은 "자동 토큰 인증.
워크플로가 워크플로 리포지토리 외부의 리소스에 액세스해야 하는 경우 을 사용할 GITHUB_TOKEN
수 없습니다. 이 경우 자격 증명을 비밀로 저장하고 아래 예제에서 을 비밀 이름으로 바꿉 GITHUB_TOKEN
니다. 비밀에 대한 자세한 내용은 "암호화된 비밀.
키워드를 run
사용하여 GitHub Actions 워크플로에서 JavaScript 스크립트를 실행하는 경우 값을 GITHUB_TOKEN
환경 변수로 저장할 수 있습니다. 스크립트는 환경 변수에 로 process.env.VARIABLE_NAME
액세스할 수 있습니다.
예를 들어 이 워크플로 단계는 라는 TOKEN
환경 변수에 저장됩니다GITHUB_TOKEN
.
- name: Run script
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
node .github/actions-scripts/use-the-api.mjs
워크플로가 실행하는 스크립트는 다음을 인증하는 데 사용합니다 process.env.TOKEN
.
import { Octokit } from "octokit";
const octokit = new Octokit({
auth: process.env.TOKEN,
});
인증 없이 인스턴스화
속도가 더 낮고 일부 엔드포인트를 사용할 수 없지만 인증 없이 REST API를 사용할 수 있습니다. 인증하지 않고 인스턴스 Octokit
를 만들려면 인수를 auth
전달하지 마세요.{ % ifversion ghes or ghae %} 기본 URL을 로 https://api.github.com
설정합니다. 을 GitHub.com의 이름으로 바꿉 [hostname]
있습니다.{ % endif %}
import { Octokit } from "octokit";
const octokit = new Octokit({ });
요청 만들기
Octokit는 요청을 만드는 여러 방법을 지원합니다. 엔드포인트에 request
대한 HTTP 동사 및 경로를 알고 있는 경우 메서드를 사용하여 요청을 만들 수 있습니다. IDE 및 입력에서 rest
자동 완성을 활용하려는 경우 메서드를 사용할 수 있습니다. 페이지를 매긴 엔드포인트의 경우 메서드를 paginate
사용하여 여러 데이터 페이지를 요청할 수 있습니다.
메서드를 request
사용하여 요청
메서드를 request
사용하여 요청을 만들려면 HTTP 메서드와 경로를 첫 번째 인수로 전달합니다. 개체의 모든 본문, 쿼리 또는 경로 매개 변수를 두 번째 인수로 전달합니다. 예를 들어 를 요청하고 , 및 per_page
매개 변수를 전달하려면 GET
다음을 owner
수행repo
합니다./repos/{owner}/{repo}/issues
await octokit.request("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 2
});
메서드는 request
헤더를 자동으로 전달합니다 Accept: application/vnd.github+json
. 추가 헤더 또는 다른 Accept
헤더를 전달하려면 두 번째 인수로 전달되는 개체에 속성을 추가 headers
합니다. headers
속성의 값은 헤더 이름을 키로, 헤더 값을 값으로 가지고 있는 개체입니다. 예를 들어 값text/plain
이 인 헤더와 x-github-api-version
값이 인 헤더를 보내 content-type
려면 다음을 2022-11-28
수행합니다.
await octokit.request("POST /markdown/raw", {
text: "Hello **world**",
headers: {
"content-type": "text/plain",
"x-github-api-version": "2022-11-28",
},
});
엔드포인트 메서드를 사용하여 rest
요청 만들기
모든 REST API 엔드포인트에는 Octokit에 연결된 rest
엔드포인트 메서드가 있습니다. 이러한 메서드는 일반적으로 편의를 위해 IDE에서 자동 완성됩니다. 모든 매개 변수를 개체로 메서드에 전달할 수 있습니다.
await octokit.rest.issues.listForRepo({
owner: "github",
repo: "docs",
per_page: 2
});
또한 TypeScript와 같은 형식화된 언어를 사용하는 경우 이러한 메서드와 함께 사용할 형식을 가져올 수 있습니다. 자세한 내용은 plugin-rest-endpoint-methods.js 추가 정보에서 TypeScript 섹션을 참조하세요.
페이지를 매긴 요청 만들기
엔드포인트가 페이지를 매긴 후 둘 이상의 결과 페이지를 가져오려는 경우 메서드를 paginate
사용할 수 있습니다. paginate
는 마지막 페이지에 도달할 때까지 결과의 다음 페이지를 가져온 다음 모든 결과를 단일 배열로 반환합니다. 페이지가 매겨진 결과를 배열로 반환하는 것과는 달리 일부 엔드포인트는 페이지를 매긴 결과를 개체의 배열로 반환합니다. paginate
원시 결과가 개체인 경우에도 항상 항목 배열을 반환합니다.
예를 들어 다음 예제에서는 리포지토리에서 github/docs
모든 문제를 가져옵니다. 한 번에 100개의 문제를 요청하지만 함수는 데이터의 마지막 페이지에 도달할 때까지 반환되지 않습니다.
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
메서드는 paginate
응답에서 원하는 데이터만 수집하는 데 사용할 수 있는 선택적 맵 함수를 허용합니다. 이렇게 하면 스크립트의 메모리 사용량이 줄어듭니다. map 함수는 마지막 페이지에 도달하기 전에 페이지 매김을 종료하기 위해 를 호출할 수 있는 두 번째 인수 done
를 사용할 수 있습니다. 이렇게 하면 페이지의 하위 집합을 가져올 수 있습니다. 예를 들어 다음 예제에서는 타이틀에 "test"가 포함된 문제가 반환될 때까지 결과를 계속 가져옵니다. 반환된 데이터 페이지의 경우 문제 제목 및 작성자만 저장됩니다.
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
},
(response, done) => response.data.map((issue) => {
if (issue.title.includes("test")) {
done()
}
return ({title: issue.title, author: issue.user.login})
})
);
모든 결과를 한 번에 가져오는 대신 를 사용하여 octokit.paginate.iterator()
한 번에 단일 페이지를 반복할 수 있습니다. 예를 들어 다음 예제에서는 한 번에 하나의 결과 페이지를 가져오고 다음 페이지를 가져오기 전에 페이지에서 각 개체를 처리합니다. 타이틀에 "test"가 포함된 문제에 도달하면 스크립트는 반복을 중지하고 처리된 각 개체의 문제 제목 및 문제 작성자를 반환합니다. 반복기는 페이지를 매긴 데이터를 가져오기 위한 가장 메모리 효율적인 방법입니다.
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
let issueData = []
let breakLoop = false
for await (const {data} of iterator) {
if (breakLoop) break
for (const issue of data) {
if (issue.title.includes("test")) {
breakLoop = true
break
} else {
issueData = [...issueData, {title: issue.title, author: issue.user.login}];
}
}
}
엔드포인트 메서드에서도 paginate
메서드를 rest
사용할 수 있습니다. 엔드포인트 메서드를 rest
첫 번째 인수로 전달합니다. 매개 변수를 두 번째 인수로 전달합니다.
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
owner: "github",
repo: "docs",
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
페이지 매김에 대한 자세한 내용은 "REST API에서 페이지 매김 사용.
오류 catch
모든 오류 Catch
경우에 따라 GitHub REST API에서 오류를 반환합니다. 예를 들어 액세스 토큰이 만료되었거나 필수 매개 변수를 생략하면 오류가 발생합니다. Octokit.js , , 401 Unauthorized
, 403 Forbidden``404 Not Found
및 422 Unprocessable Entity
이외의 오류가 400 Bad Request
발생하면 요청을 자동으로 다시 시도합니다. 재시도 후에도 API 오류가 발생하면 Octokit.js 응답의 HTTP 상태 코드() 및 응답 헤더(response.status``response.headers
)가 포함된 오류를 throw합니다. 코드에서 이러한 오류를 처리해야 합니다. 예를 들어 try/catch 블록을 사용하여 오류를 catch할 수 있습니다.
let filesChanged = []
try {
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
owner: "github",
repo: "docs",
pull_number: 22809,
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
for await (const {data} of iterator) {
filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
}
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
의도한 오류 코드 처리
GitHub이(가) 4xx 상태 코드를 사용하여 오류가 아닌 응답을 나타내는 경우가 있습니다. 사용 중인 엔드포인트에서 이 작업을 수행하는 경우 특정 오류에 대한 처리를 추가할 수 있습니다. 예를 들어 리포지토리가 GET /user/starred/{owner}/{repo}
별표가 404
지정되지 않은 경우 엔드포인트는 를 반환합니다. 다음 예제에서는 응답을 사용하여 404
리포지토리가 별표가 지정되지 않았음을 나타냅니다. 다른 모든 오류 코드는 오류로 처리됩니다.
try {
await octokit.request("GET /user/starred/{owner}/{repo}", {
owner: "github",
repo: "docs",
headers: {
"x-github-api-version": "2022-11-28",
},
});
console.log(`The repository is starred by me`);
} catch (error) {
if (error.status === 404) {
console.log(`The repository is not starred by me`);
} else {
console.error(`An error occurred while checking if the repository is starred: ${error?.response?.data?.message}`);
}
}
속도 제한 오류 처리
속도 제한 오류가 표시되면 대기한 후 요청을 다시 시도할 수 있습니다. 속도가 제한되면 GitHub이(가 403 Forbidden
) 오류로 응답하고 x-ratelimit-remaining
응답 헤더 값은 입니다 "0"
. 응답 헤더에는 현재 속도 제한 창이 재설정되는 시간을 UTC epoch 초 단위로 알려주는 헤더가 포함 x-ratelimit-reset
됩니다. 에 지정된 x-ratelimit-reset
시간 후에 요청을 다시 시도할 수 있습니다.
async function requestRetry(route, parameters) {
try {
const response = await octokit.request(route, parameters);
return response
} catch (error) {
if (error.response && error.status === 403 && error.response.headers['x-ratelimit-remaining'] === '0') {
const resetTimeEpochSeconds = error.response.headers['x-ratelimit-reset'];
const currentTimeEpochSeconds = Math.floor(Date.now() / 1000);
const secondsToWait = resetTimeEpochSeconds - currentTimeEpochSeconds;
console.log(`You have exceeded your rate limit. Retrying in ${secondsToWait} seconds.`);
setTimeout(requestRetry, secondsToWait * 1000, route, parameters);
} else {
console.error(error);
}
}
}
const response = await requestRetry("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 2
})
응답 사용
메서드는 request
요청이 성공한 경우 개체로 확인되는 프라미스를 반환합니다. 개체 속성은 data
(엔드포인트에서 반환된 응답 본문), status
(HTTP 응답 코드), url
(요청의 URL) 및 headers
(응답 헤더를 포함하는 개체)입니다. 달리 지정하지 않는 한 응답 본문은 JSON 형식입니다. 일부 엔드포인트는 응답 본문을 반환하지 않습니다. 이러한 경우 속성은 data
생략됩니다.
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}", {
owner: "github",
repo: "docs",
issue_number: 11901,
headers: {
"x-github-api-version": "2022-11-28",
},
});
console.log(`The status of the response is: ${response.status}`)
console.log(`The request URL was: ${response.url}`)
console.log(`The x-ratelimit-remaining response header is: ${response.headers["x-ratelimit-remaining"]}`)
console.log(`The issue title is: ${response.data.title}`)
마찬가지로 메서드는 paginate
promise를 반환합니다. 요청이 성공하면 프라미스는 엔드포인트에서 반환된 데이터 배열로 확인됩니다. 메서드와 request
달리 메서드는 paginate
상태 코드, URL 또는 헤더를 반환하지 않습니다.
const data = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "github",
repo: "docs",
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
console.log(`${data.length} issues were returned`)
console.log(`The title of the first issue is: ${data[0].title}`)
예제 스크립트
다음은 Octokit.js 사용하는 전체 예제 스크립트입니다. 스크립트는 를 Octokit
가져오고 의 Octokit
새 인스턴스를 만듭니다. personal access token 대신 GitHub App로 인증하려는 경우 대신 Octokit
를 가져오고 인스턴스화 App
합니다. 자세한 내용은 "GitHub App로 인증"을 참조하세요.
함수는 getChangedFiles
끌어오기 요청에 대해 변경된 모든 파일을 가져옵니다. 함수는 commentIfDataFilesChanged
함수를 호출합니다 getChangedFiles
. 끌어오기 요청이 변경된 파일이 파일 경로에 포함된 /data/
경우 함수는 끌어오기 요청에 대해 주석을 처리합니다.
import { Octokit } from "octokit";
const octokit = new Octokit({
auth: 'YOUR-TOKEN',
});
async function getChangedFiles({owner, repo, pullNumber}) {
let filesChanged = []
try {
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
owner: owner,
repo: repo,
pull_number: pullNumber,
per_page: 100,
headers: {
"x-github-api-version": "2022-11-28",
},
});
for await (const {data} of iterator) {
filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
}
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
return filesChanged
}
async function commentIfDataFilesChanged({owner, repo, pullNumber}) {
const changedFiles = await getChangedFiles({owner, repo, pullNumber});
const filePathRegex = new RegExp(/\/data\//, "i");
if (!changedFiles.some(fileName => filePathRegex.test(fileName))) {
return;
}
try {
const {data: comment} = await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", {
owner: owner,
repo: repo,
issue_number: pullNumber,
body: `It looks like you changed a data file. These files are auto-generated. \n\nYou must revert any changes to data files before your pull request will be reviewed.`,
headers: {
"x-github-api-version": "2022-11-28",
},
});
return comment.html_url;
} catch (error) {
if (error.response) {
console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
}
console.error(error)
}
}
await commentIfDataFilesChanged({owner: "github", repo: "docs", pullNumber: 191});
다음 단계
- Octokit.js 대한 자세한 내용은 Octokit.js 설명서를 참조하세요.
- 몇 가지 실제 예제는 GitHub Docs가 GitHub Docs 리포지토리를 검색하여 Octokit.js 사용하는 방법을 살펴봅니다.