Give each change the checks it needs.

An application change, a documentation edit, and another commit on the same PR do not always need every workflow to run to completion.

GenuineCI v2.4.0 adds workflow selection by changed files and an option to cancel PR builds for older commits. You can also select a Flutter version per workflow and merge a stack of dependent PRs through the PR you choose.

This article focuses on November 2–8 and includes the changes since v2.3.0, published on October 23. The SDK features below are available in the published openci_workflow 0.2.3.

Select workflows by changed paths.

CITrigger.push() and CITrigger.pullRequest() now accept paths. A workflow runs when at least one changed file matches one of its patterns.

For example, check PRs that affect a mobile application or its shared dependencies:

import 'package:openci_workflow/openci_workflow.dart';

Future<void> main() async {
  final ci = await OpenCI.init(
    workflowName: 'Mobile CI',
    ciTriggers: [
      CITrigger.pullRequest(
        branch: 'main',
        paths: [
          'apps/mobile/**',
          'packages/shared/**',
          'openci/mobile_ci.dart',
          '**/pubspec.yaml',
          'pubspec.lock',
        ],
      ),
    ],
    flutterVersion: '3.47.8',
    cancelPreviousRuns: true,
  );

  await ci.dart.checkFormat();
  await ci.flutter.staticAnalysis(dir: 'apps/mobile');
  await ci.flutter.unitTests(dir: 'apps/mobile');
}

Save this example as openci/mobile_ci.dart. Adjust the application and shared-package paths to match your repository.

Paths are relative to the repository root. * matches within one path segment; ** also matches nested directories. Include shared packages, dependency definitions, and the workflow file itself when they can affect the result.

PRs use the entire PR diff; pushes use the before-and-after diff. Excluded workflows finish their GitHub Checks as skipped without creating a build job or VM. When a complete changed-file list is unavailable, the applicable workflow runs. Omit paths to keep running whenever the event and branch match.

Replace the earlier whenChanged: argument with paths:. This is a breaking rename in SDK 0.2.0.

Switch to the latest commit's checks.

Set OpenCI.init(cancelPreviousRuns: true) to cancel queued and running jobs for older commits when a new job is scheduled for the same PR and workflow file.

The default is false. Both the old and new job must have opted in; enabling the setting does not cancel jobs created before it was enabled. Same-commit reruns, other PRs, push jobs, and completed jobs are retained. A workflow skipped by paths does not cancel a previous run.

Running jobs observe cancellation on their next heartbeat, normally about 15 seconds later, then clean up the VM and update the GitHub Check. Use this option for checks where the newest result is the one you need.

Choose a Flutter version per workflow.

Set an exact release such as flutterVersion: '3.47.8'. CI selects it through FVM before resolving dependencies and running the workflow. Releases missing from the image are installed in that job's VM.

Use a string literal for the version. Omitting it uses the image's default SDK; OpenCI does not infer the version from .fvmrc. Local workflow execution keeps the current SDK.

We also added ci.dart.checkFormat(). It checks Dart formatting without rewriting files and fails the workflow if changes are required.

Merge stacked PRs through the PR you choose.

The Stacked PR app now offers Merge stack. For main ← A ← B ← C, selecting B merges A and then B, each into main. C and sibling PRs are outside that request.

After merging a parent, the app synchronizes the next PR and waits for its updated CI, required reviews, and GitHub merge conditions. A PR comment shows progress. Cancel merge stops the remaining work; PRs already merged stay merged.

We improved recovery after GitHub automatically changes a child's base branch and prevent concurrent updates to the same stack. If a tracked stack is disconnected from the default branch, its Check identifies the unresolved branch and blocks stack merging until the connection is repaired.

Improve the work between builds.

Dispatch now looks for the oldest queued jobs when execution capacity becomes available. Rechecks are grouped while capacity is full, and releasing a VM prompts dispatch to look for the next job.

Build VMs default to 4 vCPUs, with configurable VM memory allocations per worker. Log ingestion is also batched. Build duration still depends on the workload and available workers.

Changes since the previous release and upgrade notes.

This release also includes the move of teams, GitHub connections, logs, secrets, billing, and build execution to Firebase Functions, SQL Connect, and Cloud Run. Independent Firebase projects are supported for self-hosted deployments. The legacy servers and build workers have been removed; operators should review the self-hosting guide and deployment instructions.

Workflows can now read a team-wide sequence through ci.runNumber, including for application build numbers. All workflows in the team share the sequence, and failures and reruns can leave gaps.

Generated secrets now use Secret references. Read the environment variable name with Secrets.apiToken.key and its value with Secrets.apiToken.value. After regenerating older string getters, add .value wherever the workflow needs the secret value.

Direct SDK forwarding through LOKI_URL has been removed. Commands still stream stdout and stderr, and the CI executor captures and persists the logs. The new go-genuine CLI is at an early development stage; keep using the existing genuineci command.

See GitHub Release v2.4.0 for the change list and release limitations, and the comparison with v2.3.0 for implementation details. The workflow Docs have more SDK examples.

Explore GenuineCI