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

test: Repurpose ADO release pipeline as integration testing pipeline #703

Merged
merged 25 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
406c79d
Try repurposing release pipeline as a test pipeline
c-ryan-k May 21, 2024
39a6a4b
remove entire release stage
c-ryan-k May 21, 2024
cfd15cd
Merge branch 'Azure:dev' into ado_tests
c-ryan-k May 28, 2024
beac095
try faster failures, no parallelization on central tests
c-ryan-k May 29, 2024
eec4fdd
remove maxFail from central tests
c-ryan-k May 29, 2024
40ce77b
break out adu update tets
c-ryan-k May 29, 2024
04f8daa
No need for RG role assignment of data contributor
c-ryan-k May 29, 2024
77b99f4
update some defaults, timeouts, etc
c-ryan-k May 30, 2024
65339e7
Add github workflow to trigger ADO pipeline
c-ryan-k May 30, 2024
3dd8efa
remove debug switch and change to correct branch
c-ryan-k May 30, 2024
37fb3df
stringify python mapping
c-ryan-k May 30, 2024
2b6d11a
more quotes
c-ryan-k May 30, 2024
f5e0db1
python stringification testing
May 30, 2024
fc87e49
Put ADU tests back in parallelization
c-ryan-k May 30, 2024
fe787ae
add integration tests to release workflow
c-ryan-k May 31, 2024
b7098ed
Disable 1ES pool for pipeline test
c-ryan-k May 31, 2024
116b750
quotes
c-ryan-k May 31, 2024
bb44939
Removed unused steps and params
c-ryan-k Jun 4, 2024
b41d83b
Remove JIT role assignment due to graph permissions query in 'role as…
c-ryan-k Jun 4, 2024
d7a418d
remove extra unused line
c-ryan-k Jun 4, 2024
307357f
Remove log streaming capability from external pipeline caller workflow
c-ryan-k Jun 4, 2024
41bdb96
Revert "Disable 1ES pool for pipeline test"
c-ryan-k Jun 4, 2024
4068ec0
Use github branch ref to pick which branch to run pipeline from
c-ryan-k Jun 5, 2024
c1545cb
Merge branch 'dev' into ado_tests
c-ryan-k Jun 6, 2024
abe721b
Merge branch 'dev' into ado_tests
c-ryan-k Jun 6, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@ parameters:
- name: variableGroup
type: string
default: 'aziotcli_test_primary'
- name: buildAgentPoolVar
type: string
default: 'BuildAgentPool'
- name: buildAgentVmImageVar
type: string
default: 'BuildAgentVmImage'
- name: testAgentVmImage
type: string
default: 'ubuntu-20.04'
default: 'ubuntu-22.04'
values:
- 'ubuntu-20.04'
- 'ubuntu-22.04'
- 'ubuntu-latest'
- name: pythonVersion
displayName: 'Python version for building wheel, KPIs'
type: string
default: '3.8'
default: '3.9'
values:
- '3.8'
- '3.9'
Expand Down Expand Up @@ -69,10 +63,6 @@ parameters:

variables:
- group: ${{ parameters.variableGroup }}
- name: vmImage
value: $[variables.${{ parameters.buildAgentVmImageVar }}]
- name: buildPool
value: $[variables.${{ parameters.buildAgentPoolVar }}]

stages:
- stage: 'build'
Expand All @@ -81,10 +71,7 @@ stages:

- job: 'Build_Publish_Azure_IoT_CLI_Extension'
pool:
name: $(buildPool)
vmImage: $(vmImage)
demands:
- ImageOverride -equals $(vmImage)
vmImage: ubuntu-latest
steps:
- task: UsePythonVersion@0
inputs:
Expand Down Expand Up @@ -148,7 +135,6 @@ stages:
# displayName: 'Validate Reference Document Generation'
# steps:
# - template: templates/validate-refdoc-generation.yml

- stage: 'smokeTest'
displayName: 'Run smoke tests'
dependsOn: test
Expand All @@ -172,62 +158,4 @@ stages:
- template: templates/calculate-code-coverage.yml
parameters:
pythonVersion: ${{ parameters.pythonVersion }}
architecture: ${{ parameters.architecture }}

