Пример #1
0
        private static BuildModel CreateModel(IEnumerable <BlobArtifactModel> blobArtifacts,
                                              IEnumerable <PackageArtifactModel> packageArtifacts,
                                              string manifestBuildId,
                                              string[] manifestBuildData,
                                              string manifestRepoName,
                                              string manifestBranch,
                                              string manifestCommit,
                                              bool isStableBuild,
                                              PublishingInfraVersion publishingVersion,
                                              TaskLoggingHelper log,
                                              SigningInformationModel signingInformationModel = null)
        {
            var attributes = MSBuildListSplitter.GetNamedProperties(manifestBuildData);

            if (!ManifestBuildDataHasLocationInformation(attributes))
            {
                log.LogError($"Missing 'location' property from ManifestBuildData");
            }
            BuildModel buildModel = new BuildModel(
                new BuildIdentity
            {
                Attributes        = attributes,
                Name              = manifestRepoName,
                BuildId           = manifestBuildId,
                Branch            = manifestBranch,
                Commit            = manifestCommit,
                IsStable          = isStableBuild.ToString(),
                PublishingVersion = publishingVersion
            });

            buildModel.Artifacts.Blobs.AddRange(blobArtifacts);
            buildModel.Artifacts.Packages.AddRange(packageArtifacts);
            buildModel.SigningInformation = signingInformationModel;
            return(buildModel);
        }
Пример #2
0
 /// <summary>
 /// Create a build manifest for packages, blobs, and associated signing information
 /// </summary>
 /// <param name="log">MSBuild log helper</param>
 /// <param name="blobArtifacts">Collection of blobs</param>
 /// <param name="packageArtifacts">Collection of packages</param>
 /// <param name="assetManifestPath">Asset manifest file that should be written</param>
 /// <param name="manifestRepoName">Repository name</param>
 /// <param name="manifestBuildId">Azure devops build id</param>
 /// <param name="manifestBranch">Name of the branch that was built</param>
 /// <param name="manifestCommit">Commit that was built</param>
 /// <param name="manifestBuildData">Additional build data properties</param>
 /// <param name="isStableBuild">True if the build is stable, false otherwise.</param>
 /// <param name="publishingVersion">Publishing version in use.</param>
 /// <param name="isReleaseOnlyPackageVersion">True if this repo uses release-only package versions</param>
 /// <param name="signingInformationModel">Signing information.</param>
 public static void CreateBuildManifest(TaskLoggingHelper log,
                                        IEnumerable <BlobArtifactModel> blobArtifacts,
                                        IEnumerable <PackageArtifactModel> packageArtifacts,
                                        string assetManifestPath,
                                        string manifestRepoName,
                                        string manifestBuildId,
                                        string manifestBranch,
                                        string manifestCommit,
                                        string[] manifestBuildData,
                                        bool isStableBuild,
                                        PublishingInfraVersion publishingVersion,
                                        bool isReleaseOnlyPackageVersion,
                                        SigningInformationModel signingInformationModel = null)
 {
     CreateModel(
         blobArtifacts,
         packageArtifacts,
         manifestBuildId,
         manifestBuildData,
         manifestRepoName,
         manifestBranch,
         manifestCommit,
         isStableBuild,
         publishingVersion,
         isReleaseOnlyPackageVersion,
         log,
         signingInformationModel: signingInformationModel)
     .WriteAsXml(assetManifestPath, log);
 }
