Skip to content

Models screen layout part 1 #1294

Models screen layout part 1

Models screen layout part 1 #1294

name: Geti Tune UI checks
on:
workflow_dispatch:
push:
branches:
- develop
- release/**
tags:
- "v*"
pull_request:
merge_group:
branches:
- develop
- release/**
permissions: {} # No permissions by default on workflow level
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.after }}
cancel-in-progress: true
jobs:
# Determines if workflow should execute based on event type and changed paths
# If push or workflow_dispatch -> always run
# If PR or merge_group -> run only if files in specified paths changed
check_paths:
name: Check if workflow should run
runs-on: ubuntu-latest
outputs:
run_workflow: ${{ steps.run_workflow.outputs.run }}
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Get all paths that should trigger the workflow
id: changed-files-yaml
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files_yaml: |
test:
- application/backend/**
- application/ui/**
- .github/**
- name: Set run flag
id: run_workflow
run: |
if [ "${{ github.event_name }}" = "push" ] || [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
elif [ "${{ steps.changed-files-yaml.outputs.test_any_changed }}" = "true" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi
generate-openapi-spec:
name: Generate OpenAPI Spec
runs-on: ubuntu-latest
needs: check_paths
if: needs.check_paths.outputs.run_workflow == 'true'
permissions:
contents: read # to checkout code
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Install uv and set the Python version
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
with:
version: "0.9.7"
enable-cache: false
python-version: "3.13"
- name: Install OpenCV dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgl1 libglib2.0-0
- name: Prepare venv and install Python dependencies
working-directory: application/backend
run: |
uv lock --check
uv sync --frozen --extra cpu
- name: Get OpenAPI spec
working-directory: application/backend
run: |
export PYTHONPATH=.
uv run app/cli.py gen-api --target-path openapi-spec.json
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: openapi-spec
path: application/backend/openapi-spec.json
build:
name: Build UI
runs-on: ubuntu-latest
needs: check_paths
if: needs.check_paths.outputs.run_workflow == 'true'
permissions:
contents: read # to checkout code
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup-node
with:
node-version-file: application/ui/.nvmrc
package-manager-cache: false
- name: Install dependencies
working-directory: "application/ui"
run: npm ci
- name: Build UI
working-directory: "application/ui"
run: npm run build
- name: Compress build
working-directory: "application/ui"
run: tar -czf dist.tar.gz dist
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ui-dist
path: "application/ui/dist.tar.gz"
lint:
name: Eslint checks
runs-on: ubuntu-latest
needs:
- check_paths
- generate-openapi-spec
if: needs.check_paths.outputs.run_workflow == 'true'
permissions:
contents: read # to checkout code
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup-node
with:
node-version-file: application/ui/.nvmrc
package-manager-cache: false
- name: Install dependencies
working-directory: "application/ui"
run: npm ci
- name: Download OpenAPI spec artifact
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-spec
path: application/ui/src/api
- name: Build OpenAPI type definitions
working-directory: "application/ui"
run: npm run build:api
- name: Prettier
working-directory: "application/ui"
run: npm run format:check
- name: Eslint
working-directory: "application/ui"
run: npm run lint
- name: Eslint cyclic imports
working-directory: "application/ui"
run: npm run cyclic-deps-check
- name: Typescript
working-directory: "application/ui"
run: npm run type-check
unit-tests:
name: Unit tests
runs-on: ubuntu-latest
needs:
- check_paths
- generate-openapi-spec
if: needs.check_paths.outputs.run_workflow == 'true'
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup-node
with:
node-version-file: application/ui/.nvmrc
package-manager-cache: false
- name: Install dependencies
working-directory: "application/ui"
run: npm ci
- name: Download OpenAPI spec artifact
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-spec
path: application/ui/src/api
- name: Build OpenAPI type definitions
working-directory: "application/ui"
run: npm run build:api
- name: UI Unit tests
working-directory: "application/ui"
run: npm run test:unit:coverage
- name: Generate coverage report
if: github.event.pull_request.head.repo.full_name == github.repository
working-directory: "application/ui"
run: |
echo "## 📊 Test coverage report" > coverage.md
if [ -f "coverage/coverage-summary.json" ]; then
node -e "
const fs = require('fs');
try {
const coverage = JSON.parse(fs.readFileSync('./coverage/coverage-summary.json', 'utf8'));
const lines = \`\${coverage.total.lines.pct.toFixed(1)}%\`;
const functions = \`\${coverage.total.functions.pct.toFixed(1)}%\`;
const branches = \`\${coverage.total.branches.pct.toFixed(1)}%\`;
const statements = \`\${coverage.total.statements.pct.toFixed(1)}%\`;
console.log(\`| Metric | Coverage |\`);
console.log(\`| --- | --- |\`);
console.log(\`| Lines | \${lines} |\`);
console.log(\`| Functions | \${functions} |\`);
console.log(\`| Branches | \${branches} |\`);
console.log(\`| Statements | \${statements} |\`);
} catch {
console.error('Failed to parse coverage summary');
}
" >> coverage.md
else
echo "No coverage summary found" >> coverage.md
fi
- name: Comment PR with coverage report
if: github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const fs = require('fs');
let coverageComment = '';
try {
coverageComment = fs.readFileSync('application/ui/coverage.md', 'utf8');
} catch (error) {
coverageComment = '## 📊 Test Coverage Report\n\nCoverage report generation failed.';
}
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const existingComment = comments.data.find((comment) => comment.body.includes("Test coverage report"));
if (existingComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: coverageComment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: coverageComment
});
}
playwright-tests:
name: Playwright Tests
needs:
- check_paths
- build
- generate-openapi-spec
if: needs.check_paths.outputs.run_workflow == 'true'
permissions:
contents: read # to checkout code
timeout-minutes: 60
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.57.0-jammy@sha256:6aca677c27a967caf7673d108ac67ffaf8fed134f27e17b27a05464ca0ace831
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
ref: ${{ inputs.ref || '' }}
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup-node
with:
node-version-file: application/ui/.nvmrc
package-manager-cache: false
- name: Install dependencies
working-directory: "application/ui"
run: npm ci
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ui-dist
path: "application/ui"
- name: Unpack build
working-directory: "application/ui"
run: tar -xzf dist.tar.gz
- name: Download OpenAPI spec artifact
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: openapi-spec
path: application/ui/src/api
- name: Build OpenAPI type definitions
working-directory: "application/ui"
run: npm run build:api
- name: Run Playwright tests
working-directory: "application/ui"
run: npm run test:component -- --project "component"
- name: Upload blob report to GitHub Actions Artifacts
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: always()
with:
name: playwright-report
path: application/ui/playwright-report/
retention-days: 30
required_check:
name: Required Check ui-lint-and-test
needs:
- check_paths
- generate-openapi-spec
- build
- lint
- unit-tests
- playwright-tests
runs-on: ubuntu-latest
env:
CHECKS: ${{ join(needs.*.result, ' ') }}
if: always() && !cancelled()
steps:
- name: Check jobs results
run: |
for check in ${CHECKS}; do
echo "::notice::check=${check}"
if [[ "$check" != "success" && "$check" != "skipped" ]]; then
echo "::error ::Required status checks failed. They must succeed before this pull request can be merged."
exit 1
fi
done