๐Ÿš€ 5๋ถ„ ์•ˆ์— Git ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Flutter CI/CD

11103 ๋‹จ์–ด fluttercodemagicgitandroid

๋ชฉ์ฐจ


  • What you will need
  • What you will do
  • Step 1: Deployment script
  • Step 2: Git push with tag

  • ํ•„์š”ํ•œ ๊ฒƒ

  • ๐Ÿ“ฒ A Flutter app (obviously)
  • ๐Ÿ“ฆ A Github, Gitlab or Bitbucket account
  • โœจ A Codemagic ๊ณ„์ •(์•ฑ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์—ฐ๊ฒฐ๋จ)
  • ๐Ÿ˜ ์ตœ๊ณ ์˜ ๋ฏธ์†Œ

  • ๋„Œ ๋ญ ํ• ๊ฑฐ์•ผ



    ์ƒˆ ์•ฑ ๋ฒ„์ „์ด ํฌํ•จ๋œ git ํƒœ๊ทธ๋ฅผ ๋งŒ๋“  ๋‹ค์Œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ž๋™์œผ๋กœ Codemagic ๋นŒ๋“œ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ณ  Play ์Šคํ† ์–ด ๐Ÿš€์—์„œ ์•ฑ์„ ์ถœ์‹œํ•ฉ๋‹ˆ๋‹ค.

    1๋‹จ๊ณ„: ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ๋งŒ๋“ค๊ธฐ ๐Ÿ› 

    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      
    
    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
    


    ์ด์ „ ์Šคํฌ๋ฆฝํŠธ์—์„œ "flutter_build_play_store_release"์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ„์ „์€ ํƒœ๊ทธ์—์„œ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค.

  • ๋นŒ๋“œ ๋ฒˆํ˜ธ๋Š” ํ”Œ๋ ˆ์ด ์ฝ˜์†”์—์„œ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค(๊ฐ€์žฅ ๋†’์€ ๋นŒ๋“œ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์—์„œ๋Š” ์ฆ๊ฐ€).

  • com.company.example์„ ์•ฑ ํŒจํ‚ค์ง€ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”.

    ์ด์ œ ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ํ‘ธ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Codemagic์—์„œ ๋ณผ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ์ˆ˜๋™์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    2๋‹จ๊ณ„: git ํƒœ๊ทธ ์ถ”๊ฐ€ ๐Ÿ”– -> ํ‘ธ์‹œ ๐Ÿš€

    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
    

    That's it! You should see a build running in Codemagic ๐Ÿ„โ€โ™‚๏ธ

    ๋ฌด์—‡ ํ–ฅํ›„ ๊ณ„ํš?



    Codemagic์„ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๋งŒํผ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! GUI ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”์ถœํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” ์•ŒํŒŒ์— ๋ฐฐํฌํ•˜๋ฏ€๋กœ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ๋Š๋ผ๋ฉด ํ”„๋กœ๋•์…˜์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฑฐ์˜ ๋™์ผํ•œ ์ฝ”๋“œ๋กœ iOS ์›Œํฌํ”Œ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ด ํŠœํ† ๋ฆฌ์–ผ์„ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด ๋Œ“๊ธ€, ์ข‹์•„์š” ๋˜๋Š” ์œ ๋‹ˆ์ฝ˜ ๐Ÿฆ„์„ ๋‚จ๊ฒจ์ฃผ์„ธ์š”! ๐Ÿš€๐Ÿ”–

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