• Blog
  • Info Support
  • Career
  • Training
  • International Group
  • Info Support
  • Blog
  • Career
  • Training
  • International Group
  • Search
logo InfoSupport
  • Latest blogs
  • Popular blogs
  • Experts
      • All
      • Bloggers
      • Speakers
  • Meet us
  • About us
    • nl
    • en
    • .NET
    • 3D printing
    • Advanced Analytics
    • Agile
    • Akka
    • Alexa
    • Algorithms
    • Api's
    • Architectuur
    • Artificial Intelligence
    • ATDD
    • Augmented Reality
    • AWS
    • Azure
    • Big Data
    • Blockchain
    • Business Intelligence
    • Chatbots
    • Cloud
    • Code Combat
    • Cognitive Services
    • Communicatie
    • Containers
    • Continuous Delivery
    • CQRS
    • Cyber Security
    • Dapr
    • Data
    • Data & Analystics
    • Data Science
    • Data Warehousing
    • Databricks
    • DataOps
    • Developers life
    • DevOps
    • Digital Days
    • Digital Twin
    • Docker
    • eHealth
    • Enterprise Architecture
    • Event Sourcing
    • Hacking
    • Infrastructure & Hosting
    • Innovatie
    • Integration
    • Internet of Things
    • Java
    • Machine Learning
    • Microservices
    • Microsoft
    • Microsoft Bot Framework
    • Microsoft Data Platform
    • Mobile Development
    • Mutation Testing
    • Open source
    • Pepper
    • Power BI
    • Privacy & Ethiek
    • Python
    • Quality Assistance & Test
    • Quality Assurance & Test
    • Requirements Management
    • Scala
    • Scratch
    • Security
    • SharePoint
    • Software Architecture
    • Software development
    • Software Factory
    • SQL Server
    • SSL
    • Start-up
    • Startup thinking
    • Stryker
    • Test Quality
    • Testing
    • TLS
    • TypeScript
    • Various
    • Web Development
    • Web-scale IT
    • Xamarin
    • All
    • Bloggers
    • Speakers
