Oore CI
Configuration

`.oore.yaml`

The strict repository-owned pipeline configuration schema used by Oore runners.

Place .oore.yaml in the repository root to keep pipeline execution settings with the code they build. .oore.yml is also recognized.

This page describes version: 1. Files that declare version: 2 use workflows, targets with full build commands, named steps, and vars, secrets and flavor references; see .oore.yaml version 2. Both versions are accepted, and a version 1 file runs exactly as before. To move a file to version 2, run oore pipeline migrate.

version: 1

platforms:
  - android
  - ios

flutter_version: '3.24.5'

isolation: vm

commands:
  pre_build:
    - flutter pub get
  post_build:
    - echo "Build complete"

platform_build_args:
  android:
    - '--split-per-abi'
    - '--build-number=$OORE_VERSION_CODE'

build_number_offset: 4000

env:
  - key: BUILD_FLAVOR
    value: staging

artifacts:
  patterns:
    - 'build/app/outputs/flutter-apk/*.apk'
    - 'build/ios/ipa/*.ipa'

The schema rejects unknown fields.

Top-level fields

FieldTypeRequiredDefault
versionintegerYes1 for this schema
platformsstring[]YesNo default; must not be empty
flutter_versionstringNostable
commandsobjectNoEmpty stages
platform_build_argsobjectNoEmpty arrays
platform_commandsobjectNoNo overrides
envobject[]No[]
artifactsobjectNoPlatform-specific default globs
build_number_offsetintegerNo0
runs_onstring[]No[macos]
isolationstringNohost

platforms accepts android, ios, and macos.

Isolation

isolation chooses where the build steps run:

  • host runs them directly on the Runner Mac with its installed toolchains.
  • vm runs them in a fresh Tart VM cloned from the image for the build’s Flutter version, and deletes the VM when the build ends. See Run builds in VMs.

Runner labels

runs_on takes one label or a list, such as runs_on: linux or runs_on: [macos, xcode-16]. The build fails before its commands run when the runner that claimed it lacks any of these labels. The scheduler routes builds by the pipeline’s own runs_on, so set the same value there. See Route builds with runner labels.

Commands

commands accepts three string arrays:

FieldTiming
pre_buildBefore the main or platform-specific build
buildShared main build commands
post_buildAfter successful build commands

All stages are optional, including commands.build. Commands run in order and an empty command string is invalid.

platform_build_args.android, .ios, and .macos are arrays appended to Oore’s default command for that platform. platform_commands accepts one complete command string for each platform instead. A platform command replaces the default command, so build arguments for that same platform are not applied.

For a run that may select only some configured platforms, use platform commands or Oore defaults. A shared non-empty commands.build list is not assigned to an arbitrary platform during a partial run.

Environment

Each env item contains a key and value:

env:
  - key: JAVA_HOME
    value: /opt/homebrew/opt/openjdk@17

Keys must match [A-Za-z_][A-Za-z0-9_]* and must be unique. These values are repository-owned build inputs; do not put credentials in the file. Reference a stored secret instead with ${{ secrets.NAME }}, in an env value or a command. See Use secrets in a pipeline. Oore-managed signing credentials are injected only into the signing seam and are scrubbed from repository command stages.

Version codes

Every build gets OORE_VERSION_CODE, which is the project build number plus build_number_offset. The project build number starts at 1 and has no relation to the Google Play versionCode or Apple CFBundleVersion an app already shipped, so set the offset above the highest version code the store holds before the first upload. Pass the value to Flutter with --build-number=$OORE_VERSION_CODE.

The offset must be between 0 and 2,099,999,999, and a build fails before its commands run when the sum exceeds 2,100,000,000, the highest version code Google Play accepts.

When pubspec.yaml at the repository root has a version, Oore also exports its name part as OORE_VERSION_NAME (1.4.0 for version: 1.4.0+12).

Before a Google Play upload, the runner reads the version codes Play already holds for the app. The publish step fails before anything is uploaded when the App Bundle’s version code is not higher than the highest one on the target track, or was already uploaded, and the message names both numbers.

Test results

A command that is a plain flutter test or dart test invocation, such as flutter test --coverage, reports its results to Oore without any extra configuration. The runner adds --file-reporter=json:<file> to it, so the log keeps the usual output while the build detail page gets a Tests tab with the failing tests, their messages, and their outcome in recent builds of the same pipeline. A test that failed, passed, and then failed again within the last 20 builds that reported tests is marked flaky. --file-reporter needs Flutter 3.10 or later.

Compound commands (&&, pipes, redirects) and commands that already pass --file-reporter are left unchanged. For those, or for other test tools, write a JUnit XML file or a dart test JSON report into $OORE_TEST_REPORTS_DIR:

commands:
  pre_build:
    - cd packages/core && flutter test --file-reporter=json:$OORE_TEST_REPORTS_DIR/core.json
    - ./gradlew test && cp app/build/test-results/test/*.xml "$OORE_TEST_REPORTS_DIR"

The runner reads and clears that directory after every command, including a command that failed.

Analyzer

When the env var OORE_ANALYZE is true, the runner runs dart analyze --format=json in the workspace root as a step named analyze after the commands run, including when a build or post-build command failed. Analysis is off by default for now. It reports the error, warning and info counts and the 50 most severe diagnostics, which the build detail page and the pull request check show. The step never fails the build. It is skipped when the workspace root has no pubspec.yaml, has no .dart_tool/package_config.json (packages not resolved), dart is not on the PATH, or the analyzer runs longer than 5 minutes.

Artifacts

When artifacts is omitted, Oore derives default patterns from platforms. When it is present, artifacts.patterns replaces those defaults.

Patterns:

  • must contain * or ?
  • must be at most 512 characters
  • use / and stay relative to the workspace
  • cannot contain empty, . or .. path segments
  • use ** to cross directory boundaries

A filename-only pattern such as *.apk matches that filename pattern anywhere in the workspace.

Resolution

When a pipeline pins an explicit repository config path, Oore checks only that path. Otherwise it checks .oore.yaml and then .oore.yml. If no candidate file exists, Oore uses the UI execution configuration. If a candidate exists but cannot be read or validated, the build fails instead of falling back.

The runner reads the file from the pinned checkout used for the build. A .fvmrc value takes precedence over flutter_version from whichever configuration source is active. The version picks the VM image for isolation: vm. A host build uses the Runner’s installed Flutter and fails when a pinned release does not match it; see Install Flutter where the runner can find it. A repository file replaces the UI execution configuration for that run.

Validate the file before committing:

oore pipeline validate .oore.yaml

See Move a pipeline into .oore.yaml for the task and oore pipeline validate for the command contract.