13

I'm using the new Jenkins2 pipeline to build a composed project with:

  • node frontend
  • php backend

both are in different repositories hence, the need to use pipeline to sync them, compile, and prepare them to deploy. I cannot find a simple way to deploy using FTP.

My script looks something like this:

node {
    // uncomment these 2 lines and edit the name 'node-4.4.5' according to what you choose in configuration
    def nodeHome = tool name: 'NodeJS 7.2.1', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation'
    env.PATH = "${nodeHome}/bin:${env.PATH}"

    stage("front") {
        dir('front') { // switch to subdir
            git url: ...             
            sh "npm install"

            sh "npm run build --prod"

            sh "cp -R * ../dist"
        }
    }

    stage("back") {
        dir('back') {
            git url: ...

            sh 'curl -sS https://getcomposer.org/installer | php'
            sh 'php composer.phar install'

            sh "cp -R * ../dist"
        }
    }
    stage("upload via ftp") {
        // IM NOT SURE WHAT TO DO HERE
    }
}

UPDATE 2016-12-16

To clarify what I need is a way to run something similar to "Publish via FTP" like older versions of Jenkins.

genuinefafa
  • 703
  • 1
  • 6
  • 21

6 Answers6

16

The Jenkins Publish Over FTP plugin has Pipeline support as of version 1.15.

A snippet from my Jenkinsfile that sends some files to our server:

stage('Upload')
{
    ftpPublisher alwaysPublishFromMaster: true, continueOnError: false, failOnError: false, publishers: [
        [configName: 'YOUR_CONFIG_HERE', transfers: [
            [asciiMode: false, cleanRemote: false, excludes: '', flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: "YOUR_DIRECTORY_HERE", remoteDirectorySDF: false, removePrefix: '', sourceFiles: '**.exe, **.txt']
        ], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true]
    ]
}

I generated this code snippet using the Jenkins snippet generator found under "Pipeline Syntax". Choose "ftpPublisher: send build artifacts over FTP" in the menu at "Sample Step", enter all details in the form and press "Generate Pipeline Script".

frankhermes
  • 4,720
  • 1
  • 22
  • 39
  • 2
    I get: `WorkflowScript: 16: Missing required parameter: "paramPublish"`… The documentation for this parameter makes no sense whatsoever: The name of the parameter or environment variable that will contain the expression for matching the labels. What label?… – Sardathrion - against SE abuse Jun 07 '18 at 08:37
  • 2
    @Sardathrion try including this along with first-level parameters: `paramPublish: [parameterName:""]` – d.Candela Jun 18 '18 at 13:01
  • hey, i'm trying to understand how to use this plugin with pipeline. using this snippet i get 0 output, but the operation is failed. any chance you know what is wrong with it? – 4c74356b41 Oct 12 '18 at 16:14
  • Could you add some more information in how your solution works? – Mason Oct 29 '18 at 13:21
  • 1
    To all who can't get it working: I generated this code snippet using the Jenkins snippet generator found under "pipeline syntax". Choose "ftpPublisher: send build artifacts over FTP" in the menu at "Sample Step", enter all details in the form and press "Generate Pipeline Script". If your plugin doesn't work with the above code, it may be a different version or something else. I don't know how the plugin works, I just use it. And the code in my answer works with our version of the plugin (listed as 1.15 in our plugin list in Jenkins)... – frankhermes Oct 30 '18 at 16:18
  • If this only had better documentation – Ordiel Apr 06 '19 at 21:13
  • Is there any documentation available at all? – not2savvy Mar 22 '22 at 13:20
  • https://github.com/jenkinsci/publish-over-ftp-plugin has a readme. – frankhermes Mar 22 '22 at 14:07
  • @frankhermes Yes, but it doesn't explain the pipeline syntax. – not2savvy Mar 22 '22 at 17:30
  • 1
    Your comment about the snippet generator is very useful. I'd suggest that you edit it into your answer. – not2savvy Mar 22 '22 at 17:35
  • 1
    The code generated by the snippet generator was incomplete. It only worked after inserting `masterNodeName: '', paramPublish: [parameterName:""],` at the top level (after `alwaysPublishFromMaster: false`). – not2savvy Mar 22 '22 at 17:36
  • 1
    The pipeline syntax can be found here: https://www.jenkins.io/doc/pipeline/steps/publish-over-ftp/ – gillesB Mar 23 '22 at 12:15
  • I've summarized the answer and useful comments in a new answer because I could not edit into this one. (Its "edit queue is full".) – not2savvy Mar 28 '22 at 12:06