Home » Flutter & App Center with Azure Pipelines
  • Flutter & App Center with Azure Pipelines

    • By Tom de Wildt
    • Continuous Delivery 2 years ago
    • Continuous Delivery 0 comments
    • Continuous Delivery Continuous Delivery
    Flutter & App Center with Azure Pipelines

    Continuous delivery is the ability to get application updates into production or into the hands of users, safely, quickly and in a sustainable way. App Center is a tool that can help developers deliver their app to the end user. In this blog post I will show you how to use App Center in conjunction with Flutter and Azure Pipelines.

    App Center

    Visual Studio App Center is a tool that lets users automate and manage the lifecycle of their iOS, Android, Windows, and macOS apps. A user can automate his builds, test on real devices in the cloud, distribute apps to beta testers, and monitor real-world usage with crash and analytics data.

    As of now (29-06-2020) App Center has no official support for Flutter. There is an issue on the GitHub page of App Center where users are asking for support but there is no official timeline yet. However, there are some workarounds to get support for Flutter in App Center.

    Pipeline

    You must first install the Azure Pipelines Flutter  extension to distribute Flutter apps using App Center Distribute and Azure Pipelines. It is also a good idea to setup a service connection for App Center in Azure Pipelines, you can read more about that here.

    Step 1: Define triggers

    The following code snippet makes sure that the pipeline only triggers on pushes to the master branch and tags. The advantage of having multiple triggers is that you can send builds that are triggered by a push to the beta testers group and builds that are triggered by a tag to the public group.

    trigger:
      branches:
        include:
          - master
          - refs/tags/*
    pr: none

    Step 2: Define variables

    It’s a best practice use a variables section to make it easy for other developers to update the pipeline in the future.

    variables:
      FlutterChannel: 'stable'
      FlutterVersion: 'latest'
    
      ProjectSlug: '<APP_CENTER_USERNAME>/<APP_CENTER_APP>'
      ProjectDirectory: '$(Build.SourcesDirectory)'
    
      BuildNumber: '$(Build.BuildNumber)'
      BuildMessage: '$(Build.SourceVersionMessage)'
      BuildDirectory: '$(ProjectDirectory)/build/app/outputs/apk/release/app-release.apk'

    Step 3: Setup environment

    You must first install Flutter and setup some environment variables before you can build and distribute the app. It’s recommended to use the macOS-latest image for the pipeline.

    The macOS-latest image already has Java 7, 8, 11, 12, 13 and 14 installed. You can select the version you want by appending JAVA_HOME_<VERSION>_X64 to the $PATH variable and setting the $JAVA_HOME variable to JAVA_HOME_<VERSION>_X64. You also need to append the FlutterToolPath variable (exposed by the extension) to the $PATH variable to allow the other steps in the pipeline to use the flutter command line tools.

    jobs:
      - job: Build
        pool:
          vmImage: 'macOS-latest'
        steps:
          - task: FlutterInstall@0
            displayName: Setup flutter
            inputs:
              channel: '$(FlutterChannel)'
              version: '$(FlutterVersion)'
    
          - task: PowerShell@2
            displayName: Setup environment
            inputs:
              targetType: 'inline'
              script: |
                Write-Host "##vso[task.prependpath]$(JAVA_HOME_11_X64)"
                Write-Host "##vso[task.setvariable variable=JAVA_HOME;]$(JAVA_HOME_11_X64)"
                Write-Host "##vso[task.prependpath]$(FlutterToolPath)"
                Write-Host "##vso[task.prependpath]$(FlutterToolPath)/cache/dart-sdk/bin"

    Step 4: Changing environment based on triggers

    You also need to set two variables to build and distribute the app. The build name which refers to the version number and the distribution group.

    It’s nice to use the first 7 characters of the commit sha as the build name for builds that are triggered by a push and the tag for builds that are triggered by a tag. You can set the variables by creating two steps and using conditions to run them on the right trigger.

          - task: PowerShell@2
            displayName: Setup variables (beta)
            condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/')
            inputs:
              targetType: 'inline'
              script: |
                $buildName = "$(Build.SourceVersion)".SubString(0,7)
                $distributionGroup = "<APP_CENTER_BETA_DISTRIBUTION_GROUP_ID>"
                Write-Host "##vso[task.setvariable variable=BuildName;]$buildName"
                Write-Host "##vso[task.setvariable variable=DistributionGroup;]$distributionGroup"
    
          - task: PowerShell@2
            displayName: Setup variables (public)
            condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/')
            inputs:
              targetType: 'inline'
              script: |
                $buildName = "$(Build.SourceBranch)".SubString(11)
                $distributionGroup = "<APP_CENTER_PUBLIC_DISTRIBUTION_GROUP_ID>"
                Write-Host "##vso[task.setvariable variable=BuildName;]$buildName"
                Write-Host "##vso[task.setvariable variable=DistributionGroup;]$distributionGroup"

    Step 5: Build & distribute

    All the dependencies must be installed by using `flutter pub get` before you can build and distribute the app.

          - task: CmdLine@2
            displayName: Run install
            inputs:
              script: 'flutter pub get'
    
          - task: FlutterBuild@0
            displayName: Run build
            inputs:
              target: 'apk'
              projectDirectory: '$(ProjectDirectory)'
              buildName: '$(BuildName)'
              buildNumber: '$(BuildNumber)'
    
          - task: AppCenterDistribute@3
            displayName: Run distribute
            inputs:
              serverEndpoint: 'AppCenter Service Connection'
              appSlug: '$(ProjectSlug)'
              appFile: '$(BuildDirectory)'
              releaseNotesOption: 'input'
              releaseNotesInput: '$(BuildMessage)'
              destinationType: 'groups'
              distributionGroupId: '$(DistributionGroup)'

    Step 6: Complete pipeline

    The complete pipeline should look somewhat like this:

    trigger:
      branches:
        include:
          - master
          - refs/tags/*
    pr: none
    
    variables:
      FlutterChannel: 'stable'
      FlutterVersion: 'latest'
    
      ProjectSlug: '<APP_CENTER_USERNAME>/<APP_CENTER_APP>'
      ProjectDirectory: '$(Build.SourcesDirectory)'
    
      BuildNumber: '$(Build.BuildNumber)'
      BuildMessage: '$(Build.SourceVersionMessage)'
      BuildDirectory: '$(ProjectDirectory)/build/app/outputs/apk/release/app-release.apk'
    
    jobs:
      - job: Build
        pool:
          vmImage: 'macOS-latest'
        steps:
          - task: FlutterInstall@0
            displayName: Setup flutter
            inputs:
              channel: '$(FlutterChannel)'
              version: '$(FlutterVersion)'
    
          - task: PowerShell@2
            displayName: Setup environment
            inputs:
              targetType: 'inline'
              script: |
                Write-Host "##vso[task.prependpath]$(JAVA_HOME_11_X64)"
                Write-Host "##vso[task.setvariable variable=JAVA_HOME;]$(JAVA_HOME_11_X64)"
                Write-Host "##vso[task.prependpath]$(FlutterToolPath)"
                Write-Host "##vso[task.prependpath]$(FlutterToolPath)/cache/dart-sdk/bin"
    
          - task: PowerShell@2
            displayName: Setup variables (beta)
            condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/')
            inputs:
              targetType: 'inline'
              script: |
                $buildName = "$(Build.SourceVersion)".SubString(0,7)
                $distributionGroup = "<APP_CENTER_BETA_DISTRIBUTION_GROUP_ID>"
                Write-Host "##vso[task.setvariable variable=BuildName;]$buildName"
                Write-Host "##vso[task.setvariable variable=DistributionGroup;]$distributionGroup"
    
          - task: PowerShell@2
            displayName: Setup variables (public)
            condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/')
            inputs:
              targetType: 'inline'
              script: |
                $buildName = "$(Build.SourceBranch)".SubString(11)
                $distributionGroup = "<APP_CENTER_PUBLIC_DISTRIBUTION_GROUP_ID>"
                Write-Host "##vso[task.setvariable variable=BuildName;]$buildName"
                Write-Host "##vso[task.setvariable variable=DistributionGroup;]$distributionGroup"
    
          - task: CmdLine@2
            displayName: Run install
            inputs:
              script: 'flutter pub get'
    
          - task: FlutterBuild@0
            displayName: Run build
            inputs:
              target: 'apk'
              projectDirectory: '$(ProjectDirectory)'
              buildName: '$(BuildName)'
              buildNumber: '$(BuildNumber)'
    
          - task: AppCenterDistribute@3
            displayName: Run distribute
            inputs:
              serverEndpoint: 'AppCenter Service Connection'
              appSlug: '$(ProjectSlug)'
              appFile: '$(BuildDirectory)'
              releaseNotesOption: 'input'
              releaseNotesInput: '$(BuildMessage)'
              destinationType: 'groups'
              distributionGroupId: '$(DistributionGroup)'

    Conclusion

    By using Azure Pipelines and App Center you can easily setup a continuous delivery pipeline for your Flutter project. I hope this post helps you implement your own pipeline. Feel free to leave a comment below if you have any questions.

    azure pipelines app center

    Share this

Tom de Wildt

View profile

Related IT training

Go to training website

Related Consultancy solutions

Go to infosupport.com

Related blogs

  • Adding a package to your private WinGet.RestSource feed…

    Adding a package to your private WinGet.RestSource feed… Léon Bouquiet - 1 year ago

  • Migrate Azure API Management developer portal customiza…

    Migrate Azure API Management developer portal customiza… Caspar Eldermans - 1 year ago

  • Provision an Azure VM in an Azure Pipelines Environment

    Provision an Azure VM in an Azure Pipelines Environment Ronald Bosma - 2 years ago

Data Discovery Channel

  • Explainable AI - Break open the blackbox

  • Toekomstvaste microservice data architecturen

  • Modern Data Platform

Nieuwsbrief

* verplichte velden

Contact

  • Head office NL
  • Kruisboog 42
  • 3905 TG Veenendaal
  • T +31 318 552020
  • Call
  • Mail
  • Directions
  • Head office BE
  • Generaal De Wittelaan 17
  • bus 30 2800 Mechelen
  • T +32 15 286370
  • Call
  • Mail
  • Directions

Follow us

  • Twitter
  • Facebook
  • Linkedin
  • Youtube

Newsletter

Sign in

Extra

  • Media Library
  • Disclaimer
  • Algemene voorwaarden
  • ISHBS Webmail
  • Extranet
Beheer cookie toestemming
Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
Functioneel Always active
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
Voorkeuren
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
Statistieken
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt. De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
Marketing
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
Manage options Manage services Manage vendors Read more about these purposes
Voorkeuren
{title} {title} {title}