Skip to main content

배포 제공

배포 REST API를 사용하여 서버 및 타사 앱과 상호 작용하는 사용자 지정 도구를 빌드할 수 있습니다.

REST API를 사용하여 소유한 서버의 GitHub Enterprise Cloud에 호스트된 프로젝트를 배포할 수 있습니다. 배포 및 상태를 관리하는 엔드포인트에 대한 자세한 정보는 "배포에 대한 REST API 엔드포인트"을(를) 참조하세요. REST API를 사용하면 코드가 기본 분기에 배치되는 순간, 배포를 조정할 수도 있습니다. 자세한 내용은 "CI 서버 빌드"을(를) 참조하세요.

이 가이드에서는 REST API로 사용할 수 있는 설정을 보여 줍니다. 이 시나리오에서는 다음을 수행합니다.

  • 끌어오기 요청을 병합합니다.
  • CI가 완료되면 그에 따라 끌어오기 요청의 상태를 설정합니다.
  • 끌어오기 요청이 병합되면 서버로의 배포를 실행합니다.

CI 시스템 및 호스트 서버는 상상한 그대로가 됩니다. Heroku, Amazon 또는 완전히 다른 무언가가 될 수 있습니다. 이 가이드의 핵심은 통신을 관리하는 서버를 설정하고 구성하는 것입니다.

아직 다운로드하지 않은 경우 ngrok을 다운로드하고 사용 방법을 알아보세요. 로컬 애플리케이션을 인터넷에 노출하는 데 매우 유용한 도구라고 합니다.

참고: 또는 웹후크 전달을 사용하여 웹후크를 수신하도록 로컬 환경을 설정할 수 있습니다. 자세한 내용은 "GitHub CLI를 사용하여 테스트용 웹후크 전달하기"을(를) 참조하세요.

참고: 플랫폼 샘플 리포지토리에서 이 프로젝트에 대한 전체 소스 코드를 다운로드할 수 있습니다.

서버 작성

로컬 연결이 작동하는지 증명하기 위해 빠른 Sinatra 앱을 작성합니다. 먼저 다음을 살펴보겠습니다.

require 'sinatra'
require 'json'

post '/event_handler' do
  payload = JSON.parse(params[:payload])
  "Well, it worked!"
end

(Sinatra의 작동 방식에 익숙하지 않은 경우 가이드를 읽는 것이 좋습니다.)

이 서버를 시작합니다. 기본적으로 Sinatra는 포트 4567에서 시작되므로 ngrok도 수신 대기를 시작하도록 구성할 수 있습니다.

이 서버가 작동하려면 웹후크를 사용하여 리포지토리를 설정해야 합니다. 끌어오기 요청을 만들거나 병합할 때마다 webhook가 실행되도록 구성해야 합니다.

계속 진행하여 편안하게 사용할 수 있는 리포지토리를 만듭니다. @octocat의 스푼/나이프 리포지토리를 제안해보겠습니다.

그런 다음, 리포지토리에 새 webhook를 만들고, ngrok에서 제공한 URL을 피드하고, 콘텐츠 형식으로 application/x-www-form-urlencoded를 선택합니다.

웹후크 업데이트를 클릭합니다. Well, it worked!라는 응답이 표시되어야 합니다. 좋습니다! 개별 이벤트 선택을 클릭하고 다음을 선택합니다.

  • 배포
  • 배포 상태
  • 끌어오기 요청

관련 작업이 발생할 때마다 이벤트 GitHub Enterprise Cloud에서 서버로 보내는 이벤트입니다. 이제 끌어오기 요청이 병합될 때만 처리하도록 __ 서버를 구성합니다.

post '/event_handler' do
  @payload = JSON.parse(params[:payload])

  case request.env['HTTP_X_GITHUB_EVENT']
  when "pull_request"
    if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
      puts "A pull request was merged! A deployment should start now..."
    end
  end
end

