CI/CD Robusto para Business Central no Azure DevOps

Neste artigo você aprende como estruturar um CI/CD robusto para Business Central no Azure DevOps, automatizando processos de build, validação e deploy de extensões de forma segura e eficiente.

Vinicius Pena

12/30/202514 min read

Garantir consistência e velocidade no ciclo de desenvolvimento de extensões para o Microsoft Dynamics 365 Business Central é um desafio comum. Muitas equipes ainda dependem de processos manuais, o que abre margem para erros e lentidão na entrega.

É por isso que a Integração Contínua (CI) e a Entrega Contínua (CD) são pilares fundamentais de uma operação DevOps de sucesso.20

Como criar CI/CD para o Business Central?

Qual é o objetivo deste Pipeline?

Este guia detalha a configuração de um pipeline de CI/CD projetado especificamente para soluções baseadas no Business Central. O propósito central é transformar a maneira como a Comunidade BC Brasil (ou qualquer time!) entrega valor.

Com a automação correta, conseguimos atingir três metas principais:

  1. Padronização de todas as etapas de build, garantindo que todo código seja tratado da mesma forma.

  2. Automação completa de validação, compilação e testes.

  3. Garantia de consistência na publicação de extensões (.app) nos ambientes.

Essas práticas garantem o alinhamento total com as boas práticas de DevOps no ciclo de desenvolvimento.

Estrutura e Segurança: Azure DevOps e Autenticação

A base do nosso pipeline foi estabelecida no Azure DevOps. Optamos por essa plataforma robusta para gerenciar todo o fluxo de trabalho.

Um ponto crítico foi a segurança e comunicação:

  • A comunicação com os ambientes do Business Central é feita de forma segura.

  • Utilizamos a autenticação via App Registration (com client_id e secret) para essa comunicação.

Vantagem do Compilador AL Local

Para a compilação das extensões, adotamos uma abordagem de independência. O compilador AL é extraído do Visual Studio Code e incluído diretamente no repositório.

Isso é crucial, pois:

  • Elimina a necessidade de dependências externas (como containers ou downloads dinâmicos).

Garante controle total sobre a versão do compilador AL utilizada no build, evitando surpresas.

Pré-Requisitos: O que Você Vai Precisar

Antes de mergulhar na configuração do CI/CD, você precisará garantir acesso e permissões em três ambientes principais: Azure, Business Central e Azure DevOps.

1. Azure

É o ponto de partida para a segurança e autenticação do pipeline.

  • Acesso ao Portal do Azure: Você deve ter permissões para registrar um novo aplicativo (via App Registration).

  • Geração de Chaves: É necessário gerar as chaves de autenticação (client ID e secret) que serão usadas pelo pipeline para interagir com o Business Central.

2. Dynamics 365 Business Central

  • Acesso ao Ambiente: Garanta que você tenha permissões de usuário adequadas para a publicação de extensões diretamente no ambiente.

3. Azure DevOps

Esta será a plataforma onde o pipeline será criado e executado.

  • Projeto e Repositório: Tenha um projeto criado com um repositório Git versionado.

  • Permissão de Criação: Você deve ter permissão para criar e editar pipelines em YAML.

4. Ferramentas Locais (Para Desenvolvimento e Testes)

Estas ferramentas são opcionais para o pipeline em si, mas essenciais para o desenvolvimento e testes manuais.

  • Visual Studio Code:

    • Deve ter a extensão "AL Language Extension" da Microsoft instalada.

  • Postman:

Instalado localmente, é necessário apenas para testes de autenticação e comunicação com as APIs do Business Central.

Ativação da Autenticação OAuth para o Pipeline

O uso da autenticação básica para interagir com o Dynamics 365 Business Central foi descontinuado. Para garantir a segurança e a longevidade do nosso pipeline, devemos configurar o acesso via OAuth.

Este passo a passo detalha a configuração necessária no D365 Business Central na nuvem (Cloud).

1. Criando o App Registration no Azure

O primeiro passo é registrar seu aplicativo no Microsoft Entra ID (antigo Azure AD), que será a identidade do seu pipeline.

  • Acesse o Portal do Azure: Faça login com um ID que tenha acesso ao seu Business Central.

  • Navegue até o Microsoft Entra ID: Use a barra de pesquisa para encontrar "Microsoft Entra ID".

  • Registro de Aplicativos: Dentro do Entra ID, clique em "Registro de Aplicativo" e, em seguida, em "Novo registro".

  • Configure o Aplicativo:

    • Nome: Digite um nome claro (Ex: BusinessCentralApp).

    • Tipos de Conta: Escolha quem pode usar este aplicativo.

    • URL de Redirecionamento:

