Exemple #1
0
        public static async Task Run(
            [QueueTrigger("openprmessage")] OpenPrMessage openPrMessage,
            [Table("installation", "{InstallationId}", "{RepoName}")] Installation installation,
            TraceWriter log,
            ExecutionContext context)
        {
            if (installation == null)
            {
                throw new Exception($"No installation found for InstallationId: {installation.InstallationId}");
            }

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

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

            await PullRequest.OpenAsync(new PullRequestParameters
            {
                Password  = installationToken.Token,
                RepoName  = installation.RepoName,
                RepoOwner = installation.Owner,
            });
        }
        public static async Task RunAsync(
            IInstallationTokenProvider installationTokenProvider,
            CompressImagesMessage compressImagesMessage,
            ICollector <OpenPrMessage> openPrMessages,
            IRepoChecks repoChecks,
            ILogger logger,
            ExecutionContext context)
        {
            logger.LogInformation("CompressImagesFunction: starting run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, compressImagesMessage.InstallationId),
                AppId           = KnownGitHubs.AppId,
            };

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

            // check if repo is archived before starting work
            var isArchived = await repoChecks.IsArchived(new GitHubClientParameters
            {
                Password  = installationToken.Token,
                RepoName  = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner
            });

            if (isArchived)
            {
                logger.LogInformation("CompressImagesFunction: skipping archived repo {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                return;
            }

            var compressImagesParameters = new CompressimagesParameters
            {
                CloneUrl              = compressImagesMessage.CloneUrl,
                LocalPath             = LocalPath.CloneDir(Environment.GetEnvironmentVariable("TMP") ?? "/private/tmp/", compressImagesMessage.RepoName),
                Password              = installationToken.Token,
                RepoName              = compressImagesMessage.RepoName,
                RepoOwner             = compressImagesMessage.Owner,
                PgpPrivateKeyStream   = File.OpenRead(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPrivateKeyFilename}")),
                PgPPassword           = File.ReadAllText(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPasswordFilename}")),
                CompressImagesMessage = compressImagesMessage,
            };

            var didCompress = await CompressImages.RunAsync(compressImagesParameters, logger);

            if (didCompress)
            {
                logger.LogInformation("CompressImagesFunction: Successfully compressed images for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                openPrMessages.Add(new OpenPrMessage
                {
                    InstallationId = compressImagesMessage.InstallationId,
                    RepoName       = compressImagesMessage.RepoName,
                    CloneUrl       = compressImagesMessage.CloneUrl,
                });
            }

            logger.LogInformation("CompressImagesFunction: finished run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
        }
Exemple #3
0
        public static async Task Run(
            [QueueTrigger("openprmessage")] OpenPrMessage openPrMessage,
            [Table("installation", "{InstallationId}", "{RepoName}")] Installation installation,
            ILogger logger,
            ExecutionContext context)
        {
            if (installation == null)
            {
                logger.LogError("No installation found for {InstallationId}", installation.InstallationId);
                throw new Exception($"No installation found for InstallationId: {installation.InstallationId}");
            }

            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, installation.InstallationId),
                AppId           = KnownGitHubs.AppId,
            };

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

            logger.LogInformation("OpenPrFunction: Opening pull request for {Owner}/{RepoName}", installation.Owner, installation.RepoName);
            var id = await PullRequest.OpenAsync(new PullRequestParameters
            {
                Password  = installationToken.Token,
                RepoName  = installation.RepoName,
                RepoOwner = installation.Owner,
            });

            if (id > 0)
            {
                logger.LogInformation("OpenPrFunction: Successfully opened pull request (#{PullRequestId}) for {Owner}/{RepoName}", id, installation.Owner, installation.RepoName);
            }
        }
