Skip to content

Build and Test

Build and Test #17519

Workflow file for this run

name: Build and Test
on:
merge_group:
types: [ checks_requested ]
pull_request:
branches:
- main
push:
branches:
- main
env:
GRADLE_OPTS: -Dorg.gradle.daemon=false
jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Build all classes
run: ./gradlew --stacktrace classes
build-cli:
strategy:
matrix:
target:
- name: 'Linux x64'
os: ubuntu-24.04
task: 'linkReleaseExecutableLinuxX64'
artifact: 'osc-cli-linux-x64'
buildPath: 'cli/build/bin/linuxX64/releaseExecutable/osc.kexe'
binName: 'osc'
- name: 'macOS arm64'
os: macos-15
task: 'linkReleaseExecutableMacosArm64'
artifact: 'osc-cli-macos-arm64'
buildPath: 'cli/build/bin/macosArm64/releaseExecutable/osc.kexe'
binName: 'osc'
- name: 'macOS x64'
os: macos-15-intel
task: 'linkReleaseExecutableMacosX64'
artifact: 'osc-cli-macos-x64'
buildPath: 'cli/build/bin/macosX64/releaseExecutable/osc.kexe'
binName: 'osc'
- name: 'Windows x64'
os: windows-2025
task: 'linkReleaseExecutableMingwX64'
artifact: 'osc-cli-windows-x64'
buildPath: 'cli/build/bin/mingwX64/releaseExecutable/osc.exe'
binName: 'osc.exe'
name: Build ${{ matrix.target.name }} CLI
runs-on: ${{ matrix.target.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
if: runner.os == 'Windows'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Get the Kotlin version
id: get-kotlin-plugin-info
shell: bash
run: echo "info=$(./gradlew -q :cli:properties | grep kotlin.plugin.loaded.in.projects)" >> $GITHUB_OUTPUT
- name: Cache the .konan directory
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/.konan
key: ${{ steps.get-kotlin-plugin-info.outputs.info }}
- name: Build CLI - ${{ matrix.target.name }}
run: ./gradlew --stacktrace cli:${{ matrix.target.task }}
- name: Rename CLI binary
shell: bash
run: |
mkdir -p ${{ matrix.target.artifact }}
mv ${{ matrix.target.buildPath }} ${{ matrix.target.artifact }}/${{ matrix.target.binName }}
- name: Run CLI binary
run: ./${{ matrix.target.artifact }}/${{ matrix.target.binName }} --version
- name: Upload CLI binary
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ matrix.target.artifact }}
path: ${{ matrix.target.artifact }}/${{ matrix.target.binName }}
retention-days: 7
build-ui:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Generate OpenAPI spec
run: ./gradlew --stacktrace :core:generateOpenApiSpec
- name: Install Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24
cache-dependency-path: ui/pnpm-lock.yaml
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm -C ui install
- name: Build UI
run: pnpm -C ui build
- name: Test UI
run: pnpm -C ui test
test:
needs: build
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Run tests
run: ./gradlew test allTests -Dkotest.tags='!Authorization & !Integration'
- name: Create Test Summary
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
with:
paths: "**/test-results/**/TEST-*.xml"
if: success() || failure()
- name: Upload test results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: success() || failure()
with:
name: test-results
path: "**/build/reports/tests"
retention-days: 7
authorization-test:
needs: build
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Run authorization tests
run: ./gradlew test allTests -Dkotest.tags='Authorization'
- name: Create Test Summary
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
with:
paths: "**/test-results/**/TEST-*.xml"
if: success() || failure()
- name: Upload test results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: success() || failure()
with:
name: authorization-test-results
path: "**/build/reports/tests"
retention-days: 7
integration-test:
needs: build
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Run integration tests
run: ./gradlew test allTests -Dkotest.tags='Integration'
- name: Create Test Summary
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
with:
paths: "**/test-results/**/TEST-*.xml"
if: success() || failure()
- name: Upload test results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: success() || failure()
with:
name: integration-test-results
path: "**/build/reports/tests"
retention-days: 7
publication-test:
needs: build
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Publish to local Maven repository
run: ./gradlew publishToMavenLocal
test-ui-e2e:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
- name: Generate OpenAPI spec
run: ./gradlew --stacktrace :core:generateOpenApiSpec
- name: Install Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24
cache-dependency-path: ui/pnpm-lock.yaml
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm -C ui install
- name: Generate API client and routes
run: pnpm -C ui generate:api && pnpm -C ui generate:routes
- name: Install Playwright Browsers
run: pnpm -C ui exec playwright install --with-deps
- name: Start core services
run: docker compose up -d core
- name: Wait for core readiness
run: |
echo "Waiting for core liveness endpoint..."
for i in {1..60}; do
if curl -fsS http://127.0.0.1:8080/api/v1/liveness >/dev/null; then
echo "Core liveness endpoint is available."
break
fi
if [ $i -eq 60 ]; then
echo "Core failed to report healthy within 120 seconds" >&2
docker compose logs core
exit 1
fi
sleep 2
done
- name: Run Playwright tests
env:
VITE_UI_URL: http://127.0.0.1:8082/
VITE_CLIENT_ID: ort-server-ui
run: |
# Exit on error, undefined variables, and pipe failures
set -euo pipefail
# Start the Vite dev server in the background
# The dev server is needed because Playwright tests run against a live server
pnpm -C ui dev --host 0.0.0.0 --port 8082 > ui-dev.log 2>&1 &
UI_DEV_PID=$!
# Set up cleanup to ensure the background dev server process is killed on exit
# This prevents process leaks even if the workflow fails or is cancelled
cleanup() {
if ps -p $UI_DEV_PID > /dev/null 2>&1; then
kill $UI_DEV_PID || true
fi
}
trap cleanup EXIT
echo "Waiting for UI dev server to be ready on http://localhost:8082 ..."
for i in {1..60}; do
# Fail fast if the dev server crashes - this provides better error messages
# than waiting for the timeout with no logs
if ! ps -p $UI_DEV_PID > /dev/null 2>&1; then
echo "UI dev server process exited unexpectedly. Recent logs:"
tail -n 200 ui-dev.log || true
exit 1
fi
# Check if Vite has finished building by looking for the ready message in the log
if grep -q "ready in" ui-dev.log 2>/dev/null; then
# Also verify the server actually returns HTML content
if curl -fsS http://127.0.0.1:8082 2>/dev/null | grep -q "<html"; then
echo "UI dev server is ready."
break
fi
fi
if [ $i -eq 60 ]; then
echo "UI dev server failed to become ready within 120 seconds" >&2
echo "Last 200 lines of UI dev log:"
tail -n 200 ui-dev.log || true
exit 1
fi
sleep 2
done
pnpm -C ui test:e2e
- name: Upload UI dev log
if: success() || failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ui-dev-log
path: ui-dev.log
retention-days: 7
- name: Upload Playwright report
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: success() || failure()
with:
name: playwright-report
path: ui/playwright-report
retention-days: 7