Clique em "Registrar" para finalizar.

2. Concedendo Permissões de API

Com o aplicativo registrado, precisamos dar a ele as permissões necessárias para ler e gravar dados no Business Central.

  1. Acesse o Aplicativo: Abra o aplicativo que você acabou de criar.

  2. Adicionar Permissões: Clique em "Permissão da API" no menu lateral e depois em "+Adicionar uma permissão".

  3. Selecione o Business Central:

    • Nas permissões de API disponíveis, selecione "Business Central".

    • Atenção: Se você não conseguir visualizar o Business Central, verifique se o usuário que está configurando possui uma licença válida.

Permissões Necessárias

Marque as seguintes permissões para o pipeline:

a table with a list of the top ten things to do in spanish
a table with a list of the top ten things to do in spanish
Finalizando o Consentimento

Após adicionar todas as permissões:

  • Retorne à tela de "Permissões da API".

  • Clique em "Conceder consentimento administrativo".

Confirme clicando em "Sim". O status das permissões será atualizado para verde, indicando que o acesso está ativo.

3. Gerando e Protegendo o Segredo do Cliente (Client Secret)

A chave de acesso do nosso pipeline é o Client Secret. Este é o token que o Azure DevOps usará para provar sua identidade ao Business Central.

O processo de criação é simples, mas exige atenção máxima à segurança:

  • Acesse a seção de Segredos: Dentro do painel do App Registration criado, navegue até Certificados e segredos no menu lateral.

  • Crie um Novo Segredo: Clique em Novo segredo do cliente.

  • Defina a Expiração: Insira uma descrição clara (ex: BC_Pipeline_Secret) e defina o prazo de expiração. Lembre-se: por segurança, você terá que girar este segredo (trocá-lo) quando ele expirar.

  • Clique no botão Adicionar.

  • Atenção Máxima! Imediatamente após a criação, o campo Valor será exibido. Copie e salve este valor como seu client_secret em um local seguro antes que a página seja atualizada ou você a feche. Ele nunca mais será exibido!

🔒 Lembrete Crucial de Segurança:

Guarde o client_secret e o client_id nas Variáveis de Pipeline Secretas (ou Azure Key Vault) no Azure DevOps, conforme detalhamos na seção anterior. Jamais comite esses valores no seu repositório Git!

4. Coletando os IDs Essenciais (Client ID e Tenant ID)

Além do Client Secret, precisamos de dois identificadores públicos que formam o endereço do seu ambiente:

  • Client ID (Application ID): Identifica unicamente seu aplicativo dentro do Azure.

  • Tenant ID (Directory ID): Identifica o seu ambiente (locatário) do Microsoft Entra ID (Azure AD).

Para encontrá-los:

  • Acesse a Visão Geral: Clique em Visão Geral no menu lateral do seu App Registration.

  • Copie o Client ID: Copie o valor exibido como ID do Aplicativo (cliente) e salve-o como client_id.

  • Copie o Tenant ID: Copie o valor exibido como ID do Diretório (locatário) e salve-o como tenant_id.

5. Concedendo Acesso ao Business Central (Registro AAD)

Para que o seu pipeline (o App Registration) possa interagir com o Business Central (BC) de forma automatizada, ele precisa ser explicitamente registrado e configurado para usar o fluxo de Credenciais de Cliente OAuth 2.0 (S2S - Service to Service).

Essa autenticação S2S é a base do DevOps no BC, pois fornece acesso especial às APIs de Automação (/api/microsoft/automation), essenciais para tarefas como a implantação de extensões.

5.1. Configuração do URI de Redirecionamento (Passo Final no Azure)

Embora o fluxo S2S não utilize um redirecionamento interativo, é uma etapa técnica obrigatória para garantir que o App Registration esteja corretamente configurado para o ambiente Cloud do Business Central:

  • Acesse a Autenticação: No Portal do Azure, vá ao seu App Registration (BusinessCentralApp) e clique em Autenticação no menu lateral.

  • Adicione o URI de Redirecionamento: Na seção URIs de redirecionamento da Web, adicione:

  • https://businesscentral.dynamics.com/OAuthLanding.htm

  • Finalize: Certifique-se de selecionar o tipo de conta correto e salve as alterações.

Escopo Crucial: Lembre-se que, para acessar as APIs de Automação, é necessário que seu token tenha o escopo Automation.ReadWrite.All, que já configuramos no passo 2.Concedendo Permissões de API.

