Skip to content

Commit

Permalink
Support for package sources
Browse files Browse the repository at this point in the history
  • Loading branch information
gdivis committed Aug 28, 2019
1 parent d1d94ce commit e22301d
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 11 deletions.
19 changes: 10 additions & 9 deletions NuGet/InedoExtension/InedoExtension.csproj
Expand Up @@ -33,12 +33,12 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Inedo.Agents.Client, Version=1000.0.0.0, Culture=neutral, PublicKeyToken=9de986a2f8db80fc, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.0.4\lib\net452\Inedo.Agents.Client.dll</HintPath>
<HintPath>..\packages\Inedo.SDK.1.5.0\lib\net452\Inedo.Agents.Client.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="Inedo.ExecutionEngine, Version=64.0.0.0, Culture=neutral, PublicKeyToken=68703f0e52007e75, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.0.4\lib\net452\Inedo.ExecutionEngine.dll</HintPath>
<Reference Include="Inedo.ExecutionEngine, Version=1000.0.0.0, Culture=neutral, PublicKeyToken=68703f0e52007e75, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.5.0\lib\net452\Inedo.ExecutionEngine.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
Expand All @@ -47,23 +47,24 @@
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="Inedo.SDK, Version=1.0.4.0, Culture=neutral, PublicKeyToken=29fae5dec3001603, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.0.4\lib\net452\Inedo.SDK.dll</HintPath>
<Reference Include="Inedo.SDK, Version=1.5.0.0, Culture=neutral, PublicKeyToken=29fae5dec3001603, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.5.0\lib\net452\Inedo.SDK.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="InedoLib, Version=1000.0.0.0, Culture=neutral, PublicKeyToken=112cfb71329714a6, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.0.4\lib\net452\InedoLib.dll</HintPath>
<HintPath>..\packages\Inedo.SDK.1.5.0\lib\net452\InedoLib.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.0.4\lib\net452\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Inedo.SDK.1.5.0\lib\net452\Newtonsoft.Json.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand All @@ -90,6 +91,6 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>powershell -Command "if (Test-Path C:\Projects\BuildMaster\Extensions -PathType Container) { Compress-Archive -Path '$(TargetDir)*' -DestinationPath C:\Projects\BuildMaster\Extensions\$(TargetName).zip -Force; Move-Item C:\Projects\BuildMaster\Extensions\$(TargetName).zip -Destination C:\Projects\BuildMaster\Extensions\$(TargetName).inedox -Force }"</PostBuildEvent>
<PostBuildEvent>powershell -Command "if (Test-Path C:\Projects\Extensions\Shared -PathType Container) { Compress-Archive -Path '$(TargetDir)*' -DestinationPath C:\Projects\Extensions\Shared\$(TargetName).zip -Force; Move-Item C:\Projects\Extensions\Shared\$(TargetName).zip -Destination C:\Projects\Extensions\Shared\$(TargetName).inedox -Force }"</PostBuildEvent>
</PropertyGroup>
</Project>
97 changes: 96 additions & 1 deletion NuGet/InedoExtension/Operations/PublishPackageOperation.cs
Expand Up @@ -11,6 +11,11 @@
using Inedo.Diagnostics;
using Inedo.Documentation;
using Inedo.IO;
using System.IO.Compression;
using System.Text.RegularExpressions;
using System.Linq;
using Inedo.ExecutionEngine.Executer;
using System.Xml.Linq;

