Skip to content
Urnish Tech logo
All case studies
EdTech · DevOps · 2026

ScholarLab - Unity Automation

Created a scalable DevOps solution for ScholarLab by automating Unity Asset Bundle builds across 150+ GitHub repositories with GitHub Actions and AWS self-hosted runners, enabling faster content delivery, consistent build quality, and simplified release management.

Build something like this

The challenge

ScholarLab's content library is distributed across more than 150 Unity repositories, each producing platform-specific Asset Bundles for the simulations students load at runtime. Every build was a manual desktop operation: open the project in the Unity Editor, run the bundle export, hand-name the output, upload it, and hope the next engineer used the same Unity version, the same compression settings, and the same naming convention. At that repository count the model stopped scaling. Release cycles were gated on whoever owned a given project, bundle hashes drifted between machines, a mismatched Editor version could silently ship an unloadable asset, and there was no reliable answer to which bundle version was live for which simulation. GitHub's hosted runners were not a viable fix either - Unity's licensing, multi-gigabyte Editor installs, and cold Library folders made every hosted run slow, expensive, and unrepeatable.

What we built

Urnish Tech designed and implemented a centralised Unity Asset Bundle build platform: one reusable GitHub Actions workflow, consumed by 150+ repositories, executing on a fleet of AWS self-hosted runners purpose-built for Unity. The runners ship as pre-baked EC2 AMIs with the pinned Unity Editor, target platform modules, and activated licence already resident, so a job starts building instead of installing. A warm Library cache on persistent EBS volumes removes the asset reimport penalty that dominates cold Unity builds. Shell-scripted build automation drives the Editor headlessly, exports bundles per target platform, stamps deterministic version metadata and content hashes into a manifest, and publishes to versioned S3 prefixes fronted by CloudFront for runtime delivery. Repository owners consume the pipeline by referencing the shared workflow and a small config block - no per-project CI to write or maintain. Capacity scales with the release queue and idles down between waves, so parallel builds across the fleet stay cost-bounded rather than cost-linear.

Key features

Build pipeline

  • One reusable GitHub Actions workflow consumed by 150+ Unity repositories from a single source of truth
  • Headless Unity Editor invocation via -batchmode -nographics -quit driven by shell-scripted build entry points
  • Per-platform Asset Bundle export with pinned compression, chunking, and bundle-naming policy
  • Matrix builds fan out target platforms in parallel within a single pipeline run
  • Config-block onboarding: a repository joins the platform without authoring its own CI

Self-hosted runner infrastructure

  • Custom AWS EC2 AMIs pre-baked with the pinned Unity Editor, platform modules, and activated licence
  • Persistent EBS-backed Library caches so builds skip the full asset reimport on every run
  • Runner registration and deregistration automated through the GitHub Actions API at instance lifecycle boundaries
  • Instance sizing tuned to Unity's import-and-compress profile rather than generic CI defaults
  • Ephemeral job workspaces guarantee a clean tree per run while the shared cache stays warm

Versioning & distribution

  • Deterministic version stamping derived from commit SHA and release tag on every bundle
  • Content-hash manifest published alongside each build for runtime integrity verification
  • Immutable versioned S3 prefixes so a shipped bundle is never overwritten in place
  • CloudFront distribution for low-latency global bundle delivery to the Unity client
  • Rollback by manifest pointer - previous bundle sets stay addressable indefinitely

Reliability & consistency

  • Single pinned Unity version across the fleet eliminates machine-to-machine build drift
  • Reproducible bundle output verified by hash comparison across independent runners
  • Fail-fast validation on missing assets, import errors, and empty bundle output before publish
  • Structured build logs and artefacts retained per run for post-release forensics
  • Idempotent publish step - a re-run of the same commit produces the same addressed artefacts

Cost & scale optimisation

  • Runner capacity scales with the release queue and idles down between build waves
  • Warm-cache builds cut runner-minutes per job against a cold hosted-runner baseline
  • Right-sized instance families with EBS throughput matched to Unity's import I/O profile
  • GitHub OIDC to short-lived IAM roles - no long-lived AWS credentials in any repository
  • Concurrency controls prevent duplicate builds of the same ref from consuming fleet capacity

Challenges solved

One pipeline, 150+ repositories

A single reusable workflow definition serves the entire Unity estate. A pipeline improvement - new platform target, changed compression policy, added validation gate - propagates to every repository through one merge instead of 150 hand-edited CI files.

Unity-aware runners, not generic CI

Hosted runners re-download the Editor and rebuild the Library folder on every job. Pre-baked AMIs with persistent EBS caches remove both, so build time reflects the assets that actually changed rather than fixed environment setup cost.

Reproducible bundles by construction

A pinned Editor version, fixed compression settings, and a content-hash manifest mean the same commit produces byte-identical bundles on any runner in the fleet - closing the class of defects where a bundle worked on one engineer's machine and failed at runtime.

Versioning that supports rollback

Every build publishes to an immutable versioned S3 prefix with a manifest. Shipping a fix or reverting a bad asset set is a pointer change, not a rebuild - and the previously live bundle set remains addressable for as long as clients need it.

Parallel throughput without linear cost

The fleet absorbs simultaneous builds across many repositories during release waves, then scales down when the queue drains. Capacity is provisioned against real demand rather than a permanently-on worst-case pool.

Zero standing cloud credentials

GitHub OIDC federates into short-lived IAM roles scoped to the publish path. No repository holds a long-lived AWS key, so onboarding a new project adds no credential-rotation surface.

Outcomes

150+

Repositories automated

Eliminated

Manual build steps

Parallel

Builds

Let's talk

Have a product idea or a system to scale?

Tell us what you're building. You'll hear back within one business day - from a senior engineer, not a sales rep.

  • Free 30-min discovery call
  • Fixed-scope or T&M engagements
  • NDA on request - first reply within 24h