예제 #1
0
        /// <inheritdoc />
        public override int?DeterminePullRequestId(IssuesContext context)
        {
            context.NotNull(nameof(context));

            // Not supported by GitHub Actions
            return(null);
        }
예제 #2
0
        /// <summary>
        /// Determines the build server on which the build is running.
        /// </summary>
        /// <param name="context">The Cake context.</param>
        /// <returns>The build server on which the build is running or <c>null</c> if unknown build server.</returns>
        private static IIssuesBuildServer DetermineBuildServer(IssuesContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // Could be simplified once https://github.com/cake-build/cake/issues/1684 / https://github.com/cake-build/cake/issues/1580 are fixed.
            if (!string.IsNullOrWhiteSpace(context.EnvironmentVariable("TF_BUILD")) &&
                !string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")) &&
                (
                    new Uri(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")).Host == "dev.azure.com" ||
                    new Uri(context.EnvironmentVariable("SYSTEM_COLLECTIONURI")).Host.EndsWith("visualstudio.com", StringComparison.InvariantCulture)
                ))
            {
                context.Information("Build server detected: {0}", "Azure Pipelines");
                return(new AzureDevOpsBuildServer());
            }

            if (context.AppVeyor().IsRunningOnAppVeyor)
            {
                context.Information("Build server detected: {0}", "AppVeyor");
                return(new AppVeyorBuildServer());
            }

            if (context.GitHubActions().IsRunningOnGitHubActions)
            {
                context.Information("Build server detected: {0}", "GitHub Actions");
                return(new GitHubActionsBuildServer());
            }

            return(null);
        }
        /// <inheritdoc />
        public override bool DetermineIfPullRequest(IssuesContext context)
        {
            context.NotNull(nameof(context));

            // Could be simplified once https://github.com/cake-build/cake/issues/2149 is fixed
            return(!string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID")));
        }
예제 #4
0
        /// <summary>
        /// Determines the pull request system.
        /// </summary>
        /// <param name="context">The Cake context.</param>
        /// <param name="repositoryUrl">The URL of the remote repository.</param>
        /// <returns>The pull request system or <c>null</c> if unknown pull request system.</returns>
        private static IIssuesPullRequestSystem DeterminePullRequestSystem(IssuesContext context, Uri repositoryUrl)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (repositoryUrl == null)
            {
                throw new ArgumentNullException(nameof(repositoryUrl));
            }

            if (repositoryUrl.Host == "dev.azure.com" || repositoryUrl.Host.EndsWith("visualstudio.com", StringComparison.InvariantCulture))
            {
                context.Information("Pull request system detected: {0}", "Azure Repos");
                return(new AzureDevOpsPullRequestSystem());
            }

            if (repositoryUrl.Host == "github.com")
            {
                return(new GitHubPullRequestSystem());
            }

            return(null);
        }
        /// <inheritdoc />
        public override string DetermineCommitId(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            return(context.AzurePipelines().Environment.Repository.SourceVersion);
        }
        /// <inheritdoc />
        public override Uri DetermineRepositoryRemoteUrl(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            return(new Uri(context.EnvironmentVariable("BUILD_REPOSITORY_URI")));
        }
예제 #7
0
        /// <inheritdoc />
        public override void CreateSummaryIssuesReport(
            IssuesContext context,
            [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "")
        {
            context.NotNull(nameof(context));

            // Summary issues report is not supported for GitHub Actions.
        }
예제 #8
0
        /// <inheritdoc />
        public override string DetermineCommitId(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            return(context.GitHubActions().Environment.Workflow.Sha);
        }
예제 #9
0
        /// <inheritdoc />
        public override string DetermineCommitId(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            return(context.AppVeyor().Environment.Repository.Commit.Id);
        }
예제 #10
0
        /// <inheritdoc />
        public override Uri DetermineRepositoryRemoteUrl(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            return(new Uri($"https://github.com/{context.GitHubActions().Environment.Workflow.Repository}.git"));
        }
        /// <inheritdoc />
        public virtual Uri DetermineRepositoryRemoteUrl(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));
            repositoryRootDirectory.NotNull(nameof(repositoryRootDirectory));

            return(context.State.RepositoryInfo.GetRepositoryRemoteUrl(context, repositoryRootDirectory));
        }
        /// <inheritdoc />
        public virtual string DetermineCommitId(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));
            repositoryRootDirectory.NotNull(nameof(repositoryRootDirectory));

            return(context.State.RepositoryInfo.GetCommitId(context, repositoryRootDirectory));
        }