6. Registrando o Aplicativo no Business Central

Agora, vamos fazer o Business Central reconhecer o aplicativo criado no Azure. Esta etapa é crítica e exige uma permissão de usuário elevada (SUPER ou SEGURANÇA) para conceder o consentimento necessário.

  1. Acesse a Página de AAD: No Business Central (Cloud), use a pesquisa (a lupa) para encontrar e acessar a página Aplicativos do Azure Active Directory (ou apenas pesquise por AAD).

  2. Adicione um Novo Aplicativo: Clique em Novo para criar um novo registro.

  3. Insira o Client ID:

    • Copie o seu client_id (o ID do Aplicativo (cliente)) obtido no Azure.

    • Cole-o no campo ID do Cliente no Business Central.

    • Adicione um nome na Descrição que sirva como boa referência (ex: BC_Pipeline_App). O sistema preencherá o ID e o Nome do Usuário de registro automaticamente.

  4. Conceda Permissões de BC:

    • Adicione o aplicativo ao(s) Grupo(s) de Usuários necessário(s). O grupo Extension Management – Admin é crucial para garantir que o pipeline possa publicar e gerenciar extensões.

  5. Conceda o Consentimento Final:

    • Clique no botão Conceder consentimento.

    • Uma janela pop-up será aberta solicitando as credenciais de um usuário com permissão SUPER/SEGURANÇA. Insira o nome de usuário e a senha para aceitar e confirmar as permissões solicitadas pelo seu App Registration.

Foco na Segurança:

Ao conceder o consentimento, você está autorizando o seu App Registration a atuar com o nível de permissão (Roles/Groups) que você definir para ele, incluindo a capacidade de Automation.ReadWrite.All. Certifique-se de limitar as permissões apenas ao necessário para o processo de CI/CD.

7. Validação Rápida: Testando o Token OAuth no Postman

Antes de prosseguirmos para o Azure DevOps, é crucial validar se o nosso App Registration consegue gerar um token de acesso. Se esta etapa falhar, o pipeline também falhará, e o Postman nos dá um ambiente rápido para testar a comunicação OAuth 2.0 S2S.

Configurando a Solicitação no Postman
  • Crie a Requisição: No Postman, crie uma nova coleção e adicione uma solicitação POST, chame-a de "GetToken BC".

  • Defina a URL: Cole a seguinte URL no campo, substituindo {tenant_id} pelo seu ID de Locatário real (que você copiou no passo 2.4):

https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token

  • Configure o Corpo (Body): Na seção Body, selecione a opção x-www-form-urlencoded.

Adicione os Parâmetros: Preencha os seguintes pares de chave-valor:

a table with a list of different types of the different types of the same type
a table with a list of different types of the different types of the same type
  • Envie a Solicitação: Clique em Enviar.

Se a configuração estiver correta, você deve receber uma resposta com o status 200 OK, contendo o token de acesso na chave access_token do JSON de resposta.

🎉 Sucesso!

Receber o access_token significa que seu App Registration está autenticando corretamente. O Azure DevOps usará exatamente este mesmo fluxo para obter o token e interagir com o Business Central!

Configurando a Integração Contínua (CI)

A etapa de Integração Contínua (CI) tem como objetivo automatizar a validação do código, a compilação da extensão (.app) e a execução de testes a cada alteração no repositório.

Pressuposto: Entendemos que seu projeto já está clonado, estruturado e pronto para o desenvolvimento das soluções do Business Central.

1. O Segredo da Compilação Rápida: Compilador AL Local

Para criar um pipeline rápido, leve e independente de containers BC completos, adotamos a estratégia de incluir o compilador AL (alc.exe) e suas dependências diretamente no repositório.

1.1 Estrutura do Repositório para o Compilador
  • Crie a Pasta ALC: Dentro do seu projeto (na raiz do repositório Git), crie uma pasta chamada ALC (ou tools/ALC, se preferir maior organização).

  • Copie os Arquivos do Compilador: Navegue até o diretório de instalação da extensão AL Language no seu Visual Studio Code e copie todos os arquivos da pasta do compilador para dentro da sua nova pasta ALC.

    • Caminho Típico: C:\Users\<UserProfile>\.vscode\extensions\ms-dynamics-smb.al-<Version>\bin\win32

  • Inclua as Dependências AL: Certifique-se de que a pasta .alpackages (contendo os símbolos baixados do BC, como System e Base Application) também esteja versionada no repositório. Estes arquivos são essenciais para a compilação cruzada.

  • Permissões e Objetos: Adicione seu permissionset.al (ou os vários permission sets) ao repositório, garantindo que as permissões também sejam parte do build da extensão.

