Compilar repositórios Bitbucket Cloud

Azure DevOps Services

O Azure Pipelines pode criar e validar automaticamente cada solicitação de pull e fazer commit do seu repositório Bitbucket Cloud. Este artigo descreve como configurar a integração entre o Bitbucket Cloud e o Azure Pipelines.

O Bitbucket e o Azure Pipelines são dois serviços independentes que se integram bem. Os usuários do Bitbucket Cloud não obtêm acesso automaticamente ao Azure Pipelines. Você deve adicioná-los explicitamente ao Azure Pipelines.

Acesso aos repositórios do Bitbucket

Você cria um pipeline selecionando primeiro um repositório Bitbucket Cloud e, em seguida, um arquivo YAML nesse repositório. O repositório no qual o arquivo YAML está presente é chamado de repositório self. Por padrão, esse é o repositório que o pipeline compila.

Posteriormente, você pode configurar o pipeline para marcar um repositório diferente ou vários repositórios. Para saber como fazer isso, confira check-out de vários repositórios.

O Azure Pipelines deve ter acesso aos repositórios para efetuar fetch do código durante os builds. Além disso, o usuário que está configurando o pipeline deve ter acesso de administrador ao Bitbucket, pois essa identidade é usada para registrar um webhook no Bitbucket.

Há dois tipos de autenticação para conceder acesso do Azure Pipelines aos repositórios Bitbucket Cloud durante a criação de um pipeline.

Tipo de autenticação Pipelines executados usando
1. OAuth Sua identidade pessoal do Bitbucket
2. Nome de usuário e senha Sua identidade pessoal do Bitbucket

Autenticação OAuth

O OAuth é o tipo de autenticação mais simples para começar a usar nos repositórios em sua conta pessoal do Bitbucket. As atualizações de status do Bitbucket serão executadas em nome de sua identidade pessoal do Bitbucket. Para que os pipelines continuem funcionando, o acesso ao repositório deve permanecer ativo.

Para usar o OAuth, faça logon no Bitbucket quando solicitado durante a criação do pipeline. Em seguida, clique em Autorizar para autorizar com o OAuth. Uma conexão OAuth será salva em seu projeto do Azure DevOps para uso posterior e usada no pipeline que está sendo criado.

Observação

O número máximo de repositórios Bitbucket que a interface do usuário Azure DevOps Services pode carregar é 2.000.

Autenticação de senha

As compilações e atualizações de status do Bitbucket serão executadas em nome de sua identidade pessoal. Para que os builds continuem funcionando, o acesso ao repositório deve permanecer ativo.

Para criar uma conexão de senha, visite Conexões de serviço nas configurações de projeto do Azure DevOps. Crie uma nova conexão de serviço do Bitbucket e forneça o nome de usuário e a senha para se conectar ao repositório Bitbucket Cloud.

Gatilhos de CI

Os gatilhos de CI (integração contínua) fazem com que um pipeline seja executado sempre que você envia uma atualização por push para os branches especificados ou envia tags especificadas por push.

Os pipelines YAML são configurados por padrão com um gatilho de CI em todas as ramificações, a menos que a configuração de gatilho Desabilitar CI YAML implícito, introduzida no Azure DevOps sprint 227, esteja habilitada. A configuração de gatilho Desabilitar CI YAML implícito pode ser definida no nível da organização ou no nível do projeto. Quando a configuração Desabilitar gatilho de CI YAML implícito está habilitada, os gatilhos de CI para pipelines YAML não são habilitados se o pipeline YAML não tem uma seção trigger. Por padrão, Desabilitar gatilho YAML CI implícito não está habilitado.

Branches

Você pode controlar quais branches obtêm gatilhos de CI com uma sintaxe simples:

