ci: merge end-to-end workflow into ci, permits to reduce amount of built

This commit is contained in:
Edouard Vanbelle
2026-05-11 11:24:11 +02:00
parent cc14ec53ee
commit d8625b9f39
4 changed files with 250 additions and 267 deletions
+236 -153
View File
@@ -1,153 +1,236 @@
name: CI name: CI
# IMPORTANT: using Swatinem/rust-cache@v2 : reuse same cache as playwright.yml (minimize non necessary new compilation) on:
push:
on: branches:
push: - main
branches: - dev
- main - "feat/**"
- dev - "fix/**"
- "feat/**" pull_request:
- "fix/**" branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ] env:
CARGO_TERM_COLOR: always
env: RUSTFLAGS: "-Dwarnings"
CARGO_TERM_COLOR: always DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
RUSTFLAGS: "-Dwarnings"
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test" jobs:
jobs: # Detect which parts of the codebase changed
changes:
# Detect which parts of the codebase changed runs-on: ubuntu-latest
changes: outputs:
runs-on: ubuntu-latest frontend: ${{ steps.filter.outputs.frontend }}
outputs: backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }} steps:
backend: ${{ steps.filter.outputs.backend }} - uses: actions/checkout@v4
steps: - uses: dorny/paths-filter@v3
- uses: actions/checkout@v4 id: filter
- uses: dorny/paths-filter@v3 with:
id: filter filters: |
with: frontend:
filters: | - 'static/**'
frontend: - 'biome.json'
- 'static/**' - '.grit'
- 'biome.json' - '.stylelintrc.json'
- '.grit' - 'jsconfig.json'
- '.stylelintrc.json' backend:
- 'jsconfig.json' - 'src/**'
backend: - 'Cargo.toml'
- 'src/**' - 'Cargo.lock'
- 'Cargo.toml'
- 'Cargo.lock' frontend-check:
name: Frontend — CSS and JS checks (format, lint, rules)
frontend-linter: needs: changes
name: Frontend — CSS and JS checks (format, lint, rules, etc) if: needs.changes.outputs.frontend == 'true'
needs: changes runs-on: ubuntu-latest
if: needs.changes.outputs.frontend == 'true' steps:
runs-on: ubuntu-latest - uses: actions/checkout@v4
steps:
- uses: actions/checkout@v4 - name: Install Biome
uses: biomejs/setup-biome@v2
- name: Install Biome
uses: biomejs/setup-biome@v2 - name: Run Biome check
run: biome ci static/
- name: Run Biome check
run: biome ci static/ - name: Setup Node
uses: actions/setup-node@v4
- name: Setup Node with:
uses: actions/setup-node@v4 node-version: 25
with:
node-version: 25 # because we are not using package.json
- name: Install Stylelint and plugins
# because we are not using package.json run: |
- name: Install Stylelint and plugins npm install --global \
run: | stylelint@17 \
npm install --global \ postcss@8 \
stylelint@17 \ stylelint-value-no-unknown-custom-properties@6
postcss@8 \
stylelint-value-no-unknown-custom-properties@6 - name: Run Stylelint
run: npx stylelint "static/css/**/*.{css,scss}"
- name: Run Stylelint
run: npx stylelint "static/css/**/*.{css,scss}" rust-fmt:
name: Rustfmt
rust-fmt: needs: changes
name: Rustfmt if: needs.changes.outputs.backend == 'true'
needs: changes runs-on: ubuntu-latest
if: needs.changes.outputs.backend == 'true' steps:
runs-on: ubuntu-latest - uses: actions/checkout@v6
steps: - uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v6 with:
- uses: dtolnay/rust-toolchain@stable components: rustfmt
with: - run: cargo fmt --all --check
components: rustfmt
- run: cargo fmt --all --check rust-clippy:
name: Clippy
rust-clippy: needs: changes
name: Clippy if: needs.changes.outputs.backend == 'true'
needs: changes runs-on: ubuntu-latest
if: needs.changes.outputs.backend == 'true' steps:
runs-on: ubuntu-latest - uses: actions/checkout@v6
steps: - uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v6 with:
- uses: dtolnay/rust-toolchain@stable components: clippy
with: - uses: Swatinem/rust-cache@v2
components: clippy - run: cargo clippy --all-targets --all-features -- -D warnings
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features -- -D warnings rust-test:
name: Server Unit and Functionnal Tests
rust-test: needs: changes
name: Tests if: needs.changes.outputs.backend == 'true'
needs: changes runs-on: ubuntu-latest
if: needs.changes.outputs.backend == 'true' services:
runs-on: ubuntu-latest postgres:
services: image: postgres:16-alpine
postgres: env:
image: postgres:16-alpine POSTGRES_USER: postgres
env: POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres POSTGRES_DB: oxicloud_test
POSTGRES_PASSWORD: postgres ports:
POSTGRES_DB: oxicloud_test - 5432:5432
ports: options: >-
- 5432:5432 --health-cmd "pg_isready -U postgres"
options: >- --health-interval 10s
--health-cmd "pg_isready -U postgres" --health-timeout 5s
--health-interval 10s --health-retries 5
--health-timeout 5s steps:
--health-retries 5 - uses: actions/checkout@v6
steps: - uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v6 - uses: Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2 - name: Initialize test database
run: psql -h localhost -U postgres -d oxicloud_test -f migrations/20260307000000_initial_schema.sql
- name: Initialize test database env:
run: psql -h localhost -U postgres -d oxicloud_test -f migrations/20260307000000_initial_schema.sql PGPASSWORD: postgres
env:
PGPASSWORD: postgres - name: Run tests
run: cargo test --all-features --workspace
- name: Run tests env:
run: cargo test --all-features --workspace DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
env:
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test" rust-audit:
name: Security Audit
rust-audit: needs: changes
name: Security Audit if: needs.changes.outputs.backend == 'true'
needs: changes runs-on: ubuntu-latest
if: needs.changes.outputs.backend == 'true' steps:
runs-on: ubuntu-latest - uses: actions/checkout@v6
steps: - uses: rustsec/audit-check@v2.0.0
- uses: actions/checkout@v6 with:
- uses: rustsec/audit-check@v2.0.0 token: ${{ secrets.GITHUB_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }} build:
name: Build
build: runs-on: ubuntu-latest
name: Build Check needs: [rust-fmt, rust-clippy, rust-test]
runs-on: ubuntu-latest steps:
needs: [frontend-linter, rust-fmt, rust-clippy, rust-test] - uses: actions/checkout@v6
steps: - uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v6 - uses: Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@stable - run: cargo build --release
- uses: Swatinem/rust-cache@v2 - uses: actions/upload-artifact@v4
- run: cargo build --release with:
name: oxicloud-release
path: target/release/oxicloud
retention-days: 1
api-test:
name: API tests (via Hurl)
needs: build
# if: github.event_name == 'pull_request'
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: oxicloud-release
path: target/release/
- run: chmod +x target/release/oxicloud
- name: Install Hurl
env:
HURL_MAJOR: "8"
run: |
HURL_VERSION=$(curl -fsSL -H "Authorization: Bearer ${{ github.token }}" \
https://api.github.com/repos/Orange-OpenSource/hurl/releases \
| jq -r "map(select(.tag_name | startswith(\"${HURL_MAJOR}.\"))) | first | .tag_name")
curl -fLO "https://github.com/Orange-OpenSource/hurl/releases/download/${HURL_VERSION}/hurl_${HURL_VERSION}_amd64.deb"
sudo apt-get install -y "./hurl_${HURL_VERSION}_amd64.deb"
- name: Run Hurl API tests
run: bash tests/api/run.sh
env:
BUILD_TARGET: release
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: hurl-report
path: tests/api/storage/
retention-days: 7
front-test:
name: Frontend end-to-end tests (via Playwright)
# ensure that api tests are ok before
needs: api-test
# if: github.event_name == 'pull_request'
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: oxicloud-release
path: target/release/
- run: chmod +x target/release/oxicloud
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install Node dependencies
working-directory: tests/e2e
run: npm ci
- name: Install Playwright browsers
working-directory: tests/e2e
run: npx playwright install --with-deps
- name: Run Playwright tests (spawns DB via pretest hook)
working-directory: tests/e2e
run: npm test
env:
BUILD_TARGET: release
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: tests/e2e/playwright-report/
retention-days: 30
-110
View File
@@ -1,110 +0,0 @@
name: Playwright Test (end-to-end)
# IMPORTANT: using Swatinem/rust-cache@v2 : reuse same cache as ci.yml (minimize non necessary new compilation)
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
#concurrency:
# group: rust-build-${{ github.ref }}
# cancel-in-progress: false
jobs:
api-test:
name: Hurl API tests
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache compiled binary
id: binary-cache
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/target/debug/oxicloud
key: ${{ runner.os }}-oxicloud-binary-${{ hashFiles('src/**', 'Cargo.toml', 'Cargo.lock') }}
- name: Cache Rust dependencies
if: steps.binary-cache.outputs.cache-hit != 'true'
uses: Swatinem/rust-cache@v2
- name: Build server
if: steps.binary-cache.outputs.cache-hit != 'true'
run: cargo build
- name: Install Hurl
env:
HURL_MAJOR: "8"
run: |
HURL_VERSION=$(curl -fsSL -H "Authorization: Bearer ${{ github.token }}" \
https://api.github.com/repos/Orange-OpenSource/hurl/releases \
| jq -r "map(select(.tag_name | startswith(\"${HURL_MAJOR}.\"))) | first | .tag_name")
curl -fLO "https://github.com/Orange-OpenSource/hurl/releases/download/${HURL_VERSION}/hurl_${HURL_VERSION}_amd64.deb"
sudo apt-get install -y "./hurl_${HURL_VERSION}_amd64.deb"
- name: Run Hurl API tests
run: bash tests/api/run.sh
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: hurl-report
path: tests/api/storage/
retention-days: 7
front-test:
# starts api-test first
needs: api-test
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache compiled binary
id: binary-cache
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/target/debug/oxicloud
key: ${{ runner.os }}-oxicloud-binary-${{ hashFiles('src/**', 'Cargo.toml', 'Cargo.lock') }}
- name: Cache Rust dependencies
if: steps.binary-cache.outputs.cache-hit != 'true'
uses: Swatinem/rust-cache@v2
- name: Build server
if: steps.binary-cache.outputs.cache-hit != 'true'
run: cargo build
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install Node dependencies
working-directory: tests/e2e
run: npm ci
- name: Install Playwright browsers
working-directory: tests/e2e
run: npx playwright install --with-deps
- name: Run Playwright tests (spawns DB via pretest hook)
working-directory: tests/e2e
run: npm test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: tests/e2e/playwright-report/
retention-days: 30
+11 -3
View File
@@ -66,9 +66,17 @@ mkdir -p "$OXICLOUD_STORAGE_PATH"
# ── 3. Start OxiCloud server ────────────────────────────────────────────────── # ── 3. Start OxiCloud server ──────────────────────────────────────────────────
log "Building and starting OxiCloud server on port $SERVER_PORT..." BUILD_TARGET="${BUILD_TARGET:-debug}"
cd "$REPO_ROOT" OXICLOUD_BIN="$REPO_ROOT/target/$BUILD_TARGET/oxicloud"
cargo run &
if [[ -x "$OXICLOUD_BIN" ]]; then
log "Starting pre-built OxiCloud server ($BUILD_TARGET) on port $SERVER_PORT..."
"$OXICLOUD_BIN" &
else
log "Building and starting OxiCloud server on port $SERVER_PORT..."
cd "$REPO_ROOT"
cargo run &
fi
SERVER_PID=$! SERVER_PID=$!
log "Waiting for server at $base_url..." log "Waiting for server at $base_url..."
wait_for_http "$base_url/ready" 120 wait_for_http "$base_url/ready" 120
+3 -1
View File
@@ -48,7 +48,9 @@ export default defineConfig({
], ],
webServer: { webServer: {
command: process.env.CI ? `${process.env.GITHUB_WORKSPACE}/target/debug/oxicloud` : 'cargo run', command: process.env.BUILD_TARGET
? `${process.env.GITHUB_WORKSPACE}/target/${process.env.BUILD_TARGET}/oxicloud`
: 'cargo run',
url: 'http://localhost:8087', url: 'http://localhost:8087',
timeout: 600_000, timeout: 600_000,
reuseExistingServer: false, reuseExistingServer: false,