Em outubro, o Github
lançou ações que permitem executar o IC sem sair do caixa no qual esse código está armazenado. É realmente muito conveniente. Assim que alguém envia uma solicitação pull , ou simplesmente carrega novas alterações no servidor, ou algo especial (uma lista de eventos nos quais as ações podem ser fixadas pode ser encontrada na documentação oficial ), a montagem é iniciada. Também são suportadas tarefas recorrentes agendadas ( baseadas em cron ).
Você pode criar pipelines de ação chamados fluxos de trabalho . E tudo isso é lindo e parece um futuro brilhante - com exceção da documentação.
Levei mais de uma hora para descobrir como criar um contêiner com serviços de terceiros para testar o aplicativo. Aqui está o que eu consegui descobrir. Observe que a documentação oficial é francamente desajeitada, incompleta e muitas vezes simplesmente incorreta.
A ação padrão do IC usa arquivos de configuração com sintaxe muito semelhante à usada pelo CircleCI . Essa é apenas a boa e velha YAML , que permite configurar o SO, o ambiente, os comandos de execução, etc. As ações recebem nomes exclusivos , o que permite que você se refira a outras ações e dependa delas.
Além disso, a configuração permite especificar serviços . Os serviços devem estar em execução em algum lugar da nuvem, e o GH mapeará as portas do contêiner para as portas que esses serviços expõem, de acordo com a configuração. Esta parte é pouco abordada na documentação oficial e mesmo o que está descrito contém erros.
Aqui está um exemplo de configuração funcional para um projeto Elixir que requer serviços RabbitMQ e Redis para teste.
name: Tests for My Project on: [push, pull_request] jobs: build: runs-on: ubuntu-latest container: image: elixir:1.9.1-slim services: rabbitmq: image: rabbitmq ports: - 5672:5672 env: RABBITMQ_USER: guest RABBITMQ_PASSWORD: guest RABBITMQ_VHOST: "/" redis: image: redis ports: - 6379:6379 steps: - uses: actions/checkout@v1 - name: Install Dependencies run: | MIX_ENV=ci mix local.rebar --force MIX_ENV=ci mix local.hex --force MIX_ENV=ci mix deps.get - name: Run All Tests run: | MIX_ENV=ci mix test env: RABBITMQ_HOST: rabbitmq RABBITMQ_PORT: ${{ job.services.rabbitmq.ports[5672] }} REDIS_HOST: redis REDIS_PORT: ${{ job.services.redis.ports[6379] }}
Como você pode ver, os testes serão executados no Ubuntu usando o Elixir v1.9.1. Os serviços são descritos nos principais serviços e aqui começa uma história de detetive pura. A porta física à qual a porta de serviço será vinculada é selecionada aleatoriamente pelo mecanismo de contêiner no tempo de execução e armazenada em uma variável de shell interna chamada job.services.rabbitmq.ports[5672]
. rabbitmq é o nome do serviço, conforme indicado neste arquivo na seção de serviços e 5672 é a porta de origem. A variável interna possui a sintaxe $ {{foo}} e é passada para a variável de ambiente RABBITMQ_PORT
(o último bloco de configuração, na chave env
). Em RABBITMQ_HOST
- você precisa colocar o nome do serviço, exatamente como na chave de serviços . Agora o aplicativo pode ler variáveis de ambiente como de costume e as portas serão roladas corretamente.
É assim que vamos ler essas variáveis de ambiente a partir do ambiente (esta é uma configuração para o Elixir , para outros idiomas, haverá algo muito semelhante).
import Config config :my_app, rabbitmq: [ host: System.get_env("RABBITMQ_HOST"), password: "guest", port: String.to_integer(System.get_env("RABBITMQ_PORT", "5672")), username: "guest", virtual_host: "/", x_message_ttl: "4000" ]
No arquivo do projeto, crio um ambiente especial :ci
, para distinguir entre a configuração dos testes realizados no ambiente local e os mesmos testes realizados em algum lugar na nuvem.
Além disso, no pipeline de IC , eu corro o dialyzer
em minhas fontes. Como ela é executada no contêiner, a tarefa leva algum tempo, porque você precisa reconstruir as plts
do zero todas as vezes. É por isso que faço isso uma vez por dia usando a opção de configuração de schedule
.
name: Dialyzer for My Project on: schedule: - cron: "0 1 * * *" jobs: build: runs-on: ubuntu-latest container: image: elixir:1.9.1-slim steps: - uses: actions/checkout@v1 - name: Install Dependencies run: | MIX_ENV=ci mix local.rebar --force MIX_ENV=ci mix local.hex --force MIX_ENV=ci mix deps.get - name: Run All Tests run: | MIX_ENV=ci mix code_quality
aqui code_quality
é um alias de tarefa declarado em mix.exs
defp aliases do [ code_quality: ["format", "credo --strict", "dialyzer"] ] end
Aqui, em geral, é tudo o que precisamos para um teste feliz de um projeto com dependências externas no novo fluxo de trabalho do Github
.
Integração contínua com sucesso!