# Integração Contínua + ACR

**Laboratório 2 – Pipeline com Testes de Código + Publicação de Docker Image no ACR**

* Cenário: O time agora precisa versionar builds internamente.
    
* Tarefas:
    
    * Gerar uma Docker image
        
    * Publicar no Azure Container Registry
        
    * Stages separados
        
* Desafio real: Garantir que somente builds que passam os testes são publicados.
    

## **Pré requisitos**

* Ter feito o laboratório **Pipeline CI com Validação (**[https://joaochiroli.com.br/pipeline-ci-com-validacao](https://joaochiroli.com.br/pipeline-ci-com-validacao)**)** iremos usar a mesma estrutura
    
* Nesta etapa iremos fazer as configurações direto na branch main, desabilite a politica que bloqueia edições e commits direto na branch main.
    

## **1️⃣ Step 1: Ajustar configurações no arquivo** `azure-pipelines.yml`

```yaml
trigger:
  branches:
    include:
    -  main

pr:
  branches:
    include:
    -  main


stages:

# 1️⃣ Instala, Valida e Publica o Código

  - stage: InstallAndValidate
    displayName: Install And Validate
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: InstallAndValidate
      displayName: 'InstallAndValidate'
      steps:
      - checkout: self
        displayName: 'Checkout code'

      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'
        
      - script: npm ci
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Install dependencies with ci'
        
      - script: npm run lint
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Linter (ESLint)'      

      - script: |
          npm install --save-dev prettier
          npm run prettier 
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Formatter (Prettier)'
        continueOnError: 'true'
    
      - script: CI=true npm run test
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Test (Jest) CI=true'

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
          artifact: 'validated-source'
          publishLocation: 'pipeline'
        displayName: 'Validated Source'
```

## 2️⃣ **Step 2: Configurar uma conexão com o ARM service Connection**

1. **Criar o Service Connection ARM:**
    
    * **Acesse o projeto** no Azure DevOps.
        
    * Vá até **Project Settings** (canto inferior esquerdo).
        
    * Clique em **Service connections** (na seção “Pipelines”).
        
    * Clique em **New service connection**.
        
    * Escolha **Azure Resource Manager**.
        
    * Selecione **Service principal (automatic)** e clique em **Next**.
        
    * Escolha:
        
        * **Subscription**: selecione a desejada.
            
        * **Resource Group** (opcional): para limitar o escopo.
            
        * **Service connection name**: nome amigável para uso nas pipelines.
            
    * Marque **Grant access permission to all pipelines** (se necessário).
        
    * Clique em **Save**.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747778529249/b1dbae12-d7ed-46c7-b163-d58a0027b550.jpeg align="center")
        

## 3️⃣**Step 3: Criar o Docker Container Registry no Azure**

  
1\. **Criar o ACR e Habilitar o Acesso Admin :**

* Acesse o portal do Azure.
    

* No menu lateral, clique em **"Container registries"**.
    
* Clique em **"+ Create"**.
    
* Preencha os campos:
    
    * Subscription: selecione sua assinatura.
        
    * Resource Group: escolha um existente ou clique em "Create new".
        
    * Registry name: defina um nome único (ex.: meuacrdevops).
        
    * Location: selecione a região desejada.
        
    * SKU: escolha Basic, Standard ou Premium (geralmente Standard para DevOps).
        
* Clique em "Review + Create".
    
* Clique em "Create" para finalizar.
    

1. **Habilitar o Acesso Admin (Access Keys)**
    
    1. Após criado, acesse seu ACR (vá em **Container registries → Seu Registry**).
        
    2. No menu lateral, clique em **"Access keys"**.
        
    3. Ative a opção **"Admin user"** → marque como **"Enabled"**.
        
    4. Serão exibidos:
        
        * **Username** (usuário do ACR)
            
        * **Password / Password2** (senhas geradas)  
            

## 4️⃣ **Step 4: Criar o Dockerfile na raiz do projeto**

* Nesta etapa iremos realizar também a **instalação dos pacotes** e o **build da aplicação** tudo isso direto no Dockerfile.
    
* Dockerfile:
    
    ```dockerfile
    FROM node:15 AS builder
    WORKDIR /app
    COPY . .
    RUN npm ci && npm run build
    
    FROM node:15
    WORKDIR /app
    COPY --from=builder /app .
    RUN npm ci --omit=dev
    EXPOSE 3000
    CMD ["npm", "start"]
    ```
    

## 5️⃣ **Step 5: Build e push para o ACR**

* **Criação do stage que será responsável por fazer o build e o envio da imagem para o ACR:**
    
    * ### `azure-pipelines.yml`
        

```yaml
# 2️⃣ Builda e publica a imagem no Acr

  - stage: BuildAndPackage
    displayName: Build And Package
    dependsOn: InstallAndValidate
    condition: succeeded()
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: BuildAndPackage
      displayName: 'BuildAndPackage'
      steps:
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'validated-source'
          targetPath: '$(Pipeline.Workspace)/validated-source'
       
      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'

      - task: AzureCLI@2
        inputs:
          azureSubscription: 'projeto-user-arm'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: | 
            az acr login --name acrplaygroundproject         
            docker build -t acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId) $(Pipeline.Workspace)/validated-source
            docker push acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId)
        displayName: 'Build and Push Docker Image'
```

Imagem salva no meu registry:

* Ponto de atenção: ao usar o comando `az acr login --name acrplaygroundproject` o `acrplaygroundproject` tem que ser o nome do seu acr
    

## 6️⃣ **Step 6: Arquivo yaml finalizado**

```yaml
trigger:
  branches:
    include:
    -  main

pr:
  branches:
    include:
    -  main


stages:

# 1️⃣ Instala, Valida e Publica o Código

  - stage: InstallAndValidate
    displayName: Install And Validate
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: InstallAndValidate
      displayName: 'InstallAndValidate'
      steps:
      - checkout: self
        displayName: 'Checkout code'

      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'
        
      - script: npm ci
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Install dependencies with ci'
        
      - script: npm run lint
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Linter (ESLint)'      

      - script: |
          npm install --save-dev prettier
          npm run prettier 
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Formatter (Prettier)'
        continueOnError: 'true'
    
      - script: CI=true npm run test
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Test (Jest) CI=true'

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
          artifact: 'validated-source'
          publishLocation: 'pipeline'
        displayName: 'Validated Source'

      
# 2️⃣ Builda e publica a imagem no Acr

  - stage: BuildAndPackage
    displayName: Build And Package
    dependsOn: InstallAndValidate
    condition: succeeded()
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: BuildAndPackage
      displayName: 'BuildAndPackage'
      steps:
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'validated-source'
          targetPath: '$(Pipeline.Workspace)/validated-source'
       
      - task: AzureCLI@2
        inputs:
          azureSubscription: 'projeto-user-arm'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: | 
            az acr login --name acrplaygroundproject         
            docker build -t acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId) $(Pipeline.Workspace)/validated-source
            docker push acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId)
        displayName: 'Build and Push Docker Image'
```
