Fix web E2E tests: static WASM server + preserve deep-link query para… #279
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| on: | |
| push: | |
| branches: [main] | |
| paths-ignore: | |
| - '**.md' | |
| - 'LICENSE*' | |
| - '.git*' | |
| - '.envrc' | |
| - 'garnix.yaml' | |
| - '.github/workflows/ci.yml' | |
| tags: [v*] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| no-concurrent-tag-workflow: | |
| timeout-minutes: 1 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: {fetch-depth: 0} | |
| - if: github.ref == 'refs/heads/main' # Skip (pass) if triggered by tags: [v*] | |
| run: "! git describe --tags --exact-match HEAD" # Fail if on main and tag | |
| pwa-build-deploy: | |
| needs: no-concurrent-tag-workflow | |
| timeout-minutes: 20 | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| outputs: | |
| page_url: ${{ steps.deployment.outputs.page_url }} | |
| permissions: | |
| actions: read | |
| contents: read | |
| checks: read # Required by wait-on-check-action | |
| statuses: read # Required by wait-on-check-action | |
| pages: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| lfs: true | |
| - uses: cachix/install-nix-action@v31 | |
| with: | |
| github_access_token: ${{ secrets.GITHUB_TOKEN }} | |
| extra_nix_config: | # TODO Ensure nix uses the most performant cache between Garnix and Cachix every time | |
| extra-substituters = https://cache.garnix.io | |
| extra-trusted-public-keys = cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g= | |
| - uses: cachix/cachix-action@v17 | |
| with: | |
| name: gfauredev | |
| authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' | |
| # - uses: DeterminateSystems/magic-nix-cache-action@v13 | |
| - run: sleep 5 # Sleep hoping Garnix evaluation will start after | |
| - uses: lewagon/wait-on-check-action@v1.5.0 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | |
| check-regexp: 'Evaluate flake.nix' | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| fail-on-no-checks: false | |
| allowed-conclusions: success,failure,cancelled,skipped,timed_out,neutral | |
| - uses: lewagon/wait-on-check-action@v1.5.0 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | |
| check-regexp: 'package web.*' | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| fail-on-no-checks: false | |
| allowed-conclusions: success,failure,cancelled,skipped,timed_out,neutral | |
| - if: github.ref == 'refs/heads/main' | |
| run: .script/web-preview-deploy.sh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - if: startsWith(github.ref, 'refs/tags/v') | |
| run: .script/web-deploy.sh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - uses: actions/upload-artifact@v4 | |
| with: { name: web, path: web.tar.gz } | |
| - uses: actions/upload-pages-artifact@v4 | |
| with: { path: ./web/LogOut } | |
| - uses: actions/deploy-pages@v5 | |
| id: deployment | |
| pagespeed: | |
| if: github.ref == 'refs/heads/main' && needs.pwa-build-deploy.result == 'success' | |
| needs: pwa-build-deploy | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Run PageSpeed Insights on preview URL | |
| id: pagespeed | |
| run: | | |
| PREVIEW_URL="${{ needs.pwa-build-deploy.outputs.page_url }}preview/" | |
| echo "Running PageSpeed Insights on $PREVIEW_URL" | |
| RESULT=$(curl -sf \ | |
| "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$PREVIEW_URL")&strategy=desktop${PAGESPEED_API_KEY:+&key=$PAGESPEED_API_KEY}" \ | |
| || echo '{}') | |
| PERF=$(echo "$RESULT" | jq -r '.lighthouseResult.categories.performance.score // "N/A"') | |
| A11Y=$(echo "$RESULT" | jq -r '.lighthouseResult.categories.accessibility.score // "N/A"') | |
| BP=$(echo "$RESULT" | jq -r '.lighthouseResult.categories["best-practices"].score // "N/A"') | |
| SEO=$(echo "$RESULT" | jq -r '.lighthouseResult.categories.seo.score // "N/A"') | |
| PWA=$(echo "$RESULT" | jq -r '.lighthouseResult.categories.pwa.score // "N/A"') | |
| echo "performance=$PERF" >> "$GITHUB_OUTPUT" | |
| echo "accessibility=$A11Y" >> "$GITHUB_OUTPUT" | |
| echo "best_practices=$BP" >> "$GITHUB_OUTPUT" | |
| echo "seo=$SEO" >> "$GITHUB_OUTPUT" | |
| echo "pwa=$PWA" >> "$GITHUB_OUTPUT" | |
| echo "preview_url=$PREVIEW_URL" >> "$GITHUB_OUTPUT" | |
| echo "### 🚀 PageSpeed Insights (preview)" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| URL | Perf | A11y | Best Practices | SEO | PWA |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| --- | ---- | ---- | -------------- | --- | --- |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| $PREVIEW_URL | $PERF | $A11Y | $BP | $SEO | $PWA |" >> "$GITHUB_STEP_SUMMARY" | |
| env: | |
| PAGESPEED_API_KEY: ${{ secrets.PAGESPEED_API_KEY }} | |
| e2e-web-preview: | |
| if: github.ref == 'refs/heads/main' && needs.pwa-build-deploy.result == 'success' | |
| needs: pwa-build-deploy | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 40 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: cachix/install-nix-action@v31 | |
| with: | |
| github_access_token: ${{ secrets.GITHUB_TOKEN }} | |
| extra_nix_config: | | |
| extra-substituters = https://cache.garnix.io | |
| extra-trusted-public-keys = cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g= | |
| - uses: cachix/cachix-action@v17 | |
| with: | |
| name: gfauredev | |
| authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' | |
| - name: Remove system Chrome to prevent version mismatch with nixpkgs chromedriver | |
| run: sudo apt-get remove -y google-chrome-stable | |
| - name: Run Maestro E2E tests on preview URL | |
| run: | | |
| set -o pipefail | |
| APP_URL="${{ needs.pwa-build-deploy.outputs.page_url }}preview/" \ | |
| nix run .#webE2eTestPreview |& tee maestro_console.log | |
| # Screenshot upload/post temporarily disabled | |
| # - if: failure() | |
| # env: | |
| # CLOUDINARY_CLOUD_NAME: ${{ secrets.CLOUDINARY_CLOUD_NAME }} | |
| # CLOUDINARY_UPLOAD_PRESET: ${{ secrets.CLOUDINARY_UPLOAD_PRESET }} | |
| # run: .script/e2e-web-report.sh | |
| # id: upload_screenshots | |
| # - if: failure() && steps.upload_screenshots.outputs.REPORT_BODY != '' | |
| # uses: peter-evans/create-or-update-comment@v5 | |
| # with: | |
| # issue-number: ${{ github.event.pull_request.number }} | |
| # body: ${{ steps.upload_screenshots.outputs.REPORT_BODY }} | |
| - if: failure() || cancelled() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: maestro-web-preview-report | |
| path: ~/.maestro/tests/ | |
| android-build: | |
| needs: no-concurrent-tag-workflow | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| checks: read # Required by wait-on-check-action | |
| statuses: read # Required by wait-on-check-action | |
| actions: read # Required to download artifacts from CI workflow runs | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| lfs: true | |
| - name: Check for existing CI artifact | |
| id: ci-artifact | |
| run: | | |
| RUN_ID=$(gh run list \ | |
| --workflow ci.yml \ | |
| --commit "${{ github.sha }}" \ | |
| --json databaseId \ | |
| --jq '.[0].databaseId' 2>/dev/null || echo "") | |
| if [ -n "$RUN_ID" ] && [ "$RUN_ID" != "null" ]; then | |
| JOB_STATUS=$(gh run view "$RUN_ID" --json jobs \ | |
| --jq '.jobs[] | select(.name == "android-build") | .conclusion' 2>/dev/null || echo "") | |
| if [ "$JOB_STATUS" = "success" ]; then | |
| echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT" | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| fi | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - if: steps.ci-artifact.outputs.found == 'true' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: android | |
| run-id: ${{ steps.ci-artifact.outputs.run_id }} | |
| github-token: ${{ github.token }} | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| uses: cachix/install-nix-action@v31 | |
| with: | |
| github_access_token: ${{ secrets.GITHUB_TOKEN }} | |
| extra_nix_config: | # TODO Ensure nix uses the most performant cache between Garnix and Cachix every time | |
| extra-substituters = https://cache.garnix.io | |
| extra-trusted-public-keys = cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g= | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| uses: cachix/cachix-action@v17 | |
| with: | |
| name: gfauredev | |
| authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| run: sleep 5 # Sleep hoping Garnix evaluation will start after | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| uses: lewagon/wait-on-check-action@v1.5.0 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | |
| check-regexp: 'Evaluate flake.nix' | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| fail-on-no-checks: false | |
| allowed-conclusions: success,failure,cancelled,skipped,timed_out,neutral | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| uses: lewagon/wait-on-check-action@v1.5.0 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | |
| check-regexp: 'package androidBuild.*' | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| fail-on-no-checks: false | |
| allowed-conclusions: success,failure,cancelled,skipped,timed_out,neutral | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| uses: timheuer/base64-to-file@v1.2.4 | |
| with: | |
| fileName: 'logout.jks' | |
| encodedString: ${{ secrets.ANDROID_KEYSTORE_B64 }} | |
| id: keystore | |
| - if: steps.ci-artifact.outputs.found != 'true' | |
| run: nix run .#androidBuild | |
| env: | |
| ANDROID_KEYSTORE_PATH: ${{ steps.keystore.outputs.filePath }} | |
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| - uses: actions/upload-artifact@v4 | |
| with: { name: android, path: '*.apk' } | |
| prerelease: | |
| if: github.ref == 'refs/heads/main' | |
| needs: [no-concurrent-tag-workflow, android-build] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 3 | |
| permissions: | |
| contents: write # Required by 'gh release' | |
| checks: read # Required by wait-on-check-action | |
| statuses: read # Required by wait-on-check-action | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/download-artifact@v4 | |
| with: { name: android } | |
| - run: .script/prerelease.sh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| prerelease-cleanup: | |
| needs: no-concurrent-tag-workflow | |
| timeout-minutes: 1 | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - run: .script/prerelease-cleanup.sh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| release: | |
| needs: [pwa-build-deploy, android-build] | |
| if: >- | |
| always() && | |
| startsWith(github.ref, 'refs/tags/v') && | |
| (needs.pwa-build-deploy.result == 'success' || needs.android-build.result == 'success') | |
| timeout-minutes: 3 | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # Required by 'gh release' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/download-artifact@v4 | |
| if: needs.pwa-build-deploy.result == 'success' | |
| with: { name: web } | |
| - uses: actions/download-artifact@v4 | |
| if: needs.android-build.result == 'success' | |
| with: { name: android } | |
| - run: | | |
| TAG=${GITHUB_REF#refs/tags/} | |
| PREV_TAG=$(git tag --sort=-version:refname | grep -Fxv "$TAG" | head -n 1) | |
| NOTES=$(.script/changelog-notes.sh "$PREV_TAG" "$TAG") | |
| ASSETS=$(ls *.apk web.tar.gz 2>/dev/null | tr '\n' ' ') | |
| gh release create "$TAG" $ASSETS --title "$TAG" --notes "$NOTES" | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |