No echos in bash script in Jenkins - ruby

I'm writing a Pipeline script for Jenkins on Mac that needs to execute a couple of sh steps. Some of them involve RVM and Bundler ...
sh '#!/bin/bash -xl' +
' && rvm list' +
' && rvm use 2.3.1' +
' && gem install bundler' +
' && which bundler'
As you can see I have to use the hashbang to make RVM and Bundler to work, i.e having to be in a Login Shell but the problem is I don't see any log output for this in Jenkins anymore, even with -xl flag.
Does somebody know why log output is omitted and how to enable it for this?
UPDATE:
sh returnStdout: true, script: '#!/bin/bash -xl && rvm list && rvm use 2.3.1 && gem install bundler && which bundler'
Log Output:
[Pipeline] sh
[app_ios_test_automation] Running shell script
[Pipeline] echo

The "sh" function has optional parameters. If you call it like you're doing, you won't get the standard output of the script.
If you go into your pipeline job definition, where you specify the pipeline script itself, you should see a link labeled "Pipeline Syntax". This allows you to experiment with the pipeline steps that are enabled in your Jenkins instance. If you select "sh" from the dropdown and then click the "Advanced" button, you'll see the additional options you can set, including the "returnStdout" flag.

To expand on David Karr's answer, you're probably looking for something like this:
sh(returnStdout: true, script: "your script here")

Related

Getting RVM to work with Jenkins Pipeline

So I'm trying to setup a Jenkins declarative Pipeline to run an Xcode build job. I want to use xcpretty Ruby gem but will also need several other Ruby gems later for other jobs.
stage('Pre-Build')
{
steps
{
echo "Executing Pre-Build steps ..."
sh(returnStdout: true, script: "#!/bin/bash -xle && source ~/.rvm/scripts/rvm && rvm use 2.3.1 && cd ${WORKSPACE}/${env.PROJECT_PATH} && gem install xcpretty && set -o pipefail && xcpretty")
}
}
First off all, I get no echo for the sh in Pre-Build stage whatsoever. Neither returnStdout: true nor the hashbang seem to have any effect on getting any log output from the shell invocation.
That leaves me blind on what's going on here. When running the job, the Pre-Build stage passes and then it fails at my actual build stage when I want to use xcpretty.
Here's the log output from the Pre-Build stage:
Executing Pre-Build steps ...
[Pipeline] script
[Pipeline] {
[Pipeline] sh
[job] Running shell script
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] echo
If I run it in the bash manually, no problem! On Jenkins it seems that something isn't working with RVM but I'm tapping in the dark while trying to fix this for days and it drives me insane.
Any help is appreciated!
MichaƂ Knapik has a blog post covering one hand-rolled solution which defines a groovy wrapper which replicates rvm use semantics
See:
https://blog.knapik.me/how-to-use-rvm-with-jenkins-pipeline/
node {
withRvm('ruby-2.3.1') {
sh 'ruby --version'
sh 'gem install rake'
}
}
I don't want to copy any more than this example - its his code.
Note the caveats on specifying the version

"rvm use --install" broken in Jenkins, "uname: command not found"

This is a snippet from a Jenkins job run that needs rvm 1.9.3.. I have no idea why the PATH is not being looked at. From this build the PATH environment variable looks correctly set as PATH="/usr/java/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" (as set in /etc/environment), HOME="/scratch" and SHELL="/bin/sh", so I'm mystified by this.
$ bash -c " source ~/.rvm/scripts/rvm && rvm use --install --create ruby-1.9.3 && export > rvm.env"
/scratch/.rvm/scripts/rvm: line 12: uname: command not found
/scratch/.rvm/scripts/rvm: line 15: ps: command not found
bash: rvm: command not found
I have also attempted the rbenv route but am met with similar errors indicating the absence of $PATH
Also, the Jenkins user belongs to the rvm group.
I send many internets in thanks for any assistance offered!
rvm needs login shell.
I use it like this in my builds:
echo "rvm install 2.2.3" | /bin/bash -l
Works just fine this way.

How to access secondary travis logs

