How to create a task in c# cake build to upload file with FTP?
Asked Answered
C

2

5

I noticed that cake support HTTP Operations, but no FTP Operations, do you know how to create a task to upload file via FTP?

Chafer answered 20/9, 2016 at 14:56 Comment(0)
T
12

There's nothing build in Cake today that provided functionality to transfer files using the FTP protocol.

Though if you're running Cake on "Full CLR" you can use the .NET framework built in FtpWebRequest to upload a file. The FtpWebRequest has not been ported to .NET Core so if you're running Cake.CoreCLR.

One way you could do this by creating an ftp.cake with a static FTPUpload utility method that you can reuse from your build.cake file.

Example ftp.cake

public static bool FTPUpload(
    ICakeContext context,
    string ftpUri,
    string user,
    string password,
    FilePath filePath,
    out string uploadResponseStatus
    )
{
    if (context==null)
    {
        throw new ArgumentNullException("context");
    }

    if (string.IsNullOrEmpty(ftpUri))
    {
        throw new ArgumentNullException("ftpUri");
    }

    if (string.IsNullOrEmpty(user))
    {
        throw new ArgumentNullException("user");
    }

    if (string.IsNullOrEmpty(password))
    {
        throw new ArgumentNullException("password");
    }

    if (filePath==null)
    {
        throw new ArgumentNullException("filePath");
    }

    if (!context.FileSystem.Exist(filePath))
    {
        throw new System.IO.FileNotFoundException("Source file not found.", filePath.FullPath);
    }

    uploadResponseStatus = null;
    var ftpFullPath = string.Format(
        "{0}/{1}",
        ftpUri.TrimEnd('/'),
        filePath.GetFilename()
        );
    var ftpUpload = System.Net.WebRequest.Create(ftpFullPath) as System.Net.FtpWebRequest;

    if (ftpUpload == null)
    {
        uploadResponseStatus = "Failed to create web request";
        return false;
    }

    ftpUpload.Credentials = new System.Net.NetworkCredential(user, password);
    ftpUpload.KeepAlive = false;
    ftpUpload.UseBinary = true;
    ftpUpload.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
    using (System.IO.Stream
        sourceStream = context.FileSystem.GetFile(filePath).OpenRead(),
        uploadStream = ftpUpload.GetRequestStream())
    {
        sourceStream.CopyTo(uploadStream);
        uploadStream.Close();
    }

    var uploadResponse = (System.Net.FtpWebResponse)ftpUpload.GetResponse();
    uploadResponseStatus = (uploadResponse.StatusDescription ?? string.Empty).Trim().ToUpper();
    uploadResponse.Close();
    return  uploadResponseStatus.Contains("TRANSFER COMPLETE") ||
                     uploadResponseStatus.Contains("FILE RECEIVE OK");
}

Example usage build.cake

#load "ftp.cake"

string ftpPath = "ftp://ftp.server.com/test";
string ftpUser = "john";
string ftpPassword = "top!secret";
FilePath sourceFile = File("./data.zip");


Information("Uploading to upload {0} to {1}...", sourceFile, ftpPath);
string uploadResponseStatus;
if (!FTPUpload(
        Context,
        ftpPath,
        ftpUser,
        ftpPassword,
        sourceFile,
        out uploadResponseStatus
    ))
{
    throw new Exception(string.Format(
        "Failed to upload {0} to {1} ({2})",
        sourceFile,
        ftpPath,
        uploadResponseStatus));
}

Information("Successfully uploaded file ({0})", uploadResponseStatus);

Example output

Uploading to upload log.cake to ftp://ftp.server.com/test...
Successfully uploaded file (226 TRANSFER COMPLETE.)

FtpWebRequest is very basic so you might need to adapt it to you're target ftp server, but above should be a good starting point.

Townsend answered 21/9, 2016 at 15:3 Comment(1)
@Chafer was this what you were looking for?Townsend
L
5

Although I haven't tried it myself, I "think" I am right in saying that you can do file transfer operations using this Cake Addin. Definitely worth speaking to the original author of the addin about.

If not, your best best would be to create a custom addin for Cake, that provides the abilities that you are looking for.

There is a question over whether this should make it into the Core set of Cake functionality as well, however, the first course of action would be an addin.

Lisabethlisan answered 20/9, 2016 at 15:10 Comment(5)
Putty supports SCP/SFTP protocols but not FTP.Townsend
Surely SFTP would be preferred over FTP :-)Lisabethlisan
Agree, not always an option to change the server ;)Townsend
For other people interested in this plugin, what bothers me is that putty must be installed on the machine, and available in the PATH. When you're shipping a build script, imo it should be already ready to run. No install or configuration necessary on EACH machine that wants to run the scriptLucifer
Tool resolution is built into Cake, however, there are some tools that require additional steps. One of those steps could be to download/install putty, and therefore the script could still be self-contained.Lisabethlisan

© 2022 - 2024 — McMap. All rights reserved.