From 0fa61a28937ad24e1fd04005d08873effe01cc45 Mon Sep 17 00:00:00 2001 From: Maurizio Vitale Date: Thu, 29 Jun 2023 16:27:10 +0100 Subject: [PATCH] [AAE-15499] QA Failure provide more context on slack notification (#8720) * sharing data with files * sharing data with files * disable check * add shell * skip step * skip step * fix tab * run e2e * failing e2e * failing e2e make fail * failing e2e make fail * use js action * fix template * test action * fix * fix test * fix test * use action * use action fix * use action fix * use action fix * use action fix * use action fix * use action fix * use action fix * use action fix * Normal run * verify slack groups * verify slack groups * verify slack groups * verify slack groups * refactor * remove useless code * remove useless code * use space as separator * use space as separator * use ga channel * append only for cron * run e2e job only if affected * simulate process * fix logic * fix logic * fix output * almost done --- .github/actions/artifact-append/action.yml | 90 +++++++++++++++++++ .github/actions/artifact-extract/action.yml | 40 +++++++++ .../actions/artifact-initialize/action.yml | 32 +++++++ .github/actions/e2e/action.yml | 68 +++++++++----- .github/actions/slack-group-area/action.yml | 49 ++++++++++ .github/workflows/cron-e2e.yml | 11 +++ .github/workflows/pull-request.yml | 16 +++- 7 files changed, 281 insertions(+), 25 deletions(-) create mode 100644 .github/actions/artifact-append/action.yml create mode 100644 .github/actions/artifact-extract/action.yml create mode 100644 .github/actions/artifact-initialize/action.yml create mode 100644 .github/actions/slack-group-area/action.yml diff --git a/.github/actions/artifact-append/action.yml b/.github/actions/artifact-append/action.yml new file mode 100644 index 0000000000..83bffd1ec5 --- /dev/null +++ b/.github/actions/artifact-append/action.yml @@ -0,0 +1,90 @@ +name: Append content to Artifact +description: 'Allow the user to append content to an existing artifact' + +inputs: + artifact-name: + description: 'The name of the artifact' + required: true + type: string + file-name: + description: 'The name of the file with extension created in the artifact' + required: true + type: string + content: + description: 'The content to append' + type: string + default: "" + +runs: + using: "composite" + + steps: + - run: echo "Artifact Append" + shell: bash + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + - run: ls + shell: bash + - name: Append content + uses: actions/github-script@v6 + env: + contentFile: ${{ inputs.content }} + fileName: ${{ inputs.file-name }} + with: + script: | + const fs = require('fs'); + + const affectedLib = process.env.contentFile; + const fileName = process.env.fileName; + core.info(`Input Filename: ${fileName}`); + core.info(`Input content: ${affectedLib}`); + + const content = read(fileName) + core.info(`File content: ${content}`); + appendContent(content, affectedLib); + + function read(filename) { + try { + const contentFile = fs.readFileSync(filename, 'utf8').replace('\n',''); + return contentFile; + } catch (err) { + core.error(err); + } + } + + function write(filename, content) { + try { + fs.writeFileSync(filename, content); + } catch (err) { + core.error(err); + } + } + + function appendContent(content, append) { + let changedContent; + const libs = content.split(' '); + if (libs?.length>0) { + if (libs.length === 1 && libs[0] === '') { + libs[0] = append; + changedContent = libs[0]; + } + else if (!libs.includes(append)) { + libs.push(append); + changedContent = libs.join(' '); + } else { + core.info(`Lib ${append} already affected`); + } + } + if (changedContent != undefined){ + core.info(`File content append: ${changedContent}`) + write(fileName, changedContent); + } + } + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: ${{ inputs.file-name }} + diff --git a/.github/actions/artifact-extract/action.yml b/.github/actions/artifact-extract/action.yml new file mode 100644 index 0000000000..f9aa4a50a4 --- /dev/null +++ b/.github/actions/artifact-extract/action.yml @@ -0,0 +1,40 @@ +name: Extract Artifact +description: 'Allow the user to extract content from an artifact' + +inputs: + artifact-name: + description: 'The name of the artifact' + required: true + type: string + file-name: + description: 'The name of the file with extension created in the artifact' + required: true + type: string + content: + description: 'The init content the file should have' + type: string + default: "" + +outputs: + result: + description: "the value extrated from the file inside the artifact" + value: ${{ steps.extract.outputs.result }} + +runs: + using: "composite" + + steps: + - uses: actions/checkout@v3 + - run: echo "Artifact Extract" + shell: bash + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + - id: extract + shell: bash + run: | + value=`cat ${{ inputs.file-name }}` + echo "print $value" + echo "result=$value" >> $GITHUB_OUTPUT + diff --git a/.github/actions/artifact-initialize/action.yml b/.github/actions/artifact-initialize/action.yml new file mode 100644 index 0000000000..d329856fb1 --- /dev/null +++ b/.github/actions/artifact-initialize/action.yml @@ -0,0 +1,32 @@ +name: Initialize Artifact +description: 'Allow the user to initialize an empty artifact used globally' + +inputs: + artifact-name: + description: 'The name of the artifact' + required: true + type: string + file-name: + description: 'The name of the file with extension created in the artifact' + required: true + type: string + content: + description: 'The init content the file should have' + type: string + default: "" + +runs: + using: "composite" + + steps: + - uses: actions/checkout@v3 + - name: Create empty artifact + shell: bash + run: + echo "${{inputs.content}}" > ${{ inputs.file-name }} + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: ${{ inputs.file-name }} diff --git a/.github/actions/e2e/action.yml b/.github/actions/e2e/action.yml index a471c305a8..8f3c3f44f9 100644 --- a/.github/actions/e2e/action.yml +++ b/.github/actions/e2e/action.yml @@ -46,6 +46,21 @@ inputs: runs: using: "composite" steps: + - name: Determine if affected + shell: bash + id: determine-affected + run: | + isAffected=false + affectedLibs=$(npx nx print-affected --type=lib --select=projects ${NX_CALCULATION_FLAGS} --plain) + if [[ $affectedLibs =~ "${{ inputs.e2e-test-id }}" ]]; then + isAffected=true + fi; + echo "Determine if ${{ inputs.e2e-test-id }} is affected: $isAffected"; + echo "isAffected=$isAffected" >> $GITHUB_OUTPUT + - name: print value + shell: bash + run: | + echo "value: ${{ steps.determine-affected.outputs.isAffected }}" - name: use APA as PROXY host if apa-proxy is set shell: bash run: | @@ -76,8 +91,9 @@ runs: - name: check EXTERNAL-CS is UP shell: bash - if: ${{ inputs.check-external-cs-env == 'true' }} + if: ${{ inputs.check-external-cs-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }} run: | + echo "running: check EXTERNAL-CS is UP" set -u; ./node_modules/@alfresco/adf-cli/bin/adf-cli \ check-cs-env \ @@ -87,8 +103,9 @@ runs: - name: Check CS is UP shell: bash - if: ${{ inputs.check-cs-env == 'true' }} + if: ${{ inputs.check-cs-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }} run: | + echo "Running: Check CS is UP" set -u; ./node_modules/@alfresco/adf-cli/bin/adf-cli \ check-cs-env \ @@ -98,8 +115,9 @@ runs: - name: check PS is UP shell: bash - if: ${{ inputs.check-ps-env == 'true' }} + if: ${{ inputs.check-ps-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }} run: | + echo "Running: check PS is UP" set -u; ./node_modules/@alfresco/adf-cli/bin/adf-cli init-aps-env \ --host "$E2E_HOST" \ @@ -109,8 +127,9 @@ runs: - name: check PS-CLOUD is UP shell: bash - if: ${{ inputs.check-ps-cloud-env == 'true' }} + if: ${{ inputs.check-ps-cloud-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }} run: | + echo "running: check PS-CLOUD is UP" set -u; ./node_modules/@alfresco/adf-cli/bin/adf-cli init-aae-env \ --oauth "$E2E_IDENTITY_HOST_APA" \ @@ -134,36 +153,37 @@ runs: echo $PROXY_HOST_BPM echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV - - name: run test with retries - id: retry_run + - name: run test + id: e2e_run + if: ${{ steps.determine-affected.outputs.isAffected == 'true' }} env: FOLDER: "${{ inputs.e2e-test-folder }}" PROVIDER: "${{ inputs.e2e-test-provider }}" AUTH_TYPE: "${{ inputs.e2e-test-auth }}" E2E_TEST_ID: "${{ inputs.e2e-test-id }}" DEPS: "${{ inputs.deps }}" - - uses: nick-fields/retry@v2.8.2 + shell: bash + run: | + set -u; + if [[ ${{ inputs.e2e-test-folder }} == 'content-services/upload' ]]; then + export DISPLAY=:99 + chromedriver --url-base=/wd/hub & + sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional + bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" "browser" || exit 1 + else + bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" || exit 1 + fi + - name: Trace failing e2e + if: ${{ steps.determine-affected.outputs.isAffected == 'true' && github.event_name == 'schedule' && failure() }} + uses: ./.github/actions/artifact-append with: - timeout_minutes: 40 - max_attempts: 2 - retry_wait_seconds: 30 - shell: bash - command: | - set -u; - export GH_ACTION_RETRY_COUNT=$(cat ${GITHUB_OUTPUT} | grep -E '^[0-9]{1,2}$' | tail -n1) - echo "RETRY GH_ACTION_RETRY_COUNT = <$GH_ACTION_RETRY_COUNT>" - if [[ ${{ inputs.e2e-test-folder }} == 'content-services/upload' ]]; then - export DISPLAY=:99 - chromedriver --url-base=/wd/hub & - sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional - bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" "browser" || exit 1 - else - bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" || exit 1 - fi + artifact-name: global-e2e-result + file-name: e2e-failures.txt + content: "${{ inputs.e2e-test-id }}" - name: upload artifacts on gh id: upload_gh + if: ${{ steps.determine-affected.outputs.isAffected == 'true' }} uses: actions/upload-artifact@v3 with: name: e2e-artifact-output diff --git a/.github/actions/slack-group-area/action.yml b/.github/actions/slack-group-area/action.yml new file mode 100644 index 0000000000..d15aeb8a9c --- /dev/null +++ b/.github/actions/slack-group-area/action.yml @@ -0,0 +1,49 @@ +name: Identify the slack group +description: 'Identify the slack group area based on the affected' + +inputs: + affected: + description: 'The name of the affected lib' + required: true + type: string + +outputs: + groups: + description: "the slack groups" + value: ${{ steps.group.outputs.result }} + +runs: + using: "composite" + + steps: + - name: Append group + id: group + uses: actions/github-script@v6 + env: + affectedLib: ${{ inputs.affected }} + with: + script: | + const affectedLib = process.env.affectedLib; + core.info(`Input ${affectedLib}`); + + const slackGroups = new Set(); + const AlfrescoQAGroup = '@alfresco-testing-qa'; + const HxpQAGroup = '@hxp-studio-qa-group'; + + const libs = affectedLib.split(' ') + + if (libs.includes('content-services') || libs.includes('process-services')) { + slackGroups.add(AlfrescoQAGroup); + } + if (libs.includes('process-services-cloud')) { + slackGroups.add(HxpQAGroup); + } + if (libs.includes('core')) { + slackGroups.add(AlfrescoQAGroup); + slackGroups.add(HxpQAGroup); + } + + const result = Array.from(slackGroups.values()).join(' '); + core.info(`Result ${result}`); + return result; + diff --git a/.github/workflows/cron-e2e.yml b/.github/workflows/cron-e2e.yml index 26263a5ce3..c99ff643a3 100644 --- a/.github/workflows/cron-e2e.yml +++ b/.github/workflows/cron-e2e.yml @@ -1,6 +1,7 @@ name: "cron e2e daily" on: + workflow_dispatch: schedule: - cron: '0 12 * * *' @@ -68,6 +69,16 @@ env: PROXY_HOST_ECM: ${{ secrets.E2E_HOST }} jobs: + init-artifact: + runs-on: ubuntu-latest + name: Initialize artifacts + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/artifact-initialize + with: + artifact-name: global-e2e-result + file-name: e2e-failures.txt + run-e2e: name: run e2e uses: ./.github/workflows/pull-request.yml diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 051e13d25e..df76626c4d 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -488,6 +488,20 @@ jobs: name: Final Results needs: [check-if-pr-is-approved, check-package-lock, setup, unit-tests, lint, build-libs, e2e, e2e-storybook] steps: + - uses: actions/checkout@v3 + - name: Log e2e result + id: e2e-result + if: ${{ github.event_name == 'schedule' }} + uses: ./.github/actions/artifact-extract + with: + artifact-name: global-e2e-result + file-name: e2e-failures.txt + - name: identify-slack-group + id: groups + if: ${{ github.event_name == 'schedule' }} + uses: ./.github/actions/slack-group-area + with: + affected: ${{ steps.e2e-result.outputs.result }} - uses: slackapi/slack-github-action@v1.23.0 name: Nofify QA failure if: ${{ github.event_name == 'schedule' && contains(needs.*.result, 'failure') }} @@ -495,7 +509,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} with: channel-id: 'C016SMNNL8L' #guild-channel - slack-message: "🔴 Warning: The daily ADF cronjob failed\nWorkflow run : \n" + slack-message: "🔴 Warning: The daily ADF cronjob failed\nWorkflow run : \nDetails: ${{ steps.e2e-result.outputs.result }}\nArea: ${{ steps.groups.outputs.groups}}" - name: workflow failure run: exit 1 if: ${{ contains(needs.*.result, 'failure') }}