From e29d5d0d7bdb74508de9a0e9f5b834f13f5f7faf Mon Sep 17 00:00:00 2001 From: Chase King Date: Tue, 11 Mar 2025 14:41:00 -0400 Subject: [PATCH] Moved changes to main pipeline --- azure-pipelines-automated-testing.yml | 474 -------------------------- azure-pipelines.yml | 49 +-- 2 files changed, 26 insertions(+), 497 deletions(-) delete mode 100644 azure-pipelines-automated-testing.yml diff --git a/azure-pipelines-automated-testing.yml b/azure-pipelines-automated-testing.yml deleted file mode 100644 index 6ed3654b..00000000 --- a/azure-pipelines-automated-testing.yml +++ /dev/null @@ -1,474 +0,0 @@ -trigger: - branches: - include: [ develop, release/* ] - paths: - exclude: - - deployment/* - include: - - "*" -pr: - branches: - include: [ '*' ] - paths: - exclude: - - deployment/* - include: - - "*" - -resources: - containers: - - container: node - image: packagerepository.sagaws.net:8082/safelite/node-build:18 - - container: awscli - image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9 - repositories: - - repository: AzureDevOps - type: github - name: Safelite/AzureDevOps - endpoint: Safelite - ref: refs/tags/t5.5.40 - -variables: - - group: Digital-Infrastructure - - group: ISS-BuildBranches - - name: dockerImageName - value: 'playwright-tests' - - name: imageTag - value: '$(Build.BuildId)' - - name: totalShards - value: 2 - -stages: - # PR's - - ${{ if or(eq(variables['Build.Reason'], 'PullRequest'), eq(1,1)) }}: # TODO: Change condition back to normal - - stage: TestPr - displayName: Run Tests For PullRequest - jobs: - # TODO: Put unit tests back - # - template: templates/digital/vue-jest-run-unit-tests.yml@AzureDevOps - # parameters: - # nodeContainer: node - # npmLocation: $(Build.SourcesDirectory) - # testResultsFile: junit.xml - # summaryFileLocation: $(Build.SourcesDirectory)/coverage/cobertura-coverage.xml - - job: playwright_tests - continueOnError: true - strategy: - matrix: - shard1: - shardNumber: 1 - shard2: - shardNumber: 2 - # shard3: - # shardNumber: 3 - # shard4: - # shardNumber: 4 - - steps: - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - - script: | - branch_name=$(Build.SourceBranch) #TODO: Change back to $(System.PullRequest.SourceBranch) - echo "Retrieved branch name: '$branch_name'" - jira_card_number="${branch_name##*/}" - echo "Extracted JIRA Card number: '$jira_card_number'" - # Create container and run tests - container_id=$(docker create \ - --ipc=host \ - -e CCIS_API_AUTH=$(CCIS_API_AUTH) \ - -e BASE_URL=$(BASE_URL) \ - -e CCIS_API_URL=$(CCIS_API_URL) \ - -e ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL) \ - -e SHARD=$(shardNumber) \ - -e CI=true \ - -e NODE_ENV=$(NODE_ENV) \ - $(dockerImageName):$(imageTag) \ - npx concurrently -k -n "server,playwright"\ - "sed -i \"s|^process\.env\.VUE_APP_CONSUMER_CF_DISTRO = .*|process\.env\.VUE_APP_CONSUMER_CF_DISTRO='https://digitalapi.test.safelite.io'|\" \"./vue.config.js\" && echo \"Updated config file to use TEST APIs\" && npm run serve -- --port=8080"\ - "npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@$jira_card_number\"") - - # Start container and stream logs - echo "Starting tests for shard $(shardNumber)..." - docker start -a $container_id - - # Create directory for test results - echo "Creating test results directory..." - mkdir -p $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber) - - # Copy test results from container - echo "Copying test results..." - docker cp $container_id:/app/blob-report/. $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)/ - - # Remove container - echo "Cleaning up container..." - docker rm $container_id - - # Check if tests failed - if [ $? -ne 0 ]; then - echo "Tests failed in shard $(shardNumber) or tests don't exist for this shard number!" - exit 0 # Suppress error. It will be visible in report. - fi - displayName: 'Run Playwright Tests - Shard $(shardNumber)' - - - task: PublishPipelineArtifact@1 - displayName: 'Publish Test Reports - Shard $(shardNumber)' - condition: always() - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)' - artifact: 'playwright-report-shard-$(shardNumber)' - publishLocation: 'pipeline' - - - script: | - docker rmi $(dockerImageName):$(imageTag) -f - displayName: 'Cleanup Docker Image' - condition: always() - - - job: download_and_merge_reports - dependsOn: playwright_tests - timeoutInMinutes: 8 - cancelTimeoutInMinutes: 10 - steps: - - task: DownloadPipelineArtifact@2 - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/playwright-reports' - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - bash: | - branch_name=$(Build.SourceBranch) #TODO: Change back to $(System.PullRequest.SourceBranch) - echo "Retrieved branch name: '$branch_name'" - jira_card_number="${branch_name##*/}" - echo "Extracted JIRA Card number: '$jira_card_number'" - # Create container for jira writeback - container_id=$(docker create \ - --ipc=host \ - -e JIRA_SERVER=$(JIRA_SERVER) \ - -e JIRA_USERNAME=$(JIRA_USERNAME) \ - -e JIRA_API_KEY=$(JIRA_API_KEY) \ - -e jira_card_number="$jira_card_number" \ - $(dockerImageName):$(imageTag) \ - bash -c "echo \"Moving Playwright reports out of subfolders...\" && - find ./playwright-reports/ -mindepth 2 -type f -exec mv {} ./playwright-reports/ \; && - echo \"Merging reports...\" && - PLAYWRIGHT_JUNIT_OUTPUT_DIR='/app/test-results' PLAYWRIGHT_JUNIT_OUTPUT_NAME='junit_results.xml' npx playwright merge-reports --reporter=ortoni-report,junit ./playwright-reports - echo \"Contents of ortoni-report:\" && ls ./ortoni-report && - echo 'Current dir: ' && pwd - echo 'Contents of current dir: ' && ls - echo 'Contents of /app/test-results' && ls /app/test-results - echo \"Writing report to Jira card '$jira_card_number'...\" && - /app/devops/scripts/jira_writeback.sh add_comment \"$jira_card_number\" /app/ortoni-report/ortoni-report.html \"AUTOMATED TEST RUN: $(date)\" ") - - # Start container and stream logs - echo "Starting merge" - docker start -a $container_id - - # Create directory for test results - echo "Creating test results directory..." - mkdir -p $(System.DefaultWorkingDirectory)/ortoni-report - mkdir -p $(System.DefaultWorkingDirectory)/test-results - - # Copy test results from container - echo "Copying test results..." - docker cp $container_id:/app/ortoni-report/. $(System.DefaultWorkingDirectory)/ortoni-report - docker cp $container_id:/app/test-results/junit_results.xml $(System.DefaultWorkingDirectory)/test-results - - # Remove container - echo "Cleaning up container..." - docker rm $container_id - env: - JIRA_API_KEY: $(JIRA_API_KEY) - displayName: merge_and_publish_results_to_jira - - - task: PublishTestResults@2 - displayName: 'Publish test results' - inputs: - searchFolder: 'test-results' - testResultsFormat: 'JUnit' - testResultsFiles: 'junit_results.xml' - mergeTestResults: true - failTaskOnFailedTests: false - testRunTitle: 'Playwright Tests' - condition: succeededOrFailed() - - - task: PublishPipelineArtifact@1 - displayName: 'Publish Merged Report' - condition: always() - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/ortoni-report' - artifact: 'playwright-merged-report' - publishLocation: 'pipeline' - - script: | - docker rmi $(dockerImageName):$(imageTag) -f - displayName: 'Cleanup Docker Image' - condition: always() - - - ${{ else }}: - # Dev Build/Deploy - - stage: Dev - condition: eq(variables['Build.SourceBranch'], variables['dev-branch'] ) - variables: - - group: ISS-Dev - jobs: - - deployment: devBuildDeployment - displayName: Build and Deploy ISS - Dev - environment: digitalCloud-dev - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/dev' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Dev - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistDev - awsProfile: $(devDeploymentProfile) - deployBuckets: - safelite-dev-iss-us-east-2: - clearFolder: true - deployFolder: '' - region: us-east-2 - safelite-dev-iss-us-east-1: - clearFolder: true - deployFolder: '' - region: us-east-1 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(devDeploymentProfile) - - # Test Build/Deploy - - stage: Test - condition: eq(variables['Build.SourceBranch'], variables['test-branch'] ) - variables: - - group: ISS-Test - jobs: - - deployment: testBuildDeployment - displayName: Build and Deploy ISS - Test - environment: NoApproval-All - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/test' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Test - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistTest - awsProfile: $(sysDeploymentProfile) - deployBuckets: - safelite-sys-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-sys-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(sysDeploymentProfile) - - # QA Build/Deploy - - stage: QA - condition: eq(variables['Build.SourceBranch'], variables['qa-branch'] ) - variables: - - group: ISS-QA - jobs: - - deployment: qaBuildDeployment - displayName: Build and Deploy ISS - QA - environment: NoApproval-All - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/qa' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Qa - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistQa - awsProfile: $(qaDeploymentProfile) - deployBuckets: - safelite-qa-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-qa-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(qaDeploymentProfile) - - # Prod Build/Deploy - - stage: Prod - condition: succeeded('QA') - variables: - - group: ISS-Prod - jobs: - - deployment: prodBuildDeployment - displayName: Build and Deploy ISS - Prod - environment: digitalCloud-prod - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/prod' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Prod - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistProd - awsProfile: $(prodDeploymentProfile) - deployBuckets: - safelite-prod-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-prod-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(prodDeploymentProfile) - - template: templates/digital/auto-tag.yml@AzureDevOps - parameters: - dependsOn: prodBuildDeployment - userName: SafeliteAzureDevops - userEmail: githubazuredevops@safelite.com - diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c40e2c36..3d648d3c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -36,7 +36,7 @@ variables: - name: imageTag value: '$(Build.BuildId)' - name: totalShards - value: 4 + value: 2 stages: # PR's @@ -58,10 +58,10 @@ stages: shardNumber: 1 shard2: shardNumber: 2 - shard3: - shardNumber: 3 - shard4: - shardNumber: 4 + # shard3: + # shardNumber: 3 + # shard4: + # shardNumber: 4 steps: - task: Docker@2 @@ -74,6 +74,10 @@ stages: arguments: '--no-cache --pull' - script: | + branch_name=$(System.PullRequest.SourceBranch) + echo "Retrieved branch name: '$branch_name'" + jira_card_number="${branch_name##*/}" + echo "Extracted JIRA Card number: '$jira_card_number'" # Create container and run tests container_id=$(docker create \ --ipc=host \ @@ -87,7 +91,7 @@ stages: $(dockerImageName):$(imageTag) \ npx concurrently -k -n "server,playwright"\ "sed -i \"s|^process\.env\.VUE_APP_CONSUMER_CF_DISTRO = .*|process\.env\.VUE_APP_CONSUMER_CF_DISTRO='https://digitalapi.test.safelite.io'|\" \"./vue.config.js\" && echo \"Updated config file to use TEST APIs\" && npm run serve -- --port=8080"\ - "npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@smoke | @Advanced\"") + "npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@$jira_card_number\"") # Start container and stream logs echo "Starting tests for shard $(shardNumber)..." @@ -107,8 +111,8 @@ stages: # Check if tests failed if [ $? -ne 0 ]; then - echo "Tests failed in shard $(shardNumber)!" - exit 1 + echo "Tests failed in shard $(shardNumber) or tests don't exist for this shard number!" + exit 0 # Suppress error. It will be visible in report. fi displayName: 'Run Playwright Tests - Shard $(shardNumber)' @@ -157,11 +161,11 @@ stages: bash -c "echo \"Moving Playwright reports out of subfolders...\" && find ./playwright-reports/ -mindepth 2 -type f -exec mv {} ./playwright-reports/ \; && echo \"Merging reports...\" && - npx playwright merge-reports --reporter=ortoni-report ./playwright-reports + PLAYWRIGHT_JUNIT_OUTPUT_DIR='/app/test-results' PLAYWRIGHT_JUNIT_OUTPUT_NAME='junit_results.xml' npx playwright merge-reports --reporter=ortoni-report,junit ./playwright-reports echo \"Contents of ortoni-report:\" && ls ./ortoni-report && echo 'Current dir: ' && pwd echo 'Contents of current dir: ' && ls - echo 'Contents of /app/devops/scripts' && ls /app/devops/scripts + echo 'Contents of /app/test-results' && ls /app/test-results echo \"Writing report to Jira card '$jira_card_number'...\" && /app/devops/scripts/jira_writeback.sh add_comment \"$jira_card_number\" /app/ortoni-report/ortoni-report.html \"AUTOMATED TEST RUN: $(date)\" ") @@ -172,12 +176,12 @@ stages: # Create directory for test results echo "Creating test results directory..." mkdir -p $(System.DefaultWorkingDirectory)/ortoni-report + mkdir -p $(System.DefaultWorkingDirectory)/test-results # Copy test results from container echo "Copying test results..." docker cp $container_id:/app/ortoni-report/. $(System.DefaultWorkingDirectory)/ortoni-report - # docker cp $container_id:/app/test-results/junit_results.xml $(System.DefaultWorkingDirectory) - # TODO: Update to include junit results if necessary + docker cp $container_id:/app/test-results/junit_results.xml $(System.DefaultWorkingDirectory)/test-results # Remove container echo "Cleaning up container..." @@ -186,17 +190,16 @@ stages: JIRA_API_KEY: $(JIRA_API_KEY) displayName: merge_and_publish_results_to_jira - # TODO: Enable later when working on PR gate - # - task: PublishTestResults@2 - # displayName: 'Publish test results' - # inputs: - # searchFolder: 'test-results' - # testResultsFormat: 'JUnit' - # testResultsFiles: 'junit_results.xml' - # mergeTestResults: true - # failTaskOnFailedTests: false - # testRunTitle: 'Playwright Tests' - # condition: succeededOrFailed() + - task: PublishTestResults@2 + displayName: 'Publish test results' + inputs: + searchFolder: 'test-results' + testResultsFormat: 'JUnit' + testResultsFiles: 'junit_results.xml' + mergeTestResults: true + failTaskOnFailedTests: false + testRunTitle: 'Playwright Tests' + condition: succeededOrFailed() - task: PublishPipelineArtifact@1 displayName: 'Publish Merged Report'