{"meta":{"title":"REST API 및 Ruby를 사용하여 스크립팅","intro":"Octokit.rb SDK를 사용하여 REST API와 상호 작용하는 스크립트를 작성하는 방법을 알아봅니다.","product":"REST API","breadcrumbs":[{"href":"/ko/rest","title":"REST API"},{"href":"/ko/rest/guides","title":"가이드"},{"href":"/ko/rest/guides/scripting-with-the-rest-api-and-ruby","title":"Ruby를 사용하여 스크립트"}],"documentType":"article"},"body":"# REST API 및 Ruby를 사용하여 스크립팅\n\nOctokit.rb SDK를 사용하여 REST API와 상호 작용하는 스크립트를 작성하는 방법을 알아봅니다.\n\n## Octokit.rb 정보\n\nRuby를 사용하여 REST API GitHub 와 GitHub 상호 작용하는 스크립트를 작성하려면 Octokit.rb SDK를 사용하는 것이 좋습니다. Octokit.rb는 GitHub에 의해 유지 관리됩니다. SDK는 모범 사례를 구현하고 Ruby를 통해 REST API와 보다 쉽게 상호 작용할 수 있도록 합니다. Octokit.rb는 모든 최신 브라우저, Node.rb 및 Deno에서 작동합니다. Octokit.rb에 대한 자세한 정보는 [Octokit.rb 추가 정보](https://github.com/octokit/octokit.rb/#readme)를 참조하세요.\n\n## 필수 조건\n\n이 가이드에서는 Ruby 및 REST API에 대해 잘 알고 있다고 GitHub 가정합니다. REST API에 대한 자세한 내용은 [REST API 시작](/ko/rest/using-the-rest-api/getting-started-with-the-rest-api)을(를) 참조하세요.\n\nOctokit.rb 라이브러리를 사용하려면 `octokit` 젬을 설치하고 가져와야 합니다. 이 가이드에서는 Ruby의 규칙에 따라 import 문을 사용합니다. 다른 설치 방법에 대한 자세한 내용은 [Octokit.rb README의 설치 섹션](https://github.com/octokit/octokit.rb/#installation)을 참조하세요.\n\n## 인스턴스화 및 인증\n\n> \\[!WARNING]\n> 인증 자격 증명을 암호처럼 처리합니다.\n>\n> 자격 증명을 안전하게 유지하려면 자격 증명을 비밀로 저장하고 스크립트를 실행할 GitHub Actions수 있습니다. 자세한 내용은 [GitHub Actions에서 비밀 사용](/ko/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)을(를) 참조하세요.\n\n> 자격 증명을 Codespaces secret으로 저장하고 Codespaces에서 스크립트를 실행할 수도 있습니다. 자세한 내용은 [GitHub Codespaces에 대한 계정별 비밀 관리](/ko/codespaces/managing-your-codespaces/managing-your-account-specific-secrets-for-github-codespaces)을(를) 참조하세요.\n\n> 이러한 옵션을 사용할 수없는다른 CLI 서비스를 사용하여 자격 증명을 안전하게 저장하는 것이 좋습니다.\n\n### personal access token를 사용하여 인증하기\n\n개인 용도로 REST API를 GitHub 사용하려는 경우, personal access token를 만들 수 있습니다. 자세한 내용은 personal access token 만들기에 대해 [개인용 액세스 토큰 관리](/ko/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)을 참조하세요.\n\n먼저 `octokit` 라이브러리가 필요합니다. 그런 다음 `Octokit`를 personal access token 옵션으로 전달하여 `access_token`의 인스턴스를 생성합니다. 다음 예제에서 `YOUR-TOKEN`를 사용자의 personal access token(으)로 바꾸세요.\n\n```ruby copy\nrequire 'octokit'\n\noctokit = Octokit::Client.new(access_token: 'YOUR-TOKEN')\n```\n\n### GitHub App를 사용하여 인증하기\n\n조직이나 다른 사용자를 대신하여 API를 사용하려면 GitHub에서 제안하는 GitHub App을 사용하는 것이 좋습니다. 엔드포인트를 사용할 수 있는 GitHub Apps경우 해당 엔드포인트에 대한 REST 참조 설명서에 필요한 토큰 유형 GitHub App 이 표시됩니다. 자세한 내용은 [GitHub 앱 등록](/ko/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) 및 [GitHub 앱을 사용한 인증 정보](/ko/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app)을(를) 참조하세요.\n\n`octokit`를 요구하는 대신, `Octokit::Client`의 정보를 옵션으로 전달하여 GitHub App의 인스턴스를 생성합니다. 다음 예제에서는 `APP_ID`을(를) 앱의 ID로, `PRIVATE_KEY`을(를) 앱의 프라이빗 키로, 그리고 `INSTALLATION_ID`을(를) 대신 인증하려는 앱 설치의 ID로 바꿉니다. 앱 ID를 찾고 앱의 설정 페이지 설정에서 프라이빗 키를 생성할 수 있습니다. 자세한 내용은 [GitHub 앱에 대한 프라이빗 키 관리](/ko/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)을(를) 참조하세요.\n`GET /users/{username}/installation`, `GET /repos/{owner}/{repo}/installation`, `GET /orgs/{org}/installation` 엔드포인트를 사용하여 설치 ID를 가져올 수 있습니다. 자세한 내용은 [GitHub Apps에 대한 REST API 엔드포인트](/ko/rest/apps/apps)을 참조하세요.\n\n```ruby copy\nrequire 'octokit'\n\napp = Octokit::Client.new(\n  client_id: APP_ID,\n  client_secret: PRIVATE_KEY,\n  installation_id: INSTALLATION_ID\n)\n\noctokit = Octokit::Client.new(bearer_token: app.create_app_installation.access_token)\n```\n\n### GitHub Actions에서 인증\n\n워크플로 GitHub Actions 에서 API를 GitHub 사용하려면 토큰을 만드는 대신 기본 제공 `GITHUB_TOKEN` 으로 인증하는 것이 좋습니다.\n`GITHUB_TOKEN` 키를 사용하여 `permissions`에 대한 사용 권한을 부여할 수 있습니다.\n`GITHUB_TOKEN`에 대한 자세한 내용은 [GITHUB\\_TOKEN](/ko/actions/concepts/security/github_token)을(를) 참조하세요.\n\n워크플로가 워크플로 리포지토리 외부의 리소스에 액세스해야 하는 경우 `GITHUB_TOKEN`을 사용할 수 없습니다. 이 경우 자격 증명을 비밀로 저장하고 아래 예제의 `GITHUB_TOKEN`을 비밀의 이름으로 바꿉니다. 비밀에 대한 자세한 내용은 [GitHub Actions에서 비밀 사용](/ko/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)을(를) 참조하세요.\n\n키워드를 `run` 사용하여 워크플로에서 GitHub Actions Ruby 스크립트를 실행하는 경우 값을 `GITHUB_TOKEN` 환경 변수로 저장할 수 있습니다. 스크립트는 환경 변수에 `ENV['VARIABLE_NAME']`로 액세스할 수 있습니다.\n\n예를 들어 이 워크플로 단계에서 `GITHUB_TOKEN`이라는 환경 변수에 `TOKEN`을 저장합니다.\n\n```yaml\n- name: Run script\n  env:\n    TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  run: |\n    ruby .github/actions-scripts/use-the-api.rb\n```\n\n워크플로가 실행하는 스크립트는 `ENV['TOKEN']`을 인증하는 데 사용합니다.\n\n```ruby copy\nrequire 'octokit'\n\noctokit = Octokit::Client.new(access_token: ENV['TOKEN'])\n```\n\n### 인증 없는 인스턴스화\n\n트래픽률 제한이 낮고 일부 엔드포인트를 사용할 수 없어도 인증 없이 REST API를 사용할 수 있습니다. 인증하지 않고 인스턴스 `Octokit`을(를) 만들려면 `access_token` 옵션을 전달하지 마세요.\n\n```ruby copy\nrequire 'octokit'\n\noctokit = Octokit::Client.new\n```\n\n## 요청하기\n\nOctokit은 요청을 만드는 여러 가지 방법을 지원합니다. 엔드포인트에 대한 HTTP 동사와 경로를 알고 있는 경우 `request` 메서드를 사용하여 요청을 수행할 수 있습니다. IDE에서 자동 완성 및 입력을 이용하려는 경우 `rest` 메서드를 사용할 수 있습니다. 페이지를 매긴 엔드포인트의 경우 `paginate` 메서드를 사용하여 여러 데이터 페이지를 요청할 수 있습니다.\n\n### `request` 메서드를 사용하여 요청을 수행합니다.\n\n`request` 메서드를 사용하여 요청을 만들려면 HTTP 메서드와 경로를 첫 번째 인수로 전달합니다. 해시의 본문, 쿼리, 경로 매개 변수를 두 번째 인수로 패스합니다. 예를 들어 `GET`에 `/repos/{owner}/{repo}/issues`을 요청하고 `owner`, `repo`, `per_page` 매개변수를 전달하려면 다음을 수행하세요.\n\n```ruby copy\noctokit.request(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 2)\n```\n\n`request` 메서드는 자동으로 `Accept: application/vnd.github+json` 머리글을 전달합니다. 추가 헤더 또는 다른 `Accept` 헤더를 전달하려면 두 번째 인수로 전달되는 해시에 `headers` 옵션을 추가합니다.\n`headers` 옵션의 값은 헤더 이름을 키로, 헤더 값을 값으로 가지고 있는 해시입니다. 예를 들어 `content-type`의 값과 함께 `text/plain` 헤더를 보내려면 다음을 수행합니다.\n\n```ruby copy\noctokit.request(\"POST /markdown/raw\", text: \"Hello **world**\", headers: { \"content-type\" => \"text/plain\" })\n```\n\n### `rest` 엔드포인트 메서드를 사용하여 요청을 수행하기\n\n모든 REST API 엔드포인트에는 Octokit에 연결된 `rest` 엔드포인트 메서드가 있습니다. 이러한 메서드는 일반적으로 편의를 위해 IDE에서 자동 완성됩니다. 모든 매개 변수를 해시로 메서드에 전달할 수 있습니다.\n\n```ruby copy\noctokit.rest.issues.list_for_repo(owner: \"github\", repo: \"docs\", per_page: 2)\n```\n\n### 페이지 나열된 요청 만들기\n\n엔드포인트가 페이지 단위로 나뉘어 있고 둘 이상의 결과 페이지를 가져오려는 경우 `paginate` 메서드를 사용할 수 있습니다.\n`paginate`는 마지막 페이지에 도달할 때까지 결과의 다음 페이지를 가져온 다음 모든 결과를 배열로 반환합니다. 일부 엔드포인트는 페이지네이션된 결과를 배열로 반환하는 대신 객체 내 배열 형태로 반환합니다. 원시 결과가 개체인 경우에도 `paginate`는 항상 항목 배열을 반환합니다.\n\n예를 들어 다음 예제에서는 `github/docs` 리포지토리에서 모든 이슈를 가져옵니다. 한 번에 100개의 이슈를 요청하지만 함수는 데이터의 마지막 페이지에 도달할 때까지 반환되지 않습니다.\n\n```ruby copy\nissue_data = octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 100)\n```\n\n이 `paginate` 메서드는 결과의 각 페이지를 처리하는 데 사용할 수 있는 선택적 블록을 허용합니다. 이렇게 하면 응답에서 원하는 데이터만 수집할 수 있습니다. 예를 들어 다음 예제에서는 제목에 \"test\"가 포함된 이슈가 반환될 때까지 결과를 계속 가져옵니다. 반환된 데이터 페이지의 경우 이슈 제목과 작성자만 저장됩니다.\n\n```ruby copy\nissue_data = octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 100) do |response, done|\n  response.data.map do |issue|\n    if issue.title.include?(\"test\")\n      done.call\n    end\n    { title: issue.title, author: issue.user.login }\n  end\nend\n```\n\n모든 결과를 한 번에 가져오는 대신 한 번에 단일 페이지를 반복하는 데 `octokit.paginate.iterator()`를 사용할 수 있습니다. 예를 들어 다음 예제에서는 결과의 한 페이지를 한 번에 가져오고 다음 페이지를 가져오기 전에 페이지에서 각 개체를 처리합니다. 제목에 \"test\"가 포함된 이슈에 도달하면 스크립트는 반복을 중지하고 처리된 각 개체의 이슈 제목 및 이슈 작성자를 반환합니다. 반복기는 페이지를 매긴 데이터를 가져오기 위한 가장 메모리 효율적인 메서드입니다.\n\n```ruby copy\niterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 100)\nissue_data = []\nbreak_loop = false\niterator.each do |data|\n  break if break_loop\n  data.each do |issue|\n    if issue.title.include?(\"test\")\n      break_loop = true\n      break\n    else\n      issue_data << { title: issue.title, author: issue.user.login }\n    end\n  end\nend\n```\n\n`paginate` 엔드포인트 메서드에서도 `rest` 메서드를 사용할 수 있습니다.\n`rest` 엔드포인트 메서드를 첫 번째 인수로 전달하고 매개 변수를 두 번째 인수로 전달합니다.\n\n```ruby copy\niterator = octokit.paginate.iterator(octokit.rest.issues.list_for_repo, owner: \"github\", repo: \"docs\", per_page: 100)\n```\n\n페이지 매김에 대한 자세한 내용은 [REST API에서 페이지 매김 사용](/ko/rest/using-the-rest-api/using-pagination-in-the-rest-api)을(를) 참조하세요.\n\n## 오류 포착하기\n\n### 모든 오류 포착하기\n\n경우에 따라 REST API에서 GitHub 오류를 반환합니다. 예를 들어 액세스 토큰이 만료되었거나 필수 매개 변수를 생략하면 오류가 발생합니다. Octokit.rb는 `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`및 `422 Unprocessable Entity` 이외의 오류가 발생하면 요청을 자동으로 다시 시도합니다. 재시도 후에도 API 오류가 발생하면 Octokit.rb는 응답(`response.status`) 및 응답 헤더(`response.headers`)의 HTTP 상태 코드를 포함하는 오류를 throw합니다. 코드에서 이러한 오류를 처리해야 합니다. 예를 들어 try/catch 블록을 사용하여 오류를 포착할 수 있습니다.\n\n```ruby copy\nbegin\nfiles_changed = []\n\niterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", owner: \"github\", repo: \"docs\", pull_number: 22809, per_page: 100)\niterator.each do | data |\n    files_changed.concat(data.map {\n      | file_data | file_data.filename\n    })\n  end\nrescue Octokit::Error => error\nif error.response\nputs \"Error! Status: #{error.response.status}. Message: #{error.response.data.message}\"\nend\nputs error\nend\n```\n\n### 의도한 오류 코드 처리하기\n\n경우에 따라 GitHub 4xx 상태 코드를 사용하여 오류가 아닌 응답을 나타냅니다. 사용 중인 엔드포인트에서 이 작업을 수행하는 경우, 특정 오류에 대한 처리를 추가할 수 있습니다. 예를 들어 `GET /user/starred/{owner}/{repo}` 엔드포인트는 리포지토리에 별표를 하지 않은 경우 `404`를 반환합니다. 다음 예제에서는 `404` 응답을 사용하여 리포지토리가 별표 표시되지 않았음을 나타내고 다른 모든 오류 코드는 오류로 처리됩니다.\n\n```ruby copy\nbegin\noctokit.request(\"GET /user/starred/{owner}/{repo}\", owner: \"github\", repo: \"docs\")\nputs \"The repository is starred by me\"\nrescue Octokit::NotFound => error\nputs \"The repository is not starred by me\"\nrescue Octokit::Error => error\nputs \"An error occurred while checking if the repository is starred: #{error&.response&.data&.message}\"\nend\n```\n\n### 트래픽률 제한 오류 처리\n\n트래픽률 제한 오류가 표시되는 경우 대기 후 요청을 다시 시도할 수 있습니다. 요청 한도에 도달하면 GitHub는 `403 Forbidden` 오류로 응답하며, `x-ratelimit-remaining` 응답 헤더 값은 `\"0\"`가 됩니다. 응답 헤더에는 현재 트래픽률 제한 창이 재설정되는 시간을 UTC Epoch 초 단위로 알려주는 `x-ratelimit-reset` 헤더가 포함됩니다.\n`x-ratelimit-reset`에 지정된 시간 후에 요청을 다시 시도할 수 있습니다.\n\n```ruby copy\ndef request_retry(route, parameters)\n begin\n response = octokit.request(route, parameters)\n return response\n rescue Octokit::RateLimitExceeded => error\n reset_time_epoch_seconds = error.response.headers['x-ratelimit-reset'].to_i\n current_time_epoch_seconds = Time.now.to_i\n seconds_to_wait = reset_time_epoch_seconds - current_time_epoch_seconds\n puts \"You have exceeded your rate limit. Retrying in #{seconds_to_wait} seconds.\"\n sleep(seconds_to_wait)\n retry\n rescue Octokit::Error => error\n puts error\n end\n end\n\n response = request_retry(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 2)\n```\n\n## 응답 사용\n\n`request` 메서드는 요청이 성공한 경우 응답 개체를 반환합니다. 응답 개체는 `data`(엔드포인트에서 반환된 응답 본문), `status`(HTTP 응답 코드), `url`(요청의 URL) 및 `headers`(응답 머리글을 포함하는 해시)입니다. 달리 지정하지 않는 한 응답 본문은 JSON 형식입니다. 일부 엔드포인트는 응답 본문을 반환하지 않습니다. 이 경우 `data` 속성은 생략됩니다.\n\n```ruby copy\nresponse = octokit.request(\"GET /repos/{owner}/{repo}/issues/{issue_number}\", owner: \"github\", repo: \"docs\", issue_number: 11901)\n puts \"The status of the response is: #{response.status}\"\n puts \"The request URL was: #{response.url}\"\n puts \"The x-ratelimit-remaining response header is: #{response.headers['x-ratelimit-remaining']}\"\n puts \"The issue title is: #{response.data['title']}\"\n```\n\n마찬가지로, `paginate` 메서드는 응답 개체를 반환합니다.\n`request`이(가) 성공한 경우, `response` 개체에는 데이터, 상태, URL 및 헤더가 포함됩니다.\n\n```ruby copy\nresponse = octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", owner: \"github\", repo: \"docs\", per_page: 100)\nputs \"#{response.data.length} issues were returned\"\nputs \"The title of the first issue is: #{response.data[0]['title']}\"\n```\n\n## 예제 스크립트\n\n다음은 Octokit.rb를 사용하는 전체 예제 스크립트입니다. 스크립트는 `Octokit`를 가져오고 새 인스턴스 `Octokit`를 만듭니다.\nGitHub App 대신 personal access token로 인증하려면 `App` 대신 `Octokit`를 가져와 인스턴스화하면 됩니다. 자세한 내용은 이 가이드의 [GitHub App를 사용한 인증](#authenticating-with-a-github-app)을 참조하세요.\n\n`get_changed_files` 함수는 끌어오기 요청에 대해 변경된 모든 파일을 가져옵니다.\n`comment_if_data_files_changed` 함수는 `get_changed_files` 함수를 호출합니다. 끌어오기 요청이 변경된 파일이 파일 경로에 `/data/`가 포함된 경우 함수는 끌어오기 요청에 대해 설명을 달게 됩니다.\n\n```ruby copy\nrequire \"octokit\"\n\n octokit = Octokit::Client.new(access_token: \"YOUR-TOKEN\")\n\n def get_changed_files(octokit, owner, repo, pull_number)\n files_changed = []\n\n begin\n iterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", owner: owner, repo: repo, pull_number: pull_number, per_page: 100)\n iterator.each do | data |\n     files_changed.concat(data.map {\n       | file_data | file_data.filename\n     })\n   end\n rescue Octokit::Error => error\n if error.response\n puts \"Error! Status: #{error.response.status}. Message: #{error.response.data.message}\"\n end\n puts error\n end\n\n files_changed\n end\n\n def comment_if_data_files_changed(octokit, owner, repo, pull_number)\n changed_files = get_changed_files(octokit, owner, repo, pull_number)\n\n if changed_files.any ? {\n   | file_name | /\\/data\\//i.match ? (file_name)\n }\n begin\n comment = octokit.create_pull_request_review_comment(owner, repo, pull_number, \"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.\")\n comment.html_url\n rescue Octokit::Error => error\n if error.response\n puts \"Error! Status: #{error.response.status}. Message: #{error.response.data.message}\"\n end\n puts error\n end\n end\n end\n\n# Example usage\nowner = \"github\"\nrepo = \"docs\"\npull_number = 22809\ncomment_url = comment_if_data_files_changed(octokit, owner, repo, pull_number)\n\nputs \"A comment was added to the pull request: #{comment_url}\"\n```\n\n> \\[!NOTE]\n> 이는 단지 기본적인 예제일 뿐입니다. 실제로 오류 처리 및 조건부 검사를 사용하여 다양한 시나리오를 처리할 수 있습니다.\n\n## 다음 단계\n\nGitHub REST API 및 Octokit.rb 사용 방법에 대해 자세히 알아보려면 다음 리소스를 살펴보세요.\n\n* Octokit.rb에 대한 자세한 내용은 [Octokit.rb 설명서](https://github.com/octokit/octokit.rb/#readme)를 참조하세요.\n* 요청 및 응답 구조를 포함하여 사용 가능한 REST API 엔드포인트에 대한 GitHub자세한 내용은 [GITHUB REST API 설명서](/ko/rest)을 참조하세요."}