public void GivenShippingAssets() { BuildModel expectedBuildModel = GetBuildModel(); PushMetadataToBuildAssetRegistry pushMetadata = GetPushMetadata(); PackageArtifactModel packageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", "false" }, }, Id = shippingAssetData.Name, Version = shippingAssetData.Version }; expectedBuildModel.Artifacts = new ArtifactSet { Packages = new List <PackageArtifactModel> { packageArtifact } }; BuildModel actualModel = pushMetadata.CreateMergedManifestBuildModel( ImmutableList.Create(shippingAssetData), manifestBuildData); actualModel.Should().BeEquivalentTo(expectedBuildModel); }
public void GivenAssetWithoutVersion() { BuildModel expectedBuildModel = GetBuildModel(); PushMetadataToBuildAssetRegistry pushMetadata = GetPushMetadata(); PackageArtifactModel packageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", "true" }, { "Id", assetDataWithoutVersion.Name }, { "Version", null } } }; expectedBuildModel.Artifacts = new ArtifactSet { Packages = new List <PackageArtifactModel> { packageArtifact } }; BuildModel actualModel = pushMetadata.CreateMergedManifestBuildModel( ImmutableList.Create(assetDataWithoutVersion), manifestBuildData); actualModel.Should().BeEquivalentTo(expectedBuildModel); }
private ITaskItem ConvertToPackageInfoItem(PackageArtifactModel identity) { var metadata = new Dictionary <string, string> { [NuGetPackageInfoId] = identity.Id, [NuGetPackageInfoVersion] = identity.Version.ToString() }; return(new TaskItem(identity.ToString(), metadata)); }
public void PackageArtifactModelEquals_ReturnsFalseWhenObjectsAreDifferentTypes() { PackageArtifactModel packageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", true.ToString().ToLower() }, }, Id = "AssetName", Version = null }; Assert.False(packageArtifact.Equals("thisIsNotAPackageArtifact!")); }
OrchestratedFeedPackageVersion(string packageId) { return(infos => infos .Select(info => { PackageArtifactModel match = info.GetBlobFeed()?.Artifacts.Packages .FirstOrDefault(p => p.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase)); if (match != null) { return new DependencyReplacement(match.Version, new[] { info }); } return null; }) .FirstOrDefault(r => r != null)); }
public void GivenSomeAssetsInBlobSetAndSomeNot() { BuildModel expectedBuildModel = GetBuildModel(); PushMetadataToBuildAssetRegistry pushMetadata = GetPushMetadata(); AssetData dataInBlobSet = pushMetadata.GetManifestAsAsset(ImmutableList.Create(nonShippingAssetData), "thisIsALocation", "thisIsTheManifestFileName"); PackageArtifactModel shippingPackageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", "false" }, }, Id = shippingAssetData.Name, Version = shippingAssetData.Version }; BlobArtifactModel blobArtifactModel = new BlobArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", "true" } }, Id = dataInBlobSet.Name }; expectedBuildModel.Artifacts = new ArtifactSet { Packages = new List <PackageArtifactModel> { shippingPackageArtifact }, Blobs = new List <BlobArtifactModel> { blobArtifactModel } }; BuildModel actualModel = pushMetadata.CreateMergedManifestBuildModel( ImmutableList.Create(dataInBlobSet, shippingAssetData), manifestBuildData); actualModel.Should().BeEquivalentTo(expectedBuildModel); }
private Task <int> PublishWithNugetAsync(FeedConfig feedConfig, PackageArtifactModel package) { var packageFullPath = $"{PackageAssetsBasePath}{Path.DirectorySeparatorChar}{package.Id}.{package.Version}.nupkg"; var tcs = new TaskCompletionSource <int>(); Log.LogMessage($"Publishing package {packageFullPath} to target feed {feedConfig.TargetFeedURL} with nuget.exe push"); var process = new Process { StartInfo = new ProcessStartInfo() { FileName = NugetPath, Arguments = $"push -Source {feedConfig.TargetFeedURL} -apikey {feedConfig.FeedKey} {packageFullPath}", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }, EnableRaisingEvents = true }; process.Exited += (sender, args) => { tcs.SetResult(process.ExitCode); if (process.ExitCode != 0) { Log.LogError($"Nuget push failed with exit code {process.ExitCode}. Standard error output: {process.StandardError.ReadToEnd()}"); } else { Log.LogMessage($"Successfully published package {packageFullPath} to {feedConfig.TargetFeedURL}"); } process.Dispose(); }; process.Start(); return(tcs.Task); }
public void PackageArtifactModelEquals_ReturnsTrueWhenMatchingAttributesAreNull() { PackageArtifactModel packageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", true.ToString().ToLower() }, }, Id = "AssetName", Version = null }; PackageArtifactModel otherPackageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", true.ToString().ToLower() }, }, Id = "AssetName", Version = null }; Assert.True(packageArtifact.Equals(otherPackageArtifact)); }
public void PackageArtifactModelEquals_ReturnsFalseWhenTwoObjectsDoNotHaveMatchingAttributes() { PackageArtifactModel packageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "Shipping", true.ToString().ToLower() }, }, Id = "AssetName", Version = "AssetVersion" }; PackageArtifactModel otherPackageArtifact = new PackageArtifactModel { Attributes = new Dictionary <string, string> { { "NonShipping", true.ToString().ToLower() }, }, Id = "AssetName", Version = "AssetVersion" }; Assert.False(packageArtifact.Equals(otherPackageArtifact)); }
private ITaskItem CreateItem(PackageArtifactModel model) { return(new TaskItem("Package", ArtifactMetadata(model.ToXml(), model.Attributes))); }
/// <summary> /// Push a single package to the azure devops nuget feed. /// </summary> /// <param name="feedConfig">Feed</param> /// <param name="packageToPublish">Package to push</param> /// <returns>Task</returns> /// <remarks> /// This method attempts to take the most efficient path to push the package. /// There are two cases: /// - The package does not exist, and is pushed normally /// - The package exists, and its contents may or may not be equivalent. /// The second case is is by far the most common. So, we first attempt to push the package normally using nuget.exe. /// If this fails, this could mean any number of things (like failed auth). But in normal circumstances, this might /// mean the package already exists. This either means that we are attempting to push the same package, or attemtping to push /// a different package with the same id and version. The second case is an error, as azure devops feeds are immutable, the former /// is simply a case where we should continue onward. /// </remarks> private async Task PushNugetPackageAsync(FeedConfig feedConfig, HttpClient client, PackageArtifactModel packageToPublish, string feedAccount, string feedVisibility, string feedName) { Log.LogMessage(MessageImportance.High, $"Pushing package '{packageToPublish.Id}' to feed {feedConfig.TargetFeedURL}"); PackageAssetsBasePath = PackageAssetsBasePath.TrimEnd( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; string localPackageLocation = $"{PackageAssetsBasePath}{packageToPublish.Id}.{packageToPublish.Version}.nupkg"; if (!File.Exists(localPackageLocation)) { Log.LogError($"Could not locate '{packageToPublish.Id}.{packageToPublish.Version}' at '{localPackageLocation}'"); return; } try { // The feed key when pushing to AzDo feeds is "AzureDevOps" (works with the credential helper). int result = await StartProcessAsync(NugetPath, $"push \"{localPackageLocation}\" -Source \"{feedConfig.TargetFeedURL}\" -NonInteractive -ApiKey AzureDevOps"); if (result != 0) { Log.LogMessage(MessageImportance.Low, $"Failed to push {localPackageLocation}, attempting to determine whether the package already exists on the feed with the same content."); try { string packageContentUrl = $"https://pkgs.dev.azure.com/{feedAccount}/{feedVisibility}_apis/packaging/feeds/{feedName}/nuget/packages/{packageToPublish.Id}/versions/{packageToPublish.Version}/content"; if (await IsLocalPackageIdenticalToFeedPackage(localPackageLocation, packageContentUrl, client)) { Log.LogMessage(MessageImportance.Normal, $"Package '{packageToPublish.Id}@{packageToPublish.Version}' already exists on '{feedConfig.TargetFeedURL}' but has the same content. Skipping."); } else { Log.LogError($"Package '{packageToPublish.Id}@{packageToPublish.Version}' already exists on '{feedConfig.TargetFeedURL}' with different content."); } return; } catch (Exception e) { // This is an error. It means we were unable to push using nuget, and then could not access to the package otherwise. Log.LogWarning($"Failed to determine whether an existing package on the feed has the same content as '{localPackageLocation}': {e.Message}"); } Log.LogError($"Failed to push '{packageToPublish.Id}@{packageToPublish.Version}'. Result code '{result}'."); } } catch (Exception e) { Log.LogError($"Unexpected exception pushing package '{packageToPublish.Id}@{packageToPublish.Version}': {e.Message}"); } }