trigger:
- main
- releases/*

Você pode especificar o nome completo do branch (por exemplo, main) ou um curinga (por exemplo, releases/*). Confira Curingas para obter informações sobre a sintaxe curinga.

Observação

Você não pode usar variáveis em gatilhos, pois as variáveis são avaliadas em runtime (depois que o gatilho é acionado).

Observação

Se você usar modelos para criar arquivos YAML, só poderá especificar gatilhos no arquivo YAML principal para o pipeline. Você não poderá especificar gatilhos nos arquivos de modelo.

Para gatilhos mais complexos que usam exclude ou batch, você precisa usar a sintaxe completa, conforme mostrado no exemplo a seguir.

# specific branch build
trigger:
  branches:
    include:
    - main
    - releases/*
    exclude:
    - releases/old*

No exemplo acima, o pipeline será disparado se uma alteração for enviada por push para main ou para qualquer branch de versões. No entanto, ele não será disparado se uma alteração for feita em um branch de versões que começa com old.

Se você especificar uma cláusula exclude sem uma cláusula include, isso será equivalente a especificar * na cláusula include.

Além de especificar nomes de ramificação nas listas branches, você também pode configurar gatilhos com base em tags usando o seguinte formato:

trigger:
  branches:
    include:
      - refs/tags/{tagname}
    exclude:
      - refs/tags/{othertagname}

Se você não especificou nenhum gatilho e a configuração de gatilho Desabilitar YAML CI implícito não está habilitada, o padrão é como se você escrevesse:

trigger:
  branches:
    include:
    - '*'  # must quote since "*" is a YAML reserved character; we want a string

Importante

Quando você especifica um gatilho, ele substitui o gatilho implícito padrão, e apenas pushes para branches configurados explicitamente para serem incluídos dispararão um pipeline. As inclusões são processadas primeiro e, em seguida, as exclusões são removidas dessa lista.

Execuções de CI de envio em lote

Se você tiver muitos membros da equipe carregando alterações com frequência, talvez queira reduzir o número de execuções iniciadas. Se você definir batch como true, quando um pipeline estiver em execução, o sistema aguardará até que a execução seja concluída e iniciará outra execução com todas as alterações que ainda não foram criadas.

# specific branch build with batching
trigger:
  batch: true
  branches:
    include:
    - main

Observação

batch não é compatível com gatilhos de recursos do repositório.

Para esclarecer este exemplo, digamos que um push A para main causou a execução do pipeline acima. Enquanto esse pipeline está em execução, os pushes adicionais B e C ocorrem no repositório. Essas atualizações não iniciam novas execuções independentes imediatamente. Mas depois que a primeira execução é concluída, todos os pushes até esse ponto de tempo são agrupados em lote e uma nova execução é iniciada.

Observação

Se o pipeline tiver vários trabalhos e fases, a primeira execução ainda deverá atingir um estado terminal concluindo ou ignorando todos os trabalhos e fases dela antes que a segunda execução possa ser iniciada. Por esse motivo, você precisa ter cuidado ao usar esse recurso em um pipeline com várias fases ou aprovações. Se você quiser colocar em lote seus builds nesses casos, é recomendável dividir o processo de CI/CD em dois pipelines : um para build (com envio em lote) e outro para implantações.

Caminhos

Você pode especificar caminhos de arquivo a serem incluídos ou excluídos.

# specific path build
trigger:
  branches:
    include:
    - main
    - releases/*
  paths:
    include:
    - docs
    exclude:
    - docs/README.md

Se estiver usando o Azure DevOps Server 2019.1 ou inferior, ao especificar caminhos, você precisará especificar explicitamente branches nos quais disparar. Você não pode disparar um pipeline apenas com um filtro de caminho; você também precisa ter um filtro de branch e os arquivos alterados que correspondem ao filtro de caminho precisam ser de um branch que corresponda ao filtro de branch. Se você estiver usando o Azure DevOps Server 2020 ou mais recente, poderá omitir branches para filtrar em todos os branches em conjunto com o filtro de caminho.

Os curingas são compatíveis com filtros de caminho. Por exemplo, você pode incluir todos os caminhos que correspondem a src/app/**/myapp*. Você pode usar caracteres curinga (**, * ou ?) ao especificar filtros de caminho.

  • Os caminhos são sempre especificados em relação à raiz do repositório.
  • Se você não definir filtros de caminho, a pasta raiz do repositório será incluída implicitamente por padrão.
  • Se você excluir um caminho, também não poderá incluí-lo, a menos que o qualifique para uma pasta mais profunda. Por exemplo, se você excluir /tools, poderá incluir /tools/trigger-runs-on-these
  • A ordem dos filtros de caminho não importa.
  • Os caminhos no Git diferenciam maiúsculas de minúsculas. Use a mesma formatação de maiúsculas e minúsculas que as pastas reais.
  • Você não pode usar variáveis em caminhos, pois as variáveis são avaliadas em runtime (depois que o gatilho é acionado).

Observação

Para repositórios Bitbucket Cloud, usar a sintaxe branches é a única maneira de especificar gatilhos de marca. Não há suporte para a sintaxe tags: no Bitbucket.

Recusar a CI

Desabilitar o gatilho de CI

Você pode recusar totalmente os gatilhos de CI especificando trigger: none.

# A pipeline with no CI trigger
trigger: none

Importante

Quando você envia uma alteração por push para um branch, o arquivo YAML nesse branch é avaliado para determinar se uma execução de CI deve ser iniciada.

Ignorando a CI para commits individuais

