Skip to main content

Esta versão do GitHub Enterprise será descontinuada em 2022-10-12. Nenhum lançamento de patch será feito, mesmo para questões críticas de segurança. Para obter melhor desempenho, segurança aprimorada e novos recursos, atualize para a última versão do GitHub Enterprise. Para obter ajuda com a atualização, entre em contato com o suporte do GitHub Enterprise.

Criar um servidor de CI

Crie o seu próprio sistema CI usando a API de status.

A API de Status é responsável por unir commits a um serviço de teste, de modo que cada push que você efetuar possa ser testado e representado em uma solicitação de pull do GitHub Enterprise Server.

Este guia usará a API para demonstrar uma configuração que você pode usar. No nosso cenário, iremos:

  • Executar o nosso conjunto de CI quando um pull request for aberto (iremos definir o status de CI como pendente).
  • Quando o CI terminar, definiremos o status do pull request.

O nosso sistema de CI e servidor de hospedagem serão imaginários. Eles podem ser o Travis, o Jenkins ou qualquer outro completamente diferente. O aspecto fundamental deste guia será configurar o servidor que gerencia a comunicação.

Caso ainda não tenha feito isso, baixe o ngrok e saiba como usá-lo. Achamos que ele é uma ferramenta muito útil para expor conexões locais.

Observação: baixe o código-fonte completo deste projeto no repositório platform-samples.

Escrever o seu servidor

Vamos escrever um aplicativo rápido do Sinatra para provar que nossas conexões locais estão funcionando. Vamos começar com isso:

require 'sinatra'
require 'json'

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

(Se você não estiver familiarizado com o funcionamento do Sinatra, recomendamos ler o guia do Sinatra).

Inicie este servidor. Por padrão, o Sinatra começará na porta 4567, ou seja, o ideal será configurar o ngrok para começar a escutá-la também.

Para que esse servidor funcione, precisamos configurar um repositório com um webhook. O webhook deve ser configurado para ser acionado sempre que um pull request for criado ou mesclada. Vá em frente e crie um repositório com o qual você esteja confortável para fazer testes. Podemos sugerir o repositório do Spoon/do Knife de @octocat? Depois disso, você criará um webhook no seu repositório, alimentando-o com a URL fornecida pelo ngrok e escolhendo application/x-www-form-urlencoded como o tipo de conteúdo:

Uma nova URL do ngrok

Clique em Atualizar webhook. Você verá a resposta de corpo Well, it worked!. Ótimo! Clique em Deixe-me selecionar eventos individuais e selecione o seguinte:

  • Status
  • Pull Request

Esses são os eventos que o GitHub Enterprise Server enviará ao nosso servidor sempre que ocorrer a ação relevante. Vamos atualizar nosso servidor para apenas lidar com o cenário de solicitação de pull agora:

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

  case request.env['HTTP_X_GITHUB_EVENT']
  when "pull_request"
    if @payload["action"] == "opened"
      process_pull_request(@payload["pull_request"])
    end
  end
end

helpers do
  def process_pull_request(pull_request)
    puts "It's #{pull_request['title']}"
  end
end

O que está havendo? Cada evento que o GitHub Enterprise Server envia anexa um cabeçalho HTTP X-GitHub-Event. Por enquanto, nos importaremos apenas com os eventos do PR. Daí em diante, usaremos o conteúdo das informações e retornaremos o campo de título. Em um cenário ideal, nosso servidor ficará preocupado com a atualização de cada solicitação de pull, não apenas quando ela é aberta. Isso asseguraria que todos os novos pushes passassem pelos testes de CI. Mas, para essa demonstração, nós nos preocuparemos quando ela for aberta.

Para testar esta prova de conceito, faça algumas alterações em um branch no repositório de teste e abra uma solicitação de pull. Seu servidor deve responder de acordo!

Trabalhar com status

Com o servidor implementado, estamos prontos para iniciar nosso primeiro requisito, que é configurar (e atualizar) os status de CI. Observe que, a qualquer momento, você pode clicar em Entregar novamente para enviar o mesmo conteúdo. Não há necessidade de fazer uma nova solicitação de pull toda vez que você faz uma alteração.

Como estamos interagindo com os dados da API do GitHub Enterprise Server, usaremos o Octokit.rb para gerenciar as interações. Configuraremos esse cliente com um token de acesso pessoal:

# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
# Instead, set and test environment variables, like below
ACCESS_TOKEN = ENV['MY_PERSONAL_TOKEN']

before do
  @client ||= Octokit::Client.new(:access_token => ACCESS_TOKEN)
end

Em seguida, apenas precisaremos atualizar a solicitação de pull no GitHub Enterprise Server para deixar claro que estamos fazendo o processamento na CI:

def process_pull_request(pull_request)
  puts "Processing pull request..."
  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')
end

Aqui, estamos fazendo três coisas muito básicas:

  • estamos procurando o nome completo do repositório
  • estamos procurando o último SHA do pull request
  • estamos definindo o status como "pendente"

É isso! Daí em diante, você pode executar qualquer processo de que precise para executar o conjunto de testes. Talvez você transmita seu código para o Jenkins ou ligue para outro serviço Web por meio da API, como o Travis. Em seguida, lembre-se de atualizar o status novamente. Em nosso exemplo, vamos apenas defini-lo como "success":

def process_pull_request(pull_request)
  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')
  sleep 2 # do busy work...
  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'success')
  puts "Pull request processed!"
end

Conclusão

No GitHub, usamos uma versão do Janky para gerenciar a CI por vários anos. O fluxo básico é essencialmente o mesmo que o servidor que construímos acima. No GitHub, nós:

  • Notificamos tudo ao Jenkins quando um pull request é criado ou atualizado (via Janky)
  • Esperamos por uma resposta no estado da CI
  • Se o código for verde, fazemos o merge do pull request

Toda esta comunicação é canalizada de volta para nossas salas de bate-papo. Você não precisa criar sua configuração de CI para usar este exemplo. Você sempre pode contar com as integrações do GitHub.