/// <summary> /// Download the file. If there, return it. /// </summary> /// <param name="info"></param> /// <returns></returns> private async static Task <FileInfo> DownloadFile(TCInfo info) { var outFile = new FileInfo(string.Format(@"{0}{1}-{2}-{3}", Path.GetTempPath(), info.buildName, info.buildID, Path.GetFileName(info.path))); if (outFile.Exists) { return(outFile); } var req = CreateRequest(info, string.Format("builds/id:{0}/artifacts/files/{1}", info.buildID, info.path), "GET"); ((HttpWebRequest)req).Accept = "application/octet-stream"; using (var res = await req.GetResponseAsync()) using (var readStream = res.GetResponseStream()) { using (var writer = outFile.Create()) { await readStream.CopyToAsync(writer); writer.Close(); } } outFile.Refresh(); return(outFile); }
/// <summary> /// Create a URL request to send to TeamCity. /// </summary> /// <param name="what"></param> /// <param name="method"></param> /// <param name="args"></param> /// <returns></returns> private static WebRequest CreateRequest(TCInfo info, string what, string method, params Tuple <string, string>[] args) { var urlbase = string.Format("{0}/httpAuth/app/rest/{1}/", info.urlBase, what); if (args.Length > 0) { char addon = '?'; foreach (var arg in args) { urlbase = string.Format("{0}{1}{2}={3}", urlbase, addon, arg.Item1, arg.Item2); addon = '&'; } } var req = WebRequest.Create(urlbase); req.Method = method; // Credentials if (info.cred == null) { Credential cred; if (!NativeMethods.CredRead(info.MachineName, CRED_TYPE.GENERIC, 0, out cred)) { Console.WriteLine("Error getting credentials"); Console.WriteLine(string.Format("Use the credential control panel, create a generic credential for windows domains for {0} with user name and password", info.MachineName)); throw new InvalidOperationException(); } string password; using (var m = new MemoryStream(cred.CredentialBlob, false)) using (var sr = new StreamReader(m, System.Text.Encoding.Unicode)) { password = sr.ReadToEnd(); } info.cred = new NetworkCredential(cred.UserName, password); } req.Credentials = info.cred; req.ContentType = "application/json"; ((HttpWebRequest)req).Accept = "application/json"; return(req); }
/// <summary> /// Scan the TC server for the most recent build for this file. /// </summary> /// <param name="info"></param> /// <returns></returns> private async static Task <string> FetchLaestBuildID(TCInfo info) { var req = CreateRequest(info, "builds", "GET", Tuple.Create("locator", string.Format("buildType:{0}", info.buildName))); using (var res = await req.GetResponseAsync()) using (var reader = new StreamReader(res.GetResponseStream())) { var r = JsonConvert.DeserializeObject(await reader.ReadToEndAsync()) as JContainer; if ((int)r["count"] == 0) { throw new InvalidOperationException("No builds!"); } var maxBuildNumber = (from b in (JArray)r["build"] where (string)b["number"] != "N/A" orderby(int) b["number"] descending select b["id"]).First(); return((string)maxBuildNumber); } }