예제 #13
0
        /// <inheritdoc />
        public override void ReportIssuesToBuildServer(
            IssuesContext context)
        {
            context.NotNull(nameof(context));

            context.ReportIssuesToPullRequest(
                context.State.Issues,
                context.GitHubActionsBuilds(),
                context.State.ProjectRootDirectory);
        }
예제 #14
0
        /// <inheritdoc />
        public override void PublishIssuesArtifacts(IssuesContext context)
        {
            context.NotNull(nameof(context));

            if (context.Parameters.BuildServer.ShouldPublishFullIssuesReport &&
                context.State.FullIssuesReport != null &&
                context.FileExists(context.State.FullIssuesReport))
            {
                context.AppVeyor().UploadArtifact(context.State.FullIssuesReport);
            }
        }
        /// <inheritdoc />
        public override void PublishIssuesArtifacts(IssuesContext context)
        {
            context.NotNull(nameof(context));

            if (context.Parameters.BuildServer.ShouldPublishFullIssuesReport &&
                context.State.FullIssuesReport != null &&
                context.FileExists(context.State.FullIssuesReport))
            {
                context.AzurePipelines().Commands.UploadArtifact("Issues", context.State.FullIssuesReport, "Issues");
            }
        }
예제 #16
0
        /// <inheritdoc />
        public override FileLinkSettings GetFileLinkSettings(IssuesContext context)
        {
            context.NotNull(nameof(context));

            var rootPath = context.State.RepositoryRootDirectory.GetRelativePath(context.State.ProjectRootDirectory);

            return(context.IssueFileLinkSettingsForAzureDevOpsCommit(
                       context.State.RepositoryRemoteUrl,
                       context.State.CommitId,
                       rootPath.FullPath));
        }
        /// <inheritdoc />
        public override int?DeterminePullRequestId(IssuesContext context)
        {
            context.NotNull(nameof(context));

            if (!Int32.TryParse(context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID"), out var pullRequestId))
            {
                throw new Exception($"Invalid pull request ID: {context.EnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID")}");
            }
            else
            {
                return(pullRequestId);
            }
        }
        /// <inheritdoc />
        public override void ReportIssuesToBuildServer(
            IssuesContext context)
        {
            context.NotNull(nameof(context));

            foreach (var issue in context.State.Issues)
            {
                context.AzurePipelines().Commands.WriteWarning(
                    issue.MessageText,
                    new AzurePipelinesMessageData
                {
                    SourcePath = issue.AffectedFileRelativePath?.FullPath,
                    LineNumber = issue.Line
                });
            }
        }
예제 #19
0
        /// <inheritdoc />
        public override Uri DetermineRepositoryRemoteUrl(
            IssuesContext context,
            DirectoryPath repositoryRootDirectory)
        {
            context.NotNull(nameof(context));

            switch (context.AppVeyor().Environment.Repository.Provider)
            {
            case "bitBucket": return(new Uri($"https://bitbucket.org/{context.AppVeyor().Environment.Repository.Name}/src"));

            case "gitHub": return(new Uri($"https://github.com/{context.AppVeyor().Environment.Repository.Name}.git"));

            case "gitLab": return(new Uri($"https://gitlab.com/{context.AppVeyor().Environment.Repository.Name}.git"));

            case "vso": return(new Uri($"https://dev.azure.com/{context.AppVeyor().Environment.Repository.Name}"));

            default: return(new Uri(context.AppVeyor().Environment.Repository.Name));
            }
        }
예제 #20
0
        /// <inheritdoc />
        public override void SetPullRequestIssuesState(IssuesContext context)
        {
            context.NotNull(nameof(context));

#pragma warning disable SA1123 // Do not place regions within elements
            #region DupFinder Exclusion
#pragma warning restore SA1123 // Do not place regions within elements
            if (string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_ACCESSTOKEN")))
            {
                context.Warning("SYSTEM_ACCESSTOKEN environment variable not set. Make sure the 'Allow Scripts to access OAuth token' option is enabled on the build definition.");
                return;
            }

            var pullRequestSettings =
                new AzureDevOpsPullRequestSettings(
                    context.State.BuildServer.DetermineRepositoryRemoteUrl(context, context.State.RepositoryRootDirectory),
                    context.State.BuildServer.DeterminePullRequestId(context).Value,
                    context.AzureDevOpsAuthenticationOAuth(context.EnvironmentVariable("SYSTEM_ACCESSTOKEN")));
            #endregion

            var pullRequestStatusName            = "Issues";
            var pullRequestDescriptionIfIssues   = $"Found {context.State.Issues.Count()} issues";
            var pullRequestDescriptionIfNoIssues = "No issues found";
            if (!string.IsNullOrWhiteSpace(context.Parameters.BuildIdentifier))
            {
                pullRequestStatusName            += $"-{context.Parameters.BuildIdentifier}";
                pullRequestDescriptionIfIssues   += $" for build {context.Parameters.BuildIdentifier}";
                pullRequestDescriptionIfNoIssues += $" for build {context.Parameters.BuildIdentifier}";
            }

            var pullRequestStatus =
                new AzureDevOpsPullRequestStatus(pullRequestStatusName)
            {
                Genre       = "Cake.Issues.Recipe",
                State       = context.State.Issues.Any() ? AzureDevOpsPullRequestStatusState.Failed : AzureDevOpsPullRequestStatusState.Succeeded,
                Description = context.State.Issues.Any() ? pullRequestDescriptionIfIssues : pullRequestDescriptionIfNoIssues
            };

            context.AzureDevOpsSetPullRequestStatus(
                pullRequestSettings,
                pullRequestStatus);
        }
예제 #21
0
        /// <inheritdoc />
        public override void ReportIssuesToPullRequest(IssuesContext context)
        {
            context.NotNull(nameof(context));

#pragma warning disable SA1123 // Do not place regions within elements
            #region DupFinder Exclusion
#pragma warning restore SA1123 // Do not place regions within elements
            if (string.IsNullOrWhiteSpace(context.EnvironmentVariable("SYSTEM_ACCESSTOKEN")))
            {
                context.Warning("SYSTEM_ACCESSTOKEN environment variable not set. Make sure the 'Allow Scripts to access OAuth token' option is enabled on the build definition.");
                return;
            }

            context.ReportIssuesToPullRequest(
                context.State.Issues,
                context.AzureDevOpsPullRequests(
                    context.State.BuildServer.DetermineRepositoryRemoteUrl(context, context.State.RepositoryRootDirectory),
                    context.State.BuildServer.DeterminePullRequestId(context).Value,
                    context.AzureDevOpsAuthenticationOAuth(context.EnvironmentVariable("SYSTEM_ACCESSTOKEN"))),
                GetReportIssuesToPullRequestSettings(context));
            #endregion
        }
예제 #22
0
        /// <summary>
        /// Determines the repository info provider to use.
        /// </summary>
        /// <param name="context">The Cake context.</param>
        /// <param name="repositoryInfoProviderType">Defines how information about the Git repository should be determined.</param>
        /// <returns>The repository info provider which should be used.</returns>
        private static IRepositoryInfoProvider DetermineRepositoryInfoProvider(
            IssuesContext context,
            RepositoryInfoProviderType repositoryInfoProviderType)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            switch (repositoryInfoProviderType)
            {
            case RepositoryInfoProviderType.CakeGit:
                context.Information("Using Cake.Git for providing repository information");
                return(new CliRepositoryInfoProvider());

            case RepositoryInfoProviderType.Cli:
                context.Information("Using Git CLI for providing repository information");
                return(new CliRepositoryInfoProvider());

            default:
                throw new NotImplementedException("Unsupported repository info provider");
            }
        }
예제 #23
0
        /// <summary>
        /// Creates a new instance of the <see cref="IssuesState"/> class.
        /// </summary>
        /// <param name="context">The Cake context.</param>
        /// <param name="repositoryInfoProviderType">Defines how information about the Git repository should be determined.</param>
        public IssuesState(
            IssuesContext context,
            RepositoryInfoProviderType repositoryInfoProviderType)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            this.BuildRootDirectory = context.MakeAbsolute(context.Directory("./"));
            context.Information("Build script root directory: {0}", this.BuildRootDirectory);

            this.ProjectRootDirectory = this.BuildRootDirectory.Combine("..").Collapse();
            context.Information("Project root directory: {0}", this.ProjectRootDirectory);

            this.RepositoryInfo = DetermineRepositoryInfoProvider(context, repositoryInfoProviderType);

            this.RepositoryRootDirectory = this.RepositoryInfo.GetRepositoryRootDirectory(context, this.BuildRootDirectory);
            context.Information("Repository root directory: {0}", this.RepositoryRootDirectory);

            this.BuildServer = DetermineBuildServer(context);
            if (this.BuildServer != null)
            {
                this.RepositoryRemoteUrl =
                    BuildServer.DetermineRepositoryRemoteUrl(context, this.RepositoryRootDirectory);
                context.Information("Repository remote URL: {0}", this.RepositoryRemoteUrl);

                this.CommitId =
                    BuildServer.DetermineCommitId(context, this.RepositoryRootDirectory);
                context.Information("CommitId: {0}", this.CommitId);

                this.PullRequestSystem =
                    DeterminePullRequestSystem(
                        context,
                        this.RepositoryRemoteUrl);
            }
        }
        /// <inheritdoc />
        public override void CreateSummaryIssuesReport(
            IssuesContext context,
            [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "")
        {
            context.NotNull(nameof(context));

            var summaryFileName = "summary";

            if (!string.IsNullOrWhiteSpace(context.Parameters.BuildIdentifier))
            {
                summaryFileName += $"-{context.Parameters.BuildIdentifier}";
            }
            summaryFileName += ".md";
            var summaryFilePath = context.Parameters.OutputDirectory.CombineWithFilePath(summaryFileName);

            var templateName = "Cake.Frosting.Issues.Recipe.BuildServers.AzurePipelineSummary.cshtml";

            using (var stream = this.GetType().Assembly.GetManifestResourceStream(templateName))
            {
                if (stream == null)
                {
                    throw new ApplicationException($"Could not load resource {templateName}");
                }

                using (var sr = new StreamReader(stream))
                {
                    // Create summary for Azure Pipelines using custom template.
                    context.CreateIssueReport(
                        context.State.Issues,
                        context.GenericIssueReportFormatFromContent(sr.ReadToEnd()),
                        context.State.ProjectRootDirectory,
                        summaryFilePath);
                }
            }

            context.AzurePipelines().Commands.UploadTaskSummary(summaryFilePath);
        }
예제 #25
0
        /// <inheritdoc />
        public override void PublishIssuesArtifacts(IssuesContext context)
        {
            context.NotNull(nameof(context));

            // Publishing artifacts is currently not supported for GitHub Actions.
        }
 /// <inheritdoc />
 public abstract FileLinkSettings GetFileLinkSettings(
     IssuesContext context);
        /// <summary>
        /// Returns settings for reporting issues to pull requests.
        /// </summary>
        /// <param name="context">The Cake context.</param>
        /// <returns>Settings for reporting issues to pull requests.</returns>
        protected static IReportIssuesToPullRequestSettings GetReportIssuesToPullRequestSettings(IssuesContext context)
        {
            var settings =
                new ReportIssuesToPullRequestSettings(context.State.ProjectRootDirectory)
            {
                MaxIssuesToPost                     = context.Parameters.PullRequestSystem.MaxIssuesToPost,
                MaxIssuesToPostAcrossRuns           = context.Parameters.PullRequestSystem.MaxIssuesToPostAcrossRuns,
                MaxIssuesToPostForEachIssueProvider = context.Parameters.PullRequestSystem.MaxIssuesToPostForEachIssueProvider
            };

            foreach (var providerIssueLimit in context.Parameters.PullRequestSystem.ProviderIssueLimits)
            {
                settings.ProviderIssueLimits.Add(providerIssueLimit.Key, providerIssueLimit.Value);
            }

            return(settings);
        }
예제 #28
0
        /// <inheritdoc />
        public override bool DetermineIfPullRequest(IssuesContext context)
        {
            context.NotNull(nameof(context));

            return(context.GitHubActions().Environment.PullRequest.IsPullRequest);
        }
예제 #29
0
        /// <inheritdoc />
        public override void ReportIssuesToPullRequest(IssuesContext context)
        {
            context.NotNull(nameof(context));

            // Not supported yet
        }
예제 #30
0
        /// <inheritdoc />
        public override void SetPullRequestIssuesState(IssuesContext context)
        {
            context.NotNull(nameof(context));

            // Not supported yet
        }