- stage: 'release'
displayName: 'Stage GitHub release'
dependsOn: build
condition: and(succeeded(), eq(${{ parameters.stageForPublish }}, 'true'))
jobs:
- deployment: 'StageGitHub'
displayName: 'Stage CLI extension on GitHub'
environment: 'production'

- job: 'Calculate_Sha_And_Create_Release'
displayName: 'Calculate package hash and publish'
pool:
name: $(buildPool)
vmImage: $(vmImage)
demands:
- ImageOverride -equals $(vmImage)
variables:
CLIVersion: $[ stageDependencies.build.recordVersion.outputs['setupVersion.CLIVersion'] ]
ReleaseTitle: $[ stageDependencies.build.recordVersion.outputs['setupVersion.ReleaseTitle'] ]

steps:
- task: DownloadBuildArtifacts@0
displayName : 'Download Extension wheel from Build Artifacts'
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'azure-iot'
downloadPath: '$(System.ArtifactsDirectory)/extension'

- task: PowerShell@2
displayName: 'Calculate sha for downloaded extension'
inputs:
targetType: 'inline'
script: |
$extensions = Get-ChildItem -Filter "*.whl" -Recurse | Select-Object FullName
Foreach ($extension in $extensions)
{
Write-Host "calculating sha256 for " $extension.FullName
(Get-Filehash -Path $extension.Fullname -Algorithm SHA256).Hash.ToLower()
}
Write-Host "done"
workingDirectory: '$(System.ArtifactsDirectory)/extension'

- task: GitHubRelease@1
inputs:
gitHubConnection: $(GithubReleaseConnection)
repositoryName: $(Build.Repository.Name)
action: 'create'
target: '$(Build.SourceVersion)'
tagSource: userSpecifiedTag
tag: 'v$(CLIVersion)'
title: $(ReleaseTitle)
assets: '$(System.ArtifactsDirectory)/extension/**/*.whl'
assetUploadMode: 'replace'
isDraft: true
isPreRelease: false
addChangeLog: false
architecture: ${{ parameters.architecture }}
6 changes: 5 additions & 1 deletion .azure-devops/templates/run-tests-parallel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ parameters:
- name: parallel_execution_dirs
type: object
default:
- 'azext_iot/tests/central'
- 'azext_iot/tests/digitaltwins'
- 'azext_iot/tests/deviceupdate'

Expand Down Expand Up @@ -81,6 +80,11 @@ steps:
inlineScript: |
export COVERAGE_FILE=.coverage.${{ parameters.name }}
pytest -vv ${{ parameters.path }} -k "_int.py" --dist=loadfile -n ${{ parameters.num_threads }} --reruns ${{ parameters.num_reruns }} --reruns-delay ${{ parameters.reruns_delay }} --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-int.xml --durations=0
# remove parallelization from central tests
${{ if contains(parameters.path, 'azext_iot/tests/central') }}:
inlineScript: |
export COVERAGE_FILE=.coverage.${{ parameters.name }}
pytest -vv ${{ parameters.path }} -k "_int.py" --cov=azext_iot --cov-config .coveragerc --junitxml=junit/test-iotext-int.xml
${{ if contains(parameters.path, 'azext_iot/tests/iothub') }}:
inlineScript: |
export COVERAGE_FILE=.coverage.${{ parameters.name }}
Expand Down
8 changes: 4 additions & 4 deletions .azure-devops/templates/trigger-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
serviceConnection: $(AzureServiceConnection)

- job: 'testHub_job_1'
timeoutInMinutes: 105
timeoutInMinutes: 120
displayName: 'Test IoT Hub - certificate, config, core, jobs, state'
condition: and(succeeded(), eq('${{ parameters.testHub }}', true))
strategy:
Expand All @@ -109,7 +109,7 @@ jobs:
serviceConnection: $(AzureServiceConnection)

