Skip to content

Search

Documentation

Continuous integration: build and sign on GitHub

Three reusable GitHub Actions build a Balaur game on every push: setup installs the engine, export-game signs and uploads, build-engine compiles a runtime.

In questa pagina

Three actions, each named for what it produces. A game pins one version, the engine's, and gets the engine, its runtimes and the actions from that tag.

uses: Produces
balaurengine/balaur/.github/actions/setup@v0.2.0 a published balaur on PATH, verified against the release's SHA256SUMS, with the named runtimes
balaurengine/balaur/.github/actions/export-game@v0.2.0 a signed build per target, uploaded as an artifact with build provenance
balaurengine/balaur/.github/actions/build-engine@v0.2.0 the editor and runtimes built from source, for features the published build lacks

setup installs the release its own ref names: @v0.2.0 installs v0.2.0. @main follows the rolling nightly.

A build on every tag

name: Build
on:
  push:
    tags: ["v*"]

jobs:
  export:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: balaurengine/balaur/.github/actions/setup@v0.2.0
        with:
          targets: "linux-x64 windows-x64 web"
      - uses: balaurengine/balaur/.github/actions/export-game@v0.2.0
        with:
          targets: "linux-x64 windows-x64 web"

The whole file for an unsigned build. setup downloads the engine and export-game runs it. No secret, account or Rust toolchain is needed.

Signing

  • balaur export applies every signature itself, never a step beside it.
  • An action puts each credential where that platform's own tool looks and hands the exporter the identity's name.
      - uses: balaurengine/balaur/.github/actions/export-game@v0.2.0
        with:
          targets: "macos-universal ios"
          macos-identity: "Developer ID Application: Studio (AB12CD34EF)"
          macos-certificate: ${{ secrets.MACOS_CERTIFICATE_P12 }}
          macos-certificate-password: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
          notarize: true
          notary-key: ${{ secrets.ASC_KEY_P8 }}
          notary-key-id: ${{ secrets.ASC_KEY_ID }}
          notary-issuer: ${{ secrets.ASC_ISSUER_ID }}

A GitHub secret holds text. Every file-shaped secret is stored base64-encoded: a .p12, a .p8, a .mobileprovision, a .jks, a .pfx.

base64 -i certificate.p12 | pbcopy      # macOS
base64 -w0 release.jks                  # Linux

Per target:

Target Needs Runner
linux-x64, linux-arm64 nothing; a Linux download is vouched for by its provenance attestation any
windows-x64 windows-certificate and its password, or an Azure Trusted Signing metadata JSON for a key in a cloud HSM any; a non-Windows runner signs through osslsigncode
macos-universal macos-certificate, macos-identity, and the three notary-* inputs to notarize macOS
ios ios-certificate, ios-identity and ios-provisioning-profile; ipa: true for TestFlight macOS
android android-keystore, android-key and the passwords; without them the build takes Android's debug identity, which installs but ships nowhere any with the SDK
web nothing; a browser trusts the origin any

Identities, team ids and keystore aliases are not secrets and may live in the project's [apple], [android] and [windows] tables. Passwords may not.

Provenance

Both building actions can attach Sigstore build provenance to what they upload. gh attestation verify checks it with no certificate or account. The job needs two extra permissions:

    permissions:
      contents: read
      id-token: write
      attestations: write
    steps:
      - uses: balaurengine/balaur/.github/actions/export-game@v0.2.0
        with:
          attest: true

A custom engine

The published runtimes carry window and extensions, plus apple on macOS. A different set (a smaller web build, one without the networking stack) means building the engine.

      - uses: actions/checkout@v7
        with:
          repository: balaurengine/balaur
          ref: v0.2.0
      - uses: ./.github/actions/build-engine
        with:
          target: linux-x64
          features: "window,extensions,audio"
  • Build size says what each feature costs.
  • build-engine produces the same balaur-editor-* and balaur-runtime-* files a release holds. A later export-game picks them up through BALAUR_RUNTIMES.

Runner cost

  • A macOS or iOS export needs a macos-* runner, billed at ten times a Linux minute.
  • Linux, Windows, Android and web export on a Linux runner.
  • Group targets by host. A game with four targets then spends one Mac job's minutes, not four.

Without runners of your own

Forge runs the same exports as a service. With its GitHub App installed, every push builds each target you pick on Linux, macOS and iOS included, so there are no Mac minutes. Forge signs each build with keys that never enter it and puts a Forge / <target> check on the commit. The first build guide walks through it.