Пример #3
0
        /// <summary>
        /// Create a build manifest for packages, blobs, and associated signing information
        /// </summary>
        /// <param name="log">MSBuild log helper</param>
        /// <param name="blobArtifacts">Collection of blobs</param>
        /// <param name="packageArtifacts">Collection of packages</param>
        /// <param name="assetManifestPath">Asset manifest file that should be written</param>
        /// <param name="manifestRepoName">Repository name</param>
        /// <param name="manifestBuildId">Azure devops build id</param>
        /// <param name="manifestBranch">Name of the branch that was built</param>
        /// <param name="manifestCommit">Commit that was built</param>
        /// <param name="manifestBuildData">Additional build data properties</param>
        /// <param name="isStableBuild">True if the build is stable, false otherwise.</param>
        /// <param name="publishingVersion">Publishing version in use.</param>
        /// <param name="isReleaseOnlyPackageVersion">True if this repo uses release-only package versions</param>
        /// <param name="signingInformationModel">Signing information.</param>
        public void CreateBuildManifest(
            IEnumerable <BlobArtifactModel> blobArtifacts,
            IEnumerable <PackageArtifactModel> packageArtifacts,
            string assetManifestPath,
            string manifestRepoName,
            string manifestBuildId,
            string manifestBranch,
            string manifestCommit,
            string[] manifestBuildData,
            bool isStableBuild,
            PublishingInfraVersion publishingVersion,
            bool isReleaseOnlyPackageVersion,
            SigningInformationModel signingInformationModel = null)
        {
            BuildModel model = CreateModel(
                blobArtifacts,
                packageArtifacts,
                manifestBuildId,
                manifestBuildData,
                manifestRepoName,
                manifestBranch,
                manifestCommit,
                isStableBuild,
                publishingVersion,
                isReleaseOnlyPackageVersion,
                signingInformationModel: signingInformationModel);

            _log.LogMessage(MessageImportance.High, $"Writing build manifest file '{assetManifestPath}'...");
            _fileSystem.WriteToFile(assetManifestPath, model.ToXml().ToString(SaveOptions.DisableFormatting));
        }
Пример #4
0
        [InlineData(typeof(ArgumentException), "", "bar")]                               // Can't be empty
        public void ManifestModelToXmlValidatesFileExtensionSignInfos(Type exceptionType, params string[] infos)
        {
            if (infos.Length % 2 != 0)
            {
                throw new ArgumentException();
            }

            List <FileExtensionSignInfoModel> models = new List <FileExtensionSignInfoModel>();

            // Include is first arg, cert name is second
            // InlineData can't pass tuple types so using this instead.
            for (int i = 0; i < infos.Length / 2; i++)
            {
                models.Add(new FileExtensionSignInfoModel()
                {
                    Include = infos[i * 2], CertificateName = infos[i * 2 + 1]
                });
            }

            SigningInformationModel signInfo = new SigningInformationModel()
            {
                FileExtensionSignInfo = models
            };

            VerifyToXml(exceptionType, signInfo);
        }
Пример #5
0
        [InlineData(null, "MyStrongName", "aaaaaaaaaaaaaaab", "Mycert", "MyStrongName", "aaaaaaaaaaaaaaaa", "Mycert2")]                      // No conflict
        public void ManifestModelToXmlValidatesStrongNameSignInfo(Type exceptionType, params string[] infos)
        {
            if (infos.Length % 3 != 0)
            {
                throw new ArgumentException();
            }

            List <StrongNameSignInfoModel> models = new List <StrongNameSignInfoModel>();

            for (int i = 0; i < infos.Length / 3; i++)
            {
                models.Add(new StrongNameSignInfoModel()
                {
                    Include         = infos[i * 3],
                    PublicKeyToken  = infos[i * 3 + 1],
                    CertificateName = infos[i * 3 + 2]
                });
            }

            SigningInformationModel signInfo = new SigningInformationModel()
            {
                StrongNameSignInfo = models
            };

            VerifyToXml(exceptionType, signInfo);
        }
Пример #6
0
        public void ManifestModelToXmlValidatesCertificateSignInfo(Type exceptionType, params string[] infos)
        {
            if (infos.Length % 2 != 0)
            {
                throw new ArgumentException();
            }

            List <CertificatesSignInfoModel> models = new List <CertificatesSignInfoModel>();

            for (int i = 0; i < infos.Length / 2; i++)
            {
                models.Add(new CertificatesSignInfoModel()
                {
                    Include            = infos[i * 2],
                    DualSigningAllowed = bool.Parse(infos[i * 2 + 1])
                });
            }

            SigningInformationModel signInfo = new SigningInformationModel()
            {
                CertificatesSignInfo = models
            };

            VerifyToXml(exceptionType, signInfo);
        }
