shipway 0.1.0-beta.3 copy "shipway: ^0.1.0-beta.3" to clipboard
shipway: ^0.1.0-beta.3 copied to clipboard

Local-first CI/CD for Flutter. Sets up flavors, generates fastlane lanes, and ships to TestFlight, the App Store, Google Play and Firebase from your own machine.

example/README.md

shipway example #

This is a full shipway.yaml for a Flutter app called Acme. It uses every place shipway can send a build to: Firebase App Distribution, Google Play, TestFlight and the App Store.

Acme has two flavors:

Flavor App id Firebase project
development com.acme.app.dev acme-dev
production com.acme.app acme-prod

What is in this folder #

  • shipway.yaml, the config below.
  • android/ and ios/, the fastlane files that shipway generate fastlane writes from this config, not edited by hand. A test checks they still match what shipway generates.

The config #

# An example shipway.yaml using every destination shipway ships to.
#
# Acme is a Flutter app with two flavors in two Firebase projects:
#
#   development  com.acme.app.dev   Firebase project acme-dev
#   production   com.acme.app       Firebase project acme-prod
#
# Fields ending in `_ref` name an environment variable or keychain entry.
# They never hold the secret itself; shipway refuses to load a config that
# does. Every name below is one this project chose. Rename any of them.
#
# The files beside this one are what `shipway generate fastlane` writes from
# it, unedited. A test regenerates them and fails if they drift.

version: 1

project:
  name: acme_app

apps:
  main:
    path: .

    android:
      application_id: com.acme.app
    ios:
      bundle_id: com.acme.app
      export: gym                  # gym (default) or flutter

    flavors:
      development:
        suffix: .dev               # com.acme.app.dev on both platforms
        version_name_suffix: -dev
        display_name: Acme Dev
        entrypoint: lib/main_dev.dart
        dart_defines:
          API_URL: https://dev.api.acme.app
        firebase:
          android: android/app/src/development/google-services.json
          ios: ios/config/development/GoogleService-Info.plist
          # A different Firebase project from production, so a different
          # service account. Without this block the flavor uses
          # FIREBASE_SERVICE_ACCOUNT_JSON_PATH.
          distribution:
            service_account_ref: FIREBASE_DEV_SERVICE_ACCOUNT_JSON_PATH
      production:
        suffix: ""                 # the unsuffixed id: com.acme.app
        display_name: Acme
        entrypoint: lib/main_prod.dart
        dart_defines:
          API_URL: https://api.acme.app
        firebase:
          android: android/app/src/production/google-services.json
          ios: ios/config/production/GoogleService-Info.plist

    signing:
      ios:
        team_id: ABCDE12345
        match_git_url: https://github.com/acme/certificates.git
        match_storage: git
        api_key:                   # App Store Connect API key
          key_id_ref: ASC_KEY_ID
          issuer_id_ref: ASC_ISSUER_ID
          p8_ref: ASC_KEY_P8_BASE64
      android:
        keystore_ref: ANDROID_KEYSTORE_BASE64
        key_properties:
          store_password_ref: ANDROID_STORE_PASSWORD
          key_password_ref: ANDROID_KEY_PASSWORD
          key_alias: upload

    targets:
      testflight:
        groups: [internal]
        distribute_external: false
        changelog_from: git        # git | file | prompt
      appstore:
        submit_for_review: false
        metadata_path: ios/fastlane/metadata
      play:
        track: internal            # internal | alpha | beta | production
        release_status: draft
        artifact: aab
        # Holds the service-account JSON itself. Leave it out to use a path in
        # PLAY_SERVICE_ACCOUNT_JSON_PATH instead.
        service_account_ref: PLAY_SERVICE_ACCOUNT_JSON
      firebase:                    # App Distribution, Android only for now
        groups: [qa, product]
        changelog_from: git
        # No app id variable: each flavor's app id is read from its own
        # google-services.json.

    versioning:
      strategy: remote             # ask each store for its last build number
      sync_ios_android: true

secrets:
  dotenv: .env.{flavor}
  keychain: true

notify:
  slack_webhook_ref: SLACK_WEBHOOK
  on: [failure]

pipelines:
  # Every change a tester should see: both platforms at once.
  beta:
    - analyze
    - test
    - parallel:
        - release: { flavor: development, target: firebase }
        - release: { flavor: development, target: testflight }

  # A store release. Promote on Play and submit on App Store Connect by hand.
  store:
    - analyze
    - test
    - parallel:
        - release: { flavor: production, target: play }
        - release: { flavor: production, target: appstore }

Using it in your app #

  1. Copy shipway.yaml to the root of your Flutter project, next to pubspec.yaml. Or run shipway init to start from your own project.

  2. Change the app ids, flavors, team id and repository URLs to yours. Remove the targets you do not use.

  3. Run shipway generate, then shipway secrets list --flavor development to see which credentials are still missing.

  4. Try a release with --dry-run first:

    shipway release android --flavor development --target firebase --dry-run
    

The main README walks through each step and each store in detail.

Credentials this config uses #

The *_ref fields hold names, not secrets. Put the values in your environment, in .env, or in the keychain with shipway secrets set NAME.

Name Used for
ASC_KEY_ID, ASC_ISSUER_ID, ASC_KEY_P8_BASE64 App Store Connect API key (TestFlight, App Store)
MATCH_PASSWORD Decrypting the match certificates repository
ANDROID_KEYSTORE_BASE64, ANDROID_STORE_PASSWORD, ANDROID_KEY_PASSWORD Android upload key
PLAY_SERVICE_ACCOUNT_JSON Google Play service account, as JSON
FIREBASE_SERVICE_ACCOUNT_JSON_PATH Firebase service account for production
FIREBASE_DEV_SERVICE_ACCOUNT_JSON_PATH Firebase service account for development
SLACK_WEBHOOK Slack messages when a run fails
0
likes
150
points
105
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Local-first CI/CD for Flutter. Sets up flavors, generates fastlane lanes, and ships to TestFlight, the App Store, Google Play and Firebase from your own machine.

Repository (GitHub)
View/report issues

Topics

#flutter #cli #fastlane #deployment #ci

License

MIT (license)

Dependencies

args, checked_yaml, cli_completion, collection, crypto, json_annotation, json_schema, mason_logger, meta, path, pub_updater, pubspec_parse, xml, yaml, yaml_edit

More

Packages that depend on shipway