Exemple #4
0
        public static async Task Run(
            [QueueTrigger("compressimagesmessage")] CompressImagesMessage compressImagesMessage,
            [Queue("openprmessage")] ICollector <OpenPrMessage> openPrMessages,
            ILogger logger,
            ExecutionContext context)
        {
            logger.LogInformation("CompressImagesFunction: starting run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, compressImagesMessage.InstallationId),
                AppId           = KnownGitHubs.AppId,
            };

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

            var compressImagesParameters = new CompressimagesParameters
            {
                CloneUrl            = compressImagesMessage.CloneUrl,
                LocalPath           = LocalPath.CloneDir(Environment.GetEnvironmentVariable("TMP") ?? "/private/tmp/", compressImagesMessage.RepoName),
                Password            = installationToken.Token,
                RepoName            = compressImagesMessage.RepoName,
                RepoOwner           = compressImagesMessage.Owner,
                PgpPrivateKeyStream = File.OpenRead(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPrivateKeyFilename}")),
                PgPPassword         = File.ReadAllText(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPasswordFilename}"))
            };

            var didCompress = CompressImages.Run(compressImagesParameters, logger);

            if (didCompress)
            {
                logger.LogInformation("CompressImagesFunction: Successfully compressed images for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                openPrMessages.Add(new OpenPrMessage
                {
                    InstallationId = compressImagesMessage.InstallationId,
                    RepoName       = compressImagesMessage.RepoName,
                    CloneUrl       = compressImagesMessage.CloneUrl,
                });
            }

            logger.LogInformation("CompressImagesFunction: finished run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
        }
        public static async Task Run(
            [QueueTrigger("compressimagesmessage")] CompressImagesMessage compressImagesMessage,
            [Queue("openprmessage")] ICollector <OpenPrMessage> openPrMessages,
            TraceWriter log,
            ExecutionContext context)
        {
            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = compressImagesMessage.AccessTokensUrl,
                AppId           = KnownGitHubs.AppId,
            };

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

            var compressImagesParameters = new CompressimagesParameters
            {
                CloneUrl            = compressImagesMessage.CloneUrl,
                LocalPath           = LocalPath.CloneDir(Environment.GetEnvironmentVariable("TMP") ?? "/private/tmp/", compressImagesMessage.RepoName),
                Password            = installationToken.Token,
                RepoName            = compressImagesMessage.RepoName,
                RepoOwner           = compressImagesMessage.Owner,
                PgpPrivateKeyStream = File.OpenRead(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPrivateKeyFilename}")),
                PgPPassword         = File.ReadAllText(Path.Combine(context.FunctionDirectory, $"../{KnownGitHubs.PGPPasswordFilename}"))
            };

            var didCompress = CompressImages.Run(compressImagesParameters);

            if (didCompress)
            {
                log.Info("Compressed images; Route to OpenPR");
                openPrMessages.Add(new OpenPrMessage
                {
                    InstallationId = compressImagesMessage.InstallationId,
                    RepoName       = compressImagesMessage.RepoName,
                    CloneUrl       = compressImagesMessage.CloneUrl,
                });
            }

            log.Info("Completed run");
        }
        public static async Task RunAsync(
            IInstallationTokenProvider installationTokenProvider,
            CompressImagesMessage compressImagesMessage,
            ICollector <OpenPrMessage> openPrMessages,
            IRepoChecks repoChecks,
            ILogger logger,
            ExecutionContext context)
        {
            logger.LogInformation("CompressImagesFunction: starting run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, compressImagesMessage.InstallationId),
                AppId           = KnownGitHubs.AppId,
            };

            var installationToken = await installationTokenProvider.GenerateAsync(
                installationTokenParameters,
                KnownEnvironmentVariables.APP_PRIVATE_KEY);

            // check if repo is archived before starting work
            var isArchived = await repoChecks.IsArchived(new GitHubClientParameters
            {
                Password  = installationToken.Token,
                RepoName  = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner
            });

            if (isArchived)
            {
                logger.LogInformation("CompressImagesFunction: skipping archived repo {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                return;
            }

            // check if imgbot branch already exists before starting work
            var branchExists = await repoChecks.BranchExists(new GitHubClientParameters
            {
                Password  = installationToken.Token,
                RepoName  = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner,
            });

            if (branchExists)
            {
                logger.LogInformation("CompressImagesFunction: skipping repo {Owner}/{RepoName} as branch exists", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                return;
            }

            var compressImagesParameters = new CompressimagesParameters
            {
                CloneUrl              = compressImagesMessage.CloneUrl,
                LocalPath             = LocalPath.CloneDir(KnownEnvironmentVariables.TMP ?? "/private/tmp/", compressImagesMessage.RepoName),
                Password              = installationToken.Token,
                RepoName              = compressImagesMessage.RepoName,
                RepoOwner             = compressImagesMessage.Owner,
                PgpPrivateKey         = KnownEnvironmentVariables.PGP_PRIVATE_KEY,
                PgPPassword           = KnownEnvironmentVariables.PGP_PASSWORD,
                CompressImagesMessage = compressImagesMessage,
            };

            var didCompress = CompressImages.Run(compressImagesParameters, logger);

            if (didCompress)
            {
                logger.LogInformation("CompressImagesFunction: Successfully compressed images for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                openPrMessages.Add(new OpenPrMessage
                {
                    InstallationId = compressImagesMessage.InstallationId,
                    RepoName       = compressImagesMessage.RepoName,
                    CloneUrl       = compressImagesMessage.CloneUrl,
                });
            }

            logger.LogInformation("CompressImagesFunction: finished run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
        }
Exemple #7
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,
            ILogger logger,
            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)
                    {
                        logger.LogInformation("Not listed in installation table");
                        continue;
                    }

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

                    var installationTokenParameters = new InstallationTokenParameters
                    {
                        AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, topMessage.InstallationId),
                        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();

                    logger.LogInformation("Ratelimits:\n");
                    logger.LogInformation(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
                    {
                        logger.LogInformation("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
                    {
                        logger.LogInformation("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)
                {
                    logger.LogError(e, "ERROR!");

                    // add it back to the poison queue
                    await openPrPoisonQueue.AddMessageAsync(topQueueMessage);
                }
            }
        }
        public static async Task RunAsync(
            IInstallationTokenProvider installationTokenProvider,
            CompressImagesMessage compressImagesMessage,
            ICollector<OpenPrMessage> openPrMessages,
            ICollector<CompressImagesMessage> compressImagesMessages,
            CloudTable settingsTable,
            IRepoChecks repoChecks,
            ILogger logger,
            ExecutionContext context)
        {
            logger.LogInformation("CompressImagesFunction: starting run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
            var installationTokenParameters = new InstallationTokenParameters
            {
                AccessTokensUrl = string.Format(KnownGitHubs.AccessTokensUrlFormat, compressImagesMessage.InstallationId),
                AppId = KnownGitHubs.AppId,
            };
            var installationToken = await installationTokenProvider.GenerateAsync(
                installationTokenParameters,
                KnownEnvironmentVariables.APP_PRIVATE_KEY);

            // check if repo is archived before starting work
            var isArchived = await repoChecks.IsArchived(new GitHubClientParameters
            {
                Password = installationToken.Token,
                RepoName = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner
            });

            if (isArchived)
            {
                logger.LogInformation("CompressImagesFunction: skipping archived repo {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                return;
            }

            // check if imgbot branch already exists before starting work
            var branchExists = await repoChecks.BranchExists(new GitHubClientParameters
            {
                Password = installationToken.Token,
                RepoName = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner,
            });

            if (branchExists && !compressImagesMessage.IsRebase)
            {
                logger.LogInformation("CompressImagesFunction: skipping repo {Owner}/{RepoName} as branch exists", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                return;
            }

            var compressImagesParameters = new CompressimagesParameters
            {
                CloneUrl = compressImagesMessage.CloneUrl,
                LocalPath = LocalPath.CloneDir(KnownEnvironmentVariables.TMP ?? "/private/tmp/", compressImagesMessage.RepoName),
                Password = installationToken.Token,
                RepoName = compressImagesMessage.RepoName,
                RepoOwner = compressImagesMessage.Owner,
                IsRebase = compressImagesMessage.IsRebase,
                PgpPrivateKey = KnownEnvironmentVariables.PGP_PRIVATE_KEY,
                PgPPassword = KnownEnvironmentVariables.PGP_PASSWORD,
                CompressImagesMessage = compressImagesMessage,
                Settings = await Common.TableModels.SettingsHelper.GetSettings(settingsTable, compressImagesMessage.InstallationId, compressImagesMessage.RepoName),
            };

            var didCompress = CompressImages.Run(compressImagesParameters, compressImagesMessages, logger);

            if (didCompress && compressImagesParameters.CloneUrl.Contains(".wiki.git"))
            {
                logger.LogInformation("CompressImagesFunction: Successfully compressed images for {Owner}/{RepoName}/wiki", compressImagesMessage.Owner, compressImagesMessage.RepoName);
            }
            else if (didCompress)
            {
                var update = compressImagesMessage.IsRebase;
                logger.LogInformation("CompressImagesFunction: Successfully compressed images for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
                openPrMessages.Add(new OpenPrMessage
                {
                    InstallationId = compressImagesMessage.InstallationId,
                    RepoName = compressImagesMessage.RepoName,
                    CloneUrl = compressImagesMessage.CloneUrl,
                    Update = compressImagesMessage.IsRebase,
                });
            }

            try
            {
                Directory.Delete(compressImagesParameters.LocalPath, recursive: true);
            }
            catch (Exception exception)
            {
                logger.LogError(exception, "Error cleaning up local directory");
            }

            logger.LogInformation("CompressImagesFunction: finished run for {Owner}/{RepoName}", compressImagesMessage.Owner, compressImagesMessage.RepoName);
        }