Пример #7
0
        public void ValidateSymreaderFileSignInfos()
        {
            List <FileSignInfoModel> models = new List <FileSignInfoModel>();

            models.Add(new FileSignInfoModel()
            {
                Include         = "Microsoft.DiaSymReader.dll",
                CertificateName = "MicrosoftWin8WinBlue",
                TargetFramework = ".NETFramework,Version=v2.0",
                PublicKeyToken  = "31bf3856ad364e35",
            });
            models.Add(new FileSignInfoModel()
            {
                Include         = "Microsoft.DiaSymReader.dll",
                CertificateName = "Microsoft101240624", // lgtm [cs/common-default-passwords] Safe, these are certificate names
                TargetFramework = ".NETStandard,Version=v1.1",
                PublicKeyToken  = "31bf3856ad364e35",
            });

            SigningInformationModel signInfo = new SigningInformationModel()
            {
                FileSignInfo = models
            };

            signInfo.ToXml().Should().NotBeNull();
        }
Пример #8
0
        public void ManifestModelToXmlValidatesFileSignInfos(Type exceptionType, params string[] infos)
        {
            if (infos.Length % 4 != 0)
            {
                throw new ArgumentException();
            }

            List <FileSignInfoModel> models = new List <FileSignInfoModel>();

            for (int i = 0; i < infos.Length / 4; i++)
            {
                models.Add(new FileSignInfoModel()
                {
                    Include         = infos[i * 4],
                    CertificateName = infos[i * 4 + 1],
                    TargetFramework = infos[i * 4 + 2],
                    PublicKeyToken  = infos[i * 4 + 3],
                });
            }

            SigningInformationModel signInfo = new SigningInformationModel()
            {
                FileSignInfo = models
            };

            VerifyToXml(exceptionType, signInfo);
        }
Пример #9
0
 private static void VerifyToXml(Type expectedExceptionType, SigningInformationModel signInfo)
 {
     if (expectedExceptionType != null)
     {
         Action act = () => signInfo.ToXml();
         act.Should().Throw <Exception>().And.Should().BeOfType(expectedExceptionType);
     }
     else
     {
         signInfo.ToXml().Should().NotBeNull();
     }
 }
Пример #10
0
 private static void VerifyFromXml(Type expectedExceptionType, StringBuilder builder)
 {
     if (expectedExceptionType != null)
     {
         Action act = () => SigningInformationModel.Parse(XElement.Parse(builder.ToString()));
         act.Should().Throw <Exception>().And.Should().BeOfType(expectedExceptionType);
     }
     else
     {
         SigningInformationModel.Parse(XElement.Parse(builder.ToString())).Should().NotBeNull();
     }
 }
