Home > Software engineering >  Jenkins rsync excludes do not exclude any files
Jenkins rsync excludes do not exclude any files

Time:09-06

I've got a Jenkins server running with some pipelines. I wanted to move from copying a tar file to a web server (and extracting it there) to synching the files with rsync. This works fine, but if I define an excluded file or folder, it is still synched. I have this line in my Jenkinsfile:

sh "rsync -av --dry-run --exclude={build.sh,run.sh} . ${SERVER_USER}@${SERVER}:${SERVER_DIRECTORY}"

As reference: these are the contents of ".":

$ tree src/
src/
├── build.sh
├── foo.bar
├── run.sh
└── var

1 directory, 3 files

And the contents of SERVER_DIRECTORY:

$ tree .
.
└── public
    └── index.php

1 directory, 1 file

If I run the command from above manually, then I get an incremental file list without the files build.sh and run.sh. On Jenkins they both appear in this file list:

[Pipeline] sh
  rsync -av --dry-run --exclude={build.sh,run.sh} . [email protected]:/srv/apache/projects/test
sending incremental file list
./
build.sh
foo.bar
run.sh
var/

What I tried so far:

  • using a trailing slash at the end of ".", so instead I used "./", since the man page states that this leads to creation of the directory at the destination path
  • using a trailing slash at the end of SERVER_DIRECTORY
  • comparing rsync versions, path to rsync binaries and environments, but the shells are the same and versions and paths also
// in Jenkinsfile:
sh "echo $SHELL"

// Output on Jenkins:
[Pipeline] sh
  echo /bin/bash
/bin/bash
  • did the whole rsync process manually: logged into Jenkins with jenkins user, go to build folder and run rsync command (worked as expected)

I tried it with "single excludes", meaning "--exclude build.sh --exclude run.sh", which worked, but I' curious, why the other solution only works when run manually, but not via Jenkins. Is this some kind of escaping issue or what am I missing here?

I hope that someone can help me on this and I'm looking forward to every anwser! :)

Edit #1: I got the same behaviour when I tried mkdir {foo,bar}: Jenkins creates one folder

[Pipeline] sh
  mkdir {foo,bar}
[Pipeline] sh
  ls -la
total 1504
drwxr-xr-x   2 jenkins jenkins   4096 Sep  5 14:26 {foo,bar}

CodePudding user response:

x={a,b} syntax is not something specific to rsync and it's something available in Bash.

For example, if you execute the following in bash.

echo --exclude={run.sh,deploy.sh}

You will see the following output.

--exclude=run.sh --exclude=deploy.sh

Jenkins executes shell commands using the default Shell using sh -c .... hence some of the Bash stuff will not work. In order to get around this set the Shebang line to point to bash, before executing the script.

sh"""
#!/bin/bash
rsync -av --dry-run --exclude={build.sh,run.sh} . ${SERVER_USER}@${SERVER}:${SERVER_DIRECTORY}
"""

CodePudding user response:

I solved it now by setting Jenkins > Manage Jenkins > Configure System > Shell executable to /bin/bash as in this post.

I'm not sure, why the answer of @ycr didn't work for me, since this solution obviously works for other people.

  • Related