Difference between revisions of "Azure/Azure Devops + az extension"

From Ever changing code
Jump to navigation Jump to search
(Created page with "What is Azure DevOps: * Azure Repos - SCM/VCS system hosted in Azure * Azure Pipelines - Build, test, release automations * Azure Boards - Kanban board; JIRA like to track wor...")
 
 
(41 intermediate revisions by the same user not shown)
Line 5: Line 5:
* Azure Test Plans
* Azure Test Plans
* Azure Artifacts - share Maven, npm, NuGet from private and public sources
* Azure Artifacts - share Maven, npm, NuGet from private and public sources
= [https://docs.microsoft.com/en-us/dotnet/core/tools/ dotnet commands reference] =
<source lang=batch>
dotnet restore **/*.csproj # Restores the dependencies and tools of a project
dotnet build              # Builds a project and all of its dependencies
dotnet test **/*[Tt]ests/*.csproj # .NET test driver used to execute unit tests
dotnet publish # Publishes the application and its dependencies to a folder for deployment to a hosting system
</source>
= az-cli with azure-devops extension =
There is a helpful <code>azure-devops</code> extension to <code>az</code> utility to work with ADO. Install and usage, below:
* submodules: artifacts, boards, devops, [https://docs.microsoft.com/en-us/cli/azure/ext/azure-devops/pipelines?view=azure-cli-latest pipelines], repos
* manage [https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=yaml library/variable-groups] with examples
<syntaxhighlightjs lang="bash">
az extension list
az extension show --name azure-devops
az extension add  --name azure-devops
[
  {
    "experimental": false,
    "extensionType": "whl",
    "name": "azure-devops",
    "path": "/home/piotr/.azure/cliextensions/azure-devops",
    "preview": false,
    "version": "0.18.0"
  }
]
# Azure login
az login        # login to get subscription level authentication, >> not needed for DevOps login
az account show
# Azure DevOps login
export AZURE_DEVOPS_EXT_PAT=*** # if not set you will be prompted
az devops login # login to Azure DevOps
Token: ****    # <- generate a token in AzureDevops > UserSettings > Personal tokens
# Optional. Set default organization and project
az devops configure --defaults organization=https://myorg.visualstudio.com project=myproject
# Operations
GROUP_NAME=mygroup
GROUP_ID=$(az pipelines variable-group list --group-name $GROUP_NAME --query '[].id' | jq -r .[])
az pipelines variable-group variable list --group-id $GROUP_ID -o yamlc # or --id
# >> Note secrets value won't show
az pipelines build list -o table
az pipelines variable-group list --group-name $GROUP_NAME -o yamlc --query '[].variables' # color YAML
# | available outputs: json, jsonc, none, table, tsv, yaml, yamlc.  Default: json.
# Long example
# Linux
az repos list --organization=https://myorg.visualstudio.com --project=myproject --query '[].{Name:name, Url:remoteUrl}' -o json | jq -r .[].Name
# PowerShell
(az repos list --query '[].{Name:name, Url:remoteUrl}' -o json | ConvertFrom-Json) | %{ git clone $_.Url }
</syntaxhighlightjs>
= Azure pipeline agents =
Software included:
* [https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu1804-README.md ubuntu 18.04]
* [https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#networking Networking] and weekly IP file
Environment:
<source lang=bash>
# Default working directory, also where repos get cloned
$(Build.SourcesDirectory): /home/vsts/work/1/s
# Published artifacts
cd ../name-of-artifact/
# Layout of $(Agent.BuildDirectory) that is '/home/vsts/work/1', output of 'ls -la' is shown below:
$pwd; cd .. # level up from pwd
drwxr-xr-x 7 vsts docker 4096 Sep  1 22:11 .
drwxr-xr-x 7 vsts root  4096 Sep  1 22:11 ..
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 TestResults
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 a # pipeline artifact dir
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 b # binaries directory
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 s # source directory often $PWD, where the repo code gets checked out
drwxr-xr-x 6 vsts docker 4096 Sep  1 22:11 name-of-artifact
# Layout env variables, executed from a pipeline on the agent
$ grep -e "DIRECTORY\|^AGENT" /tmp/1 | sort
AGENT_ACCEPTTEEEULA=True
AGENT_BUILDDIRECTORY=/home/vsts/work/1
AGENT_DISABLELOGPLUGIN_TESTFILEPUBLISHERPLUGIN=true
AGENT_DISABLELOGPLUGIN_TESTRESULTLOGPLUGIN=true
AGENT_HOMEDIRECTORY=/home/vsts/agents/2.174.1
AGENT_ID=9
AGENT_JOBNAME=terraform plan
AGENT_JOBSTATUS=Succeeded
AGENT_MACHINENAME=fv-az605
AGENT_NAME=Hosted Agent
AGENT_OSARCHITECTURE=X64
AGENT_OS=Linux
AGENT_READONLYVARIABLES=true
AGENT_RETAINDEFAULTENCODING=false
AGENT_ROOTDIRECTORY=/home/vsts/work
AGENT_TEMPDIRECTORY=/home/vsts/work/_temp
AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache
AGENT_VERSION=2.174.1
AGENT_WORKFOLDER=/home/vsts/work
BUILD_ARTIFACTSTAGINGDIRECTORY=/home/vsts/work/1/a
BUILD_BINARIESDIRECTORY=/home/vsts/work/1/b
BUILD_SOURCESDIRECTORY=/home/vsts/work/1/s
BUILD_STAGINGDIRECTORY=/home/vsts/work/1/a
COMMON_TESTRESULTSDIRECTORY=/home/vsts/work/1/TestResults
RUNNER_TOOLSDIRECTORY=/opt/hostedtoolcache
SYSTEM_ARTIFACTSDIRECTORY=/home/vsts/work/1/a
SYSTEM_DEFAULTWORKINGDIRECTORY=/home/vsts/work/1/s
$(Agent.BuildDirectory)  # /home/vsts/work/1
$(Build.SourcesDirectory) # /home/vsts/work/1/s
$(Build.Repository.LocalPath)
</source>
Troubleshoot snippets
<source lang=bash>
  - stage      : deploy
    displayName: deploy
    dependsOn  : plan
    jobs      :
      - deployment : deploy
        displayName: deploy
        environment: env-${{ parameters.environment }}
        strategy:
          runOnce:
            deploy:
              steps:
              - checkout: self  # this is needed for job 'deployment' type, common job type 'job' already contains git code
              - task      : AmazonWebServices.aws-vsts-tools.AWSShellScript.AWSShellScript@1
                displayName: deploy
                env        :
                  VARIBLE_1 : $(variable_2)
                inputs    :
                  awsCredentials      : $(service_connection_name)
                  regionName          : $(aws_region)
                  failOnStandardError : false
                  args                : ""
                  scriptType          : inline
                  #disableAutoCwd    : true
                  #workingDirectory  : $(Agent.BuildDirectory)/myrepo
                  inlineScript        : |
                    #!/bin/bash
                    sudo apt update  -qq
                    sudo apt install -qq tree
                    printf '\n[DEBUG] $SHELL      : %s' "$SHELL"
                    printf '\n[DEBUG] $BASH_VERSION: %s' "$BASH_VERSION"
                    printf '\n[DEBUG] $PDW        : %s' "$PWD"
                    printf '\n[DEBUG] $ENVIRONMENT=%s\n' "${ENVIRONMENT}"
                    printf '\n[DEBUG] $..(..Agent.BuildDirectory): %s' "$(Agent.BuildDirectory)"
                    printf '\n[DEBUG] pwd; ls -la\n'              ; pwd; ls -la
                    printf '\n[DEBUG] ls -la ../helm-charts\n'    ; ls -la ../helm-charts
                    printf '\n[DEBUG] ls -la ../s\n'              ; ls -la ../s
                    printf '\n[DEBUG] find ../.. -iname file.sh\n' ; find ../.. -iname file.sh
                    printf '\n[DEBUG] tree -aL 2 ..\n'            ; tree -aL 2 ..
                    time source  $(Agent.BuildDirectory)/myrepo/scripts/file.sh
                    #time source      $(Build.SourcesDirectory)/scripts/file.sh
</source>
= Pipeline [https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch variables] and secrets =
[https://github.com/MicrosoftDocs/azure-devops-docs/blob/master/docs/pipelines/process/variables.md Variables.md] are available in expressions as well as scripts; see variables to learn more about how to use them. There are some predefined build and release variables you can also rely on.
Syntax
<source lang=bash>
regionName    : "${{ variables.aws_region }}"
regionName    : $(aws_region)
# set Dynamic Variable Secret
$token = curl ...
echo "##vso[task.setvariable variable=accesstoken;isSecret=true]$token"
# print secrets, the value vertically if you print them as chars:
$Password.ToCharArray()
</source>
Resources:
* [https://adamtheautomator.com/azure-devops-variables-complete-guide/ variables-complete-guide] blog
= Pipeline tasks =
* [https://github.com/aws/aws-toolkit-azure-devops/tree/master/Tasks aws-toolkit-azure-devops] set of tasks
* [https://github.com/Microsoft/azure-pipelines-tasks azure-pipelines-tasks] by Microsoft
= Stage =
<syntaxhighlightjs lang=yaml>
stages:
  - stage      : deploy_helm
    displayName: deploy_helm
    jobs      :
      - job        : deploy_helm
        displayName: deploy_helm
        steps      :
          - task      : AmazonWebServices.aws-vsts-tools.AWSShellScript.AWSShellScript@1
            displayName: "deploy_helm"
            env        :
              DBPASSWORD : $(auth_service_client_secret)
              VALUES_PATH: $(values-path)
            inputs    :
            # https://github.com/aws/aws-toolkit-azure-devops/blob/master/Tasks/AWSShellScript/task.json
              awsCredentials: $(aws_creds)
              regionName          : $(aws_region)
              #failOnStandardError: true # default: false
              #disableAutoCwd    : true # default: false, The default behavior is to set the working directory to the script location
              #workingDirectory  : $(Build.SourcesDirectory) # | This enables you to optionally specify a different working directory.
              scriptType          : inline # default: filePath
              #filePath          : $(Build.SourcesDirectory)/scripts/connect.sh
              inlineScript        : |
                #!/bin/bash
                printf "\n[DEBUG] PWD: %s" "$PWD"
                time source $(Build.SourcesDirectory)/scripts/connect.sh || \
                  { printf "\n[ERROR] to connect"; exit 1; }
              args                : "" # Arguments passed to the shell script
</syntaxhighlightjs>
= Conditions =
<source lang=yaml>
parameters:
- name: enabled
  type: boolean
  default: false
stages:
  - stage: ${{ parameters.stage_name_prefix }}_build
    condition: and(succeeded(), eq('${{ parameters.enabled }}', 'true'))
    displayName: ${{parameters.stage_display_name}}
    jobs:
</source>
= [https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash Logging and formatting in the pipeline] =
<source>
##[group]Beginning of a group
##[warning]Warning message
##[error]Error message
##[debug]Debug text
##[command]Command-line being run
##[endgroup]
</source>
= Resources =
* [https://azuredevopsdemogenerator.azurewebsites.net/ azuredevopsdemogenerator]
* [https://www.youtube.com/watch?v=g1eZ1WLfUI0 #3 Azure DevOps w bazach danych] BitPeak, youtube
* [https://medium.com/@therealjordanlee/azure-devops-tips-each-loops-c082c692d025 azure-devops-tips-each-loops-c082c692d025] medium 2019
;Code Assessment Tools
* [https://www.microsoft.com/en-us/securityengineering/devsecops#AutomationDevOps Security Tools]
* [https://sonarcloud.io/ SonarCloud]
* [https://www.nuget.org/packages/SonarAnalyzer.CSharp/ SonarAnalyzer]
* [https://docs.microsoft.com/en-us/visualstudio/code-quality/install-fxcop-analyzers?view=vs-2017 FxCop] - check your code for security, performance, and design issues by Microsoft

Latest revision as of 02:33, 8 June 2021

What is Azure DevOps:

  • Azure Repos - SCM/VCS system hosted in Azure
  • Azure Pipelines - Build, test, release automations
  • Azure Boards - Kanban board; JIRA like to track work, code defects, issues using Kanban or Scrum
  • Azure Test Plans
  • Azure Artifacts - share Maven, npm, NuGet from private and public sources

dotnet commands reference

dotnet restore **/*.csproj # Restores the dependencies and tools of a project
dotnet build               # Builds a project and all of its dependencies
dotnet test **/*[Tt]ests/*.csproj # .NET test driver used to execute unit tests
dotnet publish # Publishes the application and its dependencies to a folder for deployment to a hosting system

az-cli with azure-devops extension

There is a helpful azure-devops extension to az utility to work with ADO. Install and usage, below:

<syntaxhighlightjs lang="bash"> az extension list az extension show --name azure-devops az extension add --name azure-devops [

 {
   "experimental": false,
   "extensionType": "whl",
   "name": "azure-devops",
   "path": "/home/piotr/.azure/cliextensions/azure-devops",
   "preview": false,
   "version": "0.18.0"
 }

]

  1. Azure login

az login # login to get subscription level authentication, >> not needed for DevOps login az account show

  1. Azure DevOps login

export AZURE_DEVOPS_EXT_PAT=*** # if not set you will be prompted az devops login # login to Azure DevOps Token: **** # <- generate a token in AzureDevops > UserSettings > Personal tokens

  1. Optional. Set default organization and project

az devops configure --defaults organization=https://myorg.visualstudio.com project=myproject

  1. Operations

GROUP_NAME=mygroup GROUP_ID=$(az pipelines variable-group list --group-name $GROUP_NAME --query '[].id' | jq -r .[]) az pipelines variable-group variable list --group-id $GROUP_ID -o yamlc # or --id

  1. >> Note secrets value won't show

az pipelines build list -o table az pipelines variable-group list --group-name $GROUP_NAME -o yamlc --query '[].variables' # color YAML

  1. | available outputs: json, jsonc, none, table, tsv, yaml, yamlc. Default: json.
  1. Long example
  2. Linux

az repos list --organization=https://myorg.visualstudio.com --project=myproject --query '[].{Name:name, Url:remoteUrl}' -o json | jq -r .[].Name

  1. PowerShell

(az repos list --query '[].{Name:name, Url:remoteUrl}' -o json | ConvertFrom-Json) | %{ git clone $_.Url } </syntaxhighlightjs>

Azure pipeline agents

Software included:

Environment:

# Default working directory, also where repos get cloned
$(Build.SourcesDirectory): /home/vsts/work/1/s

# Published artifacts
cd ../name-of-artifact/

# Layout of $(Agent.BuildDirectory) that is '/home/vsts/work/1', output of 'ls -la' is shown below:
$pwd; cd .. # level up from pwd
drwxr-xr-x 7 vsts docker 4096 Sep  1 22:11 .
drwxr-xr-x 7 vsts root   4096 Sep  1 22:11 ..
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 TestResults
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 a # pipeline artifact dir
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 b # binaries directory
drwxr-xr-x 2 vsts docker 4096 Sep  1 22:11 s # source directory often $PWD, where the repo code gets checked out
drwxr-xr-x 6 vsts docker 4096 Sep  1 22:11 name-of-artifact

# Layout env variables, executed from a pipeline on the agent 
$ grep -e "DIRECTORY\|^AGENT" /tmp/1 | sort
AGENT_ACCEPTTEEEULA=True
AGENT_BUILDDIRECTORY=/home/vsts/work/1
AGENT_DISABLELOGPLUGIN_TESTFILEPUBLISHERPLUGIN=true
AGENT_DISABLELOGPLUGIN_TESTRESULTLOGPLUGIN=true
AGENT_HOMEDIRECTORY=/home/vsts/agents/2.174.1
AGENT_ID=9
AGENT_JOBNAME=terraform plan
AGENT_JOBSTATUS=Succeeded
AGENT_MACHINENAME=fv-az605
AGENT_NAME=Hosted Agent
AGENT_OSARCHITECTURE=X64
AGENT_OS=Linux
AGENT_READONLYVARIABLES=true
AGENT_RETAINDEFAULTENCODING=false
AGENT_ROOTDIRECTORY=/home/vsts/work
AGENT_TEMPDIRECTORY=/home/vsts/work/_temp
AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache
AGENT_VERSION=2.174.1
AGENT_WORKFOLDER=/home/vsts/work
BUILD_ARTIFACTSTAGINGDIRECTORY=/home/vsts/work/1/a
BUILD_BINARIESDIRECTORY=/home/vsts/work/1/b
BUILD_SOURCESDIRECTORY=/home/vsts/work/1/s
BUILD_STAGINGDIRECTORY=/home/vsts/work/1/a
COMMON_TESTRESULTSDIRECTORY=/home/vsts/work/1/TestResults
RUNNER_TOOLSDIRECTORY=/opt/hostedtoolcache
SYSTEM_ARTIFACTSDIRECTORY=/home/vsts/work/1/a
SYSTEM_DEFAULTWORKINGDIRECTORY=/home/vsts/work/1/s

$(Agent.BuildDirectory)   # /home/vsts/work/1
$(Build.SourcesDirectory) # /home/vsts/work/1/s
$(Build.Repository.LocalPath)


Troubleshoot snippets

- stage      : deploy
    displayName: deploy
    dependsOn  : plan
    jobs       :
      - deployment : deploy
        displayName: deploy
        environment: env-${{ parameters.environment }}
        strategy:
          runOnce:
            deploy:
              steps:
              - checkout: self  # this is needed for job 'deployment' type, common job type 'job' already contains git code
              - task       : AmazonWebServices.aws-vsts-tools.AWSShellScript.AWSShellScript@1
                displayName: deploy
                env        :
                  VARIBLE_1 : $(variable_2)
                inputs     :
                  awsCredentials      : $(service_connection_name)
                  regionName          : $(aws_region)
                  failOnStandardError : false
                  args                : ""
                  scriptType          : inline
                  #disableAutoCwd     : true
                  #workingDirectory   : $(Agent.BuildDirectory)/myrepo
                  inlineScript        : |
                    #!/bin/bash
                    sudo apt update  -qq
                    sudo apt install -qq tree
                    printf '\n[DEBUG] $SHELL       : %s' "$SHELL"
                    printf '\n[DEBUG] $BASH_VERSION: %s' "$BASH_VERSION"
                    printf '\n[DEBUG] $PDW         : %s' "$PWD"
                    printf '\n[DEBUG] $ENVIRONMENT=%s\n' "${ENVIRONMENT}"
                    printf '\n[DEBUG] $..(..Agent.BuildDirectory): %s' "$(Agent.BuildDirectory)"
                    printf '\n[DEBUG] pwd; ls -la\n'               ; pwd; ls -la
                    printf '\n[DEBUG] ls -la ../helm-charts\n'     ; ls -la ../helm-charts
                    printf '\n[DEBUG] ls -la ../s\n'               ; ls -la ../s
                    printf '\n[DEBUG] find ../.. -iname file.sh\n' ; find ../.. -iname file.sh
                    printf '\n[DEBUG] tree -aL 2 ..\n'             ; tree -aL 2 ..

                    time source  $(Agent.BuildDirectory)/myrepo/scripts/file.sh
                    #time source      $(Build.SourcesDirectory)/scripts/file.sh

Pipeline variables and secrets

Variables.md are available in expressions as well as scripts; see variables to learn more about how to use them. There are some predefined build and release variables you can also rely on. Syntax

regionName    : "${{ variables.aws_region }}"
regionName    : $(aws_region)

# set Dynamic Variable Secret
$token = curl ...
echo "##vso[task.setvariable variable=accesstoken;isSecret=true]$token"

# print secrets, the value vertically if you print them as chars:
$Password.ToCharArray()


Resources:

Pipeline tasks

Stage

<syntaxhighlightjs lang=yaml> stages:

 - stage      : deploy_helm
   displayName: deploy_helm
   jobs       :
     - job        : deploy_helm
       displayName: deploy_helm
       steps      :
         - task       : AmazonWebServices.aws-vsts-tools.AWSShellScript.AWSShellScript@1
           displayName: "deploy_helm"
           env        :
             DBPASSWORD : $(auth_service_client_secret)
             VALUES_PATH: $(values-path)
           inputs     :
           # https://github.com/aws/aws-toolkit-azure-devops/blob/master/Tasks/AWSShellScript/task.json
             awsCredentials: $(aws_creds)
             regionName          : $(aws_region)
             #failOnStandardError: true # default: false
             #disableAutoCwd     : true # default: false, The default behavior is to set the working directory to the script location
             #workingDirectory   : $(Build.SourcesDirectory) # | This enables you to optionally specify a different working directory.
             scriptType          : inline # default: filePath
             #filePath           : $(Build.SourcesDirectory)/scripts/connect.sh
             inlineScript        : |
               #!/bin/bash
               printf "\n[DEBUG] PWD: %s" "$PWD"
               time source $(Build.SourcesDirectory)/scripts/connect.sh || \
                 { printf "\n[ERROR] to connect"; exit 1; }
             args                : "" # Arguments passed to the shell script

</syntaxhighlightjs>

Conditions

parameters:
- name: enabled
  type: boolean
  default: false

stages:
  - stage: ${{ parameters.stage_name_prefix }}_build
    condition: and(succeeded(), eq('${{ parameters.enabled }}', 'true'))
    displayName: ${{parameters.stage_display_name}}
    jobs:

Logging and formatting in the pipeline

##[group]Beginning of a group
##[warning]Warning message
##[error]Error message
##[debug]Debug text
##[command]Command-line being run
##[endgroup]

Resources

Code Assessment Tools