This week, we prepared for iOS builds.

In v2.1.0, we added Android APK and AAB builds to Dart workflows. This week, we turned to iOS and made it possible to prepare signing keys from the CLI.

We also improved CLI installation and updates, command completion, generated file organization, and Flutter test options. This article covers the main changes since v2.1.0 through October 9.

Create Apple keys and save them to your team.

The new genuineci setup asc-keys command walks you through Apple ID login, two-factor authentication, organization confirmation, App Store Connect API key creation, and saving the keys to GenuineCI, all from the terminal.

First, log in to GenuineCI and select the team that will own the keys. Creating new ASC keys currently requires an Apple Silicon Mac.

genuineci login
genuineci switch team
genuineci setup asc-keys
genuineci sync --secrets

Setup prepares four secrets:

  • OPENCI_GENERATED_ASC_KEY_ID
  • OPENCI_GENERATED_ASC_ISSUER_ID
  • OPENCI_GENERATED_P8_BASE64
  • OPENCI_GENERATED_IOS_CERTIFICATE_PRIVATE_KEY

Alongside the ASC keys, setup now prepares the private key used for a signing certificate. The server generates it if the team does not have one yet, or reuses the existing key.

If you already registered ASC keys and only need a certificate private key, use the dedicated command. This operation does not require Apple login.

genuineci setup ios-certificate-key
genuineci sync --secrets

These commands prepare keys. Signing certificates and provisioning profiles are fetched or created at build time.

Signed IPA builds are in progress.

The workflow SDK now includes the buildIpa() API and signing preparation. It accepts ASC credentials and a certificate private key, creates and unlocks a build keychain, and begins fetching signing files.

Changes to connect certificate import, provisioning profile application, and ExportOptions.plist generation through Codemagic CLI to flutter build ipa are currently under review. Ad Hoc distribution is the first target.

This integration has not yet been merged, and signed builds on a real VM still need verification. Checking the generated IPA and distributing it through Firebase App Distribution are the next steps.

Easier installation and everyday CLI use.

We published genuineci_cli on pub.dev, making it available through the genuineci command.

dart install genuineci_cli

Use genuineci update to update it. Normal interactive commands also check for new versions and ask whether to update. CI runs and commands with redirected output do not show automatic update prompts.

The new genuineci status command shows your current server and team, while genuineci list teams lists your teams. You can check the state before and after switching teams without leaving the terminal.

Bash and Zsh Tab completion is now supported, including command names, options, language names, and saved server profiles.

For secret management, genuineci delete secret SECRET_NAME removes an unused value from the selected team. It deletes without a confirmation prompt, so check the team and secret name before running it.

Generated files, in one directory.

genuineci sync now generates secret and path definitions together. Use flags to update only the definitions you need.

genuineci sync
genuineci sync --secrets
genuineci sync --paths

All generated files now go under openci/generated/.

openci/
  generated/
    paths.g.dart
    secrets.g.dart

Existing workflows need an update. Replace genuineci sync secrets and genuineci sync paths with genuineci sync --secrets and genuineci sync --paths, respectively. In workflow files directly under openci/, also update imports to generated/secrets.g.dart and generated/paths.g.dart.

Path generation now supports single packages without a Pub workspace. Directory names that are Dart keywords, such as switch, are exposed as getters such as switch_.

Time zones and tags for Flutter tests.

In openci_workflow 0.1.2, unitTests() gains tz and excludeTags.

await ci.flutter.unitTests(
  tz: TimeZone.asiaTokyo,
  excludeTags: 'golden',
);

Tests that work with dates and times can specify their execution time zone. TimeZone.asiaTokyo and TimeZone.utc are available. excludeTags is passed to Flutter's tag exclusion option, so expressions such as 'golden || slow' are supported.

These are workflow steps using ci created with OpenCI.init(). Imports and initialization are omitted.

A home for the documentation.

The GenuineCI website now includes Docs, with guides for getting started, workflows, Flutter, secrets, the CLI, and self-hosting.

Search across pages, use heading-based tables of contents, copy code, and switch code blocks between Light and Dark. Find the settings and commands you need while writing a workflow.

Explore GenuineCI