⚠️ Atenção à Versão:

Ao incluir o compilador alc.exe, você trava a versão que será usada pelo pipeline. Isso garante consistência. Lembre-se de atualizar manualmente esta pasta ALC quando for migrar para uma nova major ou minor versão do AL Language.

2. O Pipeline de Build (CI) no Azure DevOps

A execução da compilação é definida no arquivo azure-pipeline_CI.yml (criado na raiz ou em /.azuredevops/), que orquestra todas as tarefas necessárias.

2.1 Geração Dinâmica da Versão (Boas Práticas)

Antes de compilar, implementamos uma prática essencial para o CI/CD: versionamento automático. Isso garante que cada build bem-sucedido tenha uma versão única e rastreável.

O pipeline usa PowerShell para gerar a versão no formato Major.YYMMDD.BuildID.0:

  • $datePart: Data formatada (ex: 240510).

  • $buildId: ID único da execução do pipeline.

  • $version: O resultado final (ex: 26.240510.54321.0).

Este valor é então injetado no app.json através do script PowerShell, garantindo que o .app compilado reflita a versão exata do build.

2.2 O Código YAML

# -----------------------------------------------------------

# azure-pipeline_CI.yml - Definição do Pipeline de Build (CI)

# -----------------------------------------------------------

trigger:

branches:

include:

- test # O build é iniciado automaticamente após o push para o branch 'test'

pool:

vmImage: 'windows-latest'

variables:

# ATENÇÃO: Substitua as tags <ProjectName> e <major version>

artifactName: 'app-build'

projectFolder: '<ProjectName>' # Nome da pasta do projeto AL (Ex: MyExtension)

alcFolder: '<ProjectName>/ALC' # Caminho para a pasta com alc.exe

outputFolder: 'Output' # Pasta onde o .app será salvo

appVersion: ''

appName: 'Nexer_<ProjectName>'

applicationVersion: '<major version>' # Ex: 24, 25, 26... (Versão da Plataforma BC)

stages:

- stage: BuildApp

displayName: '1. Compilação e Versionamento AL'

jobs:

- job: Build

displayName: 'Build .app'

steps:

- checkout: self

# ----------------------------------------------------

# TAREFA 1: Geração Dinâmica da Versão

# ----------------------------------------------------

- task: PowerShell@2

displayName: 'Gerar Versão Dinâmica (Major.Date.Build.0)'

inputs:

targetType: inline

script: |

$datePart = Get-Date -Format "yyMMdd"

$buildId = $env:BUILD_BUILDID

$version = "$(applicationVersion).$datePart.$buildId.0"

Write-Host "##vso[task.setvariable variable=appVersion]$version"

Write-Host "Versão gerada: $version"

# ----------------------------------------------------

# TAREFA 2: Atualizar app.json

# ----------------------------------------------------

- task: PowerShell@2

displayName: 'Atualizar Versão no app.json'

inputs:

targetType: inline

script: |

$appJsonPath = "$(Build.SourcesDirectory)\$(projectFolder)\app.json"

if (-Not (Test-Path $appJsonPath)) {

Write-Error "Arquivo app.json NÃO encontrado em: $appJsonPath"

exit 1

}

$appJson = Get-Content $appJsonPath | ConvertFrom-Json

$appJson.version = "$(appVersion)"

$appJson | ConvertTo-Json -Depth 10 | Set-Content $appJsonPath -Encoding UTF8

Write-Host "Versão do app.json atualizada para: $($appJson.version)"

# ----------------------------------------------------

# TAREFA 3: Compilar (Usando alc.exe local)

# ----------------------------------------------------

- task: PowerShell@2

displayName: 'Compilar Localmente (ALC)'

inputs:

targetType: inline

script: |

# ... (Scripts para encontrar alc.exe e paths) ...

$alcPath = "$(Build.SourcesDirectory)\$(alcFolder)\alc.exe"

$projectPath = "$(Build.SourcesDirectory)\$(projectFolder)"

$packagesFolder = Join-Path $projectPath ".alpackages"

$outputPath = "$(Build.SourcesDirectory)\$(outputFolder)"

$outputAppName = "$(appName).app"

# Garantir que a pasta de output exista

if (-Not (Test-Path $outputPath)) { New-Item -ItemType Directory -Force -Path $outputPath | Out-Null }