8

Since this is one of the top links on google and the other answers don't work, I'll go ahead and add my two cents.

Here is the working pipeline stage that I'm using:

stage ('Deploy') {
  steps {
    ftpPublisher alwaysPublishFromMaster: true,
                 continueOnError: false,
                 failOnError: false,
                 masterNodeName: '',
                 paramPublish: null,
                 publishers: [[configName: 'External Host', transfers: [[asciiMode: false, cleanRemote: true, excludes: '', flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'public', sourceFiles: 'public/*,public/**/*']], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false]]
  }

The magic here is

  • Set up the External Host in the main Jenkins configuration page under Publish Over FTP and make sure the names match.
  • add the new new required parameters masterNodeName and paramPublish with an empty string and null respectively.

In the publishers block, these settings match what is defined in the old style Jenkins config under transfers, so refer to that for details.

I hope that helps future folks struggling with the ftpPublisher plugin in a Pipeline.

Marc Runkel
  • 167
  • 2
  • 9
  • thanks for the help... it seems to me that your solution is similar to the one from @frankhermes using `ftpPublisher` – genuinefafa Jun 14 '19 at 11:25
  • 2
    That is correct, the difference is that I’ve added the two new required parameters masterNodeName and paramPublish with valid values. – Marc Runkel Jun 15 '19 at 12:03
  • good to know! i'm not using that node right now, and cannot validate those parameters are required, however, i'll upvote the answer ;) – genuinefafa Jun 26 '19 at 18:58
  • I setup an "FTP_Server" in my Jenkins System config page, but the publisher says it can't find it? – Chris F May 18 '21 at 20:31
4

Install ncftp on the computer and run this command in Jenkins:

