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)); }
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); }
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)); }
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); }
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(); }); }
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; } }
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"; }
public static void SetBuildStarted( Build build, DateTimeOffset started) { using (var ravenSession = OpenRavenSession()) { build.Started = started; ravenSession.Store(build); ravenSession.SaveChanges(); } }
public static bool FetchRepository( Build build, string repositoryDirectory, Action<string> log) { return FetchRepository( build, repositoryDirectory, log, CreateProcess, CreateFetchRefspec, RunProcess); }
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(); } }
public static void AppendBuildOutput( Build build, string output) { using (var ravenSession = OpenRavenSession()) { lock (semaphore) { build.Ouput += output + Environment.NewLine; ravenSession.Store(build); ravenSession.SaveChanges(); } } }
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"); }
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); }
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)); }
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); }
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); }
public static string GetBuildDescription(Build build) { return(GetBuildDescription(build, false)); }
public static string GetBuildDescription(Build build) { return GetBuildDescription(build, false); }
public static string GetRepositoryDirectory(Build build) { var repositoryDirectory = Path.Combine(GetRepositoryOwnerDirectory(build), build.RepositoryName); return(repositoryDirectory); }
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; }
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); }
public static string GetBuildDescription(Build build, bool includeRefDescription) { return(GetBuildDescription(build, includeRefDescription, DateTimeOffset.UtcNow)); }
public static string GetRepositoryDirectory(Build build) { var repositoryDirectory = Path.Combine(GetRepositoryOwnerDirectory(build), build.RepositoryName); return repositoryDirectory; }