DEV Community

Cover image for 🚀 Flutter CI/CD using Git Tags in 5 minutes
Julien for Monisnap

Posted on

🚀 Flutter CI/CD using Git Tags in 5 minutes

Table of contents

What you will need

  • 📲 A Flutter app (obviously)
  • 📦 A Github, Gitlab or Bitbucket account
  • ✨ A Codemagic account (linked to your app repository)
  • 😁 Your best smile

What you will do

Alt Text

You will create a git tag containing your new app version, then push it to your repository. It will automatically trigger a Codemagic build, and release your app on the Play Store 🚀

Step 1: Create a deployment script 🛠

Below you'll find code to configure the CI/CD. You just have to add it to the root of your repository in a file named codemagic.yaml
I've used a script instead of the workflow editor (Codemagic GUI) for multiple reasons (versioned, faster...) but mainly because the version handling isn't possible using the editor.

# codemagic.yaml

# ... <- Here you will include the "reusable" parts that are described afterward

workflows:
  play-store:
    name: Play Store Release
    max_build_duration: 30
    cache: *caching

    environment:
      flutter: *flutter_version
      xcode: latest
      cocoapods: default
      vars:
        <<: *gcp_service_credentials
        <<: *keystore_release

    # ! THE IMPORTANT PART IS HERE !
    triggering:
      events:
        - tag
      branch_patterns:
        - pattern: "master"
          include: true
          source: true
      tag_patterns:
        - pattern: "*"
          include: true

    scripts:
      - *android_key_properties_setup
      - *flutter_android_properties_setup
      - *flutter_pub_get
      - *flutter_test
      - *flutter_build_play_store_release

    artifacts:      
      - build/**/outputs/**/*.aab

    publishing:
      google_play:
        credentials: *play_console_credentials
        track: alpha
        in_app_update_priority: 0      
Enter fullscreen mode Exit fullscreen mode

Next are the reusable parts, to be clean and not repeat yourself ✨. Replace the encrypted variables using your credentials and the Codemagic encrypting tool.

# codemagic.yaml

reusable:
  flutter_version: &flutter_version 1.22.6

  environment-variables:
    - &keystore_release
      FCI_KEYSTORE_PATH: /tmp/keystore.keystore
      FCI_KEYSTORE: Encrypted(...)
      FCI_KEYSTORE_PASSWORD: Encrypted(...)
      FCI_KEY_PASSWORD: Encrypted(...)
      FCI_KEY_ALIAS: Encrypted(...)

    - &gcp_service_credentials
      GCLOUD_SERVICE_ACCOUNT_CREDENTIALS: Encrypted(...)      

    - &play_console_credentials Encrypted(...)

  scripts:
    - &android_key_properties_setup
      name: Android - Setup key.properties
      script: |
        echo $FCI_KEYSTORE | base64 --decode > $FCI_KEYSTORE_PATH
        cat >> "$FCI_BUILD_DIR/android/key.properties" <<EOF
        storePassword=$FCI_KEYSTORE_PASSWORD
        keyPassword=$FCI_KEY_PASSWORD
        keyAlias=$FCI_KEY_ALIAS
        storeFile=/tmp/keystore.keystore
        EOF

    - &flutter_android_properties_setup
      name: Flutter x Android - Setup local.properties
      script: echo "flutter.sdk=$HOME/programs/flutter" > "$FCI_BUILD_DIR/android/local.properties"

    - &flutter_pub_get
      name: Flutter - Get dependencies
      script: flutter packages pub get

    - &flutter_test
      name: Flutter - Run tests
      script: flutter test --machine

    # ! THE IMPORTANT PART IS HERE !
    - &flutter_build_play_store_release
      name: Build AAB for Play Store release
      script: |
        GCLOUD_SERVICE_ACCOUNT_CREDENTIALS=$(echo $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS | base64 --decode)
        NEW_BUILD_NUMBER=$(($(google-play get-latest-build-number --package-name 'com.company.example') + 1))
        NEW_VERSION_NAME=$(git describe --tags)

        echo $NEW_VERSION_NAME
        echo $NEW_BUILD_NUMBER

        flutter build appbundle --build-name=$NEW_VERSION_NAME --build-number=$NEW_BUILD_NUMBER  --obfuscate --split-debug-info=$FCI_BUILD_DIR/debug_files

  caching: &caching
    cache_paths:
      - $HOME/.gradle/caches
      - $FLUTTER_ROOT/.pub-cache

# ... <- The workflow part described before should be here
Enter fullscreen mode Exit fullscreen mode

In the previous script, the "flutter_build_play_store_release" script handle the versioning :

  • Version is retrieved from the tag.
  • Build number is retrieved from the play console (fetching the highest build number, and incrementing it for this release).

Don't forget to replace com.company.example with your app package name

You can now push this script onto your repository. It should then be visible from Codemagic and you should be able to trigger it manually.

Step 2: Add git tag 🔖 -> push it 🚀

Creating a git tag is very easy. We will use 1.0.0 as our version, and tag.
You just have to run the following commands :

git tag -a 1.0.0 -m "Release 1.0.0"
git push origin 1.0.0
Enter fullscreen mode Exit fullscreen mode

That's it! You should see a build running in Codemagic 🏄‍♂️

What's next?

You can add as many workflows as you want using Codemagic! You can use the GUI editor, and then extract to code to have more control over the code.

Here we deploy on Alpha, so you can change to Production when you feel ready. And then, you can add an iOS workflow with mostly the same code.

Leave a comment, a like or even a unicorn 🦄 if you've achieved this tutorial! 🚀🔖

Top comments (0)