-
Notifications
You must be signed in to change notification settings - Fork 0
CI CD Integration
← Home
Batch validation and pipeline adapters - new in v0.6.0.
solarxy-cli can validate a whole directory of 3D assets in one run and emit
the results in a format your CI/CD system understands natively. Wire it into a
pipeline and a bad asset gets caught at commit time instead of mid-cook.
This page covers the validation command, then drop-in recipes for GitHub Actions, GitLab CI, Jenkins, and Perforce / Helix Core.
- The validation command
- Exit codes and
--fail-on - Adapters and formats
- The Docker image
- GitHub Actions
- GitLab CI
- Jenkins
- Perforce / Helix Core
- Troubleshooting
Batch validation runs through solarxy-cli. The shape of every invocation:
solarxy-cli --mode analyze \
--paths "assets/**/*.glb" "assets/**/*.gltf" \
--config solarxy.toml \
--adapter generic \
--adapter-format junit-xml \
--output validation-report.xml \
--fail-on error
--pathsrequires--mode analyze. The default mode isview, which just launches the GUI ---pathsis ignored there. Every batch-validation command must include--mode analyze(or the short-M analyze).
| Flag | Purpose |
|---|---|
--mode analyze |
Required - selects the analyzer. With --paths present it runs the batch validator. |
--paths <GLOB>… |
One or more quoted glob patterns. Repeatable. Quote them so your shell doesn't expand ** before the CLI sees it. |
--config <PATH> |
A specific solarxy.toml. Omit to use discovery (which, for --paths, starts in the current working directory). |
--adapter <NAME> |
generic or github-actions - see Adapters and formats. |
--adapter-format <FORMAT> |
The output format. Defaults to the adapter's preferred format. |
--output <PATH> |
Write the report to a file. - means stdout (also the default when omitted). |
--fail-on <POLICY> |
Exit-code policy - error, warning, or never. |
Validation policy - which checks run, the triangle budgets, filename
classification - comes from solarxy.toml. See Configuration.
solarxy-cli returns a process exit code so the pipeline can gate on it:
--fail-on |
Exit non-zero when… | Use for |
|---|---|---|
error (default)
|
Any asset has validation errors | The standard merge gate. |
warning |
Any asset has errors or warnings | A strict gate. |
never |
Never - always exits 0
|
Informational jobs; reports without blocking. |
Exit 0 means the run passed the policy; a non-zero exit means it failed.
flowchart TD
classDef gh fill:#1F2430,stroke:#FFC44C,color:#FFC44C
classDef gen fill:#1F2430,stroke:#78A0EE,color:#78A0EE
classDef format fill:#1F2430,stroke:#7FD962,color:#7FD962
classDef start fill:#33415E,stroke:#FFC44C,color:#FFC44C
Q[Which CI system?]:::start
Q --> GH[GitHub Actions]:::gh
Q --> Other[GitLab, Jenkins,<br/>Perforce, other]:::gen
GH --> A1[--adapter github-actions]:::gh
Other --> A2[--adapter generic]:::gen
A1 --> F1[gha-commands<br/>PR annotations]:::format
A1 --> F2[sarif<br/>Code Scanning]:::format
A2 --> F3[junit-xml<br/>Tests tab]:::format
A2 --> F4[json<br/>any consumer]:::format
A2 --> F5[text or tap<br/>plain output]:::format
Adapter and format selection by CI system. gha-commands and sarif are GitHub-specific; the rest are CI-agnostic via the generic adapter.
An adapter wraps the output conventions of a target CI ecosystem. Two ship in v0.6.0:
| Adapter | Default format | Built for |
|---|---|---|
generic |
json |
CI-agnostic. Use it for GitLab, Jenkins, Perforce, or any system that consumes a file. |
github-actions |
gha-commands |
GitHub Actions - emits workflow commands that annotate the PR, plus SARIF for Code Scanning. |
Six --adapter-format values exist; not every adapter supports every
format:
| Format | generic |
github-actions |
Notes |
|---|---|---|---|
json |
Yes | Yes | Structured run report. |
text |
Yes | Yes | Human-readable plain text. |
tap |
Yes | Yes | Test Anything Protocol. |
junit-xml |
Yes | Yes | JUnit XML - consumed by GitLab's artifacts:reports:junit and the Jenkins JUnit Plugin. |
gha-commands |
No | Yes | GitHub Actions workflow commands (PR annotations). |
sarif |
No | Yes | SARIF for GitHub Code Scanning. |
Asking generic for gha-commands or sarif fails with an
UnsupportedFormat error. The rendered report - including SARIF - is written to
wherever --output points (or stdout); there are no separate side-artifact
files.
Use the prebuilt CLI image when your CI runners don't have solarxy-cli
natively installed, or when you need a fully reproducible, container-isolated
run that pins the binary version. For bare-metal runners already provisioned
with Solarxy, skip the image and call the binary directly.
A prebuilt CLI image is published to GitHub Container Registry on every release:
| Tag | Meaning |
|---|---|
ghcr.io/marko-koljancic/solarxy-cli:latest |
Most recent stable release. Convenient, not reproducible. |
ghcr.io/marko-koljancic/solarxy-cli:0.6 |
Latest patch of the 0.6.x line. Recommended for CI - picks up fixes, no breaking changes. |
ghcr.io/marko-koljancic/solarxy-cli:0.6.0 |
An exact version. Use for fully reproducible builds. |
The image is built from
Dockerfile.cli.
If your runners can't reach ghcr.io, mirror it into your internal registry:
docker pull ghcr.io/marko-koljancic/solarxy-cli:0.6
docker tag ghcr.io/marko-koljancic/solarxy-cli:0.6 registry.internal/solarxy-cli:0.6
docker push registry.internal/solarxy-cli:0.6This workflow runs on every pull request touching the assets/ directory or
solarxy.toml, validates with the github-actions adapter, and surfaces
findings as inline annotations on the files-changed view via the default
gha-commands format.
name: Validate Assets
on:
pull_request:
paths:
- "assets/**"
- "solarxy.toml"
jobs:
validate:
runs-on: ubuntu-latest
container: ghcr.io/marko-koljancic/solarxy-cli:0.6
steps:
- uses: actions/checkout@v4
- name: Validate assets
run: |
solarxy-cli --mode analyze \
--paths "assets/**/*.glb" "assets/**/*.gltf" \
--config solarxy.toml \
--adapter github-actions \
--fail-on errorTo surface findings in the repository's Security → Code scanning tab, emit SARIF and upload it:
- name: Validate assets (SARIF)
run: |
solarxy-cli --mode analyze \
--paths "assets/**/*.glb" \
--adapter github-actions --adapter-format sarif \
--output solarxy.sarif \
--fail-on never
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: solarxy.sarif--fail-on never keeps the validation step green so the upload always runs;
if: always() makes the upload survive a failing earlier step. Code Scanning
then surfaces the findings and tracks them across commits.
This job runs on every merge request that changes asset files, validates with
the generic adapter and junit-xml format, and surfaces findings in the
merge-request Tests tab via GitLab's native artifacts:reports:junit.
validate-assets:
image: ghcr.io/marko-koljancic/solarxy-cli:0.6
script:
- solarxy-cli --mode analyze
--paths "assets/**/*.glb" "assets/**/*.gltf"
--config solarxy.toml
--adapter generic
--adapter-format junit-xml
--output validation-report.xml
--fail-on error
artifacts:
when: always
reports:
junit: validation-report.xml
paths:
- validation-report.xml
expire_in: 30 days
rules:
- changes:
- "assets/**/*"
- "solarxy.toml"Keep both reports:junit: (renders the Tests tab) and the literal path
under paths: (keeps the XML browsable as an artifact). The rules:changes:
block skips the job entirely for code-only commits.
To gate merges but keep branch builds informational, split the job: run
--fail-on never on branch pushes and --fail-on error on
$CI_PIPELINE_SOURCE == "merge_request_event".
This stage runs as part of an asset-build pipeline, validates with the
generic adapter and junit-xml format, and surfaces findings in the build's
Test Results panel via the JUnit Plugin's junit step.
stage('Validate Assets') {
agent {
docker {
image 'ghcr.io/marko-koljancic/solarxy-cli:0.6'
args '-v $WORKSPACE:/workspace -w /workspace'
}
}
steps {
sh '''
solarxy-cli --mode analyze \
--paths "Content/**/*.glb" "Content/**/*.gltf" \
--config solarxy.toml \
--adapter generic \
--adapter-format junit-xml \
--output validation-report.xml \
--fail-on error
'''
}
post {
always {
junit testResults: 'validation-report.xml', allowEmptyResults: true
}
}
}On Windows agents, swap sh for bat, use solarxy-cli.exe, and continue
lines with ^ instead of \. Install the CLI on bare-metal agents with
winget install Koljam.Solarxy or the portable .zip (see
Installation).
Stage placement: run validation before any cook / build / package stage -
per-asset validation takes seconds, a cook takes minutes. --fail-on error
aborts the pipeline before the expensive stages run.
Warning-only assets stay green in the Test Results panel by design; warning
detail surfaces in each testcase's <system-out>. Use --fail-on warning if
you want warnings to mark the build red.
For Perforce, validation runs as a change-submit trigger - a Python script
that rejects a p4 submit when it contains a bad asset. The script and a full
setup guide ship in the repo at
docs/integrations/perforce/.
Outline:
-
Copy
change-submit.pyto a stable path on the P4D server (e.g./opt/solarxy/). -
Register it in the trigger table (
p4 triggers), scoped to your depot path:solarxy-validate change-submit //depot/Project/... "/usr/bin/python3 /opt/solarxy/change-submit.py %changelist%" -
The script extracts pending model files, runs
solarxy-cli --mode analyzeagainst them, and returns:Exit Meaning Submit 0No model files, or validation passed Accepted 1Validation found errors Rejected - the artist sees the findings 2Tool error (script crash, CLI not found, …) Rejected - the artist is told to contact an admin
Requirements: Helix Core 2024.2+, Python 3.10+ on the trigger host, and
solarxy-cli on the trigger user's PATH. To disable the trigger without
removing it, prefix its line in the trigger table with #.
no model files matched / empty result. The glob ran but matched nothing.
Quote your --paths patterns - an unquoted ** is expanded by the shell before
solarxy-cli sees it. Remember globs resolve relative to the current working
directory; run the CLI from your repository root.
--paths seems to do nothing / the GUI launches. You omitted
--mode analyze. With the default --mode view, solarxy-cli tries to launch
the GUI and ignores --paths.
UnsupportedFormat error. You asked the generic adapter for
gha-commands or sarif. Those two formats are github-actions-only - see the
format support matrix.
Findings missing from the MR / build UI. The JUnit XML must be wired into
the CI system's native test reporter (artifacts:reports:junit for GitLab, the
junit step for Jenkins). Producing the file is not enough - the reporter has
to ingest it.
Wrong solarxy.toml picked up. For --paths runs, config discovery starts
in the current working directory, not the asset directory. Pass --config
explicitly, or run from the repo root. See
Configuration → Discovery order.
See also: CLI Reference · Configuration · Installation · User Guide
Solarxy - A lightweight, cross-platform 3D model viewer and validator built with Rust and wgpu.
GitHub Repository · Releases & Downloads
© 2026 Marko Koljancic · MIT License
Getting Started
Tutorials
Using Solarxy
Reference
Help
Project