212
Vote

Project Build support in codeplex

description

o Ability to perform periodical builds on the project branches and send status mails to the project members about build health
o Ability to plug-in automated tests into the build process
o Code review support like sending an email, providing/receiving feedback and tracking that feedback online would a very nice to have
o Send check-in mails with information like bugs resolved, files involved, review feedback link, description etc. to all contributors

comments

Pon_the_Pony wrote Oct 8, 2007 at 12:46 PM

This is an absolute must.It should also be able to create a release and add the output of the build to it.

MaciekN wrote Jan 16, 2008 at 3:58 PM

CruiseControl.NET will be great

codekaizen wrote Jun 2, 2008 at 6:16 PM

BTW, if you would like this functionality, you might also like the ability to display unit test / code coverage / other metrics for projects in a consistent manner. If so, take a look at this request: http://www.codeplex.com/CodePlex/WorkItem/View.aspx?WorkItemId=12734

fastbg wrote Mar 2, 2009 at 11:13 PM

This was first reported over 2 years ago and is in the top ten when ranked by votes. How many votes do we need to show we all want this? :) A codeplex hosted build/continuous integration server would be a huge addition to the site.

fkollmann wrote Jul 29, 2009 at 6:49 PM

But how is this going to work? Some of my projects require VSTS Database Edition and WiX3... I don't think there is a realistic way to realize this.

What I think might be a good thing is to be able to add external build agents to the TFS. Then you would be able to host your own build (virtual) machine and allow the TFS server to connect the build agent. This scenario shouldn't be a problem for the TFS since it already uses this concept.

Jothay wrote Nov 17, 2009 at 3:10 AM

fkollmann's suggestion is nice, but in the interim, for simple projects that don't need things like WiX3 and could easily be compiled with a simple C# (or whatever) compiler we could provide outputs for users that want to test the unreleased versions. So if our project releases 2.2.27 and there are 3 weeks work of code submissions after that, an end user could choose to download a pre-compiled copy of the new version 'at their own risk'. This prevents them from needing to download resources like Visual Studio Express editions. Let's face it, how many people really know what their doing when it comes to this stuff? Giving them something they can more easily access in case some bugs need to be worked out before a major release would be awesome.

erichexter wrote Apr 27, 2010 at 4:33 PM

Why dont you get JetBrains to donate some build tools to the community??? they did it for codebetter. It also supports TFS and Mercurial out of the box. This is a nice option since it supports the different build tools, msbuild, nant, psake.. ect

radioman wrote Jun 6, 2010 at 9:27 PM

would be great for 'hot builds'

SyntaxC4 wrote Jul 20, 2010 at 5:02 PM

I'd love to be able to do Gated Checkins

robert0muehsig wrote Nov 17, 2010 at 10:04 PM

It would be great if TFS Build would be supported. But that also means that I have an "Drop-Location" on the Codeplex Server. For debugging reasons it would be great if a the "build manage/build manager role" could have access to the build dir on the build agent as well.

LarsKemmann wrote Mar 1, 2011 at 3:04 PM

Regarding how to implement this, wouldn't providing a stock VM with Team Build agent be able to handle this? (Think customized Windows Azure VM role) Then just use a throttling/quota mechanism to regulate how much "build time" each project gets. Maybe use a tiered system based on project popularity - minor projects get one hour of build time a month, mid-level projects get four hours, and major projects get ten build hours per month.

Right now, this is the biggest reason that I might choose not to use CodePlex for a project.

victorz wrote Feb 28, 2012 at 10:58 PM

3 by votes!

radioman wrote Feb 17, 2013 at 3:09 PM

My custom CodeplexBuild server:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using Ionic.Zip;
using Service;
using System.Net;

