fix(core): reconcile read/write quantity basis for OrderLine discount… #8387
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
| name: Build & Test | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - master | |
| - minor | |
| - major | |
| paths: | |
| - 'packages/**' | |
| - 'package.json' | |
| - 'bun.lock' | |
| - 'bunfig.toml' | |
| pull_request: | |
| branches: | |
| - master | |
| - major | |
| - minor | |
| env: | |
| CI: true | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| # NOTE: The Redis service definition is duplicated across the e2e-* jobs | |
| # because GitHub Actions does not support YAML anchors or service definition reuse. | |
| # When updating the service (version bumps, env changes, health checks), update ALL four copies: | |
| # e2e-sqljs, e2e-mariadb, e2e-mysql, e2e-postgres. | |
| jobs: | |
| detect-changes: | |
| name: detect changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| packages: ${{ steps.check.outputs.packages }} | |
| dashboard: ${{ steps.check.outputs.dashboard }} | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed paths | |
| id: check | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "packages=true" >> "$GITHUB_OUTPUT" | |
| echo "dashboard=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| base="${{ github.event.pull_request.base.sha }}" | |
| if [ -z "$base" ]; then base="${{ github.event.before }}"; fi | |
| if [ -z "$base" ] || [ "$base" = "0000000000000000000000000000000000000000" ]; then | |
| base="HEAD~1" | |
| fi | |
| changed=$(git diff --name-only "$(git merge-base "$base" HEAD)" HEAD) | |
| if echo "$changed" | grep -qE '^(packages/|package\.json|bun\.lock|bunfig\.toml)'; then | |
| echo "packages=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "packages=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$changed" | grep -q '^packages/dashboard/'; then | |
| echo "dashboard=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "dashboard=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| codegen: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| permissions: | |
| contents: read | |
| uses: ./.github/workflows/codegen.yml | |
| build: | |
| name: build | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| - name: Build | |
| run: bun run build | |
| unit-tests: | |
| name: unit tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: [20.x, 22.x, 24.x] | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Build | |
| run: bunx lerna run ci | |
| - name: Unit tests | |
| run: bun run test | |
| dashboard-i18n: | |
| name: dashboard i18n sync | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.dashboard == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| - name: Check i18n catalogs are in sync | |
| working-directory: packages/dashboard | |
| run: bash scripts/check-i18n-sync.sh | |
| dashboard-e2e: | |
| name: dashboard e2e (${{ matrix.shard }}) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.dashboard == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4] | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| - name: Build | |
| run: bunx lerna run ci --scope @vendure/testing --include-dependencies | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| # The key version prefix (v2) lets us evict caches poisoned by an | |
| # earlier incomplete browser install. No restore-keys: a prefix | |
| # fallback would drag stale browser binaries forward on a Playwright | |
| # version bump, and an exact hit on that poisoned cache then skips | |
| # the install step indefinitely. | |
| key: playwright-v2-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| # chromium-headless-shell is a separate download since Playwright 1.49 | |
| # and is what headless CI runs actually launch. | |
| run: bunx playwright install chromium chromium-headless-shell | |
| working-directory: packages/dashboard | |
| - name: Install Playwright system deps | |
| run: bunx playwright install-deps chromium | |
| working-directory: packages/dashboard | |
| - name: Dashboard e2e tests | |
| run: bun run e2e:pw -- --shard=${{ matrix.shard }}/4 | |
| working-directory: packages/dashboard | |
| sonarqube: | |
| name: SonarQube | |
| needs: detect-changes | |
| # Dependabot pull requests read from the Dependabot secrets store, not | |
| # from Actions secrets, so SONAR_TOKEN resolves empty and the scan | |
| # fails. Skipping is safe: all-passed counts a skipped job as a pass, | |
| # and the scan still runs on the push to master after the merge. | |
| # | |
| # A manual `workflow_dispatch` run carries no pull request context, and | |
| # the scan action supplies no branch name for that event either, so | |
| # SonarCloud files the results against the project's main branch. | |
| # Dispatching CI on a feature branch therefore uploads that branch's | |
| # findings as if they were master's, which marks real master alerts as | |
| # fixed and reopens stale ones. Only scan on dispatch when the ref is one | |
| # of the long-lived branches. | |
| if: >- | |
| needs.detect-changes.outputs.packages == 'true' | |
| && github.actor != 'dependabot[bot]' | |
| && (github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork) | |
| && (github.event_name != 'workflow_dispatch' || contains(fromJSON('["master","minor","major"]'), github.ref_name)) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: SonarQube Scan | |
| uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6 | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| e2e-sqljs: | |
| name: e2e (sqljs) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| services: | |
| redis: | |
| image: redis:7.4.1 | |
| ports: | |
| - 6379 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: ${{ github.event_name == 'pull_request' && fromJSON('["22.x"]') || fromJSON('["20.x", "22.x", "24.x"]') }} | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Build | |
| run: bunx lerna run ci | |
| - name: e2e tests | |
| env: | |
| E2E_REDIS_PORT: ${{ job.services.redis.ports['6379'] }} | |
| DB: sqljs | |
| run: bun run e2e | |
| e2e-mariadb: | |
| name: e2e (mariadb) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| services: | |
| mariadb: | |
| # With v11.6.2+, a default was changed, (https://mariadb.com/kb/en/innodb-system-variables/#innodb_snapshot_isolation) | |
| # which causes e2e test failures currently | |
| image: mariadb:11.5 | |
| env: | |
| MARIADB_ROOT_PASSWORD: password | |
| ports: | |
| - 3306 | |
| options: --health-cmd="mariadb-admin ping -h localhost -u vendure -ppassword" --health-interval=10s --health-timeout=5s --health-retries=3 | |
| redis: | |
| image: redis:7.4.1 | |
| ports: | |
| - 6379 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: ${{ github.event_name == 'pull_request' && fromJSON('["22.x"]') || fromJSON('["20.x", "22.x", "24.x"]') }} | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Build | |
| run: bunx lerna run ci | |
| - name: e2e tests | |
| env: | |
| E2E_MARIADB_PORT: ${{ job.services.mariadb.ports['3306'] }} | |
| E2E_REDIS_PORT: ${{ job.services.redis.ports['6379'] }} | |
| DB: mariadb | |
| run: bun run e2e | |
| e2e-mysql: | |
| name: e2e (mysql) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| services: | |
| mysql: | |
| image: vendure/mysql-8-native-auth:latest | |
| # Each spec file gets its own database, so the e2e run builds the full schema | |
| # 122 times. MySQL 8 made DDL atomic, which made CREATE TABLE several times | |
| # slower than it is on MariaDB, and Oracle closed that as working as intended | |
| # (MySQL bug #106390). This job has therefore averaged 22 minutes against 12 | |
| # for the other databases, and reached 80 when the runner disk was busy. | |
| # Holding the data directory in memory takes the disk out of that path. The | |
| # binary log is switched off because a database that is deleted at the end of | |
| # the job has no use for one, and it would otherwise grow in that same memory. | |
| command: --skip-log-bin --performance-schema=OFF | |
| env: | |
| MYSQL_ROOT_PASSWORD: password | |
| ports: | |
| - 3306 | |
| options: >- | |
| --tmpfs /var/lib/mysql:rw,size=4g | |
| --health-cmd="mysqladmin ping --silent" | |
| --health-interval=10s --health-timeout=20s --health-retries=10 | |
| redis: | |
| image: redis:7.4.1 | |
| ports: | |
| - 6379 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: ${{ github.event_name == 'pull_request' && fromJSON('["22.x"]') || fromJSON('["20.x", "22.x", "24.x"]') }} | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Build | |
| run: bunx lerna run ci | |
| - name: e2e tests | |
| env: | |
| E2E_MYSQL_PORT: ${{ job.services.mysql.ports['3306'] }} | |
| E2E_REDIS_PORT: ${{ job.services.redis.ports['6379'] }} | |
| DB: mysql | |
| run: bun run e2e | |
| e2e-postgres: | |
| name: e2e (postgres) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.packages == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_USER: vendure | |
| POSTGRES_PASSWORD: password | |
| ports: | |
| - 5432 | |
| options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3 | |
| redis: | |
| image: redis:7.4.1 | |
| ports: | |
| - 6379 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: ${{ github.event_name == 'pull_request' && fromJSON('["22.x"]') || fromJSON('["20.x", "22.x", "24.x"]') }} | |
| steps: | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| - uses: ./.github/actions/setup | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Build | |
| run: bunx lerna run ci | |
| - name: e2e tests | |
| env: | |
| E2E_POSTGRES_PORT: ${{ job.services.postgres.ports['5432'] }} | |
| E2E_REDIS_PORT: ${{ job.services.redis.ports['6379'] }} | |
| DB: postgres | |
| run: bun run e2e | |
| all-passed: | |
| name: all-passed | |
| runs-on: ubuntu-latest | |
| permissions: {} | |
| if: always() | |
| needs: | |
| - detect-changes | |
| - codegen | |
| - build | |
| - unit-tests | |
| - dashboard-i18n | |
| - dashboard-e2e | |
| - sonarqube | |
| - e2e-sqljs | |
| - e2e-mariadb | |
| - e2e-mysql | |
| - e2e-postgres | |
| steps: | |
| - run: exit ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && 1 || 0 }} |