mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-15 21:35:31 +00:00
refactor: 统一多前端工程架构、插件配置与 CI (#131)
* refactor: 重构项目架构 * refactor: 重构ci和测试 * fix: 修复测试 * feat: 新增更多E2E测试 * fix: 修复E2E测试
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
name: Backend Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
pytest:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Typer otherwise forces ANSI help output when GITHUB_ACTIONS is set.
|
||||
_TYPER_FORCE_DISABLE_TERMINAL: "1"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
ruoyi-fastapi-backend/requirements.txt
|
||||
ruoyi-fastapi-backend/plugins/ai/plugin.yaml
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt pytest pytest-asyncio aiosqlite
|
||||
|
||||
- name: Install AI plugin dependencies
|
||||
run: |
|
||||
pip install \
|
||||
agno==2.8.6 \
|
||||
anthropic==0.120.2 \
|
||||
cerebras-cloud-sdk==1.91.0 \
|
||||
cohere==7.0.8 \
|
||||
google-genai==2.16.0 \
|
||||
groq==1.6.0 \
|
||||
litellm==1.94.0 \
|
||||
llama-api-client==0.6.0 \
|
||||
mistralai==2.8.0 \
|
||||
ollama==0.6.2 \
|
||||
openai==2.52.0 \
|
||||
portkey-ai==2.3.4
|
||||
|
||||
- name: Run backend tests
|
||||
run: pytest -q
|
||||
|
||||
- name: Check timezone behavior under independent host timezones
|
||||
run: |
|
||||
for zone in UTC Asia/Shanghai America/New_York; do
|
||||
TZ="$zone" python -m pytest -q tests/common/test_types.py tests/common/test_query_time.py tests/utils/test_time_util.py tests/config/test_scheduler_database.py tests/utils/test_cron_util.py tests/module_admin/controller/test_job_controller.py tests/config/test_scheduler_job_persistence.py
|
||||
done
|
||||
@@ -0,0 +1,110 @@
|
||||
name: CI / Backend
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
_TYPER_FORCE_DISABLE_TERMINAL: '1'
|
||||
PYTHONUTF8: '1'
|
||||
|
||||
jobs:
|
||||
unit-contract:
|
||||
name: Python ${{ matrix.python }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python: ['3.10', '3.11', '3.12', '3.13']
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
ruoyi-fastapi-backend/requirements*.txt
|
||||
ruoyi-fastapi-backend/plugins/ai/plugin.yaml
|
||||
- name: Install test dependencies
|
||||
run: python -m pip install -r requirements.txt -r requirements-test.txt
|
||||
- name: Install AI plugin dependencies from its manifest
|
||||
run: python ../.github/scripts/install_ai_test_dependencies.py
|
||||
- name: Run backend unit and contract tests
|
||||
run: python -m pytest tests -q -m 'not browser and not native and not integration' --strict-markers --durations=20 --junitxml=target/ci/backend.xml
|
||||
- name: Verify tests were executed
|
||||
run: python ../.github/scripts/check_test_report.py target/ci/backend.xml --allow-skips
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: backend-python-${{ matrix.python }}
|
||||
path: ruoyi-fastapi-backend/target/ci/
|
||||
retention-days: 7
|
||||
|
||||
windows-contract:
|
||||
name: Windows CLI and paths
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 20
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- run: python -m pip install -r requirements.txt -r requirements-test.txt
|
||||
- name: Verify CLI, paths, artifacts and portable runtime contracts
|
||||
run: >-
|
||||
python -m pytest tests/cli
|
||||
tests/plugins/core/test_frontend_layout.py tests/plugins/core/validation/test_frontend_dependencies.py
|
||||
tests/plugins/core/native tests/plugins/core/runtime/test_host_services.py tests/plugins/core/runtime/test_job_dispatcher.py
|
||||
tests/plugins/core/artifacts tests/plugins/core/deployment
|
||||
tests/plugins/core/management/test_release_dao.py tests/plugins/core/management/test_artifact_views.py
|
||||
tests/module_plugin/controller/test_plugin_release_controller.py tests/sql/test_plugin_release_schema.py
|
||||
tests/plugins/examples/test_task_demo.py
|
||||
-m 'not native and not browser and not integration' -q --strict-markers --durations=15 --junitxml=target/ci/windows-contract.xml
|
||||
- run: python ../.github/scripts/check_test_report.py target/ci/windows-contract.xml --allow-skips
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: backend-windows-contract
|
||||
path: ruoyi-fastapi-backend/target/ci/
|
||||
retention-days: 7
|
||||
|
||||
timezone:
|
||||
name: Host timezone contracts
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- run: python -m pip install -r requirements.txt -r requirements-test.txt
|
||||
- name: Verify UTC, Shanghai and New York in separate processes
|
||||
shell: bash
|
||||
run: |
|
||||
for zone in UTC Asia/Shanghai America/New_York; do
|
||||
report="target/ci/timezone-${zone//\//_}.xml"
|
||||
TZ="$zone" python -m pytest -q tests/common/test_types.py tests/common/test_query_time.py tests/utils/test_time_util.py tests/config/test_scheduler_database.py tests/utils/test_cron_util.py tests/module_admin/controller/test_job_controller.py tests/config/test_scheduler_job_persistence.py --junitxml="$report"
|
||||
python ../.github/scripts/check_test_report.py "$report"
|
||||
done
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: backend-timezones
|
||||
path: ruoyi-fastapi-backend/target/ci/
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,111 @@
|
||||
name: CI / E2E
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
matrix_json:
|
||||
type: string
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
browser:
|
||||
name: ${{ matrix.framework }} / ${{ matrix.database }} / Python ${{ matrix.python }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJSON(inputs.matrix_json) }}
|
||||
env:
|
||||
COMPOSE_PROJECT_NAME: ruoyi-ci-${{ github.run_id }}-${{ github.run_attempt }}-${{ strategy.job-index }}
|
||||
COMPOSE_FILE: ${{ github.workspace }}/ruoyi-fastapi-test/target/e2e/compose.json
|
||||
FRONTEND_FRAMEWORK: ${{ matrix.framework }}
|
||||
E2E_OUTPUT_DIR: ${{ github.workspace }}/ruoyi-fastapi-test/target/e2e/browser
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-test/requirements.txt
|
||||
- name: Install test runner and Chromium
|
||||
run: |
|
||||
python -m pip install -r ruoyi-fastapi-test/requirements.txt
|
||||
python -m playwright install --with-deps chromium
|
||||
- name: Verify reusable browser and isolated contexts
|
||||
working-directory: ruoyi-fastapi-test
|
||||
run: |
|
||||
python -m pytest -m harness -q --junitxml=target/e2e/harness.xml
|
||||
python ../.github/scripts/check_test_report.py target/e2e/harness.xml
|
||||
- name: Generate isolated Compose project
|
||||
run: |
|
||||
python ruoyi-fastapi-test/prepare_e2e_compose.py \
|
||||
--database '${{ matrix.database }}' --framework '${{ matrix.framework }}' \
|
||||
--python-version '${{ matrix.python }}' --project "$COMPOSE_PROJECT_NAME" \
|
||||
--output "$COMPOSE_FILE"
|
||||
docker compose config --quiet
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- name: Build frontend with reusable layers
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ruoyi-fastapi-frontend/${{ matrix.framework }}/web
|
||||
file: ruoyi-fastapi-frontend/${{ matrix.framework }}/web/Dockerfile
|
||||
load: true
|
||||
tags: ${{ env.COMPOSE_PROJECT_NAME }}-ruoyi-frontend:ci
|
||||
cache-from: type=gha,scope=e2e-frontend-${{ matrix.framework }}
|
||||
cache-to: type=gha,scope=e2e-frontend-${{ matrix.framework }},mode=max
|
||||
- name: Select database Dockerfile
|
||||
id: database
|
||||
env:
|
||||
DATABASE: ${{ matrix.database }}
|
||||
run: |
|
||||
if [ "$DATABASE" = mysql ]; then
|
||||
echo 'suffix=my' >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo 'suffix=pg' >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Build backend with reusable layers
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ruoyi-fastapi-backend
|
||||
file: ruoyi-fastapi-backend/Dockerfile.${{ steps.database.outputs.suffix }}
|
||||
load: true
|
||||
tags: ${{ env.COMPOSE_PROJECT_NAME }}-ruoyi-backend-${{ steps.database.outputs.suffix }}:ci
|
||||
build-args: |
|
||||
PYTHON_VERSION=${{ matrix.python }}
|
||||
PIP_INDEX_URL=https://pypi.org/simple
|
||||
cache-from: type=gha,scope=e2e-backend-${{ matrix.database }}-py${{ matrix.python }}
|
||||
cache-to: type=gha,scope=e2e-backend-${{ matrix.database }}-py${{ matrix.python }},mode=max
|
||||
- name: Wait for healthy database, API and frontend proxy
|
||||
run: |
|
||||
docker compose up --detach --no-build --wait --wait-timeout 240
|
||||
echo "TEST_FRONTEND_URL=http://$(docker compose port ruoyi-frontend 80)" >> "$GITHUB_ENV"
|
||||
echo "TEST_BACKEND_URL=http://$(docker compose port ruoyi-backend-${{ steps.database.outputs.suffix }} 9099)" >> "$GITHUB_ENV"
|
||||
- name: Run all application pages and functional E2E checks
|
||||
working-directory: ruoyi-fastapi-test
|
||||
run: |
|
||||
python -m pytest -m e2e -v --durations=20 --junitxml=target/e2e/junit.xml
|
||||
python ../.github/scripts/check_test_report.py target/e2e/junit.xml
|
||||
- name: Collect service diagnostics
|
||||
if: always()
|
||||
run: |
|
||||
mkdir -p ruoyi-fastapi-test/target/e2e
|
||||
if [ -f "$COMPOSE_FILE" ]; then
|
||||
docker compose ps --all > ruoyi-fastapi-test/target/e2e/services.txt 2>&1 || true
|
||||
docker compose logs --no-color --timestamps > ruoyi-fastapi-test/target/e2e/services.log 2>&1 || true
|
||||
fi
|
||||
- name: Remove only this test project's containers and data
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f "$COMPOSE_FILE" ]; then
|
||||
docker compose down --volumes --remove-orphans --timeout 20
|
||||
fi
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: e2e-${{ matrix.framework }}-${{ matrix.database }}-py${{ matrix.python }}
|
||||
path: ruoyi-fastapi-test/target/e2e
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
@@ -0,0 +1,116 @@
|
||||
name: CI / Frontend
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
matrix_json:
|
||||
description: 'JSON matrix with framework and target entries under include'
|
||||
required: true
|
||||
type: string
|
||||
full:
|
||||
description: 'Reserved for callers requesting the full project matrix'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
frontend:
|
||||
name: ${{ matrix.framework }} / ${{ matrix.target }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 35
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJSON(inputs.matrix_json) }}
|
||||
env:
|
||||
NODE_OPTIONS: ${{ matrix.framework == 'vue2' && '--openssl-legacy-provider' || '' }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-frontend/${{ matrix.framework }}/${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
- name: Install the Vue 2 Mobile package manager
|
||||
if: matrix.framework == 'vue2' && matrix.target == 'mobile'
|
||||
run: npm install --global yarn@1.22.22
|
||||
- uses: pnpm/action-setup@v5
|
||||
if: matrix.framework == 'vue3' && matrix.target == 'mobile'
|
||||
with:
|
||||
package_json_file: ruoyi-fastapi-frontend/vue3/mobile/package.json
|
||||
- name: Locate the package cache
|
||||
id: package-cache
|
||||
env:
|
||||
FRAMEWORK: ${{ matrix.framework }}
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
if [ "$TARGET" = web ]; then
|
||||
echo "path=$(npm config get cache)" >> "$GITHUB_OUTPUT"
|
||||
elif [ "$FRAMEWORK" = vue2 ]; then
|
||||
echo "path=$(yarn cache dir --silent)" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.package-cache.outputs.path }}
|
||||
# Lockfiles are intentionally not tracked in these projects.
|
||||
key: ${{ runner.os }}-node22-${{ matrix.framework }}-${{ matrix.target }}-${{ hashFiles(format('ruoyi-fastapi-frontend/{0}/{1}/package.json', matrix.framework, matrix.target)) }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node22-${{ matrix.framework }}-${{ matrix.target }}-
|
||||
- name: Install Web dependencies
|
||||
if: matrix.target == 'web'
|
||||
run: npm install --no-audit --no-fund --package-lock=false
|
||||
- name: Install Vue 2 Mobile dependencies
|
||||
if: matrix.framework == 'vue2' && matrix.target == 'mobile'
|
||||
run: yarn install --non-interactive
|
||||
- name: Install Vue 3 Mobile dependencies
|
||||
if: matrix.framework == 'vue3' && matrix.target == 'mobile'
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
- name: Run unit and component behavior tests
|
||||
run: npm run test:unit
|
||||
- name: Verify time contracts in three host timezones
|
||||
run: |
|
||||
for zone in UTC Asia/Shanghai America/New_York; do
|
||||
TZ="$zone" npm run test:contract
|
||||
done
|
||||
- name: Verify the Vue 2 Mobile browser bundle without native Intl
|
||||
if: matrix.framework == 'vue2' && matrix.target == 'mobile'
|
||||
run: npm run test:bundle
|
||||
- name: Build Web production and Docker targets
|
||||
if: matrix.target == 'web'
|
||||
run: |
|
||||
npm run build:prod
|
||||
npm run build:docker
|
||||
- name: Build Mobile H5
|
||||
if: matrix.target == 'mobile'
|
||||
run: npm run build:h5
|
||||
- uses: actions/setup-python@v6
|
||||
if: matrix.target == 'mobile'
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install the Mobile smoke browser
|
||||
if: matrix.target == 'mobile'
|
||||
run: |
|
||||
python -m pip install playwright==1.62.0
|
||||
python -m playwright install --with-deps chromium
|
||||
- name: Verify Mobile H5 login and profile
|
||||
if: matrix.target == 'mobile'
|
||||
working-directory: .
|
||||
run: python .github/scripts/mobile_smoke.py --framework ${{ matrix.framework }}
|
||||
- name: Build Mobile WeChat target
|
||||
if: matrix.target == 'mobile'
|
||||
run: npm run build:mp-weixin
|
||||
- name: Upload frontend diagnostics
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: frontend-${{ matrix.framework }}-${{ matrix.target }}
|
||||
path: |
|
||||
target/ci/mobile-smoke/${{ matrix.framework }}/
|
||||
ruoyi-fastapi-frontend/${{ matrix.framework }}/${{ matrix.target }}/test-results/
|
||||
if-no-files-found: ignore
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,218 @@
|
||||
name: CI / Integration
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
database:
|
||||
type: boolean
|
||||
default: false
|
||||
release:
|
||||
type: boolean
|
||||
default: false
|
||||
network_frameworks:
|
||||
type: string
|
||||
default: '[]'
|
||||
full:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
database-timezone:
|
||||
name: MySQL and PostgreSQL time contracts
|
||||
if: inputs.database
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
TZ: America/New_York
|
||||
PYTHONUTF8: '1'
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: timezone_test
|
||||
TZ: Asia/Shanghai
|
||||
ports: ['3306:3306']
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping -h localhost -ptimezone_test"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
postgres:
|
||||
image: postgres:14
|
||||
env:
|
||||
POSTGRES_PASSWORD: timezone_test
|
||||
TZ: America/New_York
|
||||
PGTZ: America/New_York
|
||||
ports: ['5432:5432']
|
||||
options: >-
|
||||
--health-cmd="pg_isready -U postgres"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- run: python -m pip install -r requirements.txt -r requirements-pg.txt -r requirements-test.txt
|
||||
- name: Configure isolated database verification
|
||||
run: |
|
||||
mkdir -p target/ci/timezone
|
||||
python - <<'PY'
|
||||
import json
|
||||
from pathlib import Path
|
||||
for dialect, port, username, database in [('mysql', 3306, 'root', 'mysql'), ('postgresql', 5432, 'postgres', 'postgres')]:
|
||||
source = dict(db_type=dialect, db_host='127.0.0.1', db_port=port, db_username=username,
|
||||
db_password='timezone_test', db_database=database)
|
||||
Path(f'target/ci/timezone/{dialect}.json').write_text(json.dumps(source))
|
||||
PY
|
||||
- name: Verify drivers, CRUD and scheduler persistence
|
||||
run: |
|
||||
python -m scripts.verify_timezone_database --config target/ci/timezone/mysql.json --report target/ci/timezone/mysql-report.json
|
||||
python -m scripts.verify_timezone_database --config target/ci/timezone/postgresql.json --report target/ci/timezone/postgresql-report.json
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: integration-database-timezones
|
||||
path: ruoyi-fastapi-backend/target/ci/timezone/*-report.json
|
||||
retention-days: 7
|
||||
|
||||
task-bundle:
|
||||
name: Task plugin bundle
|
||||
if: inputs.release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend/plugins/examples/python/task_demo/web
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
cache-dependency-path: ruoyi-fastapi-backend/plugins/examples/python/task_demo/web/package.json
|
||||
- run: npm install --no-audit --no-fund --package-lock=false
|
||||
- run: npm test
|
||||
- run: npm run build
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: integration-task-bundle
|
||||
path: ruoyi-fastapi-backend/plugins/examples/python/task_demo/web/dist/
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
release:
|
||||
name: Plugin maintenance / Python ${{ matrix.python }}
|
||||
needs: task-bundle
|
||||
if: inputs.release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python: ${{ fromJSON(inputs.full && '["3.10","3.11","3.12","3.13"]' || '["3.12"]') }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: ci-only-mysql
|
||||
ports: ['3306:3306']
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping -h localhost -pci-only-mysql"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
postgres:
|
||||
image: postgres:14
|
||||
env:
|
||||
POSTGRES_PASSWORD: ci-only-postgres
|
||||
ports: ['5432:5432']
|
||||
options: >-
|
||||
--health-cmd="pg_isready -U postgres"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
redis:
|
||||
image: redis:6.2
|
||||
ports: ['6379:6379']
|
||||
options: >-
|
||||
--health-cmd="redis-cli ping"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
env:
|
||||
RUOYI_PLUGIN_IT_ALLOW: '1'
|
||||
RUOYI_IT_MYSQL_PASSWORD: ci-only-mysql
|
||||
RUOYI_IT_PG_PASSWORD: ci-only-postgres
|
||||
RUOYI_IT_REDIS_PASSWORD: ''
|
||||
PYTHONUTF8: '1'
|
||||
_TYPER_FORCE_DISABLE_TERMINAL: '1'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: integration-task-bundle
|
||||
path: ruoyi-fastapi-backend/plugins/examples/python/task_demo/web/dist
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- run: python -m pip install -r requirements.txt -r requirements-pg.txt
|
||||
- name: Verify MySQL and PostgreSQL maintenance releases
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p target/ci/release
|
||||
python scripts/plugin_release_integration.py --engine mysql 2>&1 | tee target/ci/release/mysql.log
|
||||
python scripts/plugin_release_integration.py --engine postgresql 2>&1 | tee target/ci/release/postgresql.log
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: integration-release-${{ matrix.python }}
|
||||
path: ruoyi-fastapi-backend/target/ci/release/
|
||||
retention-days: 7
|
||||
|
||||
network:
|
||||
name: ${{ matrix.framework }} proxy and plugin sessions
|
||||
if: inputs.network_frameworks != '[]'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
framework: ${{ fromJSON(inputs.network_frameworks) }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
env:
|
||||
RUOYI_PLUGIN_NETWORK_SMOKE: '1'
|
||||
RUOYI_PLUGIN_FRONTEND_FRAMEWORK: ${{ matrix.framework }}
|
||||
NODE_OPTIONS: ${{ matrix.framework == 'vue2' && '--openssl-legacy-provider' || '' }}
|
||||
DB_SOURCES: '{"primary":{"db_type":"mysql","db_host":"127.0.0.1","db_port":3306,"db_username":"network-smoke","db_password":"network-smoke","db_database":"network-smoke"}}'
|
||||
JWT_SECRET_KEY: isolated-plugin-network-smoke-ci-only
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
cache-dependency-path: ruoyi-fastapi-frontend/${{ matrix.framework }}/web/package.json
|
||||
- run: python -m pip install -r requirements.txt -r requirements-test.txt playwright==1.62.0
|
||||
- run: python -m playwright install --with-deps chromium
|
||||
- run: npm --prefix ../ruoyi-fastapi-frontend/${{ matrix.framework }}/web install --no-audit --no-fund --package-lock=false
|
||||
- name: Verify HTTPS proxy, iframe sessions and long connections
|
||||
run: python -m pytest tests/plugins/integration/test_network_smoke.py -m browser --strict-markers -v --junitxml=target/plugin-network-smoke/${{ matrix.framework }}/results.xml
|
||||
- run: python ../.github/scripts/check_test_report.py target/plugin-network-smoke/${{ matrix.framework }}/results.xml
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: integration-network-${{ matrix.framework }}
|
||||
path: ruoyi-fastapi-backend/target/plugin-network-smoke/${{ matrix.framework }}/
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,80 @@
|
||||
name: CI / Native
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
PYTHONUTF8: '1'
|
||||
_TYPER_FORCE_DISABLE_TERMINAL: '1'
|
||||
|
||||
jobs:
|
||||
rust-quality:
|
||||
name: Rust format and clippy
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- run: rustup toolchain install 1.99.0 --profile minimal --component rustfmt --component clippy
|
||||
- run: rustup default 1.99.0
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
ruoyi-fastapi-backend/plugins/examples/rust/rust_demo/target
|
||||
key: rust-quality-${{ runner.os }}-1.99.0-${{ hashFiles('**/Cargo.lock') }}
|
||||
- run: cargo fmt --manifest-path plugins/examples/rust/rust_demo/Cargo.toml --check
|
||||
- run: cargo clippy --manifest-path plugins/examples/rust/rust_demo/Cargo.toml --locked -- -D warnings
|
||||
|
||||
runtime:
|
||||
name: ${{ matrix.os }} / Python ${{ matrix.python }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python: ['3.10', '3.11', '3.12', '3.13']
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- run: python -m pip install -r requirements.txt -r requirements-test.txt 'maturin>=1.15,<2'
|
||||
- run: rustup toolchain install 1.99.0 --profile minimal
|
||||
- run: rustup default 1.99.0
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
ruoyi-fastapi-backend/plugins/examples/rust/rust_demo/target
|
||||
key: rust-native-${{ runner.os }}-${{ matrix.python }}-1.99.0-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Build and assemble source-free plugin
|
||||
run: python scripts/build_native_plugin.py --output target/native-package
|
||||
- name: Exercise real native runtime and signed artifact loading
|
||||
env:
|
||||
RUOYI_NATIVE_PLUGIN_DIR: ${{ github.workspace }}/ruoyi-fastapi-backend/target/native-package/rust_demo
|
||||
run: python -m pytest tests/plugins/native tests/plugins/core/deployment -m native --strict-markers -q --durations=15 --junitxml=target/ci/native.xml
|
||||
- name: Require native tests to run without missing-artifact skips
|
||||
run: python ../.github/scripts/check_test_report.py target/ci/native.xml
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: native-${{ runner.os }}-${{ matrix.python }}
|
||||
path: ruoyi-fastapi-backend/target/ci/
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,54 @@
|
||||
name: CI / Quality
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
checks:
|
||||
name: Code and CI contracts
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: .github/requirements.txt
|
||||
- run: python -m pip install -r .github/requirements.txt
|
||||
- name: Python lint and format
|
||||
run: |
|
||||
ruff check ruoyi-fastapi-backend ruoyi-fastapi-test .github/scripts .github/tests
|
||||
ruff format --check ruoyi-fastapi-backend ruoyi-fastapi-test .github/scripts .github/tests
|
||||
- name: Test CI routing, failure gates and deployment contracts
|
||||
run: python -m pytest .github/tests -q --junitxml=target/ci/quality.xml
|
||||
- name: Validate every Compose framework selection
|
||||
run: python .github/scripts/check_compose.py
|
||||
- name: Install actionlint
|
||||
env:
|
||||
ACTIONLINT_VERSION: '1.7.12'
|
||||
run: |
|
||||
archive="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
||||
curl --fail --location --retry 3 "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/${archive}" --output "${RUNNER_TEMP}/${archive}"
|
||||
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 ${RUNNER_TEMP}/${archive}" | sha256sum --check
|
||||
tar -xzf "${RUNNER_TEMP}/${archive}" -C "$RUNNER_TEMP" actionlint
|
||||
"$RUNNER_TEMP/actionlint" -color
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
cache-dependency-path: ruoyi-fastapi-frontend/*/web/package.json
|
||||
- name: Check Web formatting with the existing project configurations
|
||||
run: |
|
||||
for framework in vue2 vue3; do
|
||||
(cd "ruoyi-fastapi-frontend/$framework/web" && npx --yes prettier@3.6.2 --check .)
|
||||
done
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: quality-reports
|
||||
path: target/ci/
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,106 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
push:
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '21 18 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
full:
|
||||
description: Run the full compatibility and end-to-end matrix
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
plan:
|
||||
name: Plan
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
backend: ${{ steps.plan.outputs.backend }}
|
||||
frontend: ${{ steps.plan.outputs.frontend }}
|
||||
integration: ${{ steps.plan.outputs.integration }}
|
||||
e2e: ${{ steps.plan.outputs.e2e }}
|
||||
native: ${{ steps.plan.outputs.native }}
|
||||
full: ${{ steps.plan.outputs.full }}
|
||||
frontend_matrix: ${{ steps.plan.outputs.frontend_matrix }}
|
||||
e2e_matrix: ${{ steps.plan.outputs.e2e_matrix }}
|
||||
network_frameworks: ${{ steps.plan.outputs.network_frameworks }}
|
||||
database: ${{ steps.plan.outputs.database }}
|
||||
release: ${{ steps.plan.outputs.release }}
|
||||
plan_json: ${{ steps.plan.outputs.plan_json }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: plan
|
||||
run: python .github/scripts/ci_plan.py plan
|
||||
|
||||
quality:
|
||||
name: Quality
|
||||
needs: plan
|
||||
uses: ./.github/workflows/ci-quality.yml
|
||||
|
||||
backend:
|
||||
name: Backend
|
||||
needs: plan
|
||||
if: needs.plan.outputs.backend == 'true'
|
||||
uses: ./.github/workflows/ci-backend.yml
|
||||
|
||||
frontend:
|
||||
name: Frontend
|
||||
needs: plan
|
||||
if: needs.plan.outputs.frontend == 'true'
|
||||
uses: ./.github/workflows/ci-frontend.yml
|
||||
with:
|
||||
matrix_json: ${{ needs.plan.outputs.frontend_matrix }}
|
||||
full: ${{ needs.plan.outputs.full == 'true' }}
|
||||
|
||||
integration:
|
||||
name: Integration
|
||||
needs: plan
|
||||
if: needs.plan.outputs.integration == 'true'
|
||||
uses: ./.github/workflows/ci-integration.yml
|
||||
with:
|
||||
database: ${{ needs.plan.outputs.database == 'true' }}
|
||||
release: ${{ needs.plan.outputs.release == 'true' }}
|
||||
network_frameworks: ${{ needs.plan.outputs.network_frameworks }}
|
||||
full: ${{ needs.plan.outputs.full == 'true' }}
|
||||
|
||||
e2e:
|
||||
name: E2E
|
||||
needs: plan
|
||||
if: needs.plan.outputs.e2e == 'true'
|
||||
uses: ./.github/workflows/ci-e2e.yml
|
||||
with:
|
||||
matrix_json: ${{ needs.plan.outputs.e2e_matrix }}
|
||||
|
||||
native:
|
||||
name: Native
|
||||
needs: plan
|
||||
if: needs.plan.outputs.native == 'true'
|
||||
uses: ./.github/workflows/ci-native.yml
|
||||
|
||||
result:
|
||||
name: Result
|
||||
if: always()
|
||||
needs: [plan, quality, backend, frontend, integration, e2e, native]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Require every selected category to succeed
|
||||
env:
|
||||
PLAN_JSON: ${{ needs.plan.outputs.plan_json }}
|
||||
NEEDS_JSON: ${{ toJSON(needs) }}
|
||||
run: python .github/scripts/ci_plan.py gate
|
||||
@@ -1,97 +0,0 @@
|
||||
name: Native Plugin
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-backend/plugins/core/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/rust/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/python/task_demo/**'
|
||||
- 'ruoyi-fastapi-backend/scripts/plugin_task_integration.py'
|
||||
- 'ruoyi-fastapi-backend/scripts/build_native_plugin.py'
|
||||
- 'ruoyi-fastapi-backend/cli/runtime/plugin/scaffold/**'
|
||||
- 'ruoyi-fastapi-backend/cli/runtime/plugin/sdk.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/developer.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/sdk.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/artifact*.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/artifact_controller.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/command.py'
|
||||
- 'ruoyi-fastapi-frontend/src/utils/pluginBridge*'
|
||||
- 'ruoyi-fastapi-backend/pyproject.toml'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/runtime/plugin/test_runtime_scaffold*.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/runtime/plugin/test_runtime_sdk.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_sdk_commands.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_artifact_commands.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_release_wait.py'
|
||||
- 'ruoyi-fastapi-backend/tests/plugins/**'
|
||||
- '.github/workflows/native-plugin.yml'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-backend/plugins/core/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/rust/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/python/task_demo/**'
|
||||
- 'ruoyi-fastapi-backend/scripts/plugin_task_integration.py'
|
||||
- 'ruoyi-fastapi-backend/scripts/build_native_plugin.py'
|
||||
- 'ruoyi-fastapi-backend/cli/runtime/plugin/scaffold/**'
|
||||
- 'ruoyi-fastapi-backend/cli/runtime/plugin/sdk.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/developer.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/sdk.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/commands/artifact*.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/artifact_controller.py'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/command.py'
|
||||
- 'ruoyi-fastapi-frontend/src/utils/pluginBridge*'
|
||||
- 'ruoyi-fastapi-backend/pyproject.toml'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/runtime/plugin/test_runtime_scaffold*.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/runtime/plugin/test_runtime_sdk.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_sdk_commands.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_artifact_commands.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_release_wait.py'
|
||||
- 'ruoyi-fastapi-backend/tests/plugins/**'
|
||||
- '.github/workflows/native-plugin.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
native:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python: ['3.10', '3.11', '3.12', '3.13']
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements.txt
|
||||
- name: Install host and build dependencies
|
||||
run: python -m pip install -r requirements.txt 'maturin>=1.15,<2' pytest pytest-asyncio aiosqlite
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install 1.99.0 --profile minimal --component rustfmt --component clippy
|
||||
- name: Select Rust
|
||||
run: rustup default 1.99.0
|
||||
- name: Check Rust formatting
|
||||
run: cargo fmt --manifest-path plugins/examples/rust/rust_demo/Cargo.toml --check
|
||||
- name: Verify v1 and v2 plugin scaffolds
|
||||
run: python -m pytest tests/cli/runtime/plugin/test_runtime_scaffold.py tests/cli/runtime/plugin/test_runtime_scaffold_v2.py -q
|
||||
- name: Verify SDK provenance and offline update commands
|
||||
run: python -m pytest tests/cli/runtime/plugin/test_runtime_sdk.py tests/cli/root/test_plugin_sdk_commands.py -q
|
||||
- name: Verify persistent task plugin
|
||||
run: python -m pytest tests/plugins/examples/test_task_demo.py -q
|
||||
- name: Build and assemble source-free plugin
|
||||
run: python scripts/build_native_plugin.py --output target/native-package
|
||||
- name: Check Rust code
|
||||
run: cargo clippy --manifest-path plugins/examples/rust/rust_demo/Cargo.toml --locked -- -D warnings
|
||||
- name: Exercise native library through the host runtime
|
||||
env:
|
||||
RUOYI_NATIVE_PLUGIN_DIR: ${{ github.workspace }}/ruoyi-fastapi-backend/target/native-package/rust_demo
|
||||
run: python -m pytest tests/plugins/native tests/plugins/core/native tests/plugins/core/runtime/test_host_services.py tests/plugins/core/runtime/test_job_dispatcher.py -q
|
||||
- name: Verify signed artifacts and maintenance releases
|
||||
env:
|
||||
RUOYI_NATIVE_PLUGIN_DIR: ${{ github.workspace }}/ruoyi-fastapi-backend/target/native-package/rust_demo
|
||||
run: python -m pytest tests/plugins/core/artifacts tests/plugins/core/deployment tests/plugins/core/management/test_release_dao.py tests/plugins/core/management/test_artifact_views.py tests/module_plugin/controller/test_plugin_release_controller.py tests/cli/root/test_plugin_artifact_commands.py tests/cli/root/test_plugin_release_wait.py tests/sql/test_plugin_release_schema.py -q
|
||||
@@ -1,174 +0,0 @@
|
||||
name: Playwright Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
mysql-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /tmp/.docker_cache
|
||||
key: ${{ runner.os }}-docker-${{ matrix.python-version }}-${{ hashFiles('**/Dockerfile*', '**/requirements.txt') }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Create temporary Dockerfile with Python ${{ matrix.python-version }}
|
||||
run: |
|
||||
# Save original Dockerfile.my
|
||||
cp ruoyi-fastapi-backend/Dockerfile.my ruoyi-fastapi-backend/Dockerfile.my.bak
|
||||
# Create temporary Dockerfile with target Python version and default PyPI index
|
||||
sed -e "s/FROM python:3.10/FROM python:${{ matrix.python-version }}/g" \
|
||||
-e 's| -i https://pypi.tuna.tsinghua.edu.cn/simple||g' \
|
||||
ruoyi-fastapi-backend/Dockerfile.my.bak > ruoyi-fastapi-backend/Dockerfile.my
|
||||
|
||||
- name: Start services with docker-compose
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
docker compose -f docker-compose.test.my.yml up -d --build
|
||||
|
||||
- name: Wait for services to be ready
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
# Wait for backend to be running
|
||||
timeout 180 bash -c 'until docker compose -f docker-compose.test.my.yml ps ruoyi-backend-my | grep -q "Up"; do sleep 5; done'
|
||||
# Wait for frontend to be running
|
||||
timeout 120 bash -c 'until docker compose -f docker-compose.test.my.yml ps ruoyi-frontend | grep -q "Up"; do sleep 5; done'
|
||||
# Additional wait for services to be fully ready and listening on ports
|
||||
sleep 30
|
||||
# Check that backend is actually responding on the API endpoint
|
||||
echo "Checking if backend service is ready..."
|
||||
for i in {1..30}; do
|
||||
if curl -f http://localhost:9099/captchaImage > /dev/null 2>&1; then
|
||||
echo "Backend service is ready!"
|
||||
break
|
||||
fi
|
||||
echo "Waiting for backend service to be ready... ($i/30)"
|
||||
sleep 5
|
||||
done
|
||||
# Final check
|
||||
if ! curl -f http://localhost:9099/captchaImage > /dev/null 2>&1; then
|
||||
echo "Backend service failed to start properly. Checking logs..."
|
||||
docker logs ruoyi-backend-my-test
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
pip install -r requirements.txt
|
||||
playwright install
|
||||
pytest -v
|
||||
|
||||
- name: Stop services
|
||||
if: always()
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
docker compose -f docker-compose.test.my.yml down
|
||||
|
||||
- name: Restore original Dockerfile.my
|
||||
if: always()
|
||||
run: |
|
||||
# Restore original Dockerfile.my after test
|
||||
mv ruoyi-fastapi-backend/Dockerfile.my.bak ruoyi-fastapi-backend/Dockerfile.my
|
||||
|
||||
pg-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /tmp/.docker_cache
|
||||
key: ${{ runner.os }}-docker-${{ matrix.python-version }}-${{ hashFiles('**/Dockerfile*', '**/requirements.txt') }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Create temporary Dockerfile with Python ${{ matrix.python-version }}
|
||||
run: |
|
||||
# Save original Dockerfile.pg
|
||||
cp ruoyi-fastapi-backend/Dockerfile.pg ruoyi-fastapi-backend/Dockerfile.pg.bak
|
||||
# Create temporary Dockerfile with target Python version and default PyPI index
|
||||
sed -e "s/FROM python:3.10/FROM python:${{ matrix.python-version }}/g" \
|
||||
-e 's| -i https://pypi.tuna.tsinghua.edu.cn/simple||g' \
|
||||
ruoyi-fastapi-backend/Dockerfile.pg.bak > ruoyi-fastapi-backend/Dockerfile.pg
|
||||
|
||||
- name: Start services with docker-compose
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
docker compose -f docker-compose.test.pg.yml up -d --build
|
||||
|
||||
- name: Wait for services to be ready
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
# Wait for backend to be running
|
||||
timeout 180 bash -c 'until docker compose -f docker-compose.test.pg.yml ps ruoyi-backend-pg | grep -q "Up"; do sleep 5; done'
|
||||
# Wait for frontend to be running
|
||||
timeout 120 bash -c 'until docker compose -f docker-compose.test.pg.yml ps ruoyi-frontend | grep -q "Up"; do sleep 5; done'
|
||||
# Additional wait for services to be fully ready and listening on ports
|
||||
sleep 30
|
||||
# Check that backend is actually responding on the API endpoint
|
||||
echo "Checking if backend service is ready..."
|
||||
for i in {1..30}; do
|
||||
if curl -f http://localhost:9099/captchaImage > /dev/null 2>&1; then
|
||||
echo "Backend service is ready!"
|
||||
break
|
||||
fi
|
||||
echo "Waiting for backend service to be ready... ($i/30)"
|
||||
sleep 5
|
||||
done
|
||||
# Final check
|
||||
if ! curl -f http://localhost:9099/captchaImage > /dev/null 2>&1; then
|
||||
echo "Backend service failed to start properly. Checking logs..."
|
||||
docker logs ruoyi-backend-pg-test
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
pip install -r requirements.txt
|
||||
playwright install
|
||||
pytest -v
|
||||
|
||||
- name: Stop services
|
||||
if: always()
|
||||
run: |
|
||||
cd ruoyi-fastapi-test
|
||||
docker compose -f docker-compose.test.pg.yml down
|
||||
|
||||
- name: Restore original Dockerfile.pg
|
||||
if: always()
|
||||
run: |
|
||||
# Restore original Dockerfile.pg after test
|
||||
mv ruoyi-fastapi-backend/Dockerfile.pg.bak ruoyi-fastapi-backend/Dockerfile.pg
|
||||
@@ -1,69 +0,0 @@
|
||||
name: Plugin Frontend Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-frontend/src/api/system/plugin.js'
|
||||
- 'ruoyi-fastapi-frontend/src/components/PluginFrame/**'
|
||||
- 'ruoyi-fastapi-frontend/src/views/system/plugin/**'
|
||||
- 'ruoyi-fastapi-frontend/src/utils/**'
|
||||
- 'ruoyi-fastapi-frontend/src/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/src/router/**'
|
||||
- 'ruoyi-fastapi-frontend/src/store/modules/permission.js'
|
||||
- 'ruoyi-fastapi-frontend/src/store/modules/user.js'
|
||||
- 'ruoyi-fastapi-frontend/src/permission.js'
|
||||
- 'ruoyi-fastapi-frontend/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/tests/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/tests/run-tests.js'
|
||||
- 'ruoyi-fastapi-frontend/package.json'
|
||||
- 'ruoyi-fastapi-frontend/package-lock.json'
|
||||
- 'ruoyi-fastapi-frontend/vite.config.js'
|
||||
- 'ruoyi-fastapi-frontend/vite/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/python/bundle_demo/web/**'
|
||||
- '.github/workflows/plugin-frontend.yml'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-frontend/src/api/system/plugin.js'
|
||||
- 'ruoyi-fastapi-frontend/src/components/PluginFrame/**'
|
||||
- 'ruoyi-fastapi-frontend/src/views/system/plugin/**'
|
||||
- 'ruoyi-fastapi-frontend/src/utils/**'
|
||||
- 'ruoyi-fastapi-frontend/src/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/src/router/**'
|
||||
- 'ruoyi-fastapi-frontend/src/store/modules/permission.js'
|
||||
- 'ruoyi-fastapi-frontend/src/store/modules/user.js'
|
||||
- 'ruoyi-fastapi-frontend/src/permission.js'
|
||||
- 'ruoyi-fastapi-frontend/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/tests/plugins/**'
|
||||
- 'ruoyi-fastapi-frontend/tests/run-tests.js'
|
||||
- 'ruoyi-fastapi-frontend/package.json'
|
||||
- 'ruoyi-fastapi-frontend/package-lock.json'
|
||||
- 'ruoyi-fastapi-frontend/vite.config.js'
|
||||
- 'ruoyi-fastapi-frontend/vite/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/python/bundle_demo/web/**'
|
||||
- '.github/workflows/plugin-frontend.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
plugins:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-frontend
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
cache-dependency-path: ruoyi-fastapi-frontend/package.json
|
||||
- name: Install frontend dependencies
|
||||
# This repository does not commit npm lockfiles, so npm ci is not available.
|
||||
run: npm install --no-audit --no-fund --package-lock=false
|
||||
- name: Verify plugin bridge, sessions and management views
|
||||
run: npm run test:plugin
|
||||
@@ -1,63 +0,0 @@
|
||||
name: Plugin Network Smoke
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-backend/plugins/**'
|
||||
- 'ruoyi-fastapi-backend/module_plugin/**'
|
||||
- 'ruoyi-fastapi-backend/module_admin/service/login_service.py'
|
||||
- 'ruoyi-fastapi-backend/common/**'
|
||||
- 'ruoyi-fastapi-backend/config/**'
|
||||
- 'ruoyi-fastapi-backend/middlewares/**'
|
||||
- 'ruoyi-fastapi-backend/utils/**'
|
||||
- 'ruoyi-fastapi-backend/tests/**'
|
||||
- 'ruoyi-fastapi-backend/requirements.txt'
|
||||
- 'ruoyi-fastapi-backend/pyproject.toml'
|
||||
- 'ruoyi-fastapi-frontend/**'
|
||||
- '.github/workflows/plugin-network-smoke.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
browser:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
env:
|
||||
RUOYI_PLUGIN_NETWORK_SMOKE: '1'
|
||||
# The fixture replaces account, DB and Redis access; no external service is used.
|
||||
DB_SOURCES: '{"primary":{"db_type":"mysql","db_host":"127.0.0.1","db_port":3306,"db_username":"network-smoke","db_password":"network-smoke","db_database":"network-smoke"}}'
|
||||
JWT_SECRET_KEY: 'isolated-plugin-network-smoke-ci-only'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements.txt
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
cache-dependency-path: ruoyi-fastapi-frontend/package.json
|
||||
- name: Install host and browser test dependencies
|
||||
run: python -m pip install -r requirements.txt pytest pytest-asyncio aiosqlite playwright
|
||||
- name: Install Chromium
|
||||
run: python -m playwright install --with-deps chromium
|
||||
- name: Install frontend dependencies
|
||||
# This repository does not commit npm lockfiles, so npm ci is not available.
|
||||
run: npm --prefix ../ruoyi-fastapi-frontend install --no-audit --no-fund --package-lock=false
|
||||
- name: Verify HTTPS proxy, iframe sessions and long connections
|
||||
run: python -m pytest tests/plugins/integration/test_network_smoke.py -v --junitxml=target/plugin-network-smoke/results.xml
|
||||
- name: Upload browser trace, screenshots and proxy log
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: plugin-network-smoke
|
||||
path: ruoyi-fastapi-backend/target/plugin-network-smoke/
|
||||
retention-days: 7
|
||||
@@ -1,94 +0,0 @@
|
||||
name: Plugin Release Integration
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'ruoyi-fastapi-backend/plugins/core/**'
|
||||
- 'ruoyi-fastapi-backend/plugins/examples/python/task_demo/**'
|
||||
- 'ruoyi-fastapi-frontend/src/utils/pluginBridge.js'
|
||||
- 'ruoyi-fastapi-backend/config/**'
|
||||
- 'ruoyi-fastapi-backend/cli/groups/plugin/**'
|
||||
- 'ruoyi-fastapi-backend/cli/runtime/plugin/**'
|
||||
- 'ruoyi-fastapi-backend/module_plugin/**'
|
||||
- 'ruoyi-fastapi-backend/server.py'
|
||||
- 'ruoyi-fastapi-backend/app.py'
|
||||
- 'ruoyi-fastapi-backend/sql/ruoyi-fastapi*.sql'
|
||||
- 'ruoyi-fastapi-backend/scripts/plugin_release_integration.py'
|
||||
- 'ruoyi-fastapi-backend/scripts/plugin_task_integration.py'
|
||||
- 'ruoyi-fastapi-backend/tests/plugins/**'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_artifact_commands.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_release_wait.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/root/test_plugin_diagnostics.py'
|
||||
- 'ruoyi-fastapi-backend/tests/cli/runtime/plugin/**'
|
||||
- 'ruoyi-fastapi-backend/tests/module_plugin/**'
|
||||
- 'ruoyi-fastapi-backend/tests/server/test_plugin_runtime.py'
|
||||
- 'ruoyi-fastapi-backend/tests/sql/test_plugin_release_schema.py'
|
||||
- 'ruoyi-fastapi-backend/pyproject.toml'
|
||||
- 'ruoyi-fastapi-backend/requirements.txt'
|
||||
- 'ruoyi-fastapi-backend/requirements-pg.txt'
|
||||
- '.github/workflows/plugin-release-integration.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python: ['3.10', '3.11', '3.12', '3.13']
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: ci-only-mysql
|
||||
ports: ['3306:3306']
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping -h localhost"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
postgres:
|
||||
image: postgres:14
|
||||
env:
|
||||
POSTGRES_PASSWORD: ci-only-postgres
|
||||
ports: ['5432:5432']
|
||||
options: >-
|
||||
--health-cmd="pg_isready -U postgres"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
redis:
|
||||
image: redis:6.2
|
||||
ports: ['6379:6379']
|
||||
options: >-
|
||||
--health-cmd="redis-cli ping"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
env:
|
||||
RUOYI_PLUGIN_IT_ALLOW: '1'
|
||||
RUOYI_IT_MYSQL_PASSWORD: ci-only-mysql
|
||||
RUOYI_IT_PG_PASSWORD: ci-only-postgres
|
||||
RUOYI_IT_REDIS_PASSWORD: ''
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- name: Install host dependencies
|
||||
run: python -m pip install -r requirements.txt -r requirements-pg.txt
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '22'
|
||||
- name: Test and build task plugin bundle
|
||||
run: |
|
||||
npm --prefix plugins/examples/python/task_demo/web install --no-audit --no-fund --package-lock=false
|
||||
npm --prefix plugins/examples/python/task_demo/web test
|
||||
npm --prefix plugins/examples/python/task_demo/web run build
|
||||
- name: Verify MySQL and Redis maintenance releases
|
||||
run: python scripts/plugin_release_integration.py --engine mysql
|
||||
- name: Verify PostgreSQL and Redis maintenance releases
|
||||
run: python scripts/plugin_release_integration.py --engine postgresql
|
||||
@@ -1,33 +0,0 @@
|
||||
name: Ruff Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
lint-format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install ruff
|
||||
|
||||
- name: Run linting
|
||||
run: |
|
||||
ruff check ruoyi-fastapi-backend
|
||||
ruff check ruoyi-fastapi-test
|
||||
|
||||
- name: Run format check
|
||||
run: |
|
||||
ruff format ruoyi-fastapi-backend --check
|
||||
ruff format ruoyi-fastapi-test --check
|
||||
@@ -1,106 +0,0 @@
|
||||
name: Timezone Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
databases:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TZ: America/New_York
|
||||
PYTHONUTF8: '1'
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: timezone_test
|
||||
TZ: Asia/Shanghai
|
||||
ports: ['3306:3306']
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping -h localhost -ptimezone_test"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
postgres:
|
||||
image: postgres:14
|
||||
env:
|
||||
POSTGRES_PASSWORD: timezone_test
|
||||
TZ: America/New_York
|
||||
PGTZ: America/New_York
|
||||
ports: ['5432:5432']
|
||||
options: >-
|
||||
--health-cmd="pg_isready -U postgres"
|
||||
--health-interval=10s --health-timeout=5s --health-retries=12
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.10'
|
||||
cache: pip
|
||||
cache-dependency-path: ruoyi-fastapi-backend/requirements*.txt
|
||||
- name: Install verification dependencies
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
run: python -m pip install -r requirements.txt asyncpg psycopg2-binary pytest pytest-asyncio aiosqlite
|
||||
- name: Create isolated source configurations
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
run: |
|
||||
mkdir -p .cache/timezone-ci
|
||||
python - <<'PY'
|
||||
import json
|
||||
from pathlib import Path
|
||||
for dialect, port, username, database in [('mysql', 3306, 'root', 'mysql'), ('postgresql', 5432, 'postgres', 'postgres')]:
|
||||
source = dict(db_type=dialect, db_host='127.0.0.1', db_port=port, db_username=username,
|
||||
db_password='timezone_test', db_database=database)
|
||||
Path(f'.cache/timezone-ci/{dialect}.json').write_text(json.dumps(source))
|
||||
PY
|
||||
- name: Verify empty databases, drivers, generated CRUD and persistent schedulers
|
||||
working-directory: ruoyi-fastapi-backend
|
||||
run: |
|
||||
python -m scripts.verify_timezone_database --config .cache/timezone-ci/mysql.json --report .cache/timezone-ci/mysql-report.json
|
||||
python -m scripts.verify_timezone_database --config .cache/timezone-ci/postgresql.json --report .cache/timezone-ci/postgresql-report.json
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: always()
|
||||
with:
|
||||
name: timezone-database-reports
|
||||
path: ruoyi-fastapi-backend/.cache/timezone-ci/*-report.json
|
||||
include-hidden-files: true
|
||||
|
||||
web-app:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: npm
|
||||
# Lockfiles are ignored by this repository; cache by the committed manifest.
|
||||
cache-dependency-path: ruoyi-fastapi-frontend/package.json
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
package_json_file: ruoyi-fastapi-app/package.json
|
||||
- name: Install Web dependencies
|
||||
working-directory: ruoyi-fastapi-frontend
|
||||
run: npm install --no-package-lock
|
||||
- name: Install App dependencies
|
||||
working-directory: ruoyi-fastapi-app
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
- name: Run time contracts in three host timezones
|
||||
run: node ruoyi-fastapi-test/time-contract/run-host-timezones.mjs
|
||||
- name: Build Web targets
|
||||
working-directory: ruoyi-fastapi-frontend
|
||||
run: |
|
||||
npm run build:prod
|
||||
npm run build:docker
|
||||
- name: Build App targets
|
||||
working-directory: ruoyi-fastapi-app
|
||||
run: |
|
||||
pnpm build:h5
|
||||
pnpm build:mp-weixin
|
||||
- name: Validate all Compose configurations
|
||||
run: |
|
||||
docker compose -f docker-compose.my.yml config --quiet
|
||||
docker compose -f docker-compose.pg.yml config --quiet
|
||||
docker compose -f ruoyi-fastapi-test/docker-compose.test.my.yml config --quiet
|
||||
docker compose -f ruoyi-fastapi-test/docker-compose.test.pg.yml config --quiet
|
||||
Reference in New Issue
Block a user