Você também pode dizer ao Azure Pipelines para ignorar a execução de um pipeline que um push normalmente dispararia. Basta incluir [skip ci] na mensagem ou descrição de qualquer um dos commits que fazem parte de um push e o Azure Pipelines ignorará a execução de CI para esse push. Você também pode usar qualquer uma das variações a seguir.

  • [skip ci] ou [ci skip]
  • skip-checks: true ou skip-checks:true
  • [skip azurepipelines] ou [azurepipelines skip]
  • [skip azpipelines] ou [azpipelines skip]
  • [skip azp] ou [azp skip]
  • ***NO_CI***

Usando o tipo de gatilho em condições

Executar diferentes etapas, trabalhos ou estágios no pipeline, dependendo do tipo de gatilho que iniciou a execução, é um cenário comum. Você pode fazer isso usando a variável do sistema Build.Reason. Por exemplo, adicione a seguinte condição à etapa, ao trabalho ou à fase para excluí-la das validações de solicitação de pull.

condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))

Comportamento dos gatilhos quando novos branches são criados

É comum configurar vários pipelines para o mesmo repositório. Por exemplo, você pode ter um pipeline para criar os documentos para seu aplicativo e outro para compilar o código-fonte. Você pode configurar gatilhos de CI com filtros de branch e filtros de caminho apropriados em cada um desses pipelines. Por exemplo, talvez você queira que um pipeline seja disparado ao enviar por push uma atualização para a pasta docs e outra para disparar quando você envia uma atualização por push para o código do aplicativo. Nesses casos, você precisa entender como os pipelines são disparados quando um novo branch é criado.

Aqui está o comportamento quando você envia por push um novo branch (que corresponde aos filtros de branch) para o repositório:

  • Se o pipeline tiver filtros de caminho, ele será disparado somente se o novo branch tiver alterações nos arquivos que correspondam a esse filtro de caminho.
  • Se o pipeline não tiver filtros de caminho, ele será disparado mesmo que não haja alterações no novo branch.

Curingas

Ao especificar um branch, uma tag ou um caminho, você pode usar um nome exato ou um curinga. Os padrões curinga permitem corresponder * a zero ou mais caracteres e ? a um determinado caractere.

  • Se você iniciar seu padrão com * em um pipeline YAML, precisará encapsular o padrão entre aspas, como "*-releases".
  • Para branches e tags:
    • Um curinga pode aparecer em qualquer lugar no padrão.
  • Para caminhos:
    • No Azure DevOps Server 2022 e superior, incluindo o Azure DevOps Services, um curinga pode aparecer em qualquer lugar dentro de um padrão de caminho e você pode usar * ou ?.
    • No Azure DevOps Server 2020 e inferior, você pode incluir * como o caractere final, mas ele não faz nada além de especificar o nome do diretório. Você pode não incluir * no meio de um filtro de caminho e talvez não use ?.