- job: 'testHub_job_2'
timeoutInMinutes: 90
timeoutInMinutes: 120
condition: and(succeeded(), eq('${{ parameters.testHub }}', true))
displayName: 'Test IoT Hub - devices, message endpoints, messaging, and modules'
strategy:
Expand All @@ -126,7 +126,7 @@ jobs:

- job: 'testADU'
timeoutInMinutes: 200
displayName: 'Test Azure Device Update'
displayName: 'Test ADU'
condition: and(succeeded(), eq('${{ parameters.testADU }}', true))
strategy:
matrix: $[ variables['pythonVersions'] ]
Expand All @@ -139,7 +139,7 @@ jobs:
azureCLIVersion: ${{ parameters.azureCLIVersion }}
pythonVersion: $(python)
num_reruns: 0
serviceConnection: $(AzureServiceConnectionAlt)
serviceConnection: $(AzureServiceConnection)

- job: 'unitTests'
displayName: 'Unit tests and code coverage'
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ jobs:
uses: ./.github/workflows/azdev_linter.yml
with:
continue-on-error: ${{ github.event.inputs.continue-on-error == 'true' }}
int_test:
needs: [build]
uses: ./.github/workflows/trigger_ado_int_tests.yml
secrets: inherit
approval:
needs: [security, build, unit-test, azdev_linter]
# only needed if (release || wheel) - conditionals allow previous jobs to be skipped and still run
Expand Down
191 changes: 191 additions & 0 deletions .github/workflows/trigger_ado_int_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: Run Azure DevOps Integration Tests
on:
workflow_call:
inputs:
testCentral:
description: Run Central tests
type: boolean
default: true
testADT:
description: Run ADT tests
type: boolean
default: true
testDPS:
description: Run DPS tests
type: boolean
default: true
testHub:
description: Run Hub tests
type: boolean
default: true
testADU:
description: Run ADU tests
type: boolean
default: true
python_versions:
description: "Python versions to test"
type: string
default: >
"{
Python38: { python: '3.8' },
Python39: { python: '3.9' },
Python310: { python: '3.10' }
}"
secrets:
ADO_PAT:
required: true
workflow_dispatch:
inputs:
testCentral:
description: Run Central tests
type: boolean
default: true
testADT:
description: Run ADT tests
type: boolean
default: true
testDPS:
description: Run DPS tests
type: boolean
default: true
testHub:
description: Run Hub tests
type: boolean
default: true
testADU:
description: Run ADU tests
type: boolean
default: true
python_versions:
description: "Python versions to test"
required: true
type: string
default: >
"{
Python38: { python: '3.8' },
Python39: { python: '3.9' },
Python310: { python: '3.10' }
}"
env:
DEFAULT_TITLE: "Azure DevOps Pipeline"
AZURE_DEVOPS_EXT_PAT: ${{ secrets.ADO_PAT }}
DEFINITION_ID: 147
ORG: azureiotdevxp
PROJECT: aziotcli
jobs:
call-ado-pipeline:
runs-on: ubuntu-latest
name: Run integration tests
outputs:
runId: ${{ steps.start.outputs.runId }}
portalUrl: ${{ steps.start.outputs.portalUrl }}
url: ${{ steps.start.outputs.url }}
steps:
- shell: bash
id: start
name: Trigger the pipeline
run: |-
set -ex
if [ -z "$ORG" ]; then
echo "::error::Organization is required"
exit 1
fi
if [ -z "$PROJECT" ]; then
echo "::error::Project is required"
exit 1
fi

cmdArgs=(--org "https://dev.azure.com/$ORG" --project "$PROJECT" --branch "${{ github.ref }}")

if [ -n "$DEFINITION_ID" ]; then
cmdArgs+=(--id "$DEFINITION_ID")
else
echo "::error::Pipeline definition ID must be provided"
exit 1
fi

