Merge pull request #8978 from QwikDev/claude/github-issue-8977-52e76b #23880
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
| # Build and test everything | |
| # | |
| # First it builds the packages and stores them in artifacts/cache. | |
| # Meanwhile it lints the code. | |
| # Then it runs the unit tests with the artifacts, as well as builds the docs and insights | |
| # Once it all works, it does a release | |
| # | |
| # NOTE: only use pnpm run scripts for build commands | |
| # This way we're sure that dev and CI environments are consistent | |
| name: Qwik CI | |
| # TODO fix e2e tests hanging and not cancelling | |
| # # We only need one instance of the workflow running at a time, per branch | |
| # concurrency: | |
| # group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} | |
| # cancel-in-progress: true | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| - upcoming | |
| - next | |
| - vercelserverless | |
| - 'build/**' | |
| workflow_dispatch: | |
| inputs: | |
| disttag: | |
| description: 'Publish "@qwik.dev/core" to NPM using this dist-tag, push the git-tag to the repo and create a GitHub release. The "latest" and "next" dist-tags will use the version number already committed in package.json.' | |
| required: true | |
| type: choice | |
| default: 'dev' | |
| options: | |
| - dev | |
| - next | |
| - latest | |
| env: | |
| # Disable incremental build, speeds up CI | |
| CARGO_INCREMENTAL: 0 | |
| CI_NODE_VERSION: 24.15.0 | |
| CI_NODE_VERSION_E2E: 22.22.2 | |
| permissions: | |
| contents: read | |
| jobs: | |
| changes: | |
| name: Setup | |
| runs-on: ubuntu-latest | |
| outputs: | |
| hash-qwik: ${{ steps.cache-qwik.outputs.cache-primary-key }} | |
| hash-rust: ${{ steps.cache-rust.outputs.cache-primary-key }} | |
| hash-others: ${{ steps.cache-others.outputs.cache-primary-key }} | |
| hash-docs: ${{ steps.cache-docs.outputs.cache-primary-key }} | |
| hash-insights: ${{ steps.cache-insights.outputs.cache-primary-key }} | |
| hash-unit: ${{ steps.cache-unit.outputs.cache-primary-key }} | |
| hash-bench: ${{ steps.cache-bench.outputs.cache-primary-key }} | |
| hash-e2e: ${{ steps.cache-e2e.outputs.cache-primary-key }} | |
| hash-cli-e2e: ${{ steps.cache-cli-e2e.outputs.cache-primary-key }} | |
| hash-docs-e2e: ${{ steps.cache-docs-e2e.outputs.cache-primary-key }} | |
| build-qwik: ${{ steps.cache-qwik.outputs.cache-hit != 'true' }} | |
| build-rust: ${{ steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-others: ${{ steps.cache-others.outputs.cache-hit != 'true' || steps.cache-qwik.outputs.cache-hit != 'true' || steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-docs: ${{ steps.cache-docs.outputs.cache-hit != 'true' }} | |
| build-insights: ${{ steps.cache-insights.outputs.cache-hit != 'true' }} | |
| build-unit: ${{ steps.cache-unit.outputs.cache-hit != 'true' || steps.cache-others.outputs.cache-hit != 'true' || steps.cache-qwik.outputs.cache-hit != 'true' || steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-bench: ${{ steps.cache-bench.outputs.cache-hit != 'true' || steps.cache-others.outputs.cache-hit != 'true' || steps.cache-qwik.outputs.cache-hit != 'true' || steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-e2e: ${{ steps.cache-e2e.outputs.cache-hit != 'true' || steps.cache-others.outputs.cache-hit != 'true' || steps.cache-qwik.outputs.cache-hit != 'true' || steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-cli-e2e: ${{ steps.cache-cli-e2e.outputs.cache-hit != 'true' || steps.cache-others.outputs.cache-hit != 'true' || steps.cache-qwik.outputs.cache-hit != 'true' || steps.cache-rust.outputs.cache-hit != 'true' }} | |
| build-docs-e2e: ${{ steps.cache-docs-e2e.outputs.cache-hit != 'true' }} | |
| disttag: ${{ steps.set_dist_tag.outputs.disttag }} | |
| steps: | |
| - name: Branch | |
| run: echo "${{ github.ref }}" | |
| - name: NPM Dist Tag from input | |
| run: echo "${{ github.event.inputs.disttag }}" | |
| - name: Github event | |
| run: echo event_name=${{ github.event_name }} | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - name: Set Dist Tag | |
| id: set_dist_tag | |
| if: | | |
| github.ref == 'refs/heads/main' && ( | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' | |
| ) | |
| run: | | |
| if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then | |
| disttag="${{ github.event.inputs.disttag }}" | |
| echo "Overriding disttag with input: $disttag" | |
| echo "disttag=${disttag}" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| is_release=false | |
| commit_id=${{ github.sha }} | |
| owner=${{ github.repository_owner }} | |
| repo=${{ github.event.repository.name }} | |
| removed_files=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| "https://api.github.com/repos/$owner/$repo/commits/$commit_id" | jq -r '.files[] | select(.status == "removed") | .filename') | |
| echo "Removed files: $removed_files" | |
| md_file_removed=false | |
| for file in $removed_files; do | |
| if [[ $file == .changeset/*.md ]]; then | |
| md_file_removed=true | |
| break | |
| fi | |
| done | |
| if [ $md_file_removed = true ]; then | |
| if ! ls .changeset/*.md > /dev/null 2>&1; then | |
| is_release=true | |
| fi | |
| fi | |
| echo "is_release: $is_release" | |
| if [ "$is_release" = true ]; then | |
| disttag='latest' | |
| else | |
| disttag="${{github.event.inputs.disttag}}" | |
| fi | |
| echo "disttag: $disttag" | |
| echo "disttag=${disttag}" >> $GITHUB_OUTPUT | |
| - run: jq .scripts package.json > scripts.json | |
| - name: 'check cache: qwik' | |
| id: cache-qwik | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: packages/qwik/dist | |
| # Note that this includes the package.json of qwik | |
| # qwik-vite source is bundled into packages/qwik/dist/optimizer.mjs by scripts/submodule-optimizer.ts, so its sources must invalidate this cache. | |
| # CI-only helpers should not invalidate compiled package output caches. | |
| key: ${{ hashfiles('pnpm-lock.yaml', 'scripts.json', 'scripts/**/*', '!scripts/ci-restore-artifacts.ts', 'packages/qwik/**/*', 'packages/qwik-vite/**/*', 'starters/features/**/*', 'starters/adapters/**/*', 'starters/templates/**/*', '!**/*.unit.*', '!**/*.rs', '!e2e/qwik-e2e/apps/e2e') }} | |
| - run: 'echo ${{ steps.cache-qwik.outputs.cache-primary-key }} > qwik-key.txt' | |
| - name: 'check cache: rust' | |
| id: cache-rust | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: packages/optimizer/ | |
| key: ${{ hashfiles('Makefile', 'rust-toolchain', '**/Cargo.toml', '**/Cargo.lock', '**/*.rs') }} | |
| - run: 'echo ${{ steps.cache-rust.outputs.cache-primary-key }} > rust-key.txt' | |
| - name: 'check cache: others' | |
| id: cache-others | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: | | |
| packages/qwik-router/lib | |
| packages/qwik-react/lib | |
| packages/qwik-utils/lib | |
| packages/eslint-plugin-qwik/dist | |
| packages/create-qwik/dist | |
| packages/devtools/dist | |
| # note that all inputs need to be listed here, including qwik, for correct cache invalidation | |
| key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-router/**/*', 'packages/qwik-react/**/*', 'packages/qwik-utils/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', 'packages/devtools/**/*', 'starters/apps/**/*', 'e2e/qwik-e2e/apps/**/*', '!**/*.unit.*') }} | |
| - run: 'echo ${{ steps.cache-others.outputs.cache-primary-key }} > others-key.txt' | |
| - name: 'check cache: docs' | |
| id: cache-docs | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: docs-build-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'packages/docs/**/*') }} | |
| - name: 'check cache: insights' | |
| id: cache-insights | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: | | |
| packages/insights/dist | |
| packages/insights/.netlify | |
| key: ${{ hashfiles('others-key.txt', 'packages/insights/**/*') }} | |
| - name: 'check cache: unit tests' | |
| id: cache-unit | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: unit-tests-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'packages/**/*.unit.*', 'packages/**/*.spec.*') }} | |
| - name: 'check cache: benchmarks' | |
| id: cache-bench | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: bench-tests-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'packages/**/*.bench.*', 'scripts/validate-bench*') }} | |
| - name: 'check cache: e2e tests' | |
| id: cache-e2e | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: e2e-tests-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'starters/**/*', 'e2e/qwik-e2e/tests/**/*', 'e2e/qwik-e2e/dev-server.ts', 'e2e/qwik-e2e/playwright.config.ts') }} | |
| - name: 'check cache: cli e2e tests' | |
| id: cache-cli-e2e | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: cli-e2e-tests-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'e2e/**/*') }} | |
| - name: 'check cache: docs e2e tests' | |
| id: cache-docs-e2e | |
| uses: actions/cache/restore@v5 | |
| with: | |
| lookup-only: true | |
| path: docs-e2e-tests-completed.txt | |
| key: ${{ hashfiles('others-key.txt', 'e2e/docs-e2e/**/*') }} | |
| ############ BUILD PLATFORM BINDINGS ############ | |
| build-bindings: | |
| if: needs.changes.outputs.build-rust == 'true' | |
| strategy: | |
| matrix: | |
| settings: | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| checks: true | |
| wasm: true | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| - host: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| name: Build optimizer ${{ matrix.settings.target }} | |
| runs-on: ${{ matrix.settings.host }} | |
| needs: changes | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - name: Install Rust toolchain | |
| uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1 | |
| with: | |
| components: clippy,rustfmt | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - run: pnpm install | |
| - name: Install Wasm build tools | |
| if: matrix.settings.wasm | |
| run: | | |
| rustup target add wasm32-unknown-unknown | |
| cargo install wasm-pack --locked | |
| - name: Lint check | |
| if: matrix.settings.checks | |
| run: pnpm lint.rust | |
| - name: Unit tests | |
| if: matrix.settings.checks | |
| run: pnpm test.rust | |
| - name: TS bridge | |
| if: matrix.settings.checks | |
| run: pnpm build --optimizer | |
| - name: Build Platform Binding | |
| run: pnpm build --platform-binding | |
| - name: Build Wasm Binding | |
| if: matrix.settings.wasm | |
| run: pnpm build --wasm | |
| - name: Print Packages Dist Build | |
| continue-on-error: true | |
| run: ls -lR packages/optimizer/bindings/ | |
| - name: Upload Platform Binding Artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-bindings-${{ matrix.settings.target }} | |
| include-hidden-files: true | |
| path: | | |
| packages/optimizer/bindings | |
| packages/optimizer/dist | |
| if-no-files-found: error | |
| ############ BUILD PACKAGE ############ | |
| combined-optimizer: | |
| name: Prepare Optimizer binaries | |
| if: always() | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build-bindings | |
| - changes | |
| steps: | |
| - name: Verify builds | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| ( | |
| ( | |
| needs.changes.outputs.build-rust == 'true' && | |
| needs.build-bindings.result == 'success' | |
| ) || | |
| ( | |
| needs.changes.outputs.build-rust != 'true' && | |
| needs.build-bindings.result == 'skipped' | |
| ) | |
| ) | |
| ) | |
| run: exit 1 | |
| - name: Restore optimizer cache | |
| if: needs.changes.outputs.build-rust != 'true' | |
| uses: actions/cache/restore@v4 | |
| with: | |
| fail-on-cache-miss: true | |
| path: packages/optimizer/ | |
| key: ${{ needs.changes.outputs.hash-rust }} | |
| - name: Restore artifacts | |
| if: needs.changes.outputs.build-rust == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-bindings-*' | |
| merge-multiple: false | |
| - name: Move Rust Artifacts | |
| if: needs.changes.outputs.build-rust == 'true' | |
| run: | | |
| mkdir -p packages/optimizer/bindings | |
| mkdir -p packages/optimizer/dist | |
| for dir in artifact-bindings-*; do | |
| if [ -d "$dir" ]; then | |
| mv "$dir"/bindings/* packages/optimizer/bindings/ | |
| fi | |
| if [ -d "$dir/dist" ]; then | |
| mv "$dir"/dist/* packages/optimizer/dist/ | |
| fi | |
| done | |
| - name: Save rust cache | |
| if: needs.changes.outputs.build-rust == 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-rust }} | |
| path: packages/optimizer/ | |
| - name: Upload optimizer artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-optimizer | |
| include-hidden-files: true | |
| path: | | |
| packages/optimizer/bindings | |
| packages/optimizer/dist | |
| if-no-files-found: error | |
| build-other-packages: | |
| name: Build Packages | |
| needs: | |
| - changes | |
| - combined-optimizer | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.combined-optimizer.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| if: needs.changes.outputs.build-qwik == 'true' || needs.changes.outputs.build-others == 'true' | |
| - name: Setup Node | |
| if: needs.changes.outputs.build-qwik == 'true' || needs.changes.outputs.build-others == 'true' | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Restore optimizer artifact | |
| if: needs.changes.outputs.build-qwik == 'true' || needs.changes.outputs.build-others == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: artifact-optimizer | |
| path: packages/optimizer/ | |
| - name: Install NPM Dependencies | |
| if: needs.changes.outputs.build-qwik == 'true' || needs.changes.outputs.build-others == 'true' | |
| run: | | |
| # Ensure that the optimizer binary gets made | |
| mkdir -p packages/optimizer/bindings/ | |
| pnpm install --frozen-lockfile | |
| - name: 'build: qwik and packages' | |
| if: needs.changes.outputs.build-qwik == 'true' && needs.changes.outputs.build-others == 'true' | |
| run: pnpm build --qwik --optimizer --insights --tsc --api --qwikrouter --cli --qwikreact --qwikutils --eslint --devtools --set-dist-tag="${{ needs.changes.outputs.disttag }}" | |
| - name: 'build: qwik' | |
| if: needs.changes.outputs.build-qwik == 'true' && needs.changes.outputs.build-others != 'true' | |
| # Also build optimizer for now | |
| run: pnpm build --qwik --optimizer --insights --set-dist-tag="${{ needs.changes.outputs.disttag }}" | |
| - name: Restore qwik cache | |
| if: needs.changes.outputs.build-qwik != 'true' | |
| uses: actions/cache/restore@v5 | |
| with: | |
| fail-on-cache-miss: true | |
| path: packages/qwik/dist | |
| key: ${{ needs.changes.outputs.hash-qwik }} | |
| - name: Print Qwik Dist Build | |
| continue-on-error: true | |
| run: tree -a packages/qwik/dist/ | |
| - name: Save qwik cache | |
| if: needs.changes.outputs.build-qwik == 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-qwik }} | |
| path: packages/qwik/dist | |
| - name: Upload Qwik artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-qwik | |
| include-hidden-files: true | |
| path: packages/qwik/dist/ | |
| if-no-files-found: error | |
| - name: 'build: qwik-router & others' | |
| if: needs.changes.outputs.build-others == 'true' && needs.changes.outputs.build-qwik != 'true' | |
| run: pnpm build --tsc --api --qwikrouter --cli --qwikreact --qwikutils --eslint --devtools --set-dist-tag="${{ needs.changes.outputs.disttag }}" | |
| - name: Save others cache | |
| if: needs.changes.outputs.build-others == 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-others }} | |
| path: | | |
| packages/qwik-router/lib | |
| packages/qwik-react/lib | |
| packages/qwik-utils/lib | |
| packages/eslint-plugin-qwik/dist | |
| packages/create-qwik/dist | |
| packages/devtools/dist | |
| - name: 'restore: qwik-router & others' | |
| if: needs.changes.outputs.build-others != 'true' | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| packages/qwik-router/lib | |
| packages/qwik-react/lib | |
| packages/qwik-utils/lib | |
| packages/eslint-plugin-qwik/dist | |
| packages/create-qwik/dist | |
| packages/devtools/dist | |
| key: ${{ needs.changes.outputs.hash-others }} | |
| - name: Print QwikRouter Lib Build | |
| run: tree -a packages/qwik-router/lib/ | |
| - name: Upload QwikRouter Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-qwikrouter | |
| include-hidden-files: true | |
| path: packages/qwik-router/lib/ | |
| if-no-files-found: error | |
| - name: Print qwik-react Lib Build | |
| run: tree -a packages/qwik-react/lib/ | |
| - name: Upload qwik-react Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-qwikreact | |
| include-hidden-files: true | |
| path: | | |
| packages/qwik-react/lib/ | |
| if-no-files-found: error | |
| - name: Print qwik-utils Lib Build | |
| run: tree -a packages/qwik-utils/lib/ | |
| - name: Upload qwik-utils Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-qwikutils | |
| include-hidden-files: true | |
| path: | | |
| packages/qwik-utils/lib/ | |
| if-no-files-found: error | |
| - name: Print Create Qwik CLI Dist Build | |
| run: tree -a packages/create-qwik/dist/ | |
| - name: Upload Create Qwik CLI Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-create-qwik | |
| include-hidden-files: true | |
| path: packages/create-qwik/dist/ | |
| if-no-files-found: error | |
| - name: Print Eslint rules Dist Build | |
| run: tree -a packages/eslint-plugin-qwik/dist/ | |
| - name: Upload Eslint rules Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-eslint-plugin-qwik | |
| include-hidden-files: true | |
| path: packages/eslint-plugin-qwik/dist/ | |
| if-no-files-found: error | |
| - name: Print devtools Dist Build | |
| run: tree -a packages/devtools/dist/ | |
| - name: Upload devtools Build Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-devtools | |
| include-hidden-files: true | |
| path: packages/devtools/dist/ | |
| if-no-files-found: error | |
| ############ BUILD INSIGHTS ############ | |
| build-insights: | |
| if: always() && needs.changes.outputs.build-insights == 'true' | |
| name: Build Insights | |
| needs: | |
| - changes | |
| - build-other-packages | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Build Qwik Insights | |
| run: pnpm run build.packages.insights | |
| - name: Save Insights Cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-insights }} | |
| path: | | |
| packages/insights/dist | |
| packages/insights/.netlify | |
| ############ BUILD DOCS ############ | |
| build-docs: | |
| if: always() && needs.changes.outputs.build-docs == 'true' | |
| name: Build Docs | |
| needs: | |
| - changes | |
| - build-other-packages | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Build Qwik Docs | |
| run: pnpm build --tsc-docs && pnpm run build.packages.docs && echo ok > docs-build-completed.txt | |
| - name: Save Docs Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: artifact-docs | |
| include-hidden-files: true | |
| path: | | |
| packages/docs/dist | |
| packages/docs/server | |
| - name: Save Docs Cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-docs }} | |
| path: docs-build-completed.txt | |
| ############ PLAYWRIGHT BROWSER CACHE ############ | |
| prepare-playwright: | |
| name: Prepare Playwright (${{ matrix.settings.host }}, ${{ matrix.settings.browser }}) | |
| if: | | |
| always() && ( | |
| needs.changes.outputs.build-e2e == 'true' || | |
| needs.changes.outputs.build-cli-e2e == 'true' || | |
| needs.changes.outputs.build-docs-e2e == 'true' | |
| ) | |
| needs: | |
| - changes | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: ubuntu-latest | |
| browser: chromium | |
| - host: windows-latest | |
| browser: chromium | |
| - host: macos-latest | |
| browser: webkit | |
| runs-on: ${{ matrix.settings.host }} | |
| env: | |
| PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright | |
| steps: | |
| - name: Verify prerequisites | |
| if: needs.changes.result != 'success' | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION_E2E }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Restore Playwright browser cache | |
| id: playwright-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: playwright-${{ runner.os }}-${{ matrix.settings.browser }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| path: .cache/ms-playwright | |
| - name: Install NPM Dependencies | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm install --frozen-lockfile | |
| - name: Install Playwright Browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm exec playwright install ${{ matrix.settings.browser }} | |
| - name: Save Playwright browser cache | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| continue-on-error: true | |
| with: | |
| key: playwright-${{ runner.os }}-${{ matrix.settings.browser }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| path: .cache/ms-playwright | |
| ############ DOCS E2E TEST ############ | |
| test-e2e-docs: | |
| timeout-minutes: 15 | |
| name: Docs E2E Tests (shard ${{ matrix.shard.shard }}/${{ matrix.shard.shardTotal }}) | |
| if: always() && needs.build-docs.result == 'success' && needs.changes.outputs.build-docs-e2e == 'true' | |
| needs: | |
| - changes | |
| - build-docs | |
| - build-other-packages | |
| - prepare-playwright | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: | |
| - shard: 1 | |
| shardTotal: 2 | |
| - shard: 2 | |
| shardTotal: 2 | |
| runs-on: ubuntu-latest | |
| env: | |
| PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' && | |
| needs.build-docs.result == 'success' && | |
| needs.prepare-playwright.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Download Docs Artifact | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: artifact-docs | |
| path: artifact-docs | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| artifact-docs | |
| - run: pnpm install --frozen-lockfile | |
| - name: Restore Playwright browser cache | |
| id: playwright-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: playwright-${{ runner.os }}-chromium-${{ hashFiles('pnpm-lock.yaml') }} | |
| path: .cache/ms-playwright | |
| - name: Install Playwright System Dependencies | |
| if: runner.os == 'Linux' | |
| run: pnpm exec playwright install-deps chromium | |
| - name: Install Playwright Browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm exec playwright install chromium | |
| - name: Docs E2E Tests | |
| run: pnpm exec playwright test --config=e2e/docs-e2e/playwright.config.ts --project=chromium --shard=${{ matrix.shard.shard }}/${{ matrix.shard.shardTotal }} | |
| - name: Upload Playwright Trace | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: docs-playwright-report-${{ matrix.shard.shard }}-${{ matrix.shard.shardTotal }} | |
| path: e2e/docs-e2e/test-results/ | |
| retention-days: 30 | |
| save-docs-e2e-tests-cache: | |
| name: Save Docs E2E Tests Cache | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - test-e2e-docs | |
| if: always() && needs.changes.outputs.build-docs-e2e == 'true' && needs.test-e2e-docs.result == 'success' | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.test-e2e-docs.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Mark docs e2e tests complete | |
| run: echo ok > docs-e2e-tests-completed.txt | |
| - name: Save docs e2e tests cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-docs-e2e }} | |
| path: docs-e2e-tests-completed.txt | |
| ############ UNIT TEST ############ | |
| test-unit: | |
| name: Unit Tests | |
| if: always() && needs.changes.outputs.build-unit == 'true' | |
| strategy: | |
| matrix: | |
| settings: | |
| - host: ubuntu-latest | |
| - host: windows-latest | |
| runs-on: ${{ matrix.settings.host }} | |
| needs: | |
| - changes | |
| - build-other-packages | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Unit Tests | |
| run: pnpm run test.unit | |
| save-unit-tests-cache: | |
| name: Save Unit Tests Cache | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - test-unit | |
| if: always() && needs.changes.outputs.build-unit == 'true' && needs.test-unit.result == 'success' | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.test-unit.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Mark unit tests complete | |
| run: echo ok > unit-tests-completed.txt | |
| - name: Save unit tests cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-unit }} | |
| path: unit-tests-completed.txt | |
| ############ BENCHMARK TEST ############ | |
| test-bench: | |
| name: Benchmark Tests | |
| if: always() && needs.changes.outputs.build-bench == 'true' | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - build-other-packages | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Timing Benchmarks | |
| run: pnpm run test.bench.timing | |
| - name: Memory Benchmarks | |
| run: pnpm run test.bench.memory | |
| save-bench-cache: | |
| name: Save Benchmark Cache | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - test-bench | |
| if: always() && needs.changes.outputs.build-bench == 'true' && needs.test-bench.result == 'success' | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.test-bench.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Mark benchmarks complete | |
| run: echo ok > bench-tests-completed.txt | |
| - name: Save benchmarks cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-bench }} | |
| path: bench-tests-completed.txt | |
| ############ E2E TEST ############ | |
| test-e2e: | |
| # Sometimes the tests just hang | |
| timeout-minutes: 20 | |
| name: E2E Tests (${{ matrix.settings.host }}, ${{ matrix.settings.browser }}, shard ${{ matrix.settings.shard }}/${{ matrix.settings.shardTotal }}) | |
| if: always() && needs.changes.outputs.build-e2e == 'true' | |
| needs: | |
| - build-other-packages | |
| - changes | |
| - prepare-playwright | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: ubuntu-latest | |
| browser: chromium | |
| shard: 1 | |
| shardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| shard: 2 | |
| shardTotal: 2 | |
| # Some tests are failing on firefox, disable for now | |
| # - host: ubuntu-latest | |
| # browser: firefox | |
| - host: windows-latest | |
| browser: chromium | |
| shard: 1 | |
| shardTotal: 4 | |
| - host: windows-latest | |
| browser: chromium | |
| shard: 2 | |
| shardTotal: 4 | |
| - host: windows-latest | |
| browser: chromium | |
| shard: 3 | |
| shardTotal: 4 | |
| - host: windows-latest | |
| browser: chromium | |
| shard: 4 | |
| shardTotal: 4 | |
| - host: macos-latest | |
| browser: webkit | |
| shard: 1 | |
| shardTotal: 4 | |
| - host: macos-latest | |
| browser: webkit | |
| shard: 2 | |
| shardTotal: 4 | |
| - host: macos-latest | |
| browser: webkit | |
| shard: 3 | |
| shardTotal: 4 | |
| - host: macos-latest | |
| browser: webkit | |
| shard: 4 | |
| shardTotal: 4 | |
| runs-on: ${{ matrix.settings.host }} | |
| env: | |
| PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' && | |
| needs.prepare-playwright.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION_E2E }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Restore Playwright browser cache | |
| id: playwright-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: playwright-${{ runner.os }}-${{ matrix.settings.browser }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| path: .cache/ms-playwright | |
| - name: Install Playwright System Dependencies | |
| if: runner.os == 'Linux' | |
| run: pnpm exec playwright install-deps ${{ matrix.settings.browser }} | |
| - name: Install Playwright Browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm exec playwright install ${{ matrix.settings.browser }} | |
| - name: Playwright E2E Tests | |
| run: pnpm exec playwright test e2e/qwik-e2e/tests --browser=${{ matrix.settings.browser }} --config=e2e/qwik-e2e/playwright.config.ts --shard=${{ matrix.settings.shard }}/${{ matrix.settings.shardTotal }} | |
| - name: Upload Playwright Trace | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() # only when tests fail | |
| with: | |
| name: playwright-report-${{ matrix.settings.host }}-${{ matrix.settings.browser }}-${{ matrix.settings.shard }}-${{ matrix.settings.shardTotal }} | |
| path: test-results/ # or test-results/ depending on your config | |
| retention-days: 30 | |
| - name: Print E2E Builds | |
| run: tree -a e2e/qwik-e2e/apps/e2e/dist e2e/qwik-e2e/apps/e2e/server e2e/qwik-e2e/apps/qwikrouter-test/dist e2e/qwik-e2e/apps/qwikrouter-test/server | |
| if: failure() | |
| test-cli-e2e: | |
| name: E2E CLI Tests (${{ matrix.settings.runtime }}, ${{ matrix.settings.host }}, ${{ matrix.settings.browser }}, shard ${{ matrix.settings.shard }}/${{ matrix.settings.shardTotal }}) | |
| if: always() && needs.changes.outputs.build-cli-e2e == 'true' | |
| needs: | |
| - build-other-packages | |
| - changes | |
| - prepare-playwright | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 1 | |
| shardTotal: 2 | |
| cliShard: 1 | |
| cliShardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 2 | |
| shardTotal: 2 | |
| cliShard: 2 | |
| cliShardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: bun | |
| integration-config: e2e/adapters-e2e/playwright.bun.config.ts | |
| run-cli: false | |
| run-qwik-react: false | |
| shard: 1 | |
| shardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: bun | |
| integration-config: e2e/adapters-e2e/playwright.bun.config.ts | |
| run-cli: false | |
| run-qwik-react: false | |
| shard: 2 | |
| shardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: deno | |
| integration-config: e2e/adapters-e2e/playwright.deno.config.ts | |
| run-cli: false | |
| run-qwik-react: false | |
| shard: 1 | |
| shardTotal: 2 | |
| - host: ubuntu-latest | |
| browser: chromium | |
| runtime: deno | |
| integration-config: e2e/adapters-e2e/playwright.deno.config.ts | |
| run-cli: false | |
| run-qwik-react: false | |
| shard: 2 | |
| shardTotal: 2 | |
| - host: macos-latest | |
| browser: webkit | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 1 | |
| shardTotal: 2 | |
| cliShard: 1 | |
| cliShardTotal: 2 | |
| - host: macos-latest | |
| browser: webkit | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 2 | |
| shardTotal: 2 | |
| cliShard: 2 | |
| cliShardTotal: 2 | |
| - host: windows-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 1 | |
| shardTotal: 4 | |
| cliShard: 1 | |
| cliShardTotal: 2 | |
| - host: windows-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: true | |
| run-qwik-react: true | |
| shard: 2 | |
| shardTotal: 4 | |
| cliShard: 2 | |
| cliShardTotal: 2 | |
| - host: windows-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: false | |
| run-qwik-react: true | |
| shard: 3 | |
| shardTotal: 4 | |
| - host: windows-latest | |
| browser: chromium | |
| runtime: node | |
| integration-config: e2e/adapters-e2e/playwright.config.ts | |
| run-cli: false | |
| run-qwik-react: true | |
| shard: 4 | |
| shardTotal: 4 | |
| runs-on: ${{ matrix.settings.host }} | |
| env: | |
| PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.build-other-packages.result == 'success' && | |
| needs.prepare-playwright.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION_E2E }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| - run: pnpm install --frozen-lockfile | |
| - name: Setup Bun | |
| if: matrix.settings.runtime == 'bun' | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version: latest | |
| - name: Setup Deno | |
| if: matrix.settings.runtime == 'deno' | |
| uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2 | |
| with: | |
| deno-version: v2.x | |
| - name: Restore Playwright browser cache | |
| id: playwright-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: playwright-${{ runner.os }}-${{ matrix.settings.browser }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| path: .cache/ms-playwright | |
| - name: Install Playwright System Dependencies | |
| if: runner.os == 'Linux' | |
| run: pnpm exec playwright install-deps ${{ matrix.settings.browser }} | |
| - name: Install Playwright Browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm exec playwright install ${{ matrix.settings.browser }} | |
| - name: Playwright E2E Integration Tests | |
| run: pnpm exec playwright test e2e/adapters-e2e/tests --project=${{ matrix.settings.browser }} --config=${{ matrix.settings.integration-config }} --shard=${{ matrix.settings.shard }}/${{ matrix.settings.shardTotal }} | |
| - name: Playwright E2E Qwik React Tests | |
| if: matrix.settings.run-qwik-react | |
| run: pnpm exec playwright test e2e/qwik-react-e2e/tests --project=${{ matrix.settings.browser }} --config=e2e/qwik-react-e2e/playwright.config.ts --shard=${{ matrix.settings.shard }}/${{ matrix.settings.shardTotal }} | |
| - name: CLI E2E Tests | |
| if: matrix.settings.run-cli | |
| run: pnpm --filter qwik-cli-e2e exec vitest run --config=vite.config.ts --shard=${{ matrix.settings.cliShard }}/${{ matrix.settings.cliShardTotal }} | |
| env: | |
| PW_BROWSER: ${{ matrix.settings.browser }} | |
| save-e2e-tests-cache: | |
| name: Save E2E Tests Cache | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - test-e2e | |
| if: always() && needs.changes.outputs.build-e2e == 'true' && needs.test-e2e.result == 'success' | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.test-e2e.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Mark e2e tests complete | |
| run: echo ok > e2e-tests-completed.txt | |
| - name: Save e2e tests cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-e2e }} | |
| path: e2e-tests-completed.txt | |
| save-cli-e2e-tests-cache: | |
| name: Save CLI E2E Tests Cache | |
| runs-on: ubuntu-latest | |
| needs: | |
| - changes | |
| - test-cli-e2e | |
| if: always() && needs.changes.outputs.build-cli-e2e == 'true' && needs.test-cli-e2e.result == 'success' | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| needs.test-cli-e2e.result == 'success' | |
| ) | |
| run: exit 1 | |
| - name: Mark cli e2e tests complete | |
| run: echo ok > cli-e2e-tests-completed.txt | |
| - name: Save cli-e2e tests cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ needs.changes.outputs.hash-cli-e2e }} | |
| path: cli-e2e-tests-completed.txt | |
| ########### LINT PACKAGES ############ | |
| lint-package: | |
| name: Lint Package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - run: pnpm install --frozen-lockfile | |
| - name: "Verify pnpm dedupe" | |
| if: always() | |
| run: NPM_CONFIG_USERCONFIG=/dev/null pnpm --config.platform=linux --config.arch=x64 dedupe --check | |
| - name: SyncPack Check | |
| if: always() | |
| run: pnpm run lint.syncpack | |
| - name: Prettier Check | |
| if: always() | |
| run: pnpm run lint.prettier | |
| - name: Build ESLint | |
| if: always() | |
| run: pnpm build --eslint | |
| - name: ESLint Check | |
| if: always() | |
| run: pnpm run lint.eslint | |
| ############ RELEASE ############ | |
| release: | |
| name: Release | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: write | |
| pull-requests: write | |
| needs: | |
| - changes | |
| - test-unit | |
| - test-e2e | |
| - test-cli-e2e | |
| # test-unit runs when any packages changes, so we have to release | |
| # on "upcoming", we always check if we have something to release | |
| # don't run on forks | |
| if: | | |
| always() && | |
| github.event_name != 'pull_request' && | |
| github.repository == 'QwikDev/qwik' && ( | |
| github.ref == 'refs/heads/main' || | |
| needs.test-unit.result == 'success' || | |
| needs.test-unit.result == 'skipped' | |
| ) | |
| steps: | |
| - name: Verify prerequisites | |
| if: | | |
| !( | |
| needs.changes.result == 'success' && | |
| ( | |
| needs.test-unit.result == 'success' || | |
| needs.test-unit.result == 'skipped' | |
| ) && | |
| ( | |
| needs.test-e2e.result == 'success' || | |
| needs.test-e2e.result == 'skipped' | |
| ) && | |
| ( | |
| needs.test-cli-e2e.result == 'success' || | |
| needs.test-cli-e2e.result == 'skipped' | |
| ) | |
| ) | |
| run: exit 1 | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: ${{ env.CI_NODE_VERSION }} | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik,devtools}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| artifact-devtools | |
| - run: pnpm install --frozen-lockfile | |
| # Do this before other release steps to avoid | |
| # publishing temporary files | |
| - name: Create Release Pull Request or Publish to npm | |
| if: github.ref == 'refs/heads/main' | |
| id: changesets | |
| uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1 | |
| with: | |
| publish: pnpm release | |
| title: V2 Version Packages | |
| branch: main | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Fixup package.json files | |
| run: pnpm run release.fixup-package-json | |
| - name: Commit Build Artifacts | |
| if: github.event_name == 'push' | |
| env: | |
| QWIK_API_TOKEN_GITHUB: ${{ secrets.QWIK_API_TOKEN_GITHUB }} | |
| run: pnpm run qwik-push-build-repos | |
| ############ PKG.PR.NEW (decoupled from tests) ############ | |
| release-pkg-pr-new: | |
| name: Release pkg.pr.new | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| needs: | |
| - changes | |
| - combined-optimizer | |
| - build-other-packages | |
| # Publish previews as soon as the build is ready, regardless of test status. | |
| if: | | |
| always() && | |
| github.repository == 'QwikDev/qwik' && | |
| github.event_name != 'workflow_dispatch' && | |
| (needs.combined-optimizer.result == 'success' || needs.combined-optimizer.result == 'skipped') && | |
| needs.build-other-packages.result == 'success' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - name: Setup Node | |
| uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 | |
| with: | |
| node-version: 24.x | |
| cache: 'pnpm' | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Download Package Artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: 'artifact-{optimizer,qwik,qwikrouter,qwikreact,qwikutils,create-qwik,eslint-plugin-qwik,devtools}' | |
| merge-multiple: false | |
| - name: Move Distribution Artifacts | |
| run: > | |
| pnpm ci.restore-artifacts | |
| artifact-optimizer | |
| artifact-qwik | |
| artifact-qwikrouter | |
| artifact-qwikreact | |
| artifact-qwikutils | |
| artifact-create-qwik | |
| artifact-eslint-plugin-qwik | |
| artifact-devtools | |
| - run: pnpm install --frozen-lockfile | |
| - name: Fixup package.json files | |
| run: pnpm run release.fixup-package-json | |
| - name: Publish packages for testing | |
| # TODO: bring back --compact in the package.json release.pkg-pr-new script after first npm public of V2 alpha | |
| run: pnpm release.pkg-pr-new | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| ############ TRIGGER QWIKKROUTER E2E TEST ############ | |
| trigger-qwikrouter-e2e: | |
| name: Trigger Qwik Router E2E | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/upcoming' | |
| needs: | |
| - changes | |
| - release | |
| steps: | |
| - name: Repository Dispatch | |
| uses: peter-evans/repository-dispatch@bf47d102fdb849e755b0b0023ea3e81a44b6f570 # v2 | |
| with: | |
| token: ${{ secrets.QWIK_API_TOKEN_GITHUB }} | |
| repository: QwikDev/qwik-city-e2e | |
| event-type: main-updated | |
| ############ Everything is fine ############ | |
| requirements-passed: | |
| name: All requirements are met | |
| runs-on: ubuntu-latest | |
| needs: | |
| - test-unit | |
| - test-bench | |
| - test-e2e | |
| - test-e2e-docs | |
| - test-cli-e2e | |
| - lint-package | |
| - build-docs | |
| - build-insights | |
| if: always() | |
| steps: | |
| - name: check status | |
| if: | | |
| !( | |
| (needs.test-unit.result == 'success' || needs.test-unit.result == 'skipped') && | |
| (needs.test-bench.result == 'success' || needs.test-bench.result == 'skipped') && | |
| (needs.test-e2e.result == 'success' || needs.test-e2e.result == 'skipped') && | |
| (needs.test-e2e-docs.result == 'success' || needs.test-e2e-docs.result == 'skipped') && | |
| (needs.test-cli-e2e.result == 'success' || needs.test-cli-e2e.result == 'skipped') && | |
| (needs.lint-package.result == 'success' || needs.lint-package.result == 'skipped') && | |
| (needs.build-docs.result == 'success' || needs.build-docs.result == 'skipped') && | |
| (needs.build-insights.result == 'success' || needs.build-insights.result == 'skipped') | |
| ) | |
| run: exit 1 |