Example #1
1
        internal static void SetGitHubBuildStatus(
            Build build,
            CommitState state,
            Func<string, string, BuildConfiguration> getBuildConfiguration,
            Func<Build, string> getBuildDescription,
            Func<string> getHost,
            Action<string, string, string, string, CommitState, Uri, string> createGitHubCommitStatus)
        {
            var buildConfiguration = getBuildConfiguration(
                build.RepositoryOwner,
                build.RepositoryName);

            if (buildConfiguration == null)
                throw new Exception("Could not find build configuration.");

            var targetUrl = new Uri(String.Format(
                "http://{0}/{1}/{2}/builds/{3}",
                getHost(),
                build.RepositoryOwner,
                build.RepositoryName,
                build.Id));

            createGitHubCommitStatus(
                buildConfiguration.Token,
                build.RepositoryOwner,
                build.RepositoryName,
                build.Revision,
                state,
                targetUrl,
                getBuildDescription(build));
        }
Example #2
0
        public static bool CloneRepository(
            BuildConfiguration buildConfiguration,
            Build build,
            string repositoryOwnerDirectory,
            string repositoryDirectory,
            Action<string> log)
        {
            log("STEP: Cloning repository.");

            Func<bool> step = () =>
            {
                log("Checking whether repository has already been cloned.");

                if (Directory.Exists(repositoryDirectory))
                {
                    log(String.Format("{0} already exists. Skipping clone.", repositoryDirectory));
                    return true;
                }

                var url = GetRepositoryUrl(buildConfiguration.Owner, buildConfiguration.Name, buildConfiguration.Token);

                using (var process = CreateProcess(
                    command: "git.exe",
                    arguments: String.Format("clone --recursive {0} {1}", url, repositoryDirectory),
                    workingDirectory: repositoryOwnerDirectory))
                {
                    return RunProcess(process, log) == 0;
                }
            };

            return RunStep(step, log);
        }
Example #3
0
        internal static string GetBuildDescription(Build build, bool includeRefDescription, DateTimeOffset now)
        {
            if (build == null) throw new ArgumentNullException("build");

            var @ref = "";
            if (includeRefDescription)
                @ref = String.Concat(" on ", GetRefDescription(build));

            if (!build.Started.HasValue)
            {
                if (!build.Queued.HasValue)
                    return String.Format("Build #{0}{1} queued.", build.Id, @ref);

                return String.Format("Build #{0}{1} queued {2} seconds ago.", build.Id, @ref, build.Queued.Value.Since(now));
            }

            if (!build.Finished.HasValue)
                return String.Format("Build #{0}{1} started {2} seconds ago.", build.Id, @ref, build.Started.Value.Since(now));

            if (!build.Succeeded.HasValue)
                return String.Format("Build #{0}{1} finished in {2} seconds.", build.Id, @ref, build.Started.Value.Until(build.Finished.Value));

            if (build.Succeeded.Value)
                return String.Format("Build #{0}{1} succeeded in {2} seconds.", build.Id, @ref, build.Started.Value.Until(build.Finished.Value));

            return String.Format("Build #{0}{1} failed in {2} seconds.", build.Id, @ref, build.Started.Value.Until(build.Finished.Value));
        }
Example #4
0
        public static bool SetGitHubBuildFinished(
            BuildConfiguration buildConfiguration,
            Build build,
            bool succeeded,
            Action<string> logBuildMessage)
        {
            var state = succeeded
                ? CommitState.Success
                : CommitState.Failure;

            var stateName = Enum.GetName(typeof(CommitState), state);

            logBuildMessage(String.Format("STEP: Updating GitHub build status to {0}.", stateName));

            return RunStep(() =>
            {
                if (buildConfiguration.Token == null)
                {
                    logBuildMessage("The build configuration has no token; skipping.");
                    return true;
                }

                if (build.Revision == null)
                {
                    logBuildMessage("The build has no SHA; skipping.");
                    return true;
                }

                SetGitHubBuildStatus(build, state);
                return true;
            }, logBuildMessage);
        }
Example #5
0
        public static void SetGitHubBuildStatus(
            Build build,
            CommitState state)
        {
            SetGitHubBuildStatus(
                build,
                state,
                GetBuildConfiguration,
                GetBuildDescription,
                GetHost,
                (token, owner, name, sha, commitState, targetUrl, description) =>
                {
                    var gitHubClient = GetGitHubClient();
                    gitHubClient.Credentials = new Credentials(token);

                    gitHubClient.Repository.CommitStatus.Create(
                        owner,
                        name,
                        sha,
                        new NewCommitStatus
                        {
                            State = commitState,
                            TargetUrl = targetUrl,
                            Description = description
                        }).Wait();
                });
        }