Пример #11
0
        public override bool Execute()
        {
            try
            {
                Log.LogMessage(MessageImportance.High, "Performing push to Azure DevOps artifacts storage.");

                if (!string.IsNullOrWhiteSpace(AssetsTemporaryDirectory))
                {
                    Log.LogMessage(MessageImportance.High, $"It's no longer necessary to specify a value for the {nameof(AssetsTemporaryDirectory)} property. " +
                                   $"Please consider patching your code to not use it.");
                }

                if (ItemsToPush == null)
                {
                    Log.LogError($"No items to push. Please check ItemGroup ItemsToPush.");
                }
                else
                {
                    IEnumerable <BlobArtifactModel>    blobArtifacts    = Enumerable.Empty <BlobArtifactModel>();
                    IEnumerable <PackageArtifactModel> packageArtifacts = Enumerable.Empty <PackageArtifactModel>();

                    var itemsToPushNoExcludes = ItemsToPush.
                                                Where(i => !string.Equals(i.GetMetadata("ExcludeFromManifest"), "true", StringComparison.OrdinalIgnoreCase));

                    if (PublishFlatContainer)
                    {
                        // Act as if %(PublishFlatContainer) were true for all items.
                        blobArtifacts = itemsToPushNoExcludes
                                        .Select(BuildManifestUtil.CreateBlobArtifactModel);
                        foreach (var blobItem in itemsToPushNoExcludes)
                        {
                            if (!File.Exists(blobItem.ItemSpec))
                            {
                                Log.LogError($"Could not find file {blobItem.ItemSpec}.");
                                continue;
                            }

                            Log.LogMessage(MessageImportance.High,
                                           $"##vso[artifact.upload containerfolder=BlobArtifacts;artifactname=BlobArtifacts]{blobItem.ItemSpec}");
                        }
                    }
                    else
                    {
                        ITaskItem[] symbolItems = itemsToPushNoExcludes
                                                  .Where(i => i.ItemSpec.Contains("symbols.nupkg"))
                                                  .Select(i =>
                        {
                            string fileName = Path.GetFileName(i.ItemSpec);
                            i.SetMetadata("RelativeBlobPath", $"{BuildManifestUtil.AssetsVirtualDir}symbols/{fileName}");
                            return(i);
                        })
                                                  .ToArray();

                        var blobItems = itemsToPushNoExcludes
                                        .Where(i =>
                        {
                            var isFlatString = i.GetMetadata("PublishFlatContainer");
                            if (!string.IsNullOrEmpty(isFlatString) &&
                                bool.TryParse(isFlatString, out var isFlat))
                            {
                                return(isFlat);
                            }

                            return(false);
                        })
                                        .Union(symbolItems)
                                        .ToArray();

                        ITaskItem[] packageItems = itemsToPushNoExcludes
                                                   .Except(blobItems)
                                                   .ToArray();

                        foreach (var packagePath in packageItems)
                        {
                            if (!File.Exists(packagePath.ItemSpec))
                            {
                                Log.LogError($"Could not find file {packagePath.ItemSpec}.");
                                continue;
                            }

                            Log.LogMessage(MessageImportance.High,
                                           $"##vso[artifact.upload containerfolder=PackageArtifacts;artifactname=PackageArtifacts]{packagePath.ItemSpec}");
                        }

                        foreach (var blobItem in blobItems)
                        {
                            if (!File.Exists(blobItem.ItemSpec))
                            {
                                Log.LogError($"Could not find file {blobItem.ItemSpec}.");
                                continue;
                            }

                            Log.LogMessage(MessageImportance.High,
                                           $"##vso[artifact.upload containerfolder=BlobArtifacts;artifactname=BlobArtifacts]{blobItem.ItemSpec}");
                        }

                        packageArtifacts = packageItems.Select(BuildManifestUtil.CreatePackageArtifactModel);
                        blobArtifacts    = blobItems.Select(BuildManifestUtil.CreateBlobArtifactModel).Where(blob => blob != null);
                    }

                    PublishingInfraVersion targetPublishingVersion = PublishingInfraVersion.Latest;

                    if (!string.IsNullOrEmpty(PublishingVersion))
                    {
                        if (!Enum.TryParse(PublishingVersion, ignoreCase: true, out targetPublishingVersion))
                        {
                            Log.LogError($"Could not parse publishing infra version '{PublishingVersion}'");
                        }
                    }

                    SigningInformationModel signingInformationModel = BuildManifestUtil.CreateSigningInformationModelFromItems(AzureDevOpsCollectionUri, AzureDevOpsProject, AzureDevOpsBuildId,
                                                                                                                               ItemsToSign, StrongNameSignInfo, FileSignInfo, FileExtensionSignInfo);

                    BuildManifestUtil.CreateBuildManifest(Log,
                                                          blobArtifacts,
                                                          packageArtifacts,
                                                          AssetManifestPath,
                                                          ManifestRepoUri,
                                                          ManifestBuildId,
                                                          ManifestBranch,
                                                          ManifestCommit,
                                                          ManifestBuildData,
                                                          IsStableBuild,
                                                          targetPublishingVersion,
                                                          signingInformationModel: signingInformationModel);

                    Log.LogMessage(MessageImportance.High,
                                   $"##vso[artifact.upload containerfolder=AssetManifests;artifactname=AssetManifests]{AssetManifestPath}");
                }
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e, true);
            }

            return(!Log.HasLoggedErrors);
        }