Write-Host "Executando compilação com alc.exe..."

& $alcPath /project:"$projectPath" /packageCachePath:"$packagesFolder" /out:"$outputPath\$outputAppName"

if ($LASTEXITCODE -ne 0) {

Write-Error "Falha na compilação do app AL."

exit $LASTEXITCODE

}

Write-Host "Compilação concluída. Arquivo gerado: $outputPath\$outputAppName"

# ----------------------------------------------------

# TAREFA 4: Publicar o Artefato

# ----------------------------------------------------

- publish: '$(Build.SourcesDirectory)/$(outputFolder)'

artifact: $(artifactName)

3. Publicando o Pipeline no Azure DevOps
  • Commit e Push: Após substituir as tags (<ProjectName>, <major version>) e salvar o arquivo, use o Git para atualizar o repositório.

  • Novo Pipeline: No Azure DevOps do seu projeto, acesse Pipelines e clique em Novo pipeline.

  • Configuração:

    • Selecione Azure Repos Git e o seu repositório.

    • Escolha Existing Azure Pipelines YAML file.

    • Selecione o branch e o caminho para o arquivo azure-pipeline_CI.yml.

  • Salvar e Executar: Salve o pipeline. Agora, a cada push para o branch test, a CI será acionada automaticamente, gerando um artefato (app-build) com a versão atualizada.

Em caso de sucesso, a saída deverá ser semelhante a esta:

Configurando a Entrega Contínua (CD): O Deploy Automatizado

Com o artefato compilado e versionado, a fase de Entrega Contínua (CD) se inicia. Usaremos o Release Pipeline Clássico no Azure DevOps para orquestrar o deploy em nossos ambientes do Business Central.

1. Criando e Vinculando o Pipeline de Release

Acesse o Menu Releases: No Azure DevOps do seu projeto, vá até Pipelines e clique em Releases. Crie um Novo pipeline a partir de um template vazio.

1.1 Vinculando o Artefato (Build)

O primeiro passo é garantir que o CD consuma o pacote gerado na CI:

  • Clique em + Add an artifact.

  • Tipo de Artefato: Selecione Construção (Build).

  • Fonte: Escolha o pipeline de CI criado (ex: azure-pipeline_CI.yml).

  • Gatilho Automático: Habilite o Continuous deployment trigger (o ícone de raio ⚡) para que o deploy seja acionado automaticamente após o sucesso de cada build de CI.

Importante: O artefato selecionado será a origem do arquivo .app (embalado com o nome definido no alias) que será enviado ao ambiente do Business Central via API.

1.2 Adicionando o Estágio (Ambiente)

Adicione um estágio e nomeie-o (ex: Deploy - Sandbox ou Deploy - UAT). Em seguida, acesse a aba Tarefas desse estágio para configurarmos a ação de deploy.


2. Definindo as Variáveis de Ambiente e Segurança

Na seção Variáveis do seu Release Pipeline, defina as informações cruciais para a comunicação com o Business Central:

⚠️ Segurança: Certifique-se de clicar no ícone de cadeado (🔒) para client_id, client_secret e tenant_id, garantindo que não sejam expostas nos logs de execução.

3. A Tarefa de Deploy (PowerShell Script)

Na aba Tarefas do seu estágio:

  • Adicione a Tarefa: Adicione uma nova tarefa do tipo PowerShell (versão 2 ou superior) ao Agent Job.

  • Tipo de Script: Selecione a opção Inline e cole o script de deploy fornecido.

Este script PowerShell é o motor do CD, pois ele usa o OAuth 2.0 S2S para obter o token e, em seguida, interage com a API de Automação do Business Central para realizar o Publish ou Install/Update da extensão.

# ================================

# Get Token

# ================================

Write-Host "Requesting token..."

$body = @{

"client_id" = "$(client_id)"

"client_secret" = "$(client_secret)"

"scope" = "https://api.businesscentral.dynamics.com/.default"

"grant_type" = "client_credentials"

}


$response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$(tenant_id)/oauth2/v2.0/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $body

$token = $response.access_token

Write-Host "Token successfully obtained"


# ================================

# Get Company ID

# ================================

Write-Host "Getting company ID..."

$companiesUrl = "https://api.businesscentral.dynamics.com/v2.0/$(tenant_id)/$(env_name)/api/microsoft/automation/v2.0/companies"

$companiesResponse = Invoke-RestMethod -Uri $companiesUrl -Headers @{ Authorization = "Bearer $token" }