ncftpput -R -v -u "ftp-username" ftp.website.com ftp-upload-path local-path/*

(Taken from Can I upload an entire folder using FTP? on Super User)

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
  • that way I will end up by using a custom setup on the jenkins node... also, no error management is made from within the pipeline, I end up by leaving all on the OS... :( tried that – genuinefafa Aug 23 '17 at 12:52
  • @genuinefafa Unfortunately it seems to be the best option at the moment. It does work fine for me at least. Although it is indeed unfortunate to have to install `ncftp` on all your Jenkins machines. – Simon Forsberg Aug 29 '17 at 08:04
  • @SimonForsberg can you please give an example of ftp-upload-path for Windows server? I am trying to set target path `C:\ftproot` with this command `./ncftpput -R -v -u "user1" 10.1.175.143 C:\ftproot test1.txt` – vel Nov 24 '21 at 15:16
  • @AndreyDonald Nope, I can't give any example of that. Have no experience with that. (And to be honest, I'm not even using ncftp on my Linux machines either anymore) – Simon Forsberg Nov 25 '21 at 16:23
2

I could not get get the Jenkins Publish Over FTP plugin to work at all so I decided to use shell scripts which work. Below is a snippet using lftp. If you do not have that installed, either install it or use vanilla ftp.

stage('FTP') {
    steps {
        sh '''if git describe --exact-match --tags HEAD; then
            lftp ftp://USER:PWD@FTP -e "cd PATH; mput *.exe; bye"
        else
            exit 0
        fi
        '''
    }
}

This will only send things to FTP if there is a tag in git.

Sardathrion - against SE abuse
  • 17,269
  • 27
  • 101
  • 156
  • the only caveat for your solution is that ftp will _run_ outside jenkins logic, but shell... it is error prone and you require an non standard command; – genuinefafa Jun 08 '18 at 20:19
  • 2
    @genuinefafa Sadly, any Jenkins specific solution (using Publish Over FTP) keeps throwing incoherent exceptions about options those documentation is utterly incomprehensible: The name of the parameter or environment variable that will contain the expression for matching the labels. What label? Why would I need this? Where is that documented? … A shell script works just fine and is far less error prone than Jenkins modules. – Sardathrion - against SE abuse Jun 11 '18 at 08:26
  • @Sardathrion-againstSEabuse can you please tell me if it is possible to transfer directory with `lftp` command? I couldn't find that – vel Nov 24 '21 at 15:17
1

So your question is how to use Linux command line to upload a file via ftp? I think it was already solved here

$ curl -T my-local-file.txt ftp://ftp.example.com --user user:secret
Community
  • 1
  • 1
hakamairi
  • 4,464
  • 4
  • 30
  • 53
  • Nop, i'm trying to upload a bunch of files to a FTP Server. Thinks of it as a "Publish via FTP". – genuinefafa Dec 16 '16 at 17:06
  • Sorry I've misunderstood you. There is no support for this plugin in pipeline yet, there's [an open bug for it](https://issues.jenkins-ci.org/browse/JENKINS-37507). What I could recommend it to run sh "curl ..." (like in the example I gave) if you have a limited fixed number of resources to upload. – hakamairi Dec 16 '16 at 17:44
  • There must be a way to use standard plugins from within pipeline! isn't it? – genuinefafa Dec 17 '16 at 19:57
  • There is - the plugin developer has to extend the plugin a bit. More details [pipeline plugins compatibility](https://github.com/jenkinsci/pipeline-plugin/blob/master/COMPATIBILITY.md), [pipeline plugins developers guide](https://github.com/jenkinsci/pipeline-plugin/blob/master/DEVGUIDE.md) – hakamairi Dec 19 '16 at 10:09
  • I solve it by using a pipeline and then copying the artifacts to a new "old style" Jenkins projects that uses de publish via FTP plugin. It is not "the best option" but it is the only one by the time apparently. – genuinefafa Jan 10 '17 at 21:49
0

Note: I've added this answer to summarize the many useful comments to @frankhermes's answer. Unfortunately, I could not add them to his answer because the "edit queue is full".


The Publish Over FTP Jenkins plugin has Pipeline support as of version 1.15.

To create a pipeline, you can use the Jenkins snippet generator. To do so

  1. go into your Pipeline project
  2. in the menu on the left, click on Pipeline syntax
  3. select ftpPublisher: send build artifacts over FTP from the dropdown list
  4. configure all details as in a classic Jenkins job
  5. press Generate Pipeline Script

This generates the pipeline code for you.

However, I experienced errors when using this code because of missing parameters. I had to add masterNodeName: '' and paramPublish: [parameterName:""] as additional top level parameters.

The pipeline syntax of the plugin is documented at https://www.jenkins.io/doc/pipeline/steps/publish-over-ftp/

Here's a full example of what worked here using version 1.16 of the plugin to upload build artifacts (jar files):

          steps {
            ftpPublisher alwaysPublishFromMaster: false, 
                    masterNodeName: '',
                    paramPublish: [ parameterName: "" ],
                    continueOnError: false, 
                    failOnError: false, 
                    publishers: 
                    [ [
                        configName: 'download.dev.localnet (Local Download Server)', 
                        transfers: 
                        [
                            [
                                asciiMode: false, 
                                cleanRemote: false, 
                                excludes: '**/*-tests.jar, **/*-javadoc.jar, **/*.lite*, **/*.common*', 
                                flatten: true, 
                                makeEmptyDirs: false, 
                                noDefaultExcludes: false, 
                                patternSeparator: '[, ]+', 
                                remoteDirectory: '/utilities/project/snapshots', 
                                remoteDirectorySDF: false, 
                                removePrefix: '', 
                                sourceFiles: '**/target/*-SNAPSHOT.jar'
                             ] 
                     ], 
                     usePromotionTimestamp: false, 
                     useWorkspaceInPromotion: false, 
                     verbose: true
                 ] ]      
            }       

Another useful note from @MarcRunkel's answer:

Set up the External Host in the main Jenkins configuration page under Publish Over FTP and then make sure to use that exact name in the configName parameter.

not2savvy
  • 2,902
  • 3
  • 22
  • 37