Example #6
0
        public static Build CreateBuild(
            string command,
            string commandArguments,
            string repositoryName,
            string repositoryOwner,
            string @ref,
            string revision,
            string eventType,
            string @event)
        {
            // TODO: validate args

            using (var ravenSession = OpenRavenSession())
            {
                var build = new Build
                {
                    Queued = DateTimeOffset.UtcNow,
                    Command = command,
                    CommandArguments = commandArguments,
                    RepositoryName = repositoryName,
                    RepositoryOwner = repositoryOwner,
                    Ref = @ref,
                    Revision = revision,
                    EventType = eventType,
                    Event = @event
                };

                ravenSession.Store(build);
                ravenSession.SaveChanges();

                return build;
            }
        }
Example #7
0
 static string GetBuildStatus(Build build)
 {
     if (build.Started == null)
         return "queued";
     if (build.Finished == null)
         return "building";
     if (build.Succeeded.HasValue && build.Succeeded.Value)
         return "succeeded";
     return "failed";
 }
Example #8
0
        public static void SetBuildStarted(
            Build build,
            DateTimeOffset started)
        {
            using (var ravenSession = OpenRavenSession())
            {
                build.Started = started;

                ravenSession.Store(build);
                ravenSession.SaveChanges();
            }
        }
Example #9
0
 public static bool FetchRepository(
     Build build,
     string repositoryDirectory,
     Action<string> log)
 {
     return FetchRepository(
         build,
         repositoryDirectory,
         log,
         CreateProcess,
         CreateFetchRefspec,
         RunProcess);
 }
Example #10
0
        public static void SetBuildFinished(
            Build build,
            bool succeeded,
            DateTimeOffset finished)
        {
            using (var ravenSession = OpenRavenSession())
            {
                build.Succeeded = succeeded;
                build.Finished = finished;

                ravenSession.Store(build);
                ravenSession.SaveChanges();
            }
        }
Example #11
0
        public static void AppendBuildOutput(
            Build build,
            string output)
        {
            using (var ravenSession = OpenRavenSession())
            {
                lock (semaphore)
                {
                    build.Ouput += output + Environment.NewLine;

                    ravenSession.Store(build);
                    ravenSession.SaveChanges();
                }
            }
        }
Example #12
0
        public static string GetRefDescription(Build build)
        {
            if (build.Ref.StartsWith("refs/heads/", StringComparison.OrdinalIgnoreCase))
            {
                var branch = build.Ref.Substring(11);
                return String.Concat(build.RepositoryName, "/", branch);
            }

            if (build.Ref.StartsWith("refs/pull/", StringComparison.OrdinalIgnoreCase))
            {
                var slashafterPrNumberIndex = build.Ref.IndexOf("/", 10, StringComparison.InvariantCultureIgnoreCase);
                var prNumber = build.Ref.Substring(10, slashafterPrNumberIndex - 10);
                return String.Concat(build.RepositoryName, " pull request #", prNumber);
            }

            throw new ArgumentException(String.Format("Unexpected type of ref: {0}.", build.Ref), "build");
        }
Example #13
0
        public static bool SetGitHubBuildStarted(
            BuildConfiguration buildConfiguration,
            Build build,
            Action<string> logBuildMessage)
        {
            logBuildMessage("STEP: Setting GitHub build status to Pending.");

            return RunStep(() =>
            {
                if (buildConfiguration.Token == null)
                {
                    logBuildMessage("The build configuration has no token; skipping.");
                    return true;
                }

                SetGitHubBuildStatus(build, CommitState.Pending);
                return true;
            }, logBuildMessage);
        }
Example #14
0
        public static bool ResetRepository(
            Build build,
            string repositoryDirectory,
            Action<string> log)
        {
            log("STEP: Reseting repository.");

            Func<bool> step = () =>
            {
                using (var process = CreateProcess(
                    "git.exe",
                    String.Concat("reset --hard ", build.Revision), repositoryDirectory))
                {
                    return RunProcess(process, log) == 0;
                }
            };

            return RunStep(step, log);
        }
        internal static string GetGitHubBuildStatusDescription(Build build)
        {
            if (build == null) throw new ArgumentNullException("build");

            var now = DateTimeOffset.UtcNow;

            if (!build.Started.HasValue)
                return String.Format("Build #{0} queued.", build.Id);

            if (!build.Finished.HasValue)
                return String.Format("Build #{0} started.", build.Id);

            if (!build.Succeeded.HasValue)
                return String.Format("Build #{0} finished in {1} seconds.", build.Id, build.Started.Value.Until(build.Finished.Value));

            if (build.Succeeded.Value)
                return String.Format("Build #{0} succeeded in {1} seconds.", build.Id, build.Started.Value.Until(build.Finished.Value));

            return String.Format("Build #{0} failed in {1} seconds.", build.Id, build.Started.Value.Until(build.Finished.Value));
        }
