flutterdartjenkinsjenkins-pipeline

Flutter Jenkins flutter not found issue


I am currently trying to build a Flutter app with Jenkins. For the initial setup I have a master-slave setup in which the slave is a Mac machine which will create the build (slave machine is connected as well).

Below is the pipeline script:


pipeline {
    agent {
        label "macos16Node"
    }
     environment {
        flutter = " /Users/username/Desktop/flutter"
    }


    stages {
        stage ('Flutter Doctor') {
            steps {
                withEnv(['PATH+EXTRA=/opt/flutter/bin']){
                    sh '$flutter doctor -v'
                }
               
            }
           
        }
        stage('GIT PULL') {
            steps {a
                git branch: 'main', credentialsId: 'github_token', url: ‘mygitrepo’
            }
        }
        stage('TEST') {
            steps {
                
                    sh ‘$flutter test'
                
                
            }
        }
        stage('BUILD') {
            steps {
                sh '''
                  #!/bin/sh
                  flutter build apk --debug
                  '''
            }
        }
        
    }
}

Whenever I build the pipeline it gives me an error.

Following is the console output:

[Pipeline] Start of Pipeline
[Pipeline] node
Running on slaveNode in /var/root/workspace/first pipeline
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Flutter Doctor)
[Pipeline] withEnv
[Pipeline] {
[Pipeline] sh
+ /Users/user/Desktop/flutter doctor -v
/var/root/workspace/first pipeline@tmp/durable-f6dbaa4a/script.sh: 1: /Users/user/Desktop/flutter: not found

I have also not set any path in the env variables in Jenkins. Why does it not detect Flutter, do I need and additional setup for this?


Solution

  • Quick answer

    Reason:

    flutter binary is not the in the PATH of jenkins shell

    Fix:

    Download flutter anywhere like /tmp/workspace/flutter and override the PATH in the environment.

    Jenkins 2.375.2

    pipeline {
        agent any
        environment {
          PATH = "$PATH:/tmp/workspace/flutter/bin"
        }    
        stages {
            stage('Setup') {
                steps {
                    print "${env.PATH}"
                }    
            }
            
            stage('Build') {
                steps {
                    sh "flutter doctor -v"
                }
            }        
        }
    }
    

    output

    enter image description here

    Detailed answer

    There is no magic with Jenkins, if it works in the shell, it will work with Jenkins.

    Steps 1: Add flutter to the shell PATH

    In the machine which jenkins will execute the build commands, try the command flutter doctor -v. You will see this error:

    enter image description here

    Similar to the jenkins error

    enter image description here

    So, install flutter with snap

    sudo snap install flutter --classic
    

    or download it with curl

    curl https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.7.3-stable.tar.xz -o /foo/bar/flutter.tar.xz
    apt-get install xz-utils
    tar xf /foo/bar/flutter.tar.xz
    

    You should have these files ls -la /foo/bar/flutter

    enter image description here

    Finally you need to add the flutter to the shell PATH variable. You could use the java style

    export FLUTTER_HOME=/foo/bar/flutter
    export PATH=$PATH:$FLUTTER_HOME/bin
    

    enter image description here

    If you run the command, it will work

    enter image description here

    Steps 2: Add flutter to the jenkins PATH

    For declarative pipeline, since PATH is a special env var, the only way to modify it is with:

    environment {
      PATH = "$PATH:/foo/bar/flutter/bin"
    }   
    

    Similar to the host shell example PATH=$PATH:$FLUTTER_HOME/bin

    After that, you could use flutter anywhere of your pipeline

    For scripted pipeline, these 2 options worked for me:

    #1 Modifying the PATH variable

    node {   
      print "${env.PATH}"
    
      def FLUTTER_HOME = "/tmp/workspace/flutter"
      env.PATH = env.PATH+":$FLUTTER_HOME/bin"
      print "${env.PATH}"
    
      sh "flutter doctor -v"
    }
    

    #2 withEnv PATH+EXTRA

    node {
      def FLUTTER_HOME = "/tmp/workspace/flutter"
    
      withEnv(["PATH+EXTRA=$FLUTTER_HOME/bin"]){
        sh 'flutter doctor -v'
      }
    
      sh "flutter doctor -v"
    }
    

    The only problem with this latest option is that flutter will work only in the withEnv{...} scope.

    enter image description here

    References