Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#171549850] add azure pipeline #594

Merged
merged 3 commits into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 251 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
# Azure DevOps pipeline to build, check source codes, run tests, and deploy.
#
# To enable the check of source code with Danger JS you need to configure a valid
# GitHub token by setting the following variable:
# - DANGER_GITHUB_API_TOKEN
# To download build dependencies from GitHub package registry you also need to set
# a GitHub token for the following variable:
# - GITHUB_TOKEN
#
# To enable the deployment in any environment you need to configure the following
# variable otherwise all the deployment jobs will be always skipped:
# - DO_DEPLOY = true
# in case of a manual run, you also need to configure the following additional
# variables based on the environment to update:
# - STAGING_ENABLE_MANUAL_DEPLOY = true
# - PRODUCTION_ENABLE_MANUAL_DEPLOY = true
#
# The following variables are also used when running the deployment jobs:
# - STAGING_DEPLOY_MODE: 'deploy_standard' || 'deploy_to_slots'
# - STAGING_AZURE_SUBSCRIPTION
# - STAGING_RESOURCE_GROUP_NAME
# - STAGING_APP_NAME
#
# - PRODUCTION_DEPLOY_MODE: 'deploy_standard' || 'deploy_to_slots'
# - PRODUCTION_AZURE_SUBSCRIPTION
# - PRODUCTION_RESOURCE_GROUP_NAME
# - PRODUCTION_APP_NAME
#

variables:
NODE_VERSION: '10.14.2'
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

# This pipeline can be manually run or is automatically triggered whenever one
# of the following conditions is true:
# - a push is made to any branch in the repository (not only 'master')
# - a pull request is created
# - a tag named 'latest' is pushed
# Note. In the last case, the tag can be (re-)created using the Git CLI, e.g.:
# git push -f origin <abfb967>:refs/tags/latest
trigger:
branches:
include:
- '*'
- refs/tags/latest

# This pipeline has been implemented to be run on hosted agent pools based both
# on 'windows' and 'ubuntu' virtual machine images and using the scripts defined
# in the package.json file. Since we are deploying on Azure Web app on Windows
# runtime, the pipeline is currently configured to use a Windows hosted image for
# verifying the build and deploying, and Linux OS for all other jobs for faster
# execution.
pool:
vmImage: 'ubuntu-latest'

stages:
# A) Build and code validation (always run)
- stage: Build
dependsOn: []
jobs:
# A1) Checkout, install module and build code (use Windows OS)
- job: make_build
pool:
vmImage: 'windows-2019'
steps:
- template: azure-templates/make-build-steps.yml
parameters:
make: build

# A2) Analyze source code to find errors with lint
- job: lint
steps:
- template: azure-templates/make-build-steps.yml
parameters:
make: install_dependencies

- script: |
yarn lint
displayName: 'Lint'

# A3) Validate API definitions
- job: lint_api
steps:
- task: UseNode@1
inputs:
version: $(NODE_VERSION)
displayName: 'Set up Node.js'

- bash: |
yarn add oval --dev
npx oval validate -p api_notifications.yaml
npx oval validate -p api_pagopa.yaml
npx oval validate -p api_backend.yaml
npx oval validate -p api_public.yaml
displayName: 'Validate openAPI'

# A4) Check source code with danger (ignore when master)
- job: danger
condition: and(succeeded(),
and(
variables['DANGER_GITHUB_API_TOKEN'],
ne(variables['Build.SourceBranch'], 'refs/heads/master')
)
)
steps:
- template: azure-templates/make-build-steps.yml
parameters:
make: install_dependencies

- bash: |
yarn danger ci
displayName: 'Danger CI'


# B) Run unit tests (use Linux OS, also required to generate certificates)
- stage: Test
dependsOn: []
jobs:
- job: unit_tests
steps:
- template: azure-templates/make-build-steps.yml
parameters:
make: build-noemit