$company_id = $companiesResponse.value[0].id

$company_name = $companiesResponse.value[0].name

Write-Host "Company Name: $company_name"

Write-Host "Company ID: $company_id"


# ================================

# Get Extension ID

# ================================

Write-Host "Getting Extension Id..."

$UrlExtUpload = "https://api.businesscentral.dynamics.com/v2.0/$(tenant_id)/$(env_name)/api/microsoft/automation/v2.0/companies($company_id)/extensionUpload"

Write-Host "POST ExtensionUpload URL: $UrlExtUpload"


try {

$headerExtensionUploadPost = @{

"Authorization" = "Bearer $token"

"Accept" = "application/json"

"Content-Type" = "application/json"

}


$BodyExtensionUploadPost = @{

schedule = "Current version"

schemaSyncMode = "Add"

} | ConvertTo-Json


Write-Host "Calling POST to initialize extension upload"

$ResponseExtUploadPost = Invoke-RestMethod -Uri $UrlExtUpload -Method Post -Headers $headerExtensionUploadPost -Body $BodyExtensionUploadPost -ContentType "application/json" -UseBasicParsing


$extension_id = $ResponseExtUploadPost.systemId

Write-Host "Extension ID obtained via POST: $extension_id"

}

catch [System.Net.WebException] {

$exception = $_.Exception

$response = $exception.Response


if ($response -ne $null -and $response.StatusCode -eq [System.Net.HttpStatusCode]::BadRequest) {

Write-Host "POST failed with 400 Bad Request. Falling back to GET..."


$headerExtensionUploadGet = @{

Accept = "application/json"

"Content-Type" = "application/json"

Authorization = "Bearer $token"

}


$ResponseExtensionUpload = Invoke-RestMethod -Uri $UrlExtUpload -Method Get -Headers $headerExtensionUploadGet -ContentType "application/json" -UseBasicParsing

$extension_id = $ResponseExtensionUpload.value[0].systemId

Write-Host "Extension ID obtained via GET: $extension_id"

}

else {

Write-Host "Unhandled error: $($exception.Message)"

exit 1

}

}


# ================================

# Upload App File (.app)

# ================================

Write-Host "Uploading App File..."

$UrlFileUpload = "https://api.businesscentral.dynamics.com/v2.0/$(tenant_id)/$(env_name)/api/microsoft/automation/v2.0/companies($company_id)/extensionUpload($extension_id)/extensionContent"


$HeaderFileUpload = @{

Accept = "*/*"

"Content-Type" = "application/octet-stream"

Authorization = "Bearer $token"

"If-Match" = "*"

}


$FilePath = "$(System.DefaultWorkingDirectory)/BC_UAT_CI/app-build/$(app_file_name)"

$response = Invoke-RestMethod -Uri $UrlFileUpload -Method Patch -Headers $HeaderFileUpload -ContentType "application/octet-stream" -InFile $FilePath -UseBasicParsing


Write-Host "App uploaded successfully."


# ================================

# Install App

# ================================

Write-Host "Installing App..."

$UrlFileInstall = "https://api.businesscentral.dynamics.com/v2.0/$(tenant_id)/$(env_name)/api/microsoft/automation/v2.0/companies($company_id)/extensionUpload($extension_id)/Microsoft.NAV.upload"


$HeaderFileInstall = @{

Accept = "*/*"

Authorization = "Bearer $token"

}


Invoke-RestMethod -Uri $UrlFileInstall -Method Post -Headers $HeaderFileInstall -UseBasicParsing

Write-Host "App installation triggered successfully."


4. Execução do Release

Ao salvar e criar o release, ele estará pronto para ser executado manualmente, ou será acionado automaticamente após o próximo build bem-sucedido da CI.

O sucesso da execução será indicado pelo status Succeeded (Concluído) do estágio, confirmando que a extensão foi publicada com sucesso no seu ambiente do Business Central.

Conclusão: O Futuro é Automatizado!

Agora você tem um Pipeline CI/CD Robusto e Seguro rodando, utilizando o que há de melhor em DevOps com Azure DevOps e D365 Business Central.

  • Sua equipe está livre de erros manuais.

  • Suas entregas são rápidas, consistentes e rastreáveis (cada .app tem uma versão de build única).

  • Você está utilizando o padrão OAuth S2S, garantindo a longevidade e segurança do seu processo de deploy.

Esperamos que este guia ajude você a acelerar a entrega de valor em seus projetos.

Qual é a sua experiência com CI/CD no BC? Compartilhe com a gente!