diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32149b45785..07effd6ffc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,12 @@ # Build and test everything # -# First it builds the packages and stores them in artifacts. +# 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 +# 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 @@ -48,11 +51,15 @@ jobs: 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-e2e: ${{ steps.cache-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' }} 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' }} + build-e2e: ${{ steps.cache-e2e.outputs.cache-hit != 'true' }} steps: - name: Branch @@ -65,20 +72,24 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - run: jq .scripts package.json > scripts.json + - name: 'check cache: qwik' id: cache-qwik uses: actions/cache/restore@v4 with: lookup-only: true path: packages/qwik/dist - key: ${{ hashfiles('pnpm-lock.yaml', 'packages/qwik/**/*') }} + key: ${{ hashfiles('pnpm-lock.yaml', 'scripts.json', 'packages/qwik/**/*', '!**/*.unit.*', '!**/*.rs') }} + - run: 'echo ${{ steps.cache-qwik.outputs.cache-primary-key }} > qwik-key.txt' - name: 'check cache: rust' id: cache-rust uses: actions/cache/restore@v4 with: lookup-only: true path: packages/qwik/bindings - key: ${{ hashfiles('rust-toolchain', '**/Cargo.toml', '**/Cargo.lock', '**/*.rs') }} + 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@v4 @@ -93,7 +104,8 @@ jobs: packages/eslint-plugin-qwik/dist packages/create-qwik/dist # note that all inputs need to be listed here, including qwik, for correct cache invalidation - key: ${{ hashfiles('pnpm-lock.yaml', 'packages/qwik/**/*', 'rust-toolchain', '**/Cargo.toml', '**/Cargo.lock', '**/*.rs', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*') }} + key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', '!**/*.unit.*') }} + - run: 'echo ${{ steps.cache-others.outputs.cache-primary-key }} > others-key.txt' - name: 'check cache: docs' id: cache-docs uses: actions/cache/restore@v4 @@ -102,7 +114,7 @@ jobs: path: | packages/docs/dist packages/docs/server - key: ${{ hashfiles('pnpm-lock.yaml', 'packages/qwik/**/*', 'rust-toolchain', '**/Cargo.toml', '**/Cargo.lock', '**/*.rs', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/docs/**/*') }} + key: ${{ hashfiles('others-key.txt', 'packages/docs/**/*') }} - name: 'check cache: insights' id: cache-insights uses: actions/cache/restore@v4 @@ -111,7 +123,21 @@ jobs: path: | packages/insights/dist packages/insights/.netlify - key: ${{ hashfiles('pnpm-lock.yaml', 'packages/qwik/**/*', 'rust-toolchain', '**/Cargo.toml', '**/Cargo.lock', '**/*.rs', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-insights/**/*') }} + key: ${{ hashfiles('others-key.txt', 'packages/qwik-insights/**/*') }} + - name: 'check cache: unit tests' + id: cache-unit + uses: actions/cache/restore@v4 + with: + lookup-only: true + path: unit-tests-completed.txt + key: ${{ hashfiles('others-key.txt', 'packages/**/*.unit.*') }} + - name: 'check cache: e2e tests' + id: cache-e2e + uses: actions/cache/restore@v4 + with: + lookup-only: true + path: e2e-tests-completed.txt + key: ${{ hashfiles('others-key.txt', 'starters/e2e/**/*', 'starters/apps/e2e/**/*') }} ############ BUILD Qwik ############ build-qwik: @@ -145,6 +171,12 @@ jobs: continue-on-error: true run: tree packages/qwik/dist/ + - name: Save qwik cache + uses: actions/cache/save@v4 + with: + key: ${{ needs.changes.outputs.hash-qwik }} + path: packages/qwik/dist + - name: Save artifacts uses: actions/upload-artifact@v4 with: @@ -152,55 +184,16 @@ jobs: path: packages/qwik/dist/ if-no-files-found: error - ############ BUILD RUST ############ - build-linux-wasm-bindings: - if: needs.changes.outputs.build-rust == 'true' - name: Build optimizer x86 Linux + wasm - needs: changes - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - # additionally install wasm32-unknown-unknown target - target: wasm32-unknown-unknown - - - uses: pnpm/action-setup@v4 - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: 'pnpm' - registry-url: https://registry.npmjs.org/ - # This installs everything + the latest wasm-pack binary - - run: pnpm install wasm-pack - - - name: Build x86 Platform Binding - run: pnpm build --platform-binding - - - name: Build wasm Platform Binding - run: pnpm build --wasm - - - name: Print Packages Dist Build - continue-on-error: true - run: ls -lR packages/qwik/bindings/ - - - name: Upload Platform Binding Artifact - uses: actions/upload-artifact@v4 - with: - name: artifact-bindings-wasm - path: packages/qwik/bindings/* - if-no-files-found: error - ############ BUILD PLATFORM BINDINGS ############ - build-other-bindings: + build-bindings: if: needs.changes.outputs.build-rust == 'true' strategy: matrix: settings: + - host: ubuntu-latest + target: x86_64-unknown-linux-gnu + wasm: true + # the last x86 macos available as a standard runner - host: macos-13 target: x86_64-apple-darwin @@ -231,10 +224,24 @@ jobs: cache: 'pnpm' registry-url: https://registry.npmjs.org/ - run: pnpm install + - if: matrix.settings.wasm + run: pnpm install wasm-pack + + - name: Lint check + if: matrix.settings.wasm + run: pnpm lint.rust + + - name: Unit tests + if: matrix.settings.wasm + run: pnpm test.rust - 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/qwik/bindings/ @@ -243,7 +250,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: artifact-bindings-${{ matrix.settings.target }} - path: packages/qwik/bindings/*.node + path: packages/qwik/bindings/ if-no-files-found: error ############ BUILD PACKAGE ############ @@ -253,8 +260,7 @@ jobs: runs-on: ubuntu-latest needs: - build-qwik - - build-linux-wasm-bindings - - build-other-bindings + - build-bindings - changes steps: @@ -262,25 +268,19 @@ jobs: if: | !( (needs.build-qwik.result == 'success' || needs.build-qwik.result == 'skipped') && - (needs.build-linux-wasm-bindings.result == 'success' || needs.build-linux-wasm-bindings.result == 'skipped') && - (needs.build-other-bindings.result == 'success' || needs.build-other-bindings.result == 'skipped') + (needs.build-bindings.result == 'success' || needs.build-bindings.result == 'skipped') ) run: exit 1 - name: Restore artifacts + if: needs.changes.outputs.build-rust == 'true' uses: actions/download-artifact@v4 - name: Restore Qwik from cache - if: needs.changes.outputs.build-qwik != 'true' uses: actions/cache/restore@v4 with: path: packages/qwik/dist key: ${{ needs.changes.outputs.hash-qwik }} - - name: Move Qwik artifact - if: needs.changes.outputs.build-qwik == 'true' - run: | - mkdir -p packages/qwik/dist/ - mv artifact-qwik-no-optimizer/* packages/qwik/dist/ - name: Restore Rust from cache if: needs.changes.outputs.build-rust != 'true' @@ -295,6 +295,13 @@ jobs: mkdir -p packages/qwik/bindings mv artifact-bindings-*/* packages/qwik/bindings + - name: Save rust cache + if: needs.changes.outputs.build-rust == 'true' + uses: actions/cache/save@v4 + with: + key: ${{ needs.changes.outputs.hash-rust }} + path: packages/qwik/bindings + - name: Upload Qwik artifact uses: actions/upload-artifact@v4 with: @@ -343,6 +350,19 @@ jobs: - name: 'build: qwik-city & others' if: needs.changes.outputs.build-others == 'true' run: pnpm build --tsc --api --qwikcity --cli --qwiklabs --qwikreact --eslint --set-dist-tag="${{ github.event.inputs.disttag }}" + - name: Save others cache + if: needs.changes.outputs.build-others == 'true' + uses: actions/cache/save@v4 + with: + key: ${{ needs.changes.outputs.hash-others }} + path: | + packages/qwik-city/lib + packages/qwik-labs/lib + packages/qwik-labs/vite + packages/qwik-react/lib + packages/qwik-react/vite + packages/eslint-plugin-qwik/dist + packages/create-qwik/dist - name: 'restore: qwik-city & others' if: needs.changes.outputs.build-others != 'true' @@ -569,9 +589,7 @@ jobs: if: | always() && ( github.ref == 'refs/heads/main' || - needs.changes.outputs.build-qwik == 'true' || - needs.changes.outputs.build-others == 'true' || - needs.changes.outputs.build-rust == 'true' + needs.changes.outputs.build-unit == 'true' ) runs-on: ubuntu-latest needs: @@ -611,7 +629,13 @@ jobs: - run: pnpm install --frozen-lockfile - name: Unit Tests - run: pnpm run test.unit + run: pnpm run test.unit && echo ok > unit-tests-completed.txt + + - name: Save unit tests cache + uses: actions/cache/save@v4 + with: + key: ${{ needs.changes.outputs.hash-unit }} + path: unit-tests-completed.txt ############ E2E TEST ############ test-e2e: @@ -620,14 +644,8 @@ jobs: name: E2E Tests if: | always() && ( - github.ref == 'refs/heads/main' || ( - needs.build-other-packages.result == 'success' && - needs.test-unit.result == 'success' && ( - needs.changes.outputs.build-qwik == 'true' || - needs.changes.outputs.build-others == 'true' || - needs.changes.outputs.build-rust == 'true' - ) - ) + github.ref == 'refs/heads/main' || + needs.changes.outputs.build-e2e == 'true' ) needs: @@ -687,33 +705,6 @@ jobs: - name: Validate Create Qwik Cli run: pnpm cli.validate - ########### LINT RUST ############ - validate-rust: - if: needs.changes.outputs.build-rust == 'true' - name: Validate Rust - runs-on: ubuntu-latest - - needs: changes - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - - - name: Format check - run: cargo fmt --check - - - name: Build check - run: cargo check --all-features - - - name: Clippy check - run: cargo clippy --all-features - - - name: Unit tests - run: make test - ########### LINT PACKAGES ############ lint-package: name: Lint Package @@ -763,8 +754,19 @@ jobs: steps: - name: Verify test-e2e - if: needs.test-e2e.result != 'success' - run: exit 1 + if: needs.test-e2e.result != 'skipped' + run: | + if [ "${{ needs.test-e2e.result }}" != success ] ; then + exit 1 + else + echo ok > e2e-tests-completed.txt + fi + - name: Save e2e tests cache + if: needs.test-e2e.result != 'skipped' + uses: actions/cache/save@v4 + with: + key: ${{ needs.changes.outputs.hash-e2e }} + path: e2e-tests-completed.txt - name: Checkout uses: actions/checkout@v4 @@ -798,32 +800,6 @@ jobs: - run: pnpm install --frozen-lockfile - - name: Save qwik cache - if: needs.changes.outputs.build-qwik == 'true' - uses: actions/cache/save@v4 - with: - key: ${{ needs.changes.outputs.hash-qwik }} - path: packages/qwik/dist - - name: Save rust cache - if: needs.changes.outputs.build-rust == 'true' - uses: actions/cache/save@v4 - with: - key: ${{ needs.changes.outputs.hash-rust }} - path: packages/qwik/bindings - - name: Save others cache - if: needs.changes.outputs.build-others == 'true' - uses: actions/cache/save@v4 - with: - key: ${{ needs.changes.outputs.hash-others }} - path: | - packages/qwik-city/lib - packages/qwik-labs/lib - packages/qwik-labs/vite - packages/qwik-react/lib - packages/qwik-react/vite - packages/eslint-plugin-qwik/dist - packages/create-qwik/dist - - name: Commit Build Artifacts if: github.event_name == 'push' env: @@ -831,8 +807,8 @@ jobs: run: pnpm run qwik-save-artifacts - name: Publish packages for testing - if: ${{ github.event_name != 'workflow_dispatch' }} - run: pnpm dlx pkg-pr-new@^0.0.9 publish --compact --pnpm ./packages/qwik ./packages/qwik-city ./packages/eslint-plugin-qwik ./packages/create-qwik + if: github.event_name != 'workflow_dispatch' + run: pnpm release.pkg-pr-new env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -879,7 +855,6 @@ jobs: needs: - test-unit - test-e2e - - validate-rust - lint-package - build-docs - build-insights @@ -890,7 +865,6 @@ jobs: !( (needs.test-unit.result == 'success' || needs.test-unit.result == 'skipped') && (needs.test-e2e.result == 'success' || needs.test-e2e.result == 'skipped') && - (needs.validate-rust.result == 'success' || needs.validate-rust.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') diff --git a/Makefile b/Makefile index ecd034c0035..8854c234170 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,10 @@ fix: cargo fmt check: - cargo fmt -- --check && cargo check + cargo fmt -- --check && cargo check --all-features lint: - cargo clippy + cargo clippy --all-features && cargo check --all-features && cargo fmt -- --check test: cargo test diff --git a/package.json b/package.json index bc6b70665b5..fa842d74646 100644 --- a/package.json +++ b/package.json @@ -201,6 +201,7 @@ "qwik-save-artifacts": "tsm ./scripts/qwik-save-artifacts.ts", "release": "changeset publish", "release.prepare": "pnpm build --prepare-release", + "release.pkg-pr-new": "pnpm dlx pkg-pr-new@^0.0.9 publish --compact --pnpm ./packages/qwik ./packages/qwik-city ./packages/eslint-plugin-qwik ./packages/create-qwik", "serve": "tsm --inspect --conditions=development starters/dev-server.ts 3300", "serve.debug": "tsm --inspect-brk --conditions=development starters/dev-server.ts 3300", "start": "concurrently \"npm:build.watch\" \"npm:tsc.watch\" -n build,tsc -c green,cyan",