- script: |
yarn generate:test-certs
displayName: 'Generate test certificates'

- script: |
yarn test:coverage
displayName: 'Unit tests exec'

- bash: |
bash <(curl -s https://codecov.io/bash)
displayName: 'Code coverage'


# C) Deploy to STAGE environment if the following conditions apply (use Windows OS):
# - continuos deployment (automatic):
# - $DO_DEPLOY == true and
# - there is a push on 'master' branch
# - manual deployment:
# - $DO_DEPLOY == true and
# - $STAGING_ENABLE_MANUAL_DEPLOY == true
# The following alternative deployment modes are supported:
# a) $STAGING_DEPLOY_MODE == 'deploy_standard': deploy to 'prodution' slot
# b) $STAGING_DEPLOY_MODE == 'deploy_to_slots': deploy to 'staging' slot and
# then swap 'staging' slot with 'production' slot
- stage: Deploy_staging
pool:
vmImage: 'windows-2019'
condition:
and(
succeeded(),
and (
eq(variables['DO_DEPLOY'], true),
or(
and(
eq(variables['Build.SourceBranch'], 'refs/heads/master'),
ne(variables['Build.Reason'], 'Manual')
),
and(
eq(variables['STAGING_ENABLE_MANUAL_DEPLOY'], true),
eq(variables['Build.Reason'], 'Manual')
)
)
)
)
dependsOn:
- Build
- Test
jobs:
# Option 1: deploy directly to 'production' slot
- job: deploy_standard
condition: and(succeeded(), eq(variables['STAGING_DEPLOY_MODE'], 'deploy_standard'))
steps:
- template: azure-templates/deploy-steps.yml
parameters:
deployType: 'deployToProductionSlot'
azureSubscription: '$(STAGING_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(STAGING_RESOURCE_GROUP_NAME)'
appName: '$(STAGING_APP_NAME)'

# Option 2: deploy to staging slot and then swap with 'production' slot
- job: deploy_to_slots
condition: and(succeeded(), eq(variables['STAGING_DEPLOY_MODE'], 'deploy_to_slots'))
steps:
- template: azure-templates/deploy-steps.yml
parameters:
deployType: 'deployToStagingSlotAndSwap'
azureSubscription: '$(STAGING_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(STAGING_RESOURCE_GROUP_NAME)'
appName: '$(STAGING_APP_NAME)'


# D) Deploy to PRODUCTION environment if the following conditions apply (use Windows OS):
# - continuos deployment (automatic):
# - $DO_DEPLOY == true and
# - the 'latest' tag is pushed
# - manual deployment:
# - $DO_DEPLOY == true and
# - $PRODUCTION_ENABLE_MANUAL_DEPLOY == true
# The following alternative deployment modes are supported:
# a) $PRODUCTION_DEPLOY_MODE == 'deploy_standard': deploy to 'prodution' slot
# b) $PRODUCTION_DEPLOY_MODE == 'deploy_to_slots': deploy to 'staging' slot and
# then swap 'staging' slot with 'production' slot
- stage: Deploy_production
pool:
vmImage: 'windows-2019'
condition:
and(
succeeded(),
and (
eq(variables['DO_DEPLOY'], true),
or(
and(
eq(variables['Build.SourceBranch'], 'refs/tags/latest'),
ne(variables['Build.Reason'], 'Manual')
),
and(
eq(variables['PRODUCTION_ENABLE_MANUAL_DEPLOY'], true),
eq(variables['Build.Reason'], 'Manual')
)
)
)
)
dependsOn:
- Build
- Test
jobs:
# Option 1: deploy directly to 'production' slot
- job: deploy_standard
condition: and(succeeded(), eq(variables['PRODUCTION_DEPLOY_MODE'], 'deploy_standard'))
steps:
- template: azure-templates/deploy-steps.yml
parameters:
deployType: 'deployToProductionSlot'
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(PRODUCTION_RESOURCE_GROUP_NAME)'
appName: '$(PRODUCTION_APP_NAME)'

# Option 2: deploy to staging slot and then swap with 'production' slot
- job: deploy_to_slots
condition: and(succeeded(), eq(variables['PRODUCTION_DEPLOY_MODE'], 'deploy_to_slots'))
steps:
- template: azure-templates/deploy-steps.yml
parameters:
deployType: 'deployToStagingSlotAndSwap'
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(PRODUCTION_RESOURCE_GROUP_NAME)'
appName: '$(PRODUCTION_APP_NAME)'
106 changes: 106 additions & 0 deletions azure-templates/deploy-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Azure DevOps template used to perform all the deploy steps including build.
#
# Note. Deployment slots let you deploy different versions of your Web app
# to different URLs. You can test a certain version and then swap content
# and configuration between slots to have minimal impact to production and also
# make rollback easily.

parameters:
- name: 'deployType'
type: string
default: deployToProductionSlot
values:
- deployToProductionSlot
- deployToStagingSlotAndSwap
- deployToStagingSlot

- name: 'azureSubscription'
type: string
default: ''

- name: 'resourceGroupName'
type: string
default: ''

- name: 'appName'
type: string
default: ''

steps:
- template: ./make-build-steps.yml
parameters:
make: predeploy_build

- task: CopyFiles@2
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
Contents: |
**/*
!.git/**/*
!.vscode/**/*
![.]*
!scripts/**/*
!**/*.js.map
!**/*.ts
!azure-templates/**/*
!azure-pipelines.yml
!*.md
!docker-compose.yml
!Dangerfile.ts
!jest.config.js
!local.settings.json
!test
!tslint.json
!tsconfig.json
displayName: 'Copy deploy files'

# Option 1: standard deployment without slots (i.e. deploy directly to main slot)
- ${{ if eq(parameters.deployType, 'deployToProductionSlot') }}:
- task: AzureWebApp@1
inputs:
azureSubscription: '${{ parameters.azureSubscription }}'
resourceGroupName: '${{ parameters.resourceGroupName }}'
appType: 'webApp'
appName: '${{ parameters.appName }}'
package: '$(Build.ArtifactStagingDirectory)/'
deploymentMethod: 'auto'
displayName: Direct deploy

# Option 2: deployment to 'staging' slot only (not used)
- ${{ if eq(parameters.deployType, 'deployToStagingSlot') }}:
- task: AzureWebApp@1
inputs:
azureSubscription: '${{ parameters.azureSubscription }}'
resourceGroupName: '${{ parameters.resourceGroupName }}'
appType: 'webApp'
appName: '${{ parameters.appName }}'
package: '$(Build.ArtifactStagingDirectory)/'
deploymentMethod: 'auto'
deployToSlotOrASE: true
slotName: 'staging'
displayName: Deploy to staging slot only

# Option 3: deployment with two slots ('staging' and 'production')
- ${{ if eq(parameters.deployType, 'deployToStagingSlotAndSwap') }}:
- task: AzureWebApp@1 # First step: deploy to 'staging' slot
inputs:
azureSubscription: '${{ parameters.azureSubscription }}'
resourceGroupName: '${{ parameters.resourceGroupName }}'
appType: 'webApp'
appName: '${{ parameters.appName }}'
package: '$(Build.ArtifactStagingDirectory)/'
deploymentMethod: 'auto'
deployToSlotOrASE: true
slotName: 'staging'
displayName: Deploy to staging slot

- task: AzureAppServiceManage@0 # Second step: swap 'staging' with 'production' slot
inputs:
azureSubscription: '${{ parameters.azureSubscription }}'
resourceGroupName: '${{ parameters.resourceGroupName }}'
webAppName: '${{ parameters.appName }}'
sourceSlot: staging
swapWithProduction: true
displayName: Swap with production slot

Loading