무슨 일입니까? GitHub Enterprise Cloud이 전송하는 모든 이벤트에는 X-GitHub-Event HTTP 헤더가 첨부되었습니다. 지금은 PR 이벤트만 신경을 써야 합니다. 끌어오기 요청이 병합되면(해당 상태는 closed이고 mergedtrue임) 배포를 시작합니다.

이 개념 증명을 테스트하려면 테스트 리포지토리의 분기를 몇 가지 변경하고 끌어오기 요청을 연 후 병합합니다. 서버가 그에 따라 응답해야 합니다!

배포 작업

서버가 배치되고 코드가 검토되고 끌어오기 요청이 병합되면 프로젝트를 배포하려고 합니다.

먼저 병합 시 끌어오기 요청을 처리하도록 이벤트 수신기를 수정하고 배포에 주의를 기울입니다.

when "pull_request"
  if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
    start_deployment(@payload["pull_request"])
  end
when "deployment"
  process_deployment(@payload)
when "deployment_status"
  update_deployment_status
end

끌어오기 요청의 정보에 따라 먼저 start_deployment 메서드를 작성합니다.

def start_deployment(pull_request)
  user = pull_request['user']['login']
  payload = JSON.generate(:environment => 'production', :deploy_user => user)
  @client.create_deployment(pull_request['head']['repo']['full_name'], pull_request['head']['sha'], {:payload => payload, :description => "Deploying my sweet branch"})
end

배포에는 일부 메타데이터가 payloaddescription 형식으로 연결되어 있을 수 있습니다. 이러한 값은 선택 사항이지만 정보를 로깅하고 나타내는 데 사용하는 것이 좋습니다.

새 배포가 만들어지면 완전히 별도의 이벤트가 트리거됩니다. 이때문에 deployment에 대한 이벤트 처리기에 새 switch 사례가 있는 것입니다. 배포가 트리거될 때 이 정보를 사용하여 알림을 받을 수 있습니다.

배포에 다소 시간이 걸릴 수 있으므로 배포가 만들어진 시기 및 배포 상태와 같은 다양한 이벤트를 수신 대기하려고 합니다.

일부 작업을 수행하는 배포를 시뮬레이트하고 출력에 미치는 영향을 살펴보겠습니다. 먼저 process_deployment 메서드를 완료해 보겠습니다.

def process_deployment
  payload = JSON.parse(@payload['payload'])
  # you can send this information to your chat room, monitor, pager, etc.
  puts "Processing '#{@payload['description']}' for #{payload['deploy_user']} to #{payload['environment']}"
  sleep 2 # simulate work
  @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'pending')
  sleep 2 # simulate work
  @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'success')
end

마지막으로, 상태 정보를 콘솔 출력으로 저장하는 과정을 시뮬레이트합니다.

def update_deployment_status
  puts "Deployment status for #{@payload['id']} is #{@payload['state']}"
end

어떤 결과가 나타나는지 분석해 보겠습니다. deployment 이벤트를 트리거하는 start_deployment에 의해 새 배포가 만들어집니다. 여기에서 process_deployment를 호출하여 진행 중인 작업을 시뮬레이트합니다. 또한 이 처리 중에 create_deployment_status를 호출하여 pending으로 상태를 전환할 때 어떤 결과가 나타나는지를 수신자가 알도록 할 수 있습니다.

배포가 완료되면 상태를 success로 설정합니다.

결론

GitHub에서는 몇 년 동안 배포를 관리하기 위해 Heaven 버전을 사용했습니다. 일반적인 흐름은 기본적으로 위에서 빌드한 서버와 동일합니다.

  • CI 검사 상태(성공 또는 실패)에 대한 응답 대기
  • 필요한 검사가 성공하면 끌어오기 요청을 병합합니다.
  • Heaven은 병합된 코드를 가져와 스테이징 및 프로덕션 서버에 배포합니다.
  • 그 동안, Heaven은 채팅방에 앉아 있는 Hubot을 통해 빌드에 대한 사항을 모두에게 알립니다.

정말 간단하죠. 이 예제를 사용하기 위해 고유한 배포 설정을 빌드할 필요가 없습니다. 항상 GitHub 통합에 의존할 수 있습니다.