Skip to content

feat: Generic Artifact System — multi-type output management, manifests, and processing pipelines #792

@frostebite

Description

@frostebite

Summary

Introduce a generic artifact management system for Orchestrator that provides convenient, built-in handling for all types of build output. Instead of treating output as a single opaque blob, artifacts are typed, manifested, and processed through configurable pipelines.

The system provides convenient defaults — test results automatically report to GitHub Checks, images get baseline-diffed, metrics get trended — while remaining fully extensible for project-specific output types.

Think of it as: every build produces an artifact manifest describing what was created, and each artifact type has a processing pipeline that knows how to handle it.

Motivation

Currently Orchestrator treats build output as a single artifact — typically a game build. But real production workflows produce many types of output that each need different handling:

  • Test results should be parsed, reported to GitHub Checks as inline annotations, and archived
  • Screenshots / render captures should be thumbnailed, diffed against baselines, and attached to PRs
  • Server builds need separate artifact paths, potentially different upload destinations
  • Exported data files (CSV, JSON, binary) need validation and may feed downstream pipelines
  • Build metrics (compile times, asset sizes, shader variants) should be tracked over time
  • Logs should be structured, searchable, and linked to specific build phases

Each output type has different storage needs, retention policies, post-processing steps, and CI integration points. Treating everything as a single artifact blob loses all of this.

Proposed Features

Output Type Declarations

Declare what outputs a build produces:

- uses: game-ci/unity-builder@v4
  with:
    targetPlatform: StandaloneLinux64
    outputTypes: build,test-results,metrics,images

Output Type Registry

Built-in output types with extensible registration:

Type Default Path Post-Processing CI Integration
build ./Builds/{platform}/ Compress, upload Artifact link on Check
test-results ./TestResults/ Parse JUnit/NUnit XML Inline annotations on PR
server-build ./Builds/{platform}-server/ Compress, upload Separate artifact link
data-export ./Exports/ Validate schema Artifact link
images ./Captures/ Thumbnail, baseline diff Image diff on PR
logs ./Logs/ Structure, index Searchable in Check details
metrics ./Metrics/ Aggregate, trend Dashboard / Check summary
coverage ./Coverage/ Generate report Coverage badge / PR comment

Output Manifest

Every build produces a structured manifest describing all outputs:

{
  "buildGuid": "abc-123",
  "timestamp": "2024-01-15T10:30:00Z",
  "outputs": [
    {
      "type": "build",
      "path": "./Builds/StandaloneLinux64/",
      "size": 524288000,
      "hash": "sha256:abc...",
      "metadata": {
        "platform": "StandaloneLinux64",
        "scripting": "IL2CPP"
      }
    },
    {
      "type": "test-results",
      "path": "./TestResults/editmode-results.xml",
      "format": "nunit3",
      "summary": {
        "total": 342,
        "passed": 340,
        "failed": 1,
        "skipped": 1
      }
    },
    {
      "type": "images",
      "path": "./Captures/",
      "files": ["main-menu.png", "gameplay-01.png"],
      "metadata": {
        "resolution": "1920x1080",
        "captureMode": "screenshot"
      }
    },
    {
      "type": "metrics",
      "path": "./Metrics/build-metrics.json",
      "metadata": {
        "compileTime": 45.2,
        "assetCount": 12500,
        "buildSize": 524288000
      }
    }
  ]
}

Per-Type Post-Processing Pipelines

Each output type has a configurable post-processing pipeline:

outputPipelines:
  test-results:
    - parse: nunit3
    - report: github-checks
    - archive: s3
  images:
    - thumbnail: { maxWidth: 256 }
    - diff: { baseline: ./Baselines/ }
    - report: github-pr-comment
  metrics:
    - aggregate: { groupBy: platform }
    - trend: { history: 30 }
    - report: github-check-summary

Custom Output Types

Projects can register custom output types:

customOutputTypes:
  - name: addressables-catalog
    path: ./ServerData/
    postProcess:
      - validate: json-schema
      - upload: cdn
  - name: localization-export
    path: ./Exports/Localization/
    postProcess:
      - validate: csv
      - archive: s3

GitHub Integration

Output types integrate with GitHub surfaces:

  • Test results → GitHub Check annotations (inline failure markers on PR files)
  • Images → PR comment with image grid and baseline diffs
  • Metrics → Check run summary with trend graphs
  • Coverage → PR comment with coverage delta
  • Build artifacts → Check run artifact links

New Inputs

Input Description
outputTypes Comma-separated output types to collect
outputManifestPath Where to write the output manifest JSON
outputPipelines YAML defining per-type post-processing
customOutputTypes YAML defining project-specific output types
imageBaselinePath Path to baseline images for visual diff
metricsHistory Number of builds to retain for trend tracking

Implementation Notes

  • New service: OutputService in src/model/orchestrator/services/output/
  • Output manifest generated at end of build, before post-build hooks
  • Per-type post-processors are pluggable (similar to provider pattern)
  • Test result parsing supports NUnit3 (Unity default), JUnit, and custom formats
  • Image diffing uses pixel-level comparison with configurable threshold
  • Metrics trending requires a storage backend (S3, rclone, or local)
  • Custom output types loaded from .game-ci/output-types.yml or passed as input

Related


Implementation

PR Description Status
#798 feat(orchestrator): generic artifact system Draft — 36+ tests
game-ci/documentation#538 docs: build output system page Draft

Tracking

Metadata

Metadata

Assignees

No one assigned

    Labels

    Next-GenOrchestrator Next-Gen experimental featuresenhancementNew feature or requestorchestratorOrchestrator module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions