diff --git a/.github/workflows/test-mobile-e2e-reusable.yml b/.github/workflows/test-mobile-e2e-reusable.yml index 047d7ea76c2e..4ed2dbe3b195 100644 --- a/.github/workflows/test-mobile-e2e-reusable.yml +++ b/.github/workflows/test-mobile-e2e-reusable.yml @@ -37,6 +37,11 @@ on: required: false type: boolean default: false + slack_notif: + description: "Send notification to Slack?" + required: false + type: boolean + default: false # Uncomment to have log-level: trace on detox run and build # (cf: apps/ledger-live-mobile/detox.config.js) @@ -124,15 +129,6 @@ jobs: if: ${{ always() && steps.simulator.outputs.id }} run: | xcrun simctl delete ${{ steps.simulator.outputs.id }} - - name: Generate single file Allure report - if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} - run: pnpm dlx allure-commandline generate apps/ledger-live-mobile/artifacts --single-file - - name: Upload Allure single file report - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} - with: - name: ios-allure-report - path: allure-report/index.html - name: Upload test artifacts uses: actions/upload-artifact@v4 if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} @@ -143,18 +139,29 @@ jobs: allure-report-ios: name: "Allure Reports Export on Server" runs-on: [ledger-live-medium] - if: ${{ !cancelled() && github.ref_name == 'develop' }} + if: ${{ failure() && (inputs.slack_notif || github.event_name == 'push') }} needs: [detox-tests-ios] + outputs: + report-url: ${{ steps.upload.outputs.report-url }} + result: ${{ steps.summary.outputs.test_result }} steps: - uses: actions/checkout@v4 with: ref: ${{ ((github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call' || github.event_name == 'pull_request') && (inputs.ref || github.ref_name)) || github.sha }} - uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop + id: upload with: platform: ios login: ${{ vars.ALLURE_USERNAME }} password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }} path: ios-test-artifacts + - name: Get summary + id: summary + if: ${{ !cancelled() }} + uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop + with: + allure-results-path: ios-test-artifacts + platform: iOS detox-tests-android: name: "Ledger Live Mobile - Android Detox Tests" @@ -272,15 +279,6 @@ jobs: DETOX_INSTALL_TIMEOUT: 120000 SEED: ${{ secrets.SEED_QAA_B2C }} INPUT_SPECULOS: ${{ inputs.speculos_tests }} - - name: Generate single file Allure report - if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} - run: pnpm dlx allure-commandline generate apps/ledger-live-mobile/artifacts --single-file - - name: Upload Allure single file report - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} - with: - name: android-allure-report - path: allure-report/index.html - name: Upload test artifacts uses: actions/upload-artifact@v4 if: ${{ !cancelled() || steps.detox.outcome == 'cancelled' }} @@ -291,7 +289,10 @@ jobs: allure-report-android: name: "Allure Reports Export on Server" runs-on: [ledger-live-medium] - if: ${{ !cancelled() && github.ref_name == 'develop' }} + if: ${{ failure() && (inputs.slack_notif || github.event_name == 'push') }} + outputs: + report-url: ${{ steps.upload.outputs.report-url }} + result: ${{ steps.summary.outputs.test_result }} needs: [detox-tests-android] steps: - name: checkout @@ -299,11 +300,19 @@ jobs: with: ref: ${{ ((github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call' || github.event_name == 'pull_request') && (inputs.ref || github.ref_name)) || github.sha }} - uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop + id: upload with: platform: android login: ${{ vars.ALLURE_USERNAME }} password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }} path: android-test-artifacts + - name: Get summary + id: summary + if: ${{ !cancelled() }} + uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop + with: + allure-results-path: android-test-artifacts + platform: android upload-to-xray: name: "Upload to Xray" @@ -362,99 +371,10 @@ jobs: shell: bash run: echo "::notice title=${{ matrix.platform }} Xray report URL::${{ env.JIRA_URL }}/${{ steps.publish-xray.outputs.xray_key }}" - report: - needs: [detox-tests-android, detox-tests-ios] - runs-on: ubuntu-22.04 - if: ${{ !cancelled() && (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call' || github.event_name == 'pull_request') }} - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref || github.sha }} - - uses: actions/github-script@v7 - name: prepare status - id: status - with: - script: | - const fs = require("fs"); - - const [ owner, repo ] = "${{ github.repository }}".split("/"); - - const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { - owner, - repo, - run_id: "${{ github.run_id }}", - attempt_number: "${{ github.run_attempt }}", - }); - - const findJobUrl = os => - jobs.find(job => job.name == `Ledger Live Mobile - ${os} Detox Tests`)?.html_url; - - const keys = { - ios: { - symbol: "🍏", - name: "iOS", - jobUrl: findJobUrl("iOS") - }, - android: { - symbol: "🤖", - name: "Android", - jobUrl: findJobUrl("Android") - }, - }; - - const report = { - ios: { - pass: ${{ needs.detox-tests-ios.outputs.status == 'success' }}, - status: "${{ needs.detox-tests-ios.outputs.status }}", - }, - android: { - pass: ${{ needs.detox-tests-android.outputs.status == 'success'}}, - status: "${{ needs.detox-tests-android.outputs.status }}", - }, - }; - - let summary = `### Detox Tests - - ` - - summary += `|` - - const reportKeys = Object.keys(report); - const detoxSuccess = Object.entries(report).every(([os, values]) => !!values.pass); - - reportKeys.forEach((k) => { - summary += ` [${keys[k].symbol} ${keys[k].name}](${keys[k].jobUrl}) |`; - }); - - summary += ` - |`; - - for (let i = 0; i < reportKeys.length; i++) { - summary += ` :--: |`; - } - - summary += ` - |`; - - Object.entries(report).forEach(([os, values]) => { - summary += ` ${values.pass ? "✅" : "❌"} (${values.status}) |`; - }); - - const output = { - summary - }; - - fs.writeFileSync("summary-detox.json", JSON.stringify(output), "utf-8"); - - uses: actions/upload-artifact@v4 - name: upload summary - with: - name: summary-detox.json - path: ${{ github.workspace }}/summary-detox.json - report-on-slack: runs-on: ubuntu-22.04 - needs: [detox-tests-android, detox-tests-ios] - if: ${{ failure() && github.event_name == 'push' }} + needs: [allure-report-android, allure-report-ios] + if: ${{ failure() && (inputs.slack_notif || github.event_name == 'push') }} steps: - name: format message uses: actions/github-script@v7 @@ -462,25 +382,28 @@ jobs: with: script: | const fs = require("fs"); - const text = `❌ 🍏 Detox tests failed ❌`; + const text = `❌ Detox tests failed ❌`; const iOSResult = [ { "type": "header", "text": { "type": "plain_text", - "text": `❌ iOS Detox tests failed ❌`, + "text": `🍏 iOS Detox tests failed ❌`, "emoji": true } }, { - "type": "divider" + "type": "section", + "text": { + "type": "mrkdwn", + "text": `${{ needs.allure-report-ios.outputs.result || 'No test results' }}` + } }, { "type": "section", "text": { "type": "mrkdwn", - "text": `😵 Build Failed - ` + "text": `<${{ needs.allure-report-ios.outputs.report-url }}|Allure Report iOS>` } } ]; @@ -489,19 +412,22 @@ jobs: "type": "header", "text": { "type": "plain_text", - "text": `❌ Android Detox tests failed ❌`, + "text": `🤖 Android Detox tests failed ❌`, "emoji": true } }, { - "type": "divider" + "type": "section", + "text": { + "type": "mrkdwn", + "text": `${{ needs.allure-report-android.outputs.result || 'No test results' }}` + } }, { "type": "section", "text": { "type": "mrkdwn", - "text": `😵 Build Failed - ` + "text": `<${{ needs.allure-report-android.outputs.report-url }}|Allure Report Android>` } } ]; @@ -512,8 +438,8 @@ jobs: { "type": "section", "text": { - "type": "mrkdwn", - "text": ` for more informations`, + "type": "mrkdwn", + "text": `<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow run> for more informations`, } } ]; diff --git a/.github/workflows/test-mobile-e2e.yml b/.github/workflows/test-mobile-e2e.yml index 54369f71fd71..aad759f1c1ca 100644 --- a/.github/workflows/test-mobile-e2e.yml +++ b/.github/workflows/test-mobile-e2e.yml @@ -33,6 +33,11 @@ on: required: false type: boolean default: false + slack_notif: + description: "Send notification to Slack?" + required: false + type: boolean + default: false # Uncomment to have log-level: trace on detox run and build # (cf: apps/ledger-live-mobile/detox.config.js) diff --git a/.github/workflows/test-ui-e2e-only-desktop.yml b/.github/workflows/test-ui-e2e-only-desktop.yml index 62b58d6ddf1b..ebdca175fe96 100644 --- a/.github/workflows/test-ui-e2e-only-desktop.yml +++ b/.github/workflows/test-ui-e2e-only-desktop.yml @@ -22,10 +22,6 @@ on: description: Ignore test having name pattern (entered in the previous field) type: boolean default: false - report_path: - description: Path where you want to store this execution's results - required: false - default: "allure-results-linux" slack_notif: description: "Send notification to Slack?" required: false @@ -163,68 +159,49 @@ jobs: name: xray-reports-${{ matrix.shardIndex }} path: apps/ledger-live-desktop/tests/artifacts/xray/xray-report.json - report-and-notify: - name: "Report and Notify" + report-to-allure: + name: "Create Allure Report and upload it" runs-on: [ledger-live-medium] needs: e2e-tests-linux - if: always() + outputs: + test_result: ${{ steps.summary.outputs.test_result }} + status_color: ${{ steps.summary.outputs.status_color }} + status_emoji: ${{ steps.summary.outputs.status_emoji }} + report-url: ${{ steps.allure-server.outputs.report-url }} + if: ${{ !cancelled() }} + env: + ALLURE_RESULTS: "allure-results" steps: - - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref || github.sha }} - - - name: Download Allure Results - uses: actions/download-artifact@v4.1.1 - with: - path: "apps/ledger-live-desktop/allure-results" - pattern: allure-results-* - merge-multiple: true - - name: Publish report on Allure Server id: allure-server if: ${{ !cancelled() }} - uses: LedgerHQ/send-to-allure-server-action@2.1.2 + uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop with: - allure-server-url: "https://ledger-live.allure.green.ledgerlabs.net" - build-name: ${{ github.workflow }} - build-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - username: ${{ vars.ALLURE_USERNAME }} + platform: linux + login: ${{ vars.ALLURE_USERNAME }} password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }} - path: ${{ github.ref_name }}/linux - allure-results: "apps/ledger-live-desktop/allure-results" - - - name: Write Allure report in summary - if: ${{ !cancelled() }} - shell: bash - run: echo "::notice title=Allure report URL::${{ steps.allure-server.outputs.report-url }}" + path: ${{ env.ALLURE_RESULTS }} - name: Get summary - if: ${{ !cancelled() }} + if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} id: summary - shell: bash - run: | - cd apps/ledger-live-desktop - allure generate - cd allure-report/widgets - passedTests=$(jq '.statistic.passed' summary.json) - failedTests=$(jq '.statistic.failed' summary.json) - brokenTests=$(jq '.statistic.broken' summary.json) - skippedTests=$(jq '.statistic.skipped' summary.json) - totalTests=$(jq '.statistic.total' summary.json) - echo "TEST_RESULT=$passedTests passed, $failedTests failed, $brokenTests broken, $skippedTests skipped, $totalTests total" >> $GITHUB_ENV - - if [ "$failedTests" -gt 0 ] || [ "$brokenTests" -gt 0 ]; then - echo "STATUS_COLOR=#FF333C" >> $GITHUB_ENV; - echo "STATUS_EMOJI=❌" >> $GITHUB_ENV; - else - echo "STATUS_COLOR=#33FF39" >> $GITHUB_ENV; - echo "STATUS_EMOJI=✅" >> $GITHUB_ENV; - fi + uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop + with: + allure-results-path: ${{ env.ALLURE_RESULTS }} + platform: linux + notify-to-slack: + name: "Notify to slack" + runs-on: [ledger-live-medium] + needs: report-to-allure + if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} + steps: - uses: actions/github-script@v7 - if: ${{ !cancelled() }} + if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} name: prepare status id: status + env: + STATUS_EMOJI: ${{ needs.report-to-allure.outputs.status_emoji }} with: script: | const fs = require("fs"); @@ -307,12 +284,10 @@ jobs: }], }; - if (${{ !inputs.slack_notif && github.event_name == 'workflow_dispatch' }}) return; - const slackPayload = { "attachments": [ { - "color": "${{ env.STATUS_COLOR }}", + "color": "${{ needs.report-to-allure.outputs.status_color }}", "blocks": [ { "type": "header", @@ -329,7 +304,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": `- 🐧 linux: ${statusEmoji} ${process.env.TEST_RESULT || 'No test results'}` + "text": `- 🐧 linux: ${statusEmoji} ${{ needs.report-to-allure.outputs.test_result || 'No test results' }}` } }, { @@ -340,7 +315,7 @@ jobs: "fields": [ { "type": "mrkdwn", - "text": "*Allure Report*\n<${{ steps.allure-server.outputs.report-url }}|allure-results-linux>" + "text": "*Allure Report*\n<${{ needs.report-to-allure.outputs.report-url }}|allure-results-linux>" }, { "type": "mrkdwn", @@ -355,19 +330,17 @@ jobs: fs.writeFileSync("payload-slack-content.json", JSON.stringify(slackPayload), "utf-8"); - name: Print Slack Payload Content - if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} run: cat ${{ github.workspace }}/payload-slack-content.json - - name: post to a Slack channel + - name: Post to a Slack channel id: slack uses: slackapi/slack-github-action@v1.23.0 - if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} with: channel-id: "C05FKJ7DFAP" payload-file-path: ${{ github.workspace }}/payload-slack-content.json env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_LIVE_CI_BOT_TOKEN }} - STATUS_COLOR: ${{ env.STATUS_COLOR }} + STATUS_COLOR: ${{ needs.report-to-allure.outputs.status_color }} upload-to-xray: name: "Upload to Xray" diff --git a/tools/actions/composites/get-allure-summary/action.yml b/tools/actions/composites/get-allure-summary/action.yml new file mode 100644 index 000000000000..f979d6dde51f --- /dev/null +++ b/tools/actions/composites/get-allure-summary/action.yml @@ -0,0 +1,51 @@ +name: "Get Allure Summary" +description: "Generates a test summary from allure report" +inputs: + platform: + description: "Platform (android, iOS or linux)" + required: true + allure-results-path: + description: "Path to allure files" + required: true +outputs: + test_result: + value: ${{ steps.get-summary.outputs.test_result }} + description: "Test result summary" + status_color: + value: ${{ steps.get-summary.outputs.status_color }} + description: "Slack Status color" + status_emoji: + value: ${{ steps.get-summary.outputs.status_emoji }} + description: "Slack Status emoji" +runs: + using: composite + steps: + - name: Get summary + id: get-summary + run: | + cd ${{ inputs.allure-results-path }} + allure generate . + cd allure-report/widgets + passedTests=$(jq '.statistic.passed' summary.json) + failedTests=$(jq '.statistic.failed' summary.json) + brokenTests=$(jq '.statistic.broken' summary.json) + skippedTests=$(jq '.statistic.skipped' summary.json) + totalTests=$(jq '.statistic.total' summary.json) + echo "test_result=$passedTests passed, $failedTests failed, $brokenTests broken, $skippedTests skipped, $totalTests total" >> "$GITHUB_OUTPUT" + + if [ "$failedTests" -gt 0 ] || [ "$brokenTests" -gt 0 ]; then + echo "status_color=#FF333C" >> "$GITHUB_OUTPUT"; + echo "status_emoji=❌" >> "$GITHUB_OUTPUT"; + else + echo "status_color=#33FF39" >> "$GITHUB_OUTPUT"; + echo "status_emoji=✅" >> "$GITHUB_OUTPUT"; + fi + shell: bash + - name: Generate single file Allure report + run: allure generate ${{ inputs.allure-results-path }} --single-file --clean + shell: bash + - name: Upload Allure single file report + uses: actions/upload-artifact@v4 + with: + name: allure-report-${{ inputs.platform }} + path: allure-report/index.html diff --git a/tools/actions/composites/upload-allure-report/action.yml b/tools/actions/composites/upload-allure-report/action.yml index 4b938bfe8c74..51a849812949 100644 --- a/tools/actions/composites/upload-allure-report/action.yml +++ b/tools/actions/composites/upload-allure-report/action.yml @@ -27,15 +27,20 @@ runs: - name: Download Allure Report uses: actions/download-artifact@v4 with: - name: ${{ inputs.path }} path: ${{ inputs.path }} + pattern: ${{ inputs.path }}* + merge-multiple: true - name: Publish report on Allure Server + id: publish-report uses: LedgerHQ/send-to-allure-server-action@2.1.2 with: allure-server-url: "https://ledger-live.allure.green.ledgerlabs.net" build-name: ${{ github.workflow }}-${{ inputs.platform }} - build-url: https://github.com/LedgerHQ/ledger-live/actions/runs/${{ github.run_id }} + build-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} username: ${{ inputs.login }} password: ${{ inputs.password }} path: "${{ steps.branch-name.outputs.current_branch }}-${{ inputs.platform }}" allure-results: ${{ inputs.path }} + - name: Write Allure report in summary + shell: bash + run: echo "::notice title=${{ inputs.platform }} Allure report URL::${{ steps.publish-report.outputs.report-url }}"