python_versions=${{inputs.python_versions}}
python_version_strings=$(echo $python_versions | jq -R .)
cmdArgs+=("--parameters")
cmdArgs+=("pythonVersionsTestingMatrix=$python_version_strings")
cmdArgs+=("testCentral=${{inputs.testCentral}}")
cmdArgs+=("testADT=${{inputs.testADT}}")
cmdArgs+=("testDPS=${{inputs.testDPS}}")
cmdArgs+=("testHub=${{inputs.testHub}}")
cmdArgs+=("testADU=${{inputs.testADU}}")
echo "Running: az pipelines run ${cmdArgs[@]}"
res=$(az pipelines run "${cmdArgs[@]}")

if [ -z "$res" ]; then
echo "::error::Failed to trigger the pipeline"
fi
runId=$(echo $res | jq -r '.id')
portalUrl="https://dev.azure.com/$ORG/$PROJECT/_build/results?buildId=$runId&view=results"
url=$(echo $res | jq -r '.url')
echo "runId=$runId" >> $GITHUB_OUTPUT
echo "portalUrl=$portalUrl" >> $GITHUB_OUTPUT
echo "url=$url" >> $GITHUB_OUTPUT
- name: Summary
id: summary
run: |-
echo "# ${PIPELINE:-$DEFAULT_TITLE} Started" >> $GITHUB_STEP_SUMMARY
echo "## Azure DevOps Pipeline" >> $GITHUB_STEP_SUMMARY
echo "You can follow the progress [here](${{ steps.start.outputs.portalUrl }})" >> $GITHUB_STEP_SUMMARY

wait-for-completion:
runs-on: ubuntu-latest
name: Wait for the pipeline to complete
needs: [call-ado-pipeline]
env:
RUN_ID: ${{ needs.call-ado-pipeline.outputs.runId }}
PORTAL_URL: ${{ needs.call-ado-pipeline.outputs.portalUrl }}
steps:
- name: Wait for the pipeline to complete
run: |
set -e
runId="${{ needs.call-ado-pipeline.outputs.runId }}"
status="none"
result="none"
lastLog=1
while [[ "$status" =~ (inProgress|notStarted|postponed|none) ]]; do
sleep 60
res=$(az pipelines runs show --id "$RUN_ID" --org "https://dev.azure.com/$ORG" --project "$PROJECT")
status=$(echo "$res" | jq -r '.status')
result=$(echo "$res" | jq -r '.result')
done

# if status is not completed, or the result is one of failed, canceled; then fail the job
if [[ "$status" != "completed" || "$result" =~ (failed|canceled) ]]; then
echo "::error::Pipeline did not complete successfully"
echo "# ❌ ${PIPELINE:-$DEFAULT_TITLE} Failed ❌" >> $GITHUB_STEP_SUMMARY
echo "The pipeline did not complete successfully. Please check the logs [here](${PORTAL_URL})" >> $GITHUB_STEP_SUMMARY
exit 1
fi

echo "# ✅ ${PIPELINE:-$DEFAULT_TITLE} Completed ✅" >> $GITHUB_STEP_SUMMARY
echo "The pipeline completed successfully. You can check the logs [here](${PORTAL_URL})" >> $GITHUB_STEP_SUMMARY
CancelPipeline:
runs-on: ubuntu-latest
needs: [call-ado-pipeline, wait-for-completion]
if: cancelled()
env:
RUN_ID: ${{ needs.call-ado-pipeline.outputs.runId }}
RUN_URL: ${{ needs.call-ado-pipeline.outputs.url }}
PORTAL_URL: ${{ needs.call-ado-pipeline.outputs.portalUrl }}
steps:
- name: Cancel the pipeline
run: |
set -ex
if [[ -z "$RUN_ID" ]]; then
echo "No pipeline to cancel"
exit 0
fi

curl \
-X PATCH \
-u ":$AZURE_DEVOPS_EXT_PAT" \
-H "Content-Type: application/json" \
-d '{"status": "cancelling"}' \
"${RUN_URL}?api-version=7.2-preview.7"
echo "# ❌ ${PIPELINE:-$DEFAULT_TITLE} Cancelled ❌" >> $GITHUB_STEP_SUMMARY
echo "The pipeline was cancelled. You can check the logs [here](${PORTAL_URL})" >> $GITHUB_STEP_SUMMARY
Loading
Loading