diff --git a/.azure-devops/create-release.yml b/.azure-devops/create-release.yml index 45d869c3b..172b2f159 100644 --- a/.azure-devops/create-release.yml +++ b/.azure-devops/create-release.yml @@ -2,9 +2,28 @@ pr: none trigger: none -variables: - pythonVersion: '3.6.x' - architecture: 'x64' +parameters: +- name: pythonVersion + type: string + default: '3.6.x' + values: + - 3.6.x + - 3.9.x +- name: architecture + type: string + default: 'x64' +- name: 'testCentral' + type: boolean + default: true +- name: 'testADT' + type: boolean + default: true +- name: 'testDPS' + type: boolean + default: true +- name: 'testHub' + type: boolean + default: true stages: - stage: 'build' @@ -13,13 +32,13 @@ stages: - job: 'Build_Publish_Azure_IoT_CLI_Extension' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: - versionSpec: $(pythonVersion) - architecture: $(architecture) + versionSpec: ${{ parameters.pythonVersion }} + architecture: ${{ parameters.architecture }} - template: templates/setup-ci-machine.yml @@ -27,13 +46,13 @@ stages: - job: 'Build_Publish_Azure_CLI_Test_SDK' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: - versionSpec: $(pythonVersion) - architecture: $(architecture) + versionSpec: ${{ parameters.pythonVersion }} + architecture: ${{ parameters.architecture }} - template: templates/setup-ci-machine.yml @@ -45,15 +64,15 @@ stages: steps: - template: templates/setup-dev-test-env.yml parameters: - pythonVersion: $(pythonVersion) - architecture: $(architecture) + pythonVersion: ${{ parameters.pythonVersion }} + architecture: ${{ parameters.architecture }} - template: templates/install-and-record-version.yml - stage: 'test' displayName: 'Run tests' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' dependsOn: build jobs: - job: 'testCentral' @@ -105,8 +124,8 @@ stages: steps: - template: templates/calculate-code-coverage.yml parameters: - pythonVersion: $(pythonVersion) - architecture: $(architecture) + pythonVersion: ${{ parameters.pythonVersion }} + architecture: ${{ parameters.architecture }} - stage: 'release' displayName: 'Stage GitHub release' diff --git a/.azure-devops/merge.yml b/.azure-devops/merge.yml index 6a620155e..e4585386e 100644 --- a/.azure-devops/merge.yml +++ b/.azure-devops/merge.yml @@ -18,7 +18,7 @@ jobs: - job: 'build_and_publish_azure_iot_cli_ext' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 @@ -31,7 +31,7 @@ jobs: - job: 'build_and_publish_azure_cli_test_sdk' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 @@ -45,7 +45,7 @@ jobs: - job: 'run_unit_tests_ubuntu' dependsOn: [ 'build_and_publish_azure_iot_cli_ext', 'build_and_publish_azure_cli_test_sdk'] pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' strategy: matrix: Python36: @@ -62,8 +62,8 @@ jobs: - template: templates/run-tests.yml parameters: pythonVersion: '$(python.version)' - runUnitTests: 'true' - runIntTests: 'false' + runUnitTests: true + runIntTests: false - job: 'run_unit_tests_macOs' dependsOn: ['build_and_publish_azure_iot_cli_ext', 'build_and_publish_azure_cli_test_sdk'] @@ -74,8 +74,8 @@ jobs: - template: templates/run-tests.yml parameters: pythonVersion: '3.8.x' - runUnitTests: 'true' - runIntTests: 'false' + runUnitTests: true + runIntTests: false - template: templates/calculate-code-coverage.yml @@ -93,13 +93,13 @@ jobs: - template: templates/run-tests.yml parameters: pythonVersion: '3.8.x' - runUnitTests: 'true' - runIntTests: 'false' + runUnitTests: true + runIntTests: false - job: 'run_style_check' dependsOn: ['build_and_publish_azure_iot_cli_ext', 'build_and_publish_azure_cli_test_sdk'] pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 @@ -124,7 +124,7 @@ jobs: dependsOn: ['build_and_publish_azure_iot_cli_ext'] displayName: 'Evaluate IoT extension command table' pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 diff --git a/.azure-devops/nightly.yml b/.azure-devops/nightly.yml new file mode 100644 index 000000000..34ce2b14d --- /dev/null +++ b/.azure-devops/nightly.yml @@ -0,0 +1,88 @@ +# Run nightly at midnight. +schedules: +- cron: "0 0 * * *" + displayName: Nightly Integration Build + branches: + include: + - dev + +variables: + pythonVersion: '3.6.x' + architecture: 'x64' + +stages: + - stage: 'build' + displayName: 'Build and Publish Artifacts' + jobs: + + - job: 'Build_Publish_Azure_IoT_CLI_Extension' + pool: + vmImage: 'ubuntu-latest' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: $(pythonVersion) + architecture: $(architecture) + + - template: templates/setup-ci-machine.yml + + - template: templates/build-publish-azure-iot-cli-extension.yml + + - job: 'Build_Publish_Azure_CLI_Test_SDK' + pool: + vmImage: 'ubuntu-latest' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: $(pythonVersion) + architecture: $(architecture) + + - template: templates/setup-ci-machine.yml + + - template: templates/build-publish-azure-cli-test-sdk.yml + + - job: 'recordVersion' + displayName: 'Install and verify version' + dependsOn: [Build_Publish_Azure_IoT_CLI_Extension, Build_Publish_Azure_CLI_Test_SDK] + steps: + - template: templates/setup-dev-test-env.yml + parameters: + pythonVersion: $(pythonVersion) + architecture: $(architecture) + + - template: templates/install-and-record-version.yml + + - stage: 'test' + displayName: 'Run all tests' + pool: + vmImage: 'ubuntu-latest' + dependsOn: build + jobs: + - job: 'azEdge' + displayName: 'Test against edge AZ CLI' + steps: + - template: templates/nightly-tests.yml + parameters: + azureCLIVersion: 'edge' + - job: 'azMin' + dependsOn: 'azEdge' + displayName: 'Test against minimum supported AZ CLI' + steps: + - template: templates/nightly-tests.yml + parameters: + azureCLIVersion: 'min' + + - stage: 'kpi' + displayName: 'Build KPIs' + dependsOn: [build, test] + jobs: + - job: 'calculateCodeCoverage' + displayName: 'Calculate distributed code coverage' + steps: + - template: templates/calculate-code-coverage.yml + parameters: + pythonVersion: $(pythonVersion) + architecture: $(architecture) + diff --git a/.azure-devops/templates/install-azure-cli-min.yml b/.azure-devops/templates/install-azure-cli-min.yml new file mode 100644 index 000000000..ad25dfbaf --- /dev/null +++ b/.azure-devops/templates/install-azure-cli-min.yml @@ -0,0 +1,14 @@ +steps: +- task: PythonScript@0 + displayName: 'Check minimum supported version of Azure CLI' + inputs: + scriptSource: 'inline' + script: | + import json + with open("$(System.DefaultWorkingDirectory)/azext_iot/azext_metadata.json") as f: + metadata = json.load(f) + version = metadata['azext.minCliCoreVersion'] + print('##vso[task.setvariable variable=min_cli_version]{}'.format(version)) +- bash: | + pip install azure-cli==$(min_cli_version) + displayName: "Install minimum supported CLI version" \ No newline at end of file diff --git a/.azure-devops/templates/nightly-tests.yml b/.azure-devops/templates/nightly-tests.yml new file mode 100644 index 000000000..baaa94e6a --- /dev/null +++ b/.azure-devops/templates/nightly-tests.yml @@ -0,0 +1,55 @@ +parameters: +- name: pythonVersion + type: string + default: '3.6.x' +- name: architecture + type: string + default: 'x64' +- name: azureCLIVersion + type: string + default: released + values: + - min + - released + - edge + +steps: + - template: setup-dev-test-env.yml + parameters: + architecture: ${{ parameters.architecture }} + pythonVersion: ${{ parameters.pythonVersion }} + azureCLIVersion: ${{ parameters.azureCLIVersion }} + + - template: set-testenv-sentinel.yml + + - script: | + pytest -vv azext_iot/tests -k "_unit" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-unit.xml + displayName: 'All unit tests' + env: + COVERAGE_FILE: .coverage.all + + - task: AzureCLI@2 + continueOnError: true + displayName: 'All integration tests' + inputs: + azureSubscription: az-cli-nightly + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + export COVERAGE_FILE=.coverage.all + pytest -vv azext_iot/tests -k "_int" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-int.xml + + - task: PublishBuildArtifacts@1 + inputs: + pathToPublish: .coverage.all + publishLocation: 'Container' + artifactName: 'coverage' + + - task: PublishTestResults@2 + condition: succeededOrFailed() + displayName: 'Publish Test Results' + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: '**/test-*.xml' + testRunTitle: 'Publish test results for Python ${{ parameters.pythonVersion }} on OS $(Agent.OS)' + searchFolder: '$(System.DefaultWorkingDirectory)' diff --git a/.azure-devops/templates/run-tests.yml b/.azure-devops/templates/run-tests.yml index 91db4af4f..dec6cc9f9 100644 --- a/.azure-devops/templates/run-tests.yml +++ b/.azure-devops/templates/run-tests.yml @@ -1,21 +1,46 @@ parameters: - pythonVersion: '3.6.x' - architecture: 'x64' - runUnitTests: 'false' - runIntTests: 'true' - runWithAzureCliReleased: 'true' - path: 'azext_iot/tests' - name: 'all' +- name: pythonVersion + type: string + default: '3.6.x' +- name: architecture + type: string + default: 'x64' +- name: runUnitTests + type: boolean + default: false +- name: runIntTests + type: boolean + default: true +- name: azureCLIVersion + type: string + default: released + values: + - min + - released + - edge +- name: path + type: string + default: 'azext_iot/tests' +- name: name + type: string + default: 'all' steps: - template: setup-dev-test-env.yml parameters: architecture: ${{ parameters.architecture }} pythonVersion: ${{ parameters.pythonVersion }} - runWithAzureCliReleased: ${{ parameters.runWithAzureCliReleased }} + azureCLIVersion: ${{ parameters.azureCLIVersion }} - template: set-testenv-sentinel.yml + - ${{ if eq(parameters.runUnitTests, 'true') }}: + - script: | + pytest -vv ${{ parameters.path }} -k "_unit" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-unit-${{ parameters.name }}.xml + displayName: '${{ parameters.name }} unit tests' + env: + COVERAGE_FILE: .coverage.${{ parameters.name }} + - ${{ if eq(parameters.runIntTests, 'true') }}: - task: AzureCLI@2 continueOnError: true @@ -28,13 +53,6 @@ steps: export COVERAGE_FILE=.coverage.${{ parameters.name }} pytest -vv ${{ parameters.path }} -k "_int" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-int-${{ parameters.name }}.xml - - ${{ if eq(parameters.runUnitTests, 'true') }}: - - script: | - pytest -vv ${{ parameters.path }} -k "_unit" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-unit-${{ parameters.name }}.xml - displayName: '${{ parameters.name }} unit tests' - env: - COVERAGE_FILE: .coverage.${{ parameters.name }} - - task: PublishBuildArtifacts@1 inputs: pathToPublish: .coverage.${{ parameters.name }} diff --git a/.azure-devops/templates/setup-dev-test-env.yml b/.azure-devops/templates/setup-dev-test-env.yml index cc6c1a875..029613517 100644 --- a/.azure-devops/templates/setup-dev-test-env.yml +++ b/.azure-devops/templates/setup-dev-test-env.yml @@ -1,7 +1,17 @@ parameters: - pythonVersion: '' - architecture: '' - runWithAzureCliReleased: 'true' +- name: pythonVersion + type: string + default: '3.6.x' +- name: architecture + type: string + default: 'x64' +- name: azureCLIVersion + type: string + default: 'released' + values: + - min + - released + - edge steps: - task: UsePythonVersion@0 @@ -9,12 +19,15 @@ steps: versionSpec: ${{ parameters.pythonVersion }} architecture: ${{ parameters.architecture }} - - ${{ if eq(parameters.runWithAzureCliReleased, 'false') }}: - - template: install-azure-cli-edge.yml + - ${{ if eq(parameters.azureCLIVersion, 'min') }}: + - template: install-azure-cli-min.yml - - ${{ if eq(parameters.runWithAzureCliReleased, 'true') }}: + - ${{ if eq(parameters.azureCLIVersion, 'released') }}: - template: install-azure-cli-released.yml + - ${{ if eq(parameters.azureCLIVersion, 'edge') }}: + - template: install-azure-cli-edge.yml + - template: download-install-local-azure-test-sdk.yml - template: setup-ci-machine.yml