I know the primary travis build logs are available on the web and with the logs command in the travis command line client, but I was wondering if there is a way to access other files generated as part of the build process, such as the file /home/travis/.rvm/log/1391454748_rbx-2.2.4/rubygems.install.log referenced in https://travis-ci.org/rspec/rspec-its/jobs/18148204
Those files are lost once the build is finished. If you want to read them, you should add a cat command to print out to the log you see.
before_script: cat /home/travis/.rvm/log/*_rbx-2.2.4/rubygems.install.log
If the install command is failing, then you should override install to install the gem for which the installation is failing:
install: gem install XXX || cat /home/travis/.rvm/log/*_rbx-2.2.4/rubygems.install.log
banzaiman's answer is good (it helped me!). But if you use:
install: gem install XXX || cat /home/travis/.rvm/log/*_rbx-2.2.4/rubygems.install.log
then the cat command will likely succeed, and so the line above will count as as success, and the build will continue. If you want the build to fail when the install fails, then you need to make sure the line has a non-zero exit status. So do something like this:
install: gem install XXX || { cat /home/travis/.rvm/log/*_rbx-2.2.4/rubygems.install.log && 1; }
The expression in curly braces will be run only if the gem install XXX fails (i.e., has a non-zero exit status). cat will presumably succeed, so the command after the && will be run. That 1 ensures a non-zero exit status for the whole line, causing the build to stop at that point.
Note the necessary whitespace around the curly braces.

How can I default to a login shell for Jenkins shell execution

I want to use rvm (or rbenv/chruby for that matter) to select different ruby versions from within my Jenkins jobs.
By default, Jenkins will use /bin/sh, which on Ubuntu, is dash.
For this to change, I can add
#!/bin/bash -l
To the top of every single shell execute function everywhere. Seeing as that's a lot of annoying work, I'd like to be able to set that somewhere central.
Using the "Shell executable" configuration setting, I can get it to run bash, adding parameters like '-l' however will fail with
"/bin/bash -l" -xe /tmp/hudson5660076222778817826.sh FATAL:
command execution failed java.io.IOException: Cannot run program
"/bin/bash -l" (in directory
"/home/jenkins/jobs/workspace/rvm-test"): error=2, No such file or
directory
I tried using the rvm plugin for jenkins, but that doesn't even install on the current release version.
Any ideas? :)
You could work around by creating a wrapper around bash:
#!/bin/sh
# for ex.: /usr/local/bin/login-bash
exec /bin/bash -l "$#"
If you want to use the default ruby just use the rvm-shell, which comes with rvm.
Login as the jenkins user and type:
$ which rvm-shell
/home/jenkins/.rvm/bin/rvm-shell
to get the path of the rvm-shell.
Use this path for the "Shell executable" option.

Why does ruby script stop when trying to start unicorn_rails as daemon?

I'm trying to start unicorn_rails in a ruby script, and after executing many commands in the script, when the script gets to the following line
%x[bash -ic "bash <(. ~/.bashrc); cd /home/www-data/rails_app; bundle exec unicorn_rails -p 8000 -E production -c /home/www-data/rails_app/config/unicorn.rb -D"]
the script stops, generating the following output
[1]+ Stopped ./setup_rails.rb
and returns to the Linux prompt. If I type "fg", the script finishes running, the line where the script had stopped gets executed and unicorn gets started as a daemon.
If I run the line in a separate script, the script completes without stopping.
UPDATE_1 -
I source .bashrc because earlier in the script I install rvm and to get it to run with the correct environment I have the following:
%x[echo "[[ -s \"$HOME/.rvm/scripts/rvm\" ]] && source \"$HOME/.rvm/scripts/rvm\"" >> .bashrc]
%x[bash -ic "bash <(. ~/.bashrc); rvm install ruby-1.9.2-p290; rvm 1.9.2-p290 --default;"]
So if I want to run correct version of rvm, ruby and bundle I need to source .bashrc
end UPDATE_1
Does anyone have any idea what could cause a ruby script to halt as if control-Z was pressed?
Not sure why it's stopping, but my general rule of thumb is to never source my .bashrc in a script -- that might be the source of your problem right there, but I can't be sure without seeing what's in it. You should be able to change your script to something like:
$ vi setup_rails.sh
#!/usr/bin/bash
# EDIT from comments below
# expanding from a one liner to a better script...
$RVM_PATH=$HOME/.rvm/scripts
# install 1.9.2-p290 unless it's installed
$RVM_PATH/rvm info 1.9.2-p290 2&>1 >/dev/null || $RVM_SH install 1.9.2-p290
# run startup command inside rvm shell
$RVM_PATH/rvm-shell 1.9.2-p290 -c "cd /home/www-data/rails_app && bundle exec unicorn_rails -p 8000 -E production -c /home/www-data/rails_app/config/unicorn.rb -D"
This should give you the same result.

Resources