namespace Inedo.Extensions.NuGet.Operations
{
Expand All @@ -22,6 +27,9 @@ namespace Inedo.Extensions.NuGet.Operations
[Tag("nuget")]
public sealed class PublishPackageOperation : RemoteExecuteOperation, IHasCredentials<UsernamePasswordCredentials>
{
[NonSerialized]
private IPackageManager packageManager;

[Required]
[ScriptAlias("Package")]
[DisplayName("Package file name")]
Expand Down Expand Up @@ -55,6 +63,22 @@ public sealed class PublishPackageOperation : RemoteExecuteOperation, IHasCreden
[PlaceholderText("Use password from credentials")]
public string Password { get; set; }

[ScriptAlias("Source")]
[Category("Advanced")]
[DisplayName("Package source")]
public string PackageSource { get; set; }
[DefaultValue(true)]
[ScriptAlias("AttachToBuild")]
[Category("Advanced")]
[DisplayName("Attach to build")]
public bool AttachToBuild { get; set; } = true;

protected override async Task BeforeRemoteExecuteAsync(IOperationExecutionContext context)
{
this.packageManager = await context.TryGetServiceAsync<IPackageManager>();
await base.BeforeRemoteExecuteAsync(context);
}

protected override async Task<object> RemoteExecuteAsync(IRemoteOperationExecutionContext context)
{
var packagePath = context.ResolvePath(this.PackagePath);
Expand All @@ -67,6 +91,8 @@ protected override async Task<object> RemoteExecuteAsync(IRemoteOperationExecuti
return null;
}

var packageInfo = PackageInfo.Extract(packagePath);

var handler = new HttpClientHandler { Proxy = WebRequest.DefaultWebProxy };

if (string.IsNullOrWhiteSpace(this.UserName) || string.IsNullOrEmpty(this.Password))
Expand Down Expand Up @@ -115,7 +141,23 @@ protected override async Task<object> RemoteExecuteAsync(IRemoteOperationExecuti
}
}

return null;
return packageInfo;
}

protected override async Task AfterRemoteExecuteAsync(object result)
{
await base.AfterRemoteExecuteAsync(result);

if (this.AttachToBuild && !string.IsNullOrWhiteSpace(this.PackageSource) && result is PackageInfo info)
{
if (this.packageManager == null)
{
this.LogWarning("Package manager is not available; cannot attach to build.");
return;
}

await this.packageManager.AttachPackageToBuildAsync(new AttachedPackage(AttachedPackageType.NuGet, info.Id, info.Version, info.SHA1, this.PackageSource), default);
}
}

protected override ExtendedRichDescription GetDescription(IOperationConfiguration config)
Expand All @@ -131,5 +173,58 @@ protected override ExtendedRichDescription GetDescription(IOperationConfiguratio
)
);
}

[Serializable]
private sealed class PackageInfo
{
private static readonly LazyRegex NuspecRegex = new LazyRegex(@"^[^/\\]+\.nuspec$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);

private PackageInfo(string id, string version, byte[] sha1)
{
this.Id = id;
this.Version = version;
this.SHA1 = sha1;
}

public string Id { get; }
public string Version { get; }
public byte[] SHA1 { get; }

public static PackageInfo Extract(string packagePath)
{
using (var fileStream = FileEx.Open(packagePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] hash;
using (var sha1 = System.Security.Cryptography.SHA1.Create())
{
hash = sha1.ComputeHash(fileStream);
}

fileStream.Position = 0;

using (var zip = new ZipArchive(fileStream, ZipArchiveMode.Read, true))
{
var nuspecFile = zip.Entries.FirstOrDefault(e => NuspecRegex.IsMatch(e.FullName));
if (nuspecFile == null)
throw new ExecutionFailureException(packagePath + " is not a valid NuGet package; it is missing a .nuspec file.");

using (var nuspecStream = nuspecFile.Open())
{
var xdoc = XDocument.Load(nuspecStream);
var ns = xdoc.Root.GetDefaultNamespace();
var id = (string)xdoc.Root.Element(ns + "metadata")?.Element(ns + "id");
if (string.IsNullOrWhiteSpace(id))
throw new ExecutionFailureException(packagePath + " has an invalid .nuspec file; missing \"id\" element.");

var version = (string)xdoc.Root.Element(ns + "metadata")?.Element(ns + "version");
if (string.IsNullOrWhiteSpace(version))
throw new ExecutionFailureException(packagePath + " has an invalid .nuspec file; missing \"version\" element.");

return new PackageInfo(id, version, hash);
}
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion NuGet/InedoExtension/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Inedo.NuGet" version="31.1" targetFramework="net452" />
<package id="Inedo.SDK" version="1.0.4" targetFramework="net452" />
<package id="Inedo.SDK" version="1.5.0" targetFramework="net452" />
</packages>

0 comments on commit e22301d

Please sign in to comment.