trigger:
  branches:
    include:
    - main
    - releases/*
    - feature/*
    exclude:
    - releases/old*
    - feature/*-working
  paths:
    include:
    - docs/*.md

Gatilhos de PR

Gatilhos de PR (solicitação de pull) fazem com que um pipeline seja executado sempre que uma solicitação de pull é aberta com um dos branches de destino especificados ou quando as atualizações são feitas para essa solicitação de pull.

Branches

Você pode especificar os branches de destino ao validar suas solicitações de pull. Por exemplo, para validar as solicitações de pull direcionadas a master e releases/*, você pode usar o gatilho pr a seguir.

pr:
- main
- releases/*

Essa configuração inicia uma nova execução na primeira vez que uma nova solicitação de pull é criada e depois de cada atualização feita na solicitação de pull.

Você pode especificar o nome completo do branch (por exemplo, master) ou um curinga (por exemplo, releases/*).

Observação

Você não pode usar variáveis em gatilhos, pois as variáveis são avaliadas em runtime (depois que o gatilho é acionado).

Observação

Se você usar modelos para criar arquivos YAML, só poderá especificar gatilhos no arquivo YAML principal para o pipeline. Você não poderá especificar gatilhos nos arquivos de modelo.

Cada nova execução cria o commit mais recente do branch de origem da solicitação de pull. Isso é diferente de como o Azure Pipelines cria solicitações de pull em outros repositórios (por exemplo, Azure Repos ou GitHub), em que ele cria o commit de mesclagem. Infelizmente, o Bitbucket não expõe as informações sobre a confirmação de mesclagem, que contém o código mesclado entre os branches de origem e de destino da solicitação de pull.

Se nenhum gatilho pr aparecer no arquivo YAML, as validações de solicitação de pull serão habilitadas automaticamente para todos os branches, como se você tivesse escrito o gatilho pr a seguir. Essa configuração dispara um build quando qualquer solicitação de pull é criada e quando os commits entram no branch de origem de qualquer solicitação de pull ativa.

pr:
  branches:
    include:
    - '*'  # must quote since "*" is a YAML reserved character; we want a string

Importante

Quando você especifica um gatilho pr, ele substitui o gatilho implícito padrão pr, e apenas pushes para branches configurados explicitamente para serem incluídos dispararão um pipeline.

Para gatilhos mais complexos que precisam excluir determinados branches, você deve usar a sintaxe completa, conforme mostrado no exemplo a seguir.

# specific branch
pr:
  branches:
    include:
    - main
    - releases/*
    exclude:
    - releases/old*

Caminhos

Você pode especificar caminhos de arquivo a serem incluídos ou excluídos. Por exemplo:

# specific path
pr:
  branches:
    include:
    - main
    - releases/*
  paths:
    include:
    - docs
    exclude:
    - docs/README.md

Dicas:

  • Não há suporte para curingas com filtros de caminho.
  • Os caminhos são sempre especificados em relação à raiz do repositório.
  • Se você não definir filtros de caminho, a pasta raiz do repositório será incluída implicitamente por padrão.
  • Se você excluir um caminho, também não poderá incluí-lo, a menos que o qualifique para uma pasta mais profunda. Por exemplo, se você excluir /tools, poderá incluir /tools/trigger-runs-on-these
  • A ordem dos filtros de caminho não importa.
  • Os caminhos no Git diferenciam maiúsculas de minúsculas. Use a mesma formatação de maiúsculas e minúsculas que as pastas reais.
  • Você não pode usar variáveis em caminhos, pois as variáveis são avaliadas em runtime (depois que o gatilho é acionado).

Várias atualizações de PR

Você pode especificar se outras atualizações para uma PR devem cancelar execuções de validação em andamento para a mesma PR. O padrão é true.

# auto cancel false
pr:
  autoCancel: false
  branches:
    include:
    - main

Recusando a validação de PR

Você pode recusar totalmente a validação da solicitação de pull especificando pr: none.

# no PR triggers
pr: none

Para obter mais informações, confira Gatilho de PR no Esquema YAML.

Observação

Se o gatilho pr não estiver sendo disparado, verifique se você não substituiu os gatilhos de PR YAML na interface do usuário.

Execuções informativas

Uma execução informativa informa que o Azure DevOps falhou ao recuperar o código-fonte de um pipeline YAML. A recuperação do código-fonte ocorre em resposta a eventos externos; por exemplo, um commit enviado por push. Também acontece em resposta a gatilhos internos; por exemplo, para verificar se há alterações de código e iniciar ou não uma execução agendada. A recuperação do código-fonte pode falhar por vários motivos. Um frequente é a limitação de solicitações pelo provedor do repositório Git. A existência de uma execução informativa não significa necessariamente que o Azure DevOps executaria o pipeline.

Uma execução informativa é semelhante à captura de tela a seguir.

Screenshot of an informational pipeline run.

Você pode reconhecer uma execução informativa pelos seguintes atributos:

  • O status é Canceled
  • A duração é < 1s
  • O nome da execução contém um dos seguintes textos:
    • Could not retrieve file content for {file_path} from repository {repo_name} hosted on {host} using commit {commit_sha}.
    • Could not retrieve content for object {commit_sha} from repository {repo_name} hosted on {host}.
    • Could not retrieve the tree object {tree_sha} from the repository {repo_name} hosted on {host}.
    • Could not find {file_path} from repository {repo_name} hosted on {host} using version {commit_sha}. One of the directories in the path contains too many files or subdirectories.
  • O nome da execução geralmente contém o erro do BitBucket/GitHub que causou falha na carga do pipeline YAML
  • Sem estágios/trabalhos/etapas

Saiba mais sobre execuções informativas.

Limitações

O Azure Pipelines carrega um máximo de 2000 ramificações de um repositório nas listas suspensas no Portal de Devops do Azure, por exemplo, na configuração Ramificação padrão para compilações manuais e agendadas ou ao escolher uma ramificação ao executar um pipeline manualmente. Se você não vir a ramificação desejada na lista, digite o nome da ramificação desejada manualmente.

Perguntas frequentes

Os problemas relacionados à integração do Bitbucket se enquadram nas seguintes categorias:

  • Gatilhos com falha: meu pipeline não está sendo disparado quando efetuo push de uma atualização para o repositório.
  • Versão errada: meu pipeline é executado, mas está usando uma versão inesperada da fonte/YAML.

Gatilhos com falha

Acabei de criar um Pipeline YAML novo com gatilhos de CI/PR, mas o pipeline não está sendo disparado.

Siga cada uma destas etapas para solucionar problemas dos gatilhos com falha:

  • Os webhooks são usados para comunicar atualizações do Bitbucket para o Azure Pipelines. No Bitbucket, navegue até as configurações do repositório e, em seguida, para Webhooks. Verifique se os webhooks existem.
  • Seu pipeline está em pausa ou desabilitado? Abra o editor do pipeline e selecione Configurações para verificar. Se o pipeline estiver em pausa ou desabilitado, os gatilhos não funcionarão.

  • Você atualizou o arquivo YAML no branch correto? Se você enviar por push uma atualização para um branch, o arquivo YAML nesse mesmo branch controlará o comportamento de CI. Se você enviar por push uma atualização para um branch de origem, o arquivo YAML resultante da mesclagem do branch de origem com o branch de destino controlará o comportamento de PR. Verifique se o arquivo YAML no branch correto tem a configuração necessária de CI ou PR.

  • Você configurou o gatilho corretamente? Ao definir um gatilho YAML, você pode especificar cláusulas include e exclude para branches, tags e caminhos. Verifique se a cláusula include corresponde aos detalhes do commit e se a cláusula exclude não os exclui. Verifique a sintaxe dos gatilhos e verifique se ela é precisa.

  • Você usou variáveis para definir o gatilho ou os caminhos? Observe que não há suporte para isso.

  • Você usou modelos para seu arquivo YAML? Nesse caso, verifique se os gatilhos estão definidos no arquivo YAML principal. Não há suporte para gatilhos definidos dentro de arquivos de modelo.

  • Você excluiu os branches ou caminhos para os quais você efetuou push das alterações? Teste enviando uma alteração por push para um caminho incluído em um branch incluído. Observe que os caminhos nos gatilhos diferenciam maiúsculas de minúsculas. Certifique-se de usar a mesma formatação de maiúsculas e minúsculas das pastas reais ao especificar os caminhos nos gatilhos.

  • Você acabou de efetuar push de um novo branch? Nesse caso, o novo branch pode não iniciar uma nova execução. Confira a seção "Comportamento dos gatilhos quando novos branches são criados".

Meus gatilhos de CI ou PR vinham funcionando bem. No entanto, eles pararam de funcionar agora.

Primeiro, siga as etapas de solução de problemas na pergunta anterior. Em seguida, siga estas etapas adicionais:

  • Você tem conflitos de mesclagem em sua PR? Para uma PR que não disparou um pipeline, abra-a e verifique se ela tem um conflito de mesclagem. Resolva o conflito de mesclagem.

  • Você está enfrentando um atraso no processamento de eventos de push ou PR? Normalmente, você pode verificar isso conferindo se o problema é específico para um determinado pipeline ou se é comum a todos os pipelines ou repositórios em seu projeto. Caso uma atualização de push ou PR para qualquer um desses repositórios apresente esse sintoma, podemos estar enfrentando atrasos no processamento dos eventos de atualização. Verifique se estamos enfrentando uma interrupção de serviço em nossa página de status. Se a página de status mostra um problema, isso significa necessariamente que nossa equipe já começou a trabalhar nele. Verifique a página com frequência para obter atualizações sobre o problema.

Não quero que os usuários substituam a lista de branches para gatilhos quando atualizarem o arquivo YAML. Como posso fazer isso?

Os usuários com permissões para contribuir com código podem atualizar o arquivo YAML e incluir/excluir branches adicionais. Como resultado, os usuários podem incluir um recurso ou branch de usuário próprio no arquivo YAML deles e efetuar push dessa atualização para um recurso ou branch de usuário. Isso pode fazer com que o pipeline seja disparado para todas as atualizações desse branch. Se você quiser evitar esse comportamento, poderá:

  1. Editar o pipeline na interface do usuário do Azure Pipelines.
  2. Navegar até o menu Gatilhos.
  3. Selecionar Substituir o gatilho de integração contínua YAML aqui.
  4. Especifique os branches a serem incluídos ou excluídos para o gatilho.

Quando você segue essas etapas, todos os gatilhos de CI especificados no arquivo YAML são ignorados.

Versão errada

Uma versão errada do arquivo YAML está sendo usada no pipeline. Por quê?

  • Para gatilhos de CI, o arquivo YAML que está no branch que você está enviando por push é avaliado para ver se um build de CI deve ser executado.
  • Para gatilhos de PR, o arquivo YAML resultante da mesclagem dos branches de origem e destino da PR é avaliado para ver se um build de PR deve ser executado.