Example #16
0
        public static bool RunBuild(
            Build build, 
            string repositoryDirectory,
            Action<string> log)
        {
            log("STEP: Running build command.");

            Func<bool> step = () =>
            {
                using (var process = CreateProcess(
                    build.Command,
                    build.CommandArguments,
                    repositoryDirectory))
                {
                    return RunProcess(process, log) == 0;
                }
            };

            return RunStep(step, log);
        }
Example #17
0
        internal static bool FetchRepository(
            Build build,
            string repositoryDirectory,
            Action<string> log,
            Func<string, string, string, Process> createProcess,
            Func<string, string> createFetchRefspec,
            Func<Process, Action<string>, int> runProcess)
        {
            log("STEP: Fetching repository.");

            Func<bool> step = () =>
            {
                using (var process = createProcess(
                    "git.exe",
                    String.Concat("fetch origin ", createFetchRefspec(build.Ref)), repositoryDirectory))
                {
                    return runProcess(process, log) == 0;
                }
            };

            return RunStep(step, log);
        }
Example #18
0
 public static string GetBuildDescription(Build build)
 {
     return(GetBuildDescription(build, false));
 }
Example #19
0
 public static string GetBuildDescription(Build build)
 {
     return GetBuildDescription(build, false);
 }
Example #20
0
        public static string GetRepositoryDirectory(Build build)
        {
            var repositoryDirectory = Path.Combine(GetRepositoryOwnerDirectory(build), build.RepositoryName);

            return(repositoryDirectory);
        }
Example #21
0
 public static string GetBuildDescription(Build build, bool includeRefDescription)
 {
     return GetBuildDescription(build, includeRefDescription, DateTimeOffset.UtcNow);
 }
 public static string GetRepositoryOwnerDirectory(Build build)
 {
     var repositoryOwnerDirectory = Path.Combine(GetRepositoriesDirectory(), build.RepositoryOwner);
     EnsureDirectoryExists(repositoryOwnerDirectory);
     return repositoryOwnerDirectory;
 }
Example #23
0
        public static bool GetHeadSha(
            Build build,
            string repositoryDirectory,
            Action<string> log)
        {
            if (build == null) throw new ArgumentNullException("build");
            if (String.IsNullOrEmpty(repositoryDirectory)) throw new ArgumentNullException("repositoryDirectory");
            if (log == null) throw new ArgumentNullException("log");

            log("STEP: Getting HEAD's SHA.");

            return RunStep(() =>
            {
                if (!string.IsNullOrEmpty(build.Revision))
                {
                    log(String.Format("Build #{0} already has a SHA. Skipping.", build.Id));
                    return true;
                }

                var repo = (LibGit2Sharp.Repository)null;
                try
                {
                    repo = new LibGit2Sharp.Repository(repositoryDirectory);
                }
                catch (Exception ex)
                {
                    log(String.Format("ERROR: Could not get repository at {0} via LibGit2Sharp. Exception: ", repositoryDirectory));
                    log(ex.ToString());
                    return false;
                }

                var head = (LibGit2Sharp.Reference)null;
                try
                {
                    string @ref;
                    if (build.Ref.StartsWith("refs/heads/", StringComparison.OrdinalIgnoreCase))
                    {
                        var branch = build.Ref.Substring(11);
                        @ref = String.Format("refs/remotes/origin/{0}", branch);
                    }

                    else if (build.Ref.StartsWith("refs/pull", StringComparison.OrdinalIgnoreCase))
                    {
                        var slashafterPrNumberIndex = build.Ref.IndexOf("/", 10, StringComparison.InvariantCultureIgnoreCase);
                        var prNumber = build.Ref.Substring(10, slashafterPrNumberIndex - 10);
                        @ref = String.Concat("refs/remotes/origin/pr/", prNumber);
                    }
                    else
                    {
                        throw new InvalidOperationException(String.Format("Unexpected type of ref: {0}.", build.Ref));
                    }

                    head = repo.Refs[@ref];

                    if (head == null)
                        throw new InvalidOperationException(String.Format("The specified ref, '{0}', does not exist.", @ref));
                }
                catch (Exception ex)
                {
                    log(String.Format("ERROR: Could not get HEAD for ref {0}. Exception: ", build.Ref));
                    log(ex.ToString());
                    return false;
                }

                log(String.Format("Setting SHA to {0}.", head.TargetIdentifier));
                SetBuildRevision(build, head.TargetIdentifier);

                return true;

            }, log);
        }
Example #24
0
 public static string GetBuildDescription(Build build, bool includeRefDescription)
 {
     return(GetBuildDescription(build, includeRefDescription, DateTimeOffset.UtcNow));
 }
Example #25
0
 public static string GetRepositoryDirectory(Build build)
 {
     var repositoryDirectory = Path.Combine(GetRepositoryOwnerDirectory(build), build.RepositoryName);
     return repositoryDirectory;
 }