Flutter Jenkins flutter not found issue - flutter

Hello all i am currently trying to build the flutter app with jenkins.
for the initial setup what i have done is there is master-slave setup in which the slave is 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
'''
}
}
}
}
when ever i build the pipeline it gives me the 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.
If any one can let me know why it does not detect flutter, or do i need and additional setup for this one.

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
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:
Similar to the jenkins error
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
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
If you run the command, it will work
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.
References
https://docs.flutter.dev/get-started/install/linux
https://www.geeksforgeeks.org/how-to-install-flutter-on-linux/
https://www.cyberithub.com/how-to-install-flutter-on-ubuntu-20-04-lts-focal-fossa/
https://www.freecodecamp.org/news/how-to-install-and-setup-flutter-on-ubuntu/
How to set PATH in Jenkins Declarative Pipeline
unable to override env PATH variable in Jenkins
https://gist.github.com/thinhdanggroup/90528c34e4fd4c9e1c9a945f9b88d89c
https://dsstream.com/declarative-vs-scripted-pipeline-key-differences/

Related

I have created a Git Action Workflow with Terraform giving exec: "PowerShell": executable file not found in $PATH. error

I have created a Git Action Workflow with Terraform which uses local-exec to run a powershell script.
However in the workflow I am getting an this error exec: "PowerShell": executable file not found in $PATH. Please help me to resolve this. I am using a default runner (not a self-hosted).
resource "null_resource" "PowerShellScript" {
triggers = {
trigger = "${uuid()}"
}
provisioner "local-exec" {
working_dir = "${path.module}/../scripts/"
command = "post-deployment-policy-assignment.ps1 -RgName ${data.azurerm_resource_group.apim_rg.name} -ApimName ${data.azurerm_api_management.apim.name} -Env ${var.azure.environment}"
interpreter = ["PowerShell", "-Command"]
}
}
enter image description here

Can't run flutter build from Jenkins

I tried to run a flutter build from jenkins using the following pipeline code :
pipeline {
agent any
stages {
stage('build') {
steps {
bat 'C:\\path_to_doc\\flutter_dev\\flutter\\bin\\flutter.bat build web -t "C:\\path_to_doc\\lib\\src\\main\\main.dart"'
}
}
}
post{
always {
archiveArtifacts artifacts: 'C:\\path_to_doc\\build\\web\\index.html', fingerprint: true, followSymlinks: false
}
}
}
I got this error in jenkins :
I tried to write the flutter build code in a bat file in the root of my flutter project, and then execute this file on the pipeline code, got the same error.
What is the correct way to proceed to avoid this error ?
Jenkins has a habit of reverting to the initial workspace directory for each separate command. Try setting the directory after your steps{ line:
dir('C:\\path_to_doc\\flutter_dev\\flutter\\bin\\') {
bat 'flutter.bat build web -t "C:\\path_to_doc\\lib\\src\\main\\main.dart"'
}
This will ensure that your script will run in this location. So if your pubspec.yaml is in this location, it should be able to find it. In any case, this is a problem with the directory, so if this doesn't work, some manual debugging would be necessary to see what went wrong.

Push version Number to git/azure devops automatically

I have these three commands in my package.json
{
"build-major": "npm version major --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
"build-minor": "npm version minor --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
"build-patch": "npm version patch --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
}
My replace.build.js Contains following Code:
var replace = require('replace-in-file');
var package = require("./package.json");
var buildVersion = package.version;
const options = {
files: 'src/environments/environment.prod.ts',
from: /version: '(.*)'/g,
to: "version: '"+ buildVersion + "'",
allowEmptyPaths: false,
};
const htmlOptions={
files:'src/index.html',
from: /<meta name="version" content="(.*)">/g,
to: '<meta name="version" content="'+buildVersion+'">',
allowEmptyPaths: false
}
try {
let changedFiles = replace.sync(options);
if (changedFiles == 0) {
throw "Please make sure that file '" + options.files + "' has \"version: ''\"";
}
let indexFileChanged = replace.sync(htmlOptions);
if (indexFileChanged == 0) {
throw "Index.html Version Change Failed";
}
console.log('Build version set: ' + buildVersion);
}
catch (error) {
console.error('Error occurred:', error);
throw error
}
So every time i take my Angular Build, i get 3 files changes?
index.html, environment.prod.ts and package.json
I am looking at a solution to make these changes get pushed to the current branch too while build is in Process or a Standard way to maintain the Build Number in sync with all Branches.
I am looking at a solution to make these changes get pushed to the
current branch too while build is in Process or a Standard way to
maintain the Build Number in sync with all Branches.
Just put a git-related task at the end of your pipeline to push the changed files to remote branch. You can use CMD task, Powershell task or third-party git tasks here to push the changed files.
For my pipeline that calls Replace token task to modify one file:
1.The cmd task at the start of the pipeline:
git checkout $(Build.SourceBranchName)
git config --global user.email "xxx#xxx.com"
git config --global user.name "xxx"
For build source directory, git repo is in HEAD detached by default, so we need to switch to the build branch by git checkout first.
2.The cmd task at the end of the pipeline:
git add .
git commit -m "Update files in Build $(Build.BuildNumber)."
git push https://{MyPat}#dev.azure.com/{OrganizationName}/{ProjectName}/_git/{RepoName} $(Build.SourceBranchName)
Check this similar issue for more details about git push command. About PAT see here. You can also define the PAT as an secret variable and reference it in command.
You can put your real tasks between the first CMD and the last CMD, then every time when the pipeline is finished, the changes will be pushed to current branch. (With BuildNumber in commit message.)

How do you get a grunt error to return on a VSTS hosted build agent

I'm trying to run grunt tasks through a batch script and am calling grunt as follows:
call npm install
call npm install grunt
However, if this returns an error, then the VSTS build on the hosted build agent still shows up as successful (even with a logged error in the script). Does anyone have any good examples of how to get it to return an error to the build?
I've been looking at using powershell, but without any luck so far, with code as follows:
In gruntfile.js:
grunt.initConfig({
shell: {
ps: {
options: {
stdout: true
},
command: 'powershell ../../errors.ps1'
}
}
});
grunt.registerTask('default', function() {
try {
grunt.task.run([
'less:desktop',
'less:tablet',
'less:smartphone',
'less:homepage_desktop',
'less:homepage_tablet']);
} catch(e) {
grunt.task.run([
'shell:ps']);
throw e;
}
});
In errors.ps1:
$URL_Format_Error = [string]"Error found in running grunt. Please investigate grunt logs"
Write-Error $URL_Format_Error -ErrorAction:Stop
return
The code run in the exception handler never gets called, and a warning is output with a compilation error in the .less file, but the powershell is never run. Is there a way I can hook into the warning perhaps, and run my powershell then?
As an alternative, when I try to add a grunt task to the VSTS build definition after a batch script to run the NPM install, I just keep getting the following error (even after seeing a successful NPM installation in the batch script):
Fatal error: Unable to find local grunt
Hence, I'm not sure if I can run the grunt task in a separate task the VSTS build definition, if I'm using a hosted build agent. I'm inclined to think that would only work if I had my own build server.
Just try to use Write-Error in combination with an exit 1 in your script.
Write-Error ("Some error")
exit 1
Reference this thread : How to fail the build from a PowerShell task in TFS 2015

How to fix "Test reports were found but none of them are new. Did tests run?" in Jenkins

I am getting the error "Test reports were found but none of them are new. Did tests run?" when trying to send unit test results by email. The reason is that I have a dedicated Jenkins job that imports the artifacts from a test job to itself, and sends the test results by email. The reason why I am doing this is because I don't want Jenkins to send all the developers email during the night :) so I am "post-poning" the email sending since Jenkins itself does not support delayed email notifications (sadly).
However, by the time the "send test results by email" job executes, the tests are hours old and I get the error as specified in the question title. Any ideas on how to get around this problem?
You could try updating the timestamps of the test reports as a build step ("Execute shell script"). E.g.
cd path/to/test/reports
touch *.xml
mvn clean test
via terminal or jenkins. This generates new tests reports.
The other answer that says cd path/to/test/reports touch *.xml didn't work for me, but mvn clean test yes.
Updating the last modified date can also be achieved in gradle itself is desired:
task jenkinsTest{
inputs.files test.outputs.files
doLast{
def timestamp = System.currentTimeMillis()
test.testResultsDir.eachFile { it.lastModified = timestamp }
}
}
build.dependsOn(jenkinsTest)
As mentioned here: http://www.practicalgradle.org/blog/2011/06/incremental-tests-with-jenkins/
Here's an updated version for Jenkinsfile (Declarative Pipeline):
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make build'
}
}
stage('Test') {
steps {
sh 'make test'
script {
def testResults = findFiles(glob: 'build/reports/**/*.xml')
for(xml in testResults) {
touch xml.getPath()
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
junit 'build/reports/**/*.xml'
}
}
}
Because gradle caches results from previous builds I ran into the same problem.
I fixed it by adding this line to my publish stage:
sh 'find . -name "TEST-*.xml" -exec touch {} \\;'
So my file is like this:
....
stage('Unit Tests') {
sh './gradlew test'
}
stage('Publish Results') {
// Fool Jenkins into thinking the tests results are new
sh 'find . -name "TEST-*.xml" -exec touch {} \\;'
junit '**/build/test-results/test/TEST-*.xml'
}
Had same issue for jobs running repeatedly (every 30 mins).
For the job, go to Configure, Build, Advanced and within the Switches section add:
--stacktrace
--continue
--rerun-tasks
This worked for me
Navigate to report directory cd /report_directory
Delete all older report rm *.xml
Add junit report_directory/*.xml in pipeline
Rerun the test script , navigate to Build Number → Test Result
Make sure you have one successful build without any failure, only after this you can able to see the reports
Make sure that you have mentioned the correct path against "Test report XMLs" under jenkins configuration, such as "target/surefire-reports/*.xml"
There is no need to touch *.xml as jenkins won't complain even though test results xml file does not change.
if you use Windows slave, you can 'touch' results using groovy pipeline stage with powershell:
powershell 'ls "junitreports\\*.*" | foreach-object { $_.LastWriteTime = Get-Date }'
It happens if you are using a test report which is not modified by that job in that run.
In case for test purpose if you are testing with already created file then, add below command inside jenkins job under Build > Execute Shell
chmod -R 775 /root/.jenkins/workspace/JmeterTest/output.xml
echo " " >> /root/.jenkins/workspace/JmeterTest/output.xml
Above command changes timestamp of file hence error wont display.
Note: To achieve same in Execute Shell instead of above, do not try renaming file using move mv command etc. it won't work , append and delete same for change file timestamp only works.
For me commands like chmod -R 775 test-results.xml or touch test-results.xml does not work due to permission error. As work around use is to set new file in test report settings and command to copy old xml report file to new file.
you can add following shell command to your "Pre Steps" section when configure your job on Jenkins
mvn clean test
this will clean the test
Here's an updated version of the gradle task that touch each test result files.
From Jenkins pipeline script, just call "testAndTouchTestResult" task instead of "test" task.
The code below is with Kotlin syntax:
tasks {
register("testAndTouchTestResult") {
setGroup("verification")
setDescription("touch Test Results for Jenkins")
inputs.files(test.get().outputs)
doLast {
val timestamp = System.currentTimeMillis()
fileTree(test.get().reports.junitXml.destination).forEach { f ->
f.setLastModified(timestamp)
}
}
}
}
The solution for me was delete node_modules and change node version (from 7.1 to 8.4) on jenkins. That's it.