Ejemplo n.º 1
0
        static Build GetBuildFromDBItems(DBWork work, DBRevisionWork revisionWork)
        {
            DBRevision revision;
            DBLane     lane, parentLane;
            DBHost     host;

            using (DB db = new DB()) {
                revision   = DBRevision_Extensions.Create(db, revisionWork.revision_id);
                lane       = DBLane_Extensions.Create(db, revisionWork.lane_id);
                parentLane = GetTopMostParent(lane, db);
                host       = DBHost_Extensions.Create(db, revisionWork.host_id);
            }

            var url = Configuration.GetWebSiteUrl();

            url += string.Format("/ViewLane.aspx?lane_id={0}&host_id={1}&revision_id={2}", lane.id, host.id, revision.id);

            return(new Build {
                Commit = revision.revision,
                CommitId = revision.id,
                Date = revisionWork.completed ? revisionWork.endtime : revision.date,
                Lane = lane.lane,
                Project = parentLane.lane,
                State = revisionWork.State,
                Author = revision.author,
                BuildBot = host.host,
                Url = url
            });
        }
Ejemplo n.º 2
0
        private void DownloadRevisionLog(int revision_id, bool diff /* diff or log */)
        {
            DBRevision revision;
            DBLane     lane;

            using (DB db = new DB()) {
                WebServiceLogin login = Authentication.CreateLogin(Request);

                revision = DBRevision_Extensions.Create(db, revision_id);

                // no access restricion on revision logs/diffs
                Authentication.VerifyAnonymousAccess(Context, db, login);

                Response.ContentType = MimeTypes.TXT;

                if (revision == null)
                {
                    Response.Write("Revision not found.");
                }
                else
                {
                    lane = DBLane_Extensions.Create(db, revision.lane_id);
                    using (Process git = new Process()) {
                        git.StartInfo.RedirectStandardOutput = true;
                        git.StartInfo.RedirectStandardError  = true;
                        git.StartInfo.UseShellExecute        = false;
                        git.StartInfo.FileName = "git";
                        if (diff)
                        {
                            git.StartInfo.Arguments = "diff --no-color --no-prefix " + revision.revision + "~ " + revision.revision;
                        }
                        else
                        {
                            git.StartInfo.Arguments = "log -1 --no-color --no-prefix " + revision.revision;
                        }
                        git.StartInfo.WorkingDirectory = Configuration.GetSchedulerRepositoryCacheDirectory(lane.repository);
                        git.OutputDataReceived        += (object sender, DataReceivedEventArgs ea) =>
                        {
                            Response.Write(ea.Data);
                            Response.Write('\n');
                        };
                        git.ErrorDataReceived += (object sender, DataReceivedEventArgs ea) =>
                        {
                            Response.Write(ea.Data);
                            Response.Write('\n');
                        };
                        // Logger.Log ("Executing: '{0} {1}' in {2}", git.StartInfo.FileName, git.StartInfo.Arguments, git.StartInfo.WorkingDirectory);
                        git.Start();
                        git.BeginErrorReadLine();
                        git.BeginOutputReadLine();
                        if (!git.WaitForExit(1000 * 60 * 5 /* 5 minutes */))
                        {
                            git.Kill();
                            Response.Write("Error: git diff didn't finish in 5 minutes, aborting.\n");
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        static DBLane GetTopMostParent(DBLane forLane, DB db)
        {
            var parent = forLane;

            while (parent.parent_lane_id != null)
            {
                parent = DBLane_Extensions.Create(db, parent.parent_lane_id.Value);
            }
            return(parent);
        }
Ejemplo n.º 4
0
        public virtual void Notify(DBWork work, DBRevisionWork revision_work)
        {
            List <DBPerson> people = new List <DBPerson> ();
            DBRevision      revision;
            DBLane          lane;
            DBHost          host;
            string          message;
            bool            nonfatal;

            log.DebugFormat("NotificationBase.Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0})", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);

            nonfatal = false;

            if (!Evaluate(work, revision_work, out nonfatal))
            {
                log.DebugFormat("NotificationBase.Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) = evaluation returned false", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                return;
            }

            if (nonfatal)
            {
                message = "Test failure";
            }
            else
            {
                message = "{red}{bold}Build failure{default}";
            }

            using (DB db = new DB()) {
                revision = DBRevision_Extensions.Create(db, revision_work.revision_id);
                lane     = DBLane_Extensions.Create(db, revision_work.lane_id);
                host     = DBHost_Extensions.Create(db, revision_work.host_id);
            }

            message = string.Format("{0} in revision {1} on {2}/{3}: {4}/ViewLane.aspx?lane_id={5}&host_id={6}&revision_id={7}",
                                    message,
                                    (revision.revision.Length > 8 ? revision.revision.Substring(0, 8) : revision.revision),
                                    lane.lane, host.host, Configuration.GetWebSiteUrl(), lane.id, host.id, revision.id);

            MonkeyWrench.Scheduler.Scheduler.FindPeopleForCommit(lane, revision, people);
            people = FindPeople(people);

            Notify(work, revision_work, people, message);
        }
Ejemplo n.º 5
0
        protected override void Notify(DBWork work, DBRevisionWork revision_work, List <DBPerson> people, string message)
        {
            if (!this.emails.Any())
            {
                log.DebugFormat("Notify no emails");
                return;
            }

            if (this.emails.Any(x => !x.EndsWith("@hipchat.xamarin.com", StringComparison.OrdinalIgnoreCase)))
            {
                log.Warn("EmailNotification.Notify skipping non-HipChat emails because we don't know how to send email!");
                return;
            }

            var actionableEmails = this.emails.Where(x => x.EndsWith("@hipchat.xamarin.com")).ToList();

            if (!actionableEmails.Any())
            {
                log.Debug("Notify no actionable emails!");
                return;
            }

            log.DebugFormat("Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) enabled: {4}, {5} people", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id, true, people.Count);

            bool nonfatal = false;

            if (!Evaluate(work, revision_work, out nonfatal))
            {
                log.DebugFormat("Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) = evaluation returned false", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                return;
            }

            if (nonfatal)
            {
                message = "Test failure";
            }
            else
            {
                message = "Build failure";
            }

            DBRevision revision;
            DBLane     lane;
            DBHost     host;

            using (DB db = new DB()) {
                revision = DBRevision_Extensions.Create(db, revision_work.revision_id);
                lane     = DBLane_Extensions.Create(db, revision_work.lane_id);
                host     = DBHost_Extensions.Create(db, revision_work.host_id);
            }

            message = string.Format("{0} in revision {1} on {2}/{3} ({4}/ViewLane.aspx?lane_id={5}&host_id={6}&revision_id={7})",
                                    message,
                                    (revision.revision.Length > 8 ? revision.revision.Substring(0, 8) : revision.revision),
                                    lane.lane, host.host, Configuration.GetWebSiteUrl(), lane.id, host.id, revision.id);

            foreach (var person in people)
            {
                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    using (var db = new DB()) {
                        var computed_nicks = new List <string> ();
                        var email_lists    = new List <IEnumerable <string> > ();
                        email_lists.Add(person.GetEmails(db));
                        if (person.Emails != null)
                        {
                            email_lists.Add(person.Emails);
                        }

                        foreach (var emails in email_lists)
                        {
                            foreach (var email in emails)
                            {
                                var at = email.IndexOf('@');
                                if (at > 0)
                                {
                                    computed_nicks.Add(email.Substring(0, at));
                                }
                            }
                        }
                        if (computed_nicks.Count == 0 && !string.IsNullOrEmpty(person.fullname))
                        {
                            computed_nicks.Add(person.fullname);
                        }
                        person.irc_nicknames = string.Join(",", computed_nicks.ToArray());
                    }
                }

                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    log.DebugFormat("could not find somebody to notify for revision with id {0} on lane {1}", revision_work.revision_id, revision_work.lane_id);
                    continue;
                }
            }

            var          apiToken = identity.password;
            var          rooms    = actionableEmails.Select(email => email.Split('@') [0]).ToList();
            const string finalApi = "https://hipchat.xamarin.com/v1/rooms/message";

            var webClient = new WebClient();

            foreach (var r in rooms)
            {
                string prefix;
                string room = r;
                if (room.StartsWith("*"))
                {
                    room   = room.Substring(1);
                    prefix = "";
                }
                else
                {
                    prefix = "@";
                }

                var prefixNames  = string.Join(", ", people.SelectMany(x => x.irc_nicknames.Split(',')).Distinct().Select(x => string.Format("{1}{0}", x, prefix)));
                var finalMessage = prefixNames + ": " + message;

                if (cache [room + "|" + finalMessage] != null)
                {
                    continue;
                }
                cache.Add(room + "|" + finalMessage, string.Empty, new DateTimeOffset(DateTime.UtcNow.AddHours(1), TimeSpan.Zero));

                var postData = new NameValueCollection();
                postData.Add("auth_token", apiToken);
                postData.Add("room_id", room);
                postData.Add("from", "Wrench");
                postData.Add("message", finalMessage);
                postData.Add("notify", nonfatal ? "0" : "1");
                // TODO: Maybe send HTML eventually, though HTML doesn't allow @-mentions. :(
                postData.Add("message_format", "text");
                postData.Add("color", nonfatal ? "yellow" : "red");
                postData.Add("format", "json");
                var res       = webClient.UploadValues(finalApi, postData);
                var resString = Encoding.UTF8.GetString(res);

                log.DebugFormat("response from server: {0}", resString);
            }
        }
Ejemplo n.º 6
0
        public DBLane CloneLane(int lane_id, string new_name, bool copy_files)
        {
            DBLane result = null;
            DBLane master = DBLane_Extensions.Create(this, lane_id);

            if (this.LookupLane(new_name, false) != null)
            {
                throw new Exception(string.Format("The lane '{0}' already exists.", new_name));
            }

            try {
                using (IDbTransaction transaction = BeginTransaction()) {
                    result                  = new DBLane();
                    result.lane             = new_name;
                    result.max_revision     = master.max_revision;
                    result.min_revision     = master.min_revision;
                    result.repository       = master.repository;
                    result.source_control   = master.source_control;
                    result.parent_lane_id   = master.parent_lane_id;
                    result.additional_roles = master.additional_roles;
                    result.enabled          = master.enabled;
                    result.Save(this);

                    foreach (DBLanefile filemaster in master.GetFiles(this, null))
                    {
                        int fid;

                        if (copy_files)
                        {
                            DBLanefile clone = new DBLanefile();
                            clone.contents         = filemaster.contents;
                            clone.mime             = filemaster.mime;
                            clone.name             = filemaster.name;
                            clone.additional_roles = filemaster.additional_roles;
                            clone.Save(this);
                            fid = clone.id;
                        }
                        else
                        {
                            fid = filemaster.id;
                        }

                        DBLanefiles lane_files = new DBLanefiles();
                        lane_files.lane_id     = result.id;
                        lane_files.lanefile_id = fid;
                        lane_files.Save(this);
                    }

                    foreach (DBCommand cmdmaster in GetCommands(master.id))
                    {
                        DBCommand clone = new DBCommand();
                        clone.lane_id           = result.id;
                        clone.alwaysexecute     = cmdmaster.alwaysexecute;
                        clone.arguments         = cmdmaster.arguments;
                        clone.command           = cmdmaster.command;
                        clone.filename          = cmdmaster.filename;
                        clone.nonfatal          = cmdmaster.nonfatal;
                        clone.sequence          = cmdmaster.sequence;
                        clone.timeout           = cmdmaster.timeout;
                        clone.working_directory = cmdmaster.working_directory;
                        clone.upload_files      = cmdmaster.upload_files;
                        clone.Save(this);
                    }

                    foreach (DBHostLaneView hostlanemaster in master.GetHosts(this))
                    {
                        DBHostLane clone = new DBHostLane();
                        clone.enabled = false;
                        clone.lane_id = result.id;
                        clone.host_id = hostlanemaster.host_id;
                        clone.Save(this);
                    }

                    foreach (DBEnvironmentVariable env in master.GetEnvironmentVariables(this))
                    {
                        DBEnvironmentVariable clone = new DBEnvironmentVariable();
                        clone.host_id = env.host_id;
                        clone.lane_id = result.id;
                        clone.name    = env.name;
                        clone.value   = env.value;
                        clone.Save(this);
                    }

                    foreach (DBLaneNotification notification in master.GetNotifications(this))
                    {
                        DBLaneNotification clone = new DBLaneNotification();
                        clone.lane_id         = result.id;
                        clone.notification_id = notification.notification_id;
                        clone.Save(this);
                    }

                    foreach (var tag in master.GetTags(this))
                    {
                        var clone = new DBLaneTag();
                        clone.lane_id = result.id;
                        clone.tag     = tag.tag;
                        clone.Save(this);
                    }

                    transaction.Commit();
                }
            } catch {
                result = null;
                throw;
            }

            return(result);
        }
Ejemplo n.º 7
0
        void NotifySlack(DBWork work, DBRevisionWork revision_work, List <DBPerson> people, string message)
        {
            bool nonfatal = false;

            if (!Evaluate(work, revision_work, out nonfatal))
            {
                log.DebugFormat("SlackNotification: lane_id: {1} revision_id: {2} host_id: {3} State: {0}: evaluation returned false", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                return;
            }
            else
            {
                log.DebugFormat("SlackNotification: lane_id: {1} revision_id: {2} host_id: {3} State: {0} enabled: {4}, {5} people", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id, enabled, people.Count);
            }

            if (nonfatal)
            {
                message = "Test failure";
            }
            else
            {
                message = "Build failure";
            }

            DBRevision revision;
            DBLane     lane;
            DBHost     host;

            using (DB db = new DB()) {
                revision = DBRevision_Extensions.Create(db, revision_work.revision_id);
                lane     = DBLane_Extensions.Create(db, revision_work.lane_id);
                host     = DBHost_Extensions.Create(db, revision_work.host_id);
            }

            message = string.Format("{0} in revision {1} on {2}/{3} ({4}/ViewLane.aspx?lane_id={5}&host_id={6}&revision_id={7})",
                                    message,
                                    (revision.revision.Length > 8 ? revision.revision.Substring(0, 8) : revision.revision),
                                    lane.lane, host.host, Configuration.GetWebSiteUrl(), lane.id, host.id, revision.id);

            foreach (var person in people)
            {
                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    using (var db = new DB()) {
                        var computed_nicks = new List <string> ();
                        var email_lists    = new List <IEnumerable <string> > ();
                        email_lists.Add(person.GetEmails(db));
                        if (person.Emails != null)
                        {
                            email_lists.Add(person.Emails);
                        }

                        foreach (var emails in email_lists)
                        {
                            foreach (var email in emails)
                            {
                                var at = email.IndexOf('@');
                                if (at > 0)
                                {
                                    computed_nicks.Add(email.Substring(0, at));
                                }
                            }
                        }
                        if (computed_nicks.Count == 0 && !string.IsNullOrEmpty(person.fullname))
                        {
                            computed_nicks.Add(person.fullname);
                        }
                        person.irc_nicknames = string.Join(",", computed_nicks.ToArray());
                    }
                }

                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    log.DebugFormat("SlackNotification: could not find somebody to notify for revision with id {0} on lane {1}", revision_work.revision_id, revision_work.lane_id);
                    continue;
                }
            }

            var rooms    = identity.channels.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var finalApi = identity.servers;

            var webClient = new WebClient();

            foreach (var r in rooms)
            {
                string prefix;
                string room = r;
                if (room.StartsWith("*"))
                {
                    room   = room.Substring(1);
                    prefix = "";
                }
                else
                {
                    prefix = "@";
                }

                var prefixNames  = string.Join(", ", people.SelectMany(x => x.irc_nicknames.Split(',')).Distinct().Select(x => string.Format("{1}{0}", x, prefix)));
                var finalMessage = prefixNames + ": " + message;

                if (cache [room + "|" + finalMessage] != null)
                {
                    continue;
                }
                cache.Add(room + "|" + finalMessage, string.Empty, new DateTimeOffset(DateTime.UtcNow.AddHours(1), TimeSpan.Zero));
                var json = string.Format(@"
{{
	""channel"": ""{0}"",
	""username"": ""Wrench"",
	""text"": ""*{1}*"",
	""link_names"": ""{5}"",
	""attachments"": [
		{{
			""fallback"": ""{2}{3}"",
			""color"": ""{4}"",
			""fields"":[
				{{
					""value"": ""{2}{3}"",
					""short"": false
				}}
			]
		}}
	]
}}
",
                                         r,
                                         nonfatal ? "Test failure" : "Build failure",
                                         nonfatal ? ":crying_cat_face: " : ":pouting_cat: ",
                                         finalMessage.Replace("\\", "\\\\").Replace("\"", "\\\""),
                                         nonfatal ? "warning" : "danger",
                                         nonfatal ? "0" : "1"
                                         );

                var postData = new NameValueCollection();
                postData.Add("payload", json);
                try {
                    var res       = webClient.UploadValues(finalApi, postData);
                    var resString = Encoding.UTF8.GetString(res);
                    log.DebugFormat("SlackNotification: response from server: {0}", resString);
                } catch (WebException wex) {
                    string responseText = null;

                    if (wex.Response != null)
                    {
                        using (var responseStream = wex.Response.GetResponseStream()) {
                            if (responseStream != null)
                            {
                                using (var reader = new StreamReader(responseStream))
                                    responseText = reader.ReadToEnd();
                            }
                        }
                    }
                    if (responseText == null)
                    {
                        log.ErrorFormat("SlackNotification: exception from server (no response): {0}", wex.Message);
                    }
                    else
                    {
                        log.ErrorFormat("SlackNotification: server error: {0} with exception: {1}", responseText, wex.Message);
                    }
                }
            }
        }