16

I am triggering builds with string parameters from the command line in Jenkins with:

curl http://jenkins:8080/job/Build/buildWithParameters?PARAM=value&token=token

I now want to trigger a build with a file as a file parameter from the command line.

For example if my project builds main.c then I would like to be able to trigger a build and upload my main.c from the command line.

Is this possible?

Russell Gallop
  • 1,631
  • 2
  • 17
  • 34
  • Not sure whether you can do this from the HTTP interface, but it may be possible from the CLI (see https://ci.jenkins-ci.org/cli). There you can normally just provide the path to the file on the command line and it's uploaded appropriately. – Christopher Orr Nov 12 '12 at 17:34
  • Do you have a special reason why you need to upload your source file to the Jenkins build, rather than having the build retrieve it from source control ? The latter method is a fundamental capability of Jenkins, so it's a lot easier to set up. – gareth_bowles Nov 12 '12 at 18:00
  • Christopher: I'll try that. gareth_bowles: that's not really what I want to do but I thought it might explain the question. I'm actually trying to upload a mercurial forest snapshot which I don't believe is handled by Jenkins. Maybe that should be another question... – Russell Gallop Nov 13 '12 at 00:14
  • @Christopher That works really nicely. If you post it as an answer I'd vote for it. – Russell Gallop Nov 13 '12 at 14:00

4 Answers4

17

This is described in the Jenkins Remote access API page:

curl http://jenkins/job/$JOB_NAME/build -F file0=@PATH_TO_FILE -F json='{"parameter": [{"name":"FILE_LOCATION_AS_SET_IN_JENKINS", "file":"file0"}]}'

Note that you need to use the URL /build instead of /buildWithParameters

Sampo
  • 4,308
  • 6
  • 35
  • 51
  • 2
    **Note:** At least when running Jenkins 2.46.2, posting a file (multipart form data) to /build instead of /buildWithParameters causes the "Location" response header to not point to a queue item (e.g. [JENKINS]/queue/item/55/). Instead "Location" will just point to the job base url (e.g. [JENKINS]/job/[JOB_NAME]/). This makes it hard to know which build number the triggered build corresponds to! – Strille Jul 13 '17 at 11:13
  • Strille's comment is still valid as of version 2.73. So, when you need to pass a file, the options are a) use the `/build` URL (but then there's no option to retrieve the build number), or b) use the `/buildWithParameters` URL, which breaks the file upload, but which gives a build number. Is there really no way to get the build number for builds with file parameters...? – Alex O Jul 26 '18 at 18:06
14

If you need to send both string parameters and a file parameter, you can do the following:

json='{"parameter": [{"name": "param1", "value": "value1"},
  {"name": "param2", "value": "value2"},
  {"name":"fileParam", "file":"file0"}]}'

url=http://jenkins/job/My_Remote_Jenkins_Job/build

curl -v $url -F file0=@/some/folder/path/template.zip -F json="$json" --user username:password

I had to make sure that the parameters param1, param2 and fileParm exist in the Jenkins job My_Remote_Jenkins_Job.

oberlies
  • 11,503
  • 4
  • 63
  • 110
pmgarvey
  • 701
  • 6
  • 4
  • Thanks, I went this route but failed to see the `@` character before the file name... works great now. – altendky Feb 15 '14 at 21:02
  • Does anyone know how to do this with libcurl? – Dan Sep 21 '15 at 21:00
  • But do you know what exactly path to file should be ? `file0=@/some/folder/path/template.zip` When I'm trying to pass the file from my local machine, it doesn't work. `curl -X POST https://ctech.jjc-devops.com/job/ctech/job/pipeline/job/dev/job/storage/buildWithParameters?token=ctech --user username:userpass --form file0=@D:/Repository/test.yml --form json='{"parameter": [{"name":"pipeline.yaml", "file":"file0"}, {"name":"source_env.json", "file":""}, {"name":"target_env.json", "file":""}]}' ` – user3152984 Mar 23 '16 at 09:01
7

The solution I have used (based on Christophers suggestion of using jenkins-cli) is:

java -jar jenkins-cli.jar -s http://jenkins:8080 build Build -p main.c=hello.c

Which with a File Parameter of main.c will upload your local hello.c to the the workspace of the Build job as main.c

tashuhka
  • 5,028
  • 4
  • 45
  • 64
Russell Gallop
  • 1,631
  • 2
  • 17
  • 34
  • Doesn't work anymore as of Jenkins 2.165, see [my answer](https://stackoverflow.com/a/61111936/7571258) for a fix. – zett42 Apr 09 '20 at 00:05
0

Unfortunately Russels answer for using the CLI doesn't work anymore since Jenkins 2.165, because the “Remoting” operation mode of the Jenkins command-line interface has been removed.

From the Jenkins blog:

Command options or arguments which took either a local file or = for standard input/output (e.g., install-plugin, build -p, support) now only accept the latter.

This means the command-line must be changed like this:

java -jar jenkins-cli.jar -s http://jenkins:8080 build Build -p main.c= <hello.c

By passing an empty string for the file parameter "main.c", we indicate to the CLI that the file should be read from standard input. We are using shell redirection operator "<" to redirect the file "hello.c" to standard input.

zett42
  • 25,437
  • 3
  • 35
  • 72
  • 1
    What about multiple file parameters? We can only redirect single file from standard input – Lukman Aug 20 '20 at 13:08
  • @Lukman Yeah, that's not possible using the CLI. Another big issue is the very slow upload. Both can be avoided by using the [REST API](https://www.jenkins.io/doc/book/using/remote-access-api/). – zett42 Aug 21 '20 at 10:50