namespace CodeplexBuild
{
   public class MainWindow
   {
      [STAThread]
      public static void Main()
      {
         try
         {
            ServicePointManager.MaxServicePointIdleTime = 0;
            ServicePointManager.ServerCertificateValidationCallback = delegate
            {
               return (true);
            };
         }
         catch(Exception ex)
         {
            Console.WriteLine(ex.ToString());
            Console.ReadLine();
            return;
         }

         Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Idle;
         DateTime today = DateTime.Today;
         while(true)
         {
            try
            {
               if(today.Date != DateTime.Today)
               {
                  today = DateTime.Today;
                  Console.Clear();
               }

               Console.WriteLine(DateTime.Now + ", starting...");

               string text = string.Empty;

               using(Process process = new Process())
               {
                  process.StartInfo.FileName = "cmd.exe";
                  process.StartInfo.UseShellExecute = false;
                  process.StartInfo.CreateNoWindow = true;
                  process.StartInfo.RedirectStandardInput = true;
                  process.StartInfo.RedirectStandardOutput = true;
                  process.Start();
                  process.PriorityClass = ProcessPriorityClass.Idle;

                  using(StreamWriter sw = process.StandardInput)
                  {
                     if(sw.BaseStream.CanWrite)
                     {
                        //del /q /s .\GMap.NET\Build\Release\*.*  
                        //hg --repository .\GMap.NET pull --update https://hg01.codeplex.com/greatmaps
                        //hg --repository .\GMap.NET tip

                        sw.WriteLine(@"del /q /s .\GMap.NET\Build\Release\*.*");
                        sw.WriteLine(@"hg --repository .\GMap.NET pull --update https://hg01.codeplex.com/greatmaps");
                        sw.WriteLine(@"hg --repository .\GMap.NET tip");
                     }

                     sw.Close();
                  }

                  text = process.StandardOutput.ReadToEnd();

                  process.WaitForExit();
                  process.Close();
               }

               Console.WriteLine(text);

               string[] source = text.Split(new string[]
                    {
                        Environment.NewLine
                    }, StringSplitOptions.RemoveEmptyEntries);

               string text2 = source.FirstOrDefault((string q) => q.StartsWith("changeset"));
               if(!string.IsNullOrEmpty(text2))
               {
                  string[] source2 = text2.Split(new char[]
                        {
                            '\n'
                        }, StringSplitOptions.RemoveEmptyEntries);

                  text2 = string.Empty + Environment.NewLine;
                  foreach(var ti in source2.Reverse())
                  {
                     text2 += ti + Environment.NewLine;
                  }

                  string text3 = source2.FirstOrDefault((string q) => q.StartsWith("changeset:"));
                  if(!string.IsNullOrEmpty(text3))
                  {
                     string text4 = text3.Split(new char[]
                            {
                                ':'
                            })[2];
                     if(text4.Length == "8bc8313b9099".Length)
                     {
                        string username = "xxx";
                        string password = "xxx";
                        ReleaseServiceSoapClient releaseServiceSoapClient = new ReleaseServiceSoapClient();
                        releaseServiceSoapClient.Open();
                        releaseServiceSoapClient.InnerChannel.OperationTimeout = TimeSpan.FromMinutes(5.0);
                        Release release = releaseServiceSoapClient.GetRelease("greatmaps", "Hot Build", username, password);
                        if(release.ChangesetId != text4)
                        {
                           Console.WriteLine("New change: " + text2);

                           string lastBuild = string.Empty;

                           using(Process process2 = new Process())
                           {
                              process2.StartInfo.FileName = @"Build All.bat";
                              process2.StartInfo.UseShellExecute = false;
                              process2.StartInfo.CreateNoWindow = true;
                              process2.StartInfo.RedirectStandardOutput = true;

                              var bef = Environment.CurrentDirectory;
                              try
                              {
                                 Environment.CurrentDirectory = @".\GMap.NET\Build\";

                                 process2.Start();
                                 process2.PriorityClass = ProcessPriorityClass.Idle;

                                 lastBuild = process2.StandardOutput.ReadToEnd();
                              }
                              finally
                              {
                                 Environment.CurrentDirectory = bef;
                              }

                              File.WriteAllText("lastBuild.txt", lastBuild);

                              process2.Close();
                           }

                           if(!string.IsNullOrEmpty(lastBuild) && !lastBuild.Contains("error"))
                           {
                              string text6 = "GMap.NET Build " + text4 + ".zip";

                              Console.WriteLine(text6);

                              try
                              {
                                 using(ZipFile zipFile = new ZipFile())
                                 {
                                    zipFile.AddDirectory(@".\GMap.NET\Build\Release-NETv4.0", ".\\NETv4.0");
                                    zipFile.AddDirectory(@".\GMap.NET\Build\Release-NETv3.5", ".\\NETv3.5");
                                    zipFile.AddDirectory(@".\GMap.NET\Build\Release-NETv2.0", ".\\NETv2.0");

                                    zipFile.AddFile(@".\GMap.NET\Info\License.txt", ".\\NETv4.0");
                                    zipFile.AddFile(@".\GMap.NET\Info\License.txt", ".\\NETv3.5");
                                    zipFile.AddFile(@".\GMap.NET\Info\License.txt", ".\\NETv2.0");

                                    if(File.Exists(text6))
                                    {
                                       File.Delete(text6);
                                    }
                                    zipFile.Save(text6);
                                 }

                                 //if(false)
                                 {
                                    List<ReleaseFile> list = new List<ReleaseFile>();
                                    list.Add(new ReleaseFile
                                    {
                                       Name = text6,
                                       MimeType = "application/octet-stream",
                                       FileName = text6,
                                       FileType = "RuntimeBinary",
                                       FileData = File.ReadAllBytes(text6)
                                    });

                                    var sizeMB = list[0].FileData.LongLength / 1024 / 1024;

                                    if(sizeMB > 4)
                                    {
                                       Console.WriteLine("UploadTheReleaseFiles...");
                                       releaseServiceSoapClient.UploadTheReleaseFiles("greatmaps", "Hot Build", list.ToArray(), text6, username, password);

                                       Console.WriteLine("UpdateRelease...");
                                       releaseServiceSoapClient.UpdateRelease("greatmaps", release.Id, "Hot Build", text2, DateTime.Now.ToString(), "Beta", true, false, text4, username, password);
                                    }
                                    else
                                    {
                                       Console.WriteLine("Too small zip file: " + sizeMB + "MB");
                                    }
                                 }
                              }
                              finally
                              {
                                 if(File.Exists(text6))
                                 {
                                    File.Delete(text6);
                                 }
                              }
                           }
                           else
                           {
                              Console.WriteLine("Build error in " + text4);
                           }
                        }
                        else
                        {
                           Console.WriteLine("No changes yet...");
                           Console.WriteLine("Old changeset: " + text2);
                        }
                        releaseServiceSoapClient.Close();
                     }
                  }
                  Console.WriteLine("--------------------------");
               }
            }
            catch(Exception ex)
            {
               Console.WriteLine(ex.Message);
            }
            Thread.Sleep(TimeSpan.FromHours(4.0));
         }
      }
   }
}