Skip to content

feat: expand Queue/Job/Worker API parity with Node.js BullMQ [rust] #10853

feat: expand Queue/Job/Worker API parity with Node.js BullMQ [rust]

feat: expand Queue/Job/Worker API parity with Node.js BullMQ [rust] #10853

Workflow file for this run

# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Tests
on:
push:
branches: [master]
pull_request:
branches: [master, next]
concurrency:
group: test-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
# Fast smoke test gate. Runs a small subset of fast, representative tests
# against the default (node + ioredis) adapter with --bail so we fail fast.
# All other heavier jobs depend on this so a quick failure cancels the rest.
# (Vulnerability scanning runs in the separate `osv-scanner.yml` workflow
# and gates merging via branch protection / required checks.)
smoke:
runs-on: ubuntu-latest
name: smoke (lint + fast tests on node@lts, ioredis, redis@7)
env:
node-version: lts/*
redis-version: 7-alpine
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ env.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ env.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- name: Run ESLint
run: yarn lint
- run: yarn build
- run: yarn test:smoke
# Primary ioredis test run on a single (current LTS) Node version.
# Also produces the coverage report — the test set executed by
# `yarn coverage` is exactly `yarn test` + `yarn test:ioredis`, so running
# them under coverage avoids doing the same work twice in CI.
# Acts as the gating job for the other adapters: if this passes,
# node-redis, node-valkey, node-dragonflydb, bun, and the additional
# ioredis Node/Redis version matrix run in parallel.
ioredis-redis:
runs-on: ubuntu-latest
needs: smoke
name: testing node@${{ matrix.node-version }}, redis@${{ matrix.redis-version }}
env:
allowed_coverage_change: -0.25
strategy:
matrix:
node-version: [lts/*]
redis-version: [7-alpine]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ matrix.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- name: Run tests with coverage (default + ioredis-only suites)
run: yarn coverage
- name: Upload LCOV to Coveralls
if: ${{ ( github.event_name == 'pull_request' && github.event.pull_request.head.fork == false ) || github.event_name == 'push' }}
uses: coverallsapp/github-action@0a51d2e0b5417d06e4ecceb534aec87defc53926 # branch=master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check coverage change not below threshold
if: ${{ ( github.event_name == 'pull_request' && github.event.pull_request.head.fork == false ) || github.event_name == 'push' }}
shell: bash
run: |
sleep 2
COVERAGE_CHANGE=$(curl -s https://coveralls.io/builds/${{ github.sha }}.json | jq '.coverage_change')
echo coverage changed by ${COVERAGE_CHANGE}%
if [[ -z "$(echo ${COVERAGE_CHANGE} ${{ env.allowed_coverage_change }} | awk '$1 >= $2')" ]]; then
echo current coverage change ${COVERAGE_CHANGE}% below threshold ${{ env.allowed_coverage_change }}%
exit 1
fi
# Additional ioredis matrix coverage. Only runs once the primary
# ioredis-redis job has passed to avoid burning runner time on
# multiple Node/Redis versions when the suite is already broken.
ioredis-redis-extra:
runs-on: ubuntu-latest
needs: ioredis-redis
name: testing node@${{ matrix.node-version }}, redis@${{ matrix.redis-version }}
strategy:
fail-fast: false
matrix:
node-version: [lts/-1, lts/-2]
redis-version: [7-alpine]
include:
- node-version: 'lts/*'
redis-version: 6-alpine
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ matrix.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn test
- run: yarn test:ioredis
node-redis:
runs-on: ubuntu-latest
needs: ioredis-redis
name: testing node-redis node@${{ matrix.node-version }}, redis@${{ matrix.redis-version }}
strategy:
matrix:
node-version: [lts/*]
redis-version: [7-alpine]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ matrix.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn test:adapter-conformance
- run: yarn test:node-redis
node-valkey:
runs-on: ubuntu-latest
needs: ioredis-redis
env:
node-version: lts/*
name: testing node@lts/*, valkey@8
services:
valkey:
image: valkey/valkey:8-alpine3.20
ports:
- 6379:6379
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: lts/*
cache: 'yarn'
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn test
node-dragonflydb:
runs-on: ubuntu-latest
needs: ioredis-redis
env:
node-version: lts/*
name: testing node@lts/*, dragonflydb@latest
services:
dragonflydb:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
env:
DFLY_cluster_mode: emulated
DFLY_lock_on_hashtags: true
HEALTHCHECK_PORT: 6379
ports:
- 6379:6379
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: lts/*
cache: 'yarn'
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: BULLMQ_TEST_PREFIX={b} yarn test
bun-redis:
runs-on: ubuntu-latest
needs: ioredis-redis
name: testing bun@${{ matrix.bun-version }}, redis@${{ matrix.redis-version }}
strategy:
matrix:
bun-version: [latest]
redis-version: [7-alpine]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ matrix.bun-version }}
- name: Use Node.js for yarn
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: lts/*
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ matrix.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn test:bun:smoke
- run: yarn test:bun
# node-upstash:
# runs-on: ubuntu-latest
# continue-on-error: true
# env:
# node-version: lts/*
# REDIS_HOST: ${{ secrets.REDIS_HOST }}
# name: testing node@lts/*, upstash@latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v3 # v3
# - name: Use Node.js ${{ env.node-version }}
# uses: actions/setup-node@v3 # v3
# with:
# node-version: lts/*
# cache: 'yarn'
# - run: yarn install --ignore-engines --frozen-lockfile --non-interactive
# - run: yarn build
# - run: yarn test
python:
runs-on: ubuntu-latest
# Depend on the primary node suite (which also runs coverage) so a Node
# test failure aborts the cross-language jobs before they consume runner
# time. `ioredis-redis` itself depends on `smoke`.
needs: ioredis-redis
name: testing python@${{ matrix.python-version }}, redis@${{ matrix.redis-version }}
strategy:
matrix:
node-version: [lts/*]
redis-version: [7-alpine]
python-version: ['3.13']
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: ${{ matrix.redis-version }}
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn copy:lua:python
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 mypy types-redis
pip install -r python/requirements.txt
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 ./python --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 ./python --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
cd python
pytest -v
python-dragonflydb:
runs-on: ubuntu-latest
needs: ioredis-redis
name: testing python@${{ matrix.python-version }}, dragonflydb@latest
strategy:
matrix:
node-version: [lts/*]
python-version: ['3.13']
services:
dragonflydb:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
env:
DFLY_cluster_mode: emulated
DFLY_lock_on_hashtags: true
HEALTHCHECK_PORT: 6379
ports:
- 6379:6379
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn copy:lua:python
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 mypy types-redis
pip install -r python/requirements.txt
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 ./python --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 ./python --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
cd python
export BULLMQ_TEST_PREFIX="{b}"
pytest -v
php:
runs-on: ubuntu-latest
needs: ioredis-redis
name: testing php@${{ matrix.php-version }}, redis@7
strategy:
matrix:
node-version: [lts/*]
php-version: ['8.1', '8.2', '8.3']
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Start Redis
uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # 1.8.1
with:
redis-version: 7-alpine
- run: yarn install --ignore-engines --frozen-lockfile --non-interactive
- run: yarn build
- run: yarn copy:lua:php
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: redis, msgpack
tools: composer:v2
- name: Get Composer Cache Directory
id: composer-cache
working-directory: php
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache Composer dependencies
uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ hashFiles('php/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-${{ matrix.php-version }}-
- name: Install PHP dependencies
working-directory: php
run: composer install --prefer-dist --no-progress
- name: Run PHPStan
working-directory: php
run: ./vendor/bin/phpstan analyse src --level=6
- name: Run tests
working-directory: php
run: ./vendor/bin/phpunit