Exemple #1
0
        public async Task <List <Repository> > GetRepositories(InstallationToken token)
        {
            var result = await Execute <InstallationRepositories>(HttpMethod.Get, $"{Base}installation/repositories", token);

            return(result.Repositories);
        }
Exemple #2
0
        private async Task <T> Execute <T>(HttpMethod method, string uri, InstallationToken token = null, string payload = null)
        {
            var response = await Execute(method, uri, token, payload);

            return(JsonConvert.DeserializeObject <T>(response));
        }
Exemple #3
0
        private async Task <HttpRequestMessage> GetMessage(HttpMethod method, string uri, InstallationToken token = null)
        {
            var message = new HttpRequestMessage(method, $"{uri}?per_page=100");

            message.Headers.Add("Accept", "application/vnd.github.machine-man-preview+json");
            message.Headers.Add("Accept", "application/vnd.github.antiope-preview+json");
            message.Headers.Add("User-Agent", "Mhanafy-GithubClient");
            if (token != null)
            {
                if (!token.IsValid)
                {
                    token = await GetInstallationToken(token.InstallationId);
                }

                message.Headers.Add("Authorization", $"token {token.Token}");
            }
            else
            {
                if (_appToken == null || !_appToken.IsValid)
                {
                    _appToken = _jwtHelper.GetJwtToken(1);
                }
                message.Headers.Add("Authorization", $"Bearer {_appToken.Value}");
            }

            return(message);
        }
Exemple #4
0
        public static async Task Run(
            [TimerTrigger("0 */30 * * * *", RunOnStartup = true)] TimerInfo timerInfo,
            [Table("installation")] CloudTable installationTable,
            [Queue("openprmessage")] CloudQueue openPrQueue,
            [Queue("openprmessage-poison")] CloudQueue openPrPoisonQueue,
            TraceWriter log,
            ExecutionContext context)
        {
            for (var i = 0; i < 100; i++)
            {
                System.Threading.Thread.Sleep(1000);

                var topQueueMessage = await openPrPoisonQueue.GetMessageAsync();

                if (topQueueMessage == null)
                {
                    continue;
                }

                // pre-emptively delete the message from the queue we are pulling from
                await openPrPoisonQueue.DeleteMessageAsync(topQueueMessage);

                var topMessage = JsonConvert.DeserializeObject <OpenPrMessage>(topQueueMessage.AsString);

                try
                {
                    var installation = (Installation)(await installationTable.ExecuteAsync(
                                                          TableOperation.Retrieve <Installation>(topMessage.InstallationId.ToString(), topMessage.RepoName)))
                                       .Result;

                    if (installation == null)
                    {
                        log.Info("Not listed in installation table");
                        continue;
                    }

                    log.Info($"https://github.com/{installation.Owner}/{installation.RepoName}");

                    var installationTokenParameters = new InstallationTokenParameters
                    {
                        AccessTokensUrl = installation.AccessTokensUrl,
                        AppId           = KnownGitHubs.AppId,
                    };

                    var installationToken = await InstallationToken.GenerateAsync(
                        installationTokenParameters,
                        File.OpenText(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.AppPrivateKey}")));

                    var appClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue("MyApp"))
                    {
                        Credentials = new Octokit.Credentials(installationToken.Token, Octokit.AuthenticationType.Bearer)
                    };

                    var limits = await appClient.Miscellaneous.GetRateLimits();

                    log.Info("Ratelimits:\n");
                    log.Info(JsonConvert.SerializeObject(limits));

                    // check if an 'imgbot' branch is open
                    var branches = await appClient.Repository.Branch.GetAll(installation.Owner, installation.RepoName);

                    var imgbotBranches = branches.Where(x => x.Name == "imgbot");

                    if (imgbotBranches.Count() == 0)
                    {
                        // we have no open imgbot branches right now, let's just leave
                        continue;
                    }
                    else
                    {
                        log.Info("Open 'imgbot' branch found");
                    }

                    // check for ImgBot PRs
                    var prs = await appClient.Repository.PullRequest.GetAllForRepository(installation.Owner, installation.RepoName);

                    var imgbotPrs = prs.Where(x => x.Head.Ref == "imgbot");

                    if (imgbotPrs.Count() > 0)
                    {
                        // we have an open imgbot PR right now, let's just leave
                        continue;
                    }
                    else
                    {
                        log.Info("Open 'imgbot' PR not found, do we need to open one?");
                    }

                    // query for closed ImgBot PRs
                    var searchRequest = new Octokit.SearchIssuesRequest("imgbot")
                    {
                        Type  = Octokit.IssueTypeQualifier.PullRequest,
                        Repos = new Octokit.RepositoryCollection {
                            installation.Owner + "/" + installation.RepoName
                        }
                    };

                    var imgbotIssues = await appClient.Search.SearchIssues(searchRequest);

                    if (imgbotIssues.TotalCount == 0)
                    {
                        // no imgbot prs in history, let's queue a message to get the pr open
                        await openPrQueue.AddMessageAsync(new CloudQueueMessage(JsonConvert.SerializeObject(topMessage)));
                    }
                    else
                    {
                        // this is the case where an 'imgbot' branch exists, but there are closed imgbot prs
                        var latestClosedPr  = imgbotIssues.Items.OrderByDescending(x => x.ClosedAt).First();
                        var potentialBranch = branches.First(x => x.Name == "imgbot");

                        var commitInImgbotBranch = await appClient.Repository.Commit
                                                   .Get(installation.Owner, installation.RepoName, potentialBranch.Commit.Sha);

                        if (commitInImgbotBranch.Commit.Author.Date > latestClosedPr.ClosedAt)
                        {
                            // if the branch is newer than the last closed imgbot PR then we should queue a message to get the pr open
                            await openPrQueue.AddMessageAsync(new CloudQueueMessage(JsonConvert.SerializeObject(topMessage)));
                        }
                    }
                }
                catch (Exception e)
                {
                    log.Error("ERROR!", e);

                    // add it back to the poison queue
                    await openPrPoisonQueue.AddMessageAsync(topQueueMessage);
                }
            }
        }