mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Build script updates (#33)
- Make generated NuGet packages deterministic. - Add a signing option to the build script. - Set versions for pre-release builds. - Publish packages to a MyGet feed. - Make Windows-produced artifacts match Linux-produced ones
This commit is contained in:
parent
0e118ae170
commit
b68261a092
9 changed files with 671 additions and 235 deletions
|
@ -1 +1 @@
|
||||||
2.1.500
|
2.2.103
|
5
GitVersion.yml
Normal file
5
GitVersion.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mode: ContinuousDeployment
|
||||||
|
increment: Patch
|
||||||
|
branches:
|
||||||
|
master:
|
||||||
|
tag: alpha
|
|
@ -1,5 +1,8 @@
|
||||||
version: 0.1.3-{build}
|
version: 0.1.3-{build}
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2017
|
||||||
|
environment:
|
||||||
|
myget_api_key:
|
||||||
|
secure: 0xJoYAtR6psXCRvk1qm5czDObkeRjHKPjfe5gIExXVFPwA0VVODYv/hBZYUtz2F3
|
||||||
build_script:
|
build_script:
|
||||||
- ps: .\build.ps1
|
- ps: .\build.ps1
|
||||||
test: off
|
test: off
|
18
build.ps1
18
build.ps1
|
@ -1,6 +1,7 @@
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
Param(
|
Param(
|
||||||
#[switch]$CustomParam,
|
#[switch]$CustomParam,
|
||||||
|
[switch]$BuildDotnetCoreOnly,
|
||||||
[Parameter(Position = 0, Mandatory = $false, ValueFromRemainingArguments = $true)]
|
[Parameter(Position = 0, Mandatory = $false, ValueFromRemainingArguments = $true)]
|
||||||
[string[]]$BuildArguments
|
[string[]]$BuildArguments
|
||||||
)
|
)
|
||||||
|
@ -43,14 +44,17 @@ try {
|
||||||
if (Test-Path $DotNetGlobalFile) {
|
if (Test-Path $DotNetGlobalFile) {
|
||||||
$DotNetVersion = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json).sdk.version
|
$DotNetVersion = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json).sdk.version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$DotNetDirectory = "$TempDirectory\dotnet-win"
|
||||||
|
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
|
||||||
|
|
||||||
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
|
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
|
||||||
if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
|
if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
|
||||||
(!(Test-Path variable:DotNetVersion) -or $(& cmd.exe /c 'dotnet --version 2>&1') -eq $DotNetVersion)) {
|
(!(Test-Path variable:DotNetVersion) -or $(& cmd.exe /c 'dotnet --version 2>&1') -eq $DotNetVersion)) {
|
||||||
$env:DOTNET_EXE = (Get-Command "dotnet").Path
|
$env:DOTNET_EXE = (Get-Command "dotnet").Path
|
||||||
}
|
}
|
||||||
else {
|
elseif ($null -eq (Get-Command $env:DOTNET_EXE -ErrorAction SilentlyContinue) -and `
|
||||||
$DotNetDirectory = "$TempDirectory\dotnet-win"
|
(!(Test-Path variable:DotNetVersion) -or $(& cmd.exe /c '$env:DOTNET_EXE --version 2>&1') -ne $DotNetVersion)) {
|
||||||
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
|
|
||||||
|
|
||||||
# Download install script
|
# Download install script
|
||||||
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
|
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
|
||||||
|
@ -68,8 +72,16 @@ try {
|
||||||
|
|
||||||
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
|
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
|
||||||
|
|
||||||
|
if($BuildDotnetCoreOnly) {
|
||||||
|
$BuildArguments += "-DoCoreBuildOnly"
|
||||||
|
$BuildArguments += "true"
|
||||||
|
}
|
||||||
|
|
||||||
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments }
|
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments }
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output $_.Exception.Message
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
if (Test-Path $DotNetGlobalFile) {
|
if (Test-Path $DotNetGlobalFile) {
|
||||||
Remove-Item $DotNetGlobalFile
|
Remove-Item $DotNetGlobalFile
|
||||||
|
|
40
build.sh
40
build.sh
|
@ -3,7 +3,7 @@
|
||||||
echo $(bash --version 2>&1 | head -n 1)
|
echo $(bash --version 2>&1 | head -n 1)
|
||||||
|
|
||||||
#CUSTOMPARAM=0
|
#CUSTOMPARAM=0
|
||||||
BUILD_ARGUMENTS=()
|
BUILD_ARGUMENTS=("-DoCoreBuildOnly")
|
||||||
for i in "$@"; do
|
for i in "$@"; do
|
||||||
case $(echo $1 | awk '{print tolower($0)}') in
|
case $(echo $1 | awk '{print tolower($0)}') in
|
||||||
# -custom-param) CUSTOMPARAM=1;;
|
# -custom-param) CUSTOMPARAM=1;;
|
||||||
|
@ -37,37 +37,41 @@ export NUGET_XMLDOC_MODE="skip"
|
||||||
function FirstJsonValue {
|
function FirstJsonValue {
|
||||||
perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2}
|
perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2}
|
||||||
}
|
}
|
||||||
trap "rm -f $DOTNET_GLOBAL_FILE" INT TERM EXIT
|
trap "rm -f \"$DOTNET_GLOBAL_FILE\"" INT TERM EXIT
|
||||||
|
|
||||||
dotnetCliVersion=$(cat DotnetCliVersion.txt)
|
dotnetCliVersion=$(cat DotnetCliVersion.txt)
|
||||||
|
|
||||||
json="{\"sdk\":{\"version\":\"$dotnetCliVersion\"}}"
|
json="{\"sdk\":{\"version\":\"$dotnetCliVersion\"}}"
|
||||||
echo "$json" > $DOTNET_GLOBAL_FILE
|
echo "$json" > "$DOTNET_GLOBAL_FILE"
|
||||||
|
|
||||||
# If global.json exists, load expected version
|
# If global.json exists, load expected version
|
||||||
if [ -f "$DOTNET_GLOBAL_FILE" ]; then
|
if [ -f "$DOTNET_GLOBAL_FILE" ]; then
|
||||||
DOTNET_VERSION=$dotnetCliVersion
|
DOTNET_VERSION=$dotnetCliVersion
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
|
||||||
|
export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
|
||||||
|
|
||||||
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
|
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
|
||||||
if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
|
if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
|
||||||
export DOTNET_EXE="$(command -v dotnet)"
|
export DOTNET_EXE="$(command -v dotnet)"
|
||||||
else
|
elif [[ ! (-x "$DOTNET_EXE" && (-z ${DOTNET_VERSION+x} || $($DOTNET_EXE --version) == "$DOTNET_VERSION")) ]]; then
|
||||||
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
|
|
||||||
export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
|
# Download install script
|
||||||
|
DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
|
||||||
|
mkdir -p "$TEMP_DIRECTORY"
|
||||||
|
|
||||||
|
if [ ! -x "$DOTNET_INSTALL_FILE" ]; then
|
||||||
|
curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
|
||||||
|
chmod +x "$DOTNET_INSTALL_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
# Download install script
|
# Install by channel or version
|
||||||
DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
|
if [ -z ${DOTNET_VERSION+x} ]; then
|
||||||
mkdir -p "$TEMP_DIRECTORY"
|
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
|
||||||
curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
|
else
|
||||||
chmod +x "$DOTNET_INSTALL_FILE"
|
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
|
||||||
|
fi
|
||||||
# Install by channel or version
|
|
||||||
if [ -z ${DOTNET_VERSION+x} ]; then
|
|
||||||
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
|
|
||||||
else
|
|
||||||
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
|
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
|
||||||
|
|
691
build/Build.cs
691
build/Build.cs
|
@ -4,265 +4,538 @@ using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using ILRepacking;
|
using ILRepacking;
|
||||||
using Nuke.Common;
|
using Nuke.Common;
|
||||||
|
using Nuke.Common.BuildServers;
|
||||||
using Nuke.Common.Git;
|
using Nuke.Common.Git;
|
||||||
using Nuke.Common.ProjectModel;
|
using Nuke.Common.ProjectModel;
|
||||||
using Nuke.Common.Tools.DotNet;
|
using Nuke.Common.Tools.DotNet;
|
||||||
|
using Nuke.Common.Tools.GitVersion;
|
||||||
|
using Nuke.Common.Tools.SignTool;
|
||||||
using static Nuke.Common.IO.FileSystemTasks;
|
using static Nuke.Common.IO.FileSystemTasks;
|
||||||
using static Nuke.Common.IO.PathConstruction;
|
using static Nuke.Common.IO.PathConstruction;
|
||||||
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
||||||
|
|
||||||
class Build : NukeBuild
|
namespace LibHacBuild
|
||||||
{
|
{
|
||||||
public static int Main() => Execute<Build>(x => x.Results);
|
partial class Build : NukeBuild
|
||||||
|
{
|
||||||
|
public static int Main() => Execute<Build>(x => x.Results);
|
||||||
|
|
||||||
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
|
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
|
||||||
readonly string Configuration = IsLocalBuild ? "Debug" : "Release";
|
readonly string Configuration = IsLocalBuild ? "Debug" : "Release";
|
||||||
|
|
||||||
[Solution("LibHac.sln")] readonly Solution Solution;
|
[Parameter("Build only .NET Core targets if true. Default is false on Windows")]
|
||||||
[GitRepository] readonly GitRepository GitRepository;
|
readonly bool DoCoreBuildOnly;
|
||||||
|
|
||||||
AbsolutePath SourceDirectory => RootDirectory / "src";
|
[Solution("LibHac.sln")] readonly Solution Solution;
|
||||||
AbsolutePath TestsDirectory => RootDirectory / "tests";
|
[GitRepository] readonly GitRepository GitRepository;
|
||||||
AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts";
|
[GitVersion] readonly GitVersion GitVersion;
|
||||||
AbsolutePath TempDirectory => RootDirectory / ".tmp";
|
|
||||||
AbsolutePath CliCoreDir => TempDirectory / "hactoolnet_netcoreapp2.1";
|
|
||||||
AbsolutePath CliFrameworkDir => TempDirectory / "hactoolnet_net46";
|
|
||||||
AbsolutePath CliFrameworkZip => ArtifactsDirectory / "hactoolnet.zip";
|
|
||||||
AbsolutePath CliCoreZip => ArtifactsDirectory / "hactoolnet_netcore.zip";
|
|
||||||
|
|
||||||
AbsolutePath CliMergedExe => ArtifactsDirectory / "hactoolnet.exe";
|
AbsolutePath SourceDirectory => RootDirectory / "src";
|
||||||
|
AbsolutePath TestsDirectory => RootDirectory / "tests";
|
||||||
|
AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts";
|
||||||
|
AbsolutePath SignedArtifactsDirectory => ArtifactsDirectory / "signed";
|
||||||
|
AbsolutePath TempDirectory => RootDirectory / ".tmp";
|
||||||
|
AbsolutePath CliCoreDir => TempDirectory / "hactoolnet_netcoreapp2.1";
|
||||||
|
AbsolutePath CliFrameworkDir => TempDirectory / "hactoolnet_net46";
|
||||||
|
AbsolutePath CliFrameworkZip => ArtifactsDirectory / "hactoolnet.zip";
|
||||||
|
AbsolutePath CliCoreZip => ArtifactsDirectory / "hactoolnet_netcore.zip";
|
||||||
|
|
||||||
Project LibHacProject => Solution.GetProject("LibHac").NotNull();
|
AbsolutePath CliMergedExe => ArtifactsDirectory / "hactoolnet.exe";
|
||||||
Project LibHacTestProject => Solution.GetProject("LibHac.Tests").NotNull();
|
|
||||||
Project HactoolnetProject => Solution.GetProject("hactoolnet").NotNull();
|
|
||||||
|
|
||||||
Target Clean => _ => _
|
Project LibHacProject => Solution.GetProject("LibHac").NotNull();
|
||||||
.Executes(() =>
|
Project LibHacTestProject => Solution.GetProject("LibHac.Tests").NotNull();
|
||||||
{
|
Project HactoolnetProject => Solution.GetProject("hactoolnet").NotNull();
|
||||||
DeleteDirectories(GlobDirectories(SourceDirectory, "**/bin", "**/obj"));
|
|
||||||
DeleteDirectories(GlobDirectories(TestsDirectory, "**/bin", "**/obj"));
|
|
||||||
EnsureCleanDirectory(ArtifactsDirectory);
|
|
||||||
EnsureCleanDirectory(CliCoreDir);
|
|
||||||
EnsureCleanDirectory(CliFrameworkDir);
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Restore => _ => _
|
string AppVeyorVersion { get; set; }
|
||||||
.DependsOn(Clean)
|
Dictionary<string, object> VersionProps { get; set; } = new Dictionary<string, object>();
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
DotNetRestoreSettings settings = new DotNetRestoreSettings()
|
|
||||||
.SetProjectFile(Solution);
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsUnix) settings = settings.RemoveRuntimes("net46");
|
const string CertFileName = "cert.pfx";
|
||||||
|
|
||||||
DotNetRestore(s => settings);
|
Target SetVersion => _ => _
|
||||||
});
|
.OnlyWhenStatic(() => GitRepository != null)
|
||||||
|
.Executes(() =>
|
||||||
Target Compile => _ => _
|
|
||||||
.DependsOn(Restore)
|
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
DotNetBuildSettings buildSettings = new DotNetBuildSettings()
|
|
||||||
.SetProjectFile(Solution)
|
|
||||||
.EnableNoRestore()
|
|
||||||
.SetConfiguration(Configuration);
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsUnix) buildSettings = buildSettings.SetFramework("netcoreapp2.1");
|
|
||||||
|
|
||||||
DotNetBuild(s => buildSettings);
|
|
||||||
|
|
||||||
DotNetPublishSettings publishSettings = new DotNetPublishSettings()
|
|
||||||
.EnableNoRestore()
|
|
||||||
.SetConfiguration(Configuration);
|
|
||||||
|
|
||||||
DotNetPublish(s => publishSettings
|
|
||||||
.SetProject(HactoolnetProject)
|
|
||||||
.SetFramework("netcoreapp2.1")
|
|
||||||
.SetOutput(CliCoreDir));
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsWin)
|
|
||||||
{
|
{
|
||||||
|
AppVeyorVersion = $"{GitVersion.AssemblySemVer}-{GitVersion.PreReleaseTag}+{GitVersion.Sha.Substring(0, 8)}";
|
||||||
|
|
||||||
|
VersionProps = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["VersionPrefix"] = GitVersion.AssemblySemVer,
|
||||||
|
["VersionSuffix"] = GitVersion.PreReleaseTag
|
||||||
|
};
|
||||||
|
|
||||||
|
Console.WriteLine($"Building version {AppVeyorVersion}");
|
||||||
|
|
||||||
|
if (Host == HostType.AppVeyor)
|
||||||
|
{
|
||||||
|
SetAppVeyorVersion(AppVeyorVersion);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Clean => _ => _
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
DeleteDirectories(GlobDirectories(SourceDirectory, "**/bin", "**/obj"));
|
||||||
|
DeleteDirectories(GlobDirectories(TestsDirectory, "**/bin", "**/obj"));
|
||||||
|
EnsureCleanDirectory(ArtifactsDirectory);
|
||||||
|
EnsureCleanDirectory(CliCoreDir);
|
||||||
|
EnsureCleanDirectory(CliFrameworkDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Restore => _ => _
|
||||||
|
.DependsOn(Clean)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
DotNetRestoreSettings settings = new DotNetRestoreSettings()
|
||||||
|
.SetProjectFile(Solution);
|
||||||
|
|
||||||
|
DotNetRestore(s => settings);
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Compile => _ => _
|
||||||
|
.DependsOn(Restore, SetVersion)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
DotNetBuildSettings buildSettings = new DotNetBuildSettings()
|
||||||
|
.SetProjectFile(Solution)
|
||||||
|
.EnableNoRestore()
|
||||||
|
.SetConfiguration(Configuration)
|
||||||
|
.SetProperties(VersionProps);
|
||||||
|
|
||||||
|
if (DoCoreBuildOnly) buildSettings = buildSettings.SetFramework("netcoreapp2.1");
|
||||||
|
|
||||||
|
DotNetBuild(s => buildSettings);
|
||||||
|
|
||||||
|
DotNetPublishSettings publishSettings = new DotNetPublishSettings()
|
||||||
|
.EnableNoRestore()
|
||||||
|
.SetConfiguration(Configuration);
|
||||||
|
|
||||||
DotNetPublish(s => publishSettings
|
DotNetPublish(s => publishSettings
|
||||||
.SetProject(HactoolnetProject)
|
.SetProject(HactoolnetProject)
|
||||||
.SetFramework("net46")
|
.SetFramework("netcoreapp2.1")
|
||||||
.SetOutput(CliFrameworkDir));
|
.SetOutput(CliCoreDir)
|
||||||
}
|
.SetProperties(VersionProps));
|
||||||
|
|
||||||
// Hack around OS newline differences
|
if (!DoCoreBuildOnly)
|
||||||
if (EnvironmentInfo.IsUnix)
|
|
||||||
{
|
|
||||||
foreach (string filename in Directory.EnumerateFiles(CliCoreDir, "*.json"))
|
|
||||||
{
|
{
|
||||||
ReplaceLineEndings(filename);
|
DotNetPublish(s => publishSettings
|
||||||
|
.SetProject(HactoolnetProject)
|
||||||
|
.SetFramework("net46")
|
||||||
|
.SetOutput(CliFrameworkDir)
|
||||||
|
.SetProperties(VersionProps));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Pack => _ => _
|
// Hack around OS newline differences
|
||||||
.DependsOn(Compile)
|
if (EnvironmentInfo.IsUnix)
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
DotNetPackSettings settings = new DotNetPackSettings()
|
|
||||||
.SetProject(LibHacProject)
|
|
||||||
.EnableNoBuild()
|
|
||||||
.SetConfiguration(Configuration)
|
|
||||||
.EnableIncludeSymbols()
|
|
||||||
.SetOutputDirectory(ArtifactsDirectory);
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsUnix)
|
|
||||||
settings = settings.SetProperties(
|
|
||||||
new Dictionary<string, object> { ["TargetFrameworks"] = "netcoreapp2.1" });
|
|
||||||
|
|
||||||
DotNetPack(s => settings);
|
|
||||||
|
|
||||||
if (Host != HostType.AppVeyor) return;
|
|
||||||
|
|
||||||
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory, "*.nupkg"))
|
|
||||||
{
|
|
||||||
PushArtifact(filename);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Merge => _ => _
|
|
||||||
.DependsOn(Compile)
|
|
||||||
.OnlyWhen(() => EnvironmentInfo.IsWin)
|
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
string[] libraries = Directory.GetFiles(CliFrameworkDir, "*.dll");
|
|
||||||
var cliList = new List<string> { CliFrameworkDir / "hactoolnet.exe" };
|
|
||||||
cliList.AddRange(libraries);
|
|
||||||
|
|
||||||
var cliOptions = new RepackOptions
|
|
||||||
{
|
|
||||||
OutputFile = CliMergedExe,
|
|
||||||
InputAssemblies = cliList.ToArray(),
|
|
||||||
SearchDirectories = new[] { "." }
|
|
||||||
};
|
|
||||||
|
|
||||||
new ILRepack(cliOptions).Repack();
|
|
||||||
|
|
||||||
if (Host == HostType.AppVeyor)
|
|
||||||
{
|
|
||||||
PushArtifact(CliMergedExe);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Test => _ => _
|
|
||||||
.DependsOn(Compile)
|
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
DotNetTestSettings settings = new DotNetTestSettings()
|
|
||||||
.SetProjectFile(LibHacTestProject)
|
|
||||||
.EnableNoBuild()
|
|
||||||
.SetConfiguration(Configuration);
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsUnix) settings = settings.SetFramework("netcoreapp2.1");
|
|
||||||
|
|
||||||
DotNetTest(s => settings);
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Zip => _ => _
|
|
||||||
.DependsOn(Pack)
|
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
string[] namesFx = Directory.EnumerateFiles(CliFrameworkDir, "*.exe")
|
|
||||||
.Concat(Directory.EnumerateFiles(CliFrameworkDir, "*.dll"))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
string[] namesCore = Directory.EnumerateFiles(CliCoreDir, "*.json")
|
|
||||||
.Concat(Directory.EnumerateFiles(CliCoreDir, "*.dll"))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
if (EnvironmentInfo.IsWin)
|
|
||||||
{
|
|
||||||
ZipFiles(CliFrameworkZip, namesFx);
|
|
||||||
Console.WriteLine($"Created {CliFrameworkZip}");
|
|
||||||
}
|
|
||||||
|
|
||||||
ZipFiles(CliCoreZip, namesCore);
|
|
||||||
Console.WriteLine($"Created {CliCoreZip}");
|
|
||||||
|
|
||||||
if (Host == HostType.AppVeyor)
|
|
||||||
{
|
|
||||||
PushArtifact(CliFrameworkZip);
|
|
||||||
PushArtifact(CliCoreZip);
|
|
||||||
PushArtifact(CliMergedExe);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Target Results => _ => _
|
|
||||||
.DependsOn(Test, Zip, Merge)
|
|
||||||
.Executes(() =>
|
|
||||||
{
|
|
||||||
Console.WriteLine("SHA-1:");
|
|
||||||
using (SHA1 sha = SHA1.Create())
|
|
||||||
{
|
|
||||||
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory))
|
|
||||||
{
|
{
|
||||||
using (var stream = new FileStream(filename, FileMode.Open))
|
foreach (string filename in Directory.EnumerateFiles(CliCoreDir, "*.json"))
|
||||||
{
|
{
|
||||||
string hash = BitConverter.ToString(sha.ComputeHash(stream)).Replace("-", "");
|
ReplaceLineEndings(filename);
|
||||||
Console.WriteLine($"{hash} - {Path.GetFileName(filename)}");
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Pack => _ => _
|
||||||
|
.DependsOn(Compile)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
DotNetPackSettings settings = new DotNetPackSettings()
|
||||||
|
.SetProject(LibHacProject)
|
||||||
|
.EnableNoBuild()
|
||||||
|
.SetConfiguration(Configuration)
|
||||||
|
.EnableIncludeSymbols()
|
||||||
|
.SetSymbolPackageFormat(DotNetSymbolPackageFormat.snupkg)
|
||||||
|
.SetOutputDirectory(ArtifactsDirectory)
|
||||||
|
.SetProperties(VersionProps);
|
||||||
|
|
||||||
|
if (DoCoreBuildOnly)
|
||||||
|
settings = settings.SetProperty("TargetFrameworks", "netcoreapp2.1");
|
||||||
|
|
||||||
|
DotNetPack(s => settings);
|
||||||
|
|
||||||
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory, "*.*nupkg"))
|
||||||
|
{
|
||||||
|
RepackNugetPackage(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Host != HostType.AppVeyor) return;
|
||||||
|
|
||||||
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory, "*.*nupkg"))
|
||||||
|
{
|
||||||
|
PushArtifact(filename);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Merge => _ => _
|
||||||
|
.DependsOn(Compile)
|
||||||
|
.OnlyWhenStatic(() => !DoCoreBuildOnly)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
string[] libraries = Directory.GetFiles(CliFrameworkDir, "*.dll");
|
||||||
|
var cliList = new List<string> { CliFrameworkDir / "hactoolnet.exe" };
|
||||||
|
cliList.AddRange(libraries);
|
||||||
|
|
||||||
|
var cliOptions = new RepackOptions
|
||||||
|
{
|
||||||
|
OutputFile = CliMergedExe,
|
||||||
|
InputAssemblies = cliList.ToArray(),
|
||||||
|
SearchDirectories = new[] { "." }
|
||||||
|
};
|
||||||
|
|
||||||
|
new ILRepack(cliOptions).Repack();
|
||||||
|
|
||||||
|
foreach (AbsolutePath file in ArtifactsDirectory.GlobFiles("*.exe.config"))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Host == HostType.AppVeyor)
|
||||||
|
{
|
||||||
|
PushArtifact(CliMergedExe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Test => _ => _
|
||||||
|
.DependsOn(Compile)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
DotNetTestSettings settings = new DotNetTestSettings()
|
||||||
|
.SetProjectFile(LibHacTestProject)
|
||||||
|
.EnableNoBuild()
|
||||||
|
.SetConfiguration(Configuration);
|
||||||
|
|
||||||
|
if (DoCoreBuildOnly) settings = settings.SetFramework("netcoreapp2.1");
|
||||||
|
|
||||||
|
DotNetTest(s => settings);
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Zip => _ => _
|
||||||
|
.DependsOn(Pack)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
string[] namesFx = Directory.EnumerateFiles(CliFrameworkDir, "*.exe")
|
||||||
|
.Concat(Directory.EnumerateFiles(CliFrameworkDir, "*.dll"))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
string[] namesCore = Directory.EnumerateFiles(CliCoreDir, "*.json")
|
||||||
|
.Concat(Directory.EnumerateFiles(CliCoreDir, "*.dll"))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (!DoCoreBuildOnly)
|
||||||
|
{
|
||||||
|
ZipFiles(CliFrameworkZip, namesFx);
|
||||||
|
Console.WriteLine($"Created {CliFrameworkZip}");
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipFiles(CliCoreZip, namesCore);
|
||||||
|
Console.WriteLine($"Created {CliCoreZip}");
|
||||||
|
|
||||||
|
if (Host == HostType.AppVeyor)
|
||||||
|
{
|
||||||
|
PushArtifact(CliFrameworkZip);
|
||||||
|
PushArtifact(CliCoreZip);
|
||||||
|
PushArtifact(CliMergedExe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Publish => _ => _
|
||||||
|
.DependsOn(Test)
|
||||||
|
.OnlyWhenStatic(() => Host == HostType.AppVeyor)
|
||||||
|
.OnlyWhenStatic(() => AppVeyor.Instance.PullRequestTitle == null)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
AbsolutePath nupkgFile = ArtifactsDirectory.GlobFiles("*.nupkg").Single();
|
||||||
|
AbsolutePath snupkgFile = ArtifactsDirectory.GlobFiles("*.snupkg").Single();
|
||||||
|
|
||||||
|
string apiKey = EnvironmentInfo.Variable("myget_api_key");
|
||||||
|
DotNetNuGetPushSettings settings = new DotNetNuGetPushSettings()
|
||||||
|
.SetApiKey(apiKey)
|
||||||
|
.SetSymbolApiKey(apiKey)
|
||||||
|
.SetSource("https://www.myget.org/F/libhac/api/v2/package")
|
||||||
|
.SetSymbolSource("https://www.myget.org/F/libhac/symbols/api/v2/package");
|
||||||
|
|
||||||
|
DotNetNuGetPush(settings.SetTargetPath(nupkgFile));
|
||||||
|
DotNetNuGetPush(settings.SetTargetPath(snupkgFile));
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Results => _ => _
|
||||||
|
.DependsOn(Test, Zip, Merge, Sign, Publish)
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("SHA-1:");
|
||||||
|
using (SHA1 sha = SHA1.Create())
|
||||||
|
{
|
||||||
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory))
|
||||||
|
{
|
||||||
|
using (var stream = new FileStream(filename, FileMode.Open))
|
||||||
|
{
|
||||||
|
string hash = BitConverter.ToString(sha.ComputeHash(stream)).Replace("-", "");
|
||||||
|
Console.WriteLine($"{hash} - {Path.GetFileName(filename)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Target Sign => _ => _
|
||||||
|
.DependsOn(Test, Zip, Merge)
|
||||||
|
.OnlyWhenStatic(() => !DoCoreBuildOnly)
|
||||||
|
.OnlyWhenStatic(() => File.Exists(CertFileName))
|
||||||
|
.Executes(() =>
|
||||||
|
{
|
||||||
|
string pwd = ReadPassword();
|
||||||
|
|
||||||
|
if (pwd == string.Empty)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Skipping sign task");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignAndReZip(pwd);
|
||||||
|
});
|
||||||
|
|
||||||
|
public static void ZipFiles(string outFile, IEnumerable<string> files)
|
||||||
|
{
|
||||||
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
||||||
|
{
|
||||||
|
s.SetLevel(9);
|
||||||
|
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
var entry = new ZipEntry(Path.GetFileName(file));
|
||||||
|
entry.DateTime = DateTime.UnixEpoch;
|
||||||
|
|
||||||
|
using (FileStream fs = File.OpenRead(file))
|
||||||
|
{
|
||||||
|
entry.Size = fs.Length;
|
||||||
|
s.PutNextEntry(entry);
|
||||||
|
fs.CopyTo(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
public static void ZipFiles(string outFile, string[] files)
|
public static void ZipDirectory(string outFile, string directory)
|
||||||
{
|
|
||||||
using (var s = new ZipOutputStream(File.Create(outFile)))
|
|
||||||
{
|
{
|
||||||
s.SetLevel(9);
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
||||||
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
{
|
||||||
var entry = new ZipEntry(Path.GetFileName(file));
|
s.SetLevel(9);
|
||||||
entry.DateTime = DateTime.UnixEpoch;
|
|
||||||
|
|
||||||
using (FileStream fs = File.OpenRead(file))
|
foreach (string filePath in Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
entry.Size = fs.Length;
|
string relativePath = Path.GetRelativePath(directory, filePath);
|
||||||
s.PutNextEntry(entry);
|
|
||||||
fs.CopyTo(s);
|
var entry = new ZipEntry(relativePath);
|
||||||
|
entry.DateTime = DateTime.UnixEpoch;
|
||||||
|
|
||||||
|
using (FileStream fs = File.OpenRead(filePath))
|
||||||
|
{
|
||||||
|
entry.Size = fs.Length;
|
||||||
|
s.PutNextEntry(entry);
|
||||||
|
fs.CopyTo(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static void PushArtifact(string path)
|
public static void ZipDirectory(string outFile, string directory, IEnumerable<string> files)
|
||||||
{
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Unable to add artifact {path}");
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
||||||
|
{
|
||||||
|
s.SetLevel(9);
|
||||||
|
|
||||||
|
foreach (string filePath in files)
|
||||||
|
{
|
||||||
|
string absolutePath = Path.Combine(directory, filePath);
|
||||||
|
|
||||||
|
var entry = new ZipEntry(filePath);
|
||||||
|
entry.DateTime = DateTime.UnixEpoch;
|
||||||
|
|
||||||
|
using (FileStream fs = File.OpenRead(absolutePath))
|
||||||
|
{
|
||||||
|
entry.Size = fs.Length;
|
||||||
|
s.PutNextEntry(entry);
|
||||||
|
fs.CopyTo(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var psi = new ProcessStartInfo
|
public static void UnzipFiles(string zipFile, string outDir)
|
||||||
{
|
{
|
||||||
FileName = "appveyor",
|
using (var s = new ZipInputStream(File.OpenRead(zipFile)))
|
||||||
Arguments = $"PushArtifact \"{path}\"",
|
{
|
||||||
UseShellExecute = false,
|
ZipEntry entry;
|
||||||
RedirectStandardOutput = true,
|
while ((entry = s.GetNextEntry()) != null)
|
||||||
RedirectStandardError = true
|
{
|
||||||
};
|
string outPath = Path.Combine(outDir, entry.Name);
|
||||||
|
|
||||||
var proc = new Process
|
string directoryName = Path.GetDirectoryName(outPath);
|
||||||
|
string fileName = Path.GetFileName(outPath);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(directoryName))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(fileName))
|
||||||
|
{
|
||||||
|
using (FileStream outFile = File.Create(outPath))
|
||||||
|
{
|
||||||
|
s.CopyTo(outFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PushArtifact(string path)
|
||||||
{
|
{
|
||||||
StartInfo = psi
|
if (!File.Exists(path))
|
||||||
};
|
{
|
||||||
|
Console.WriteLine($"Unable to add artifact {path}");
|
||||||
|
}
|
||||||
|
|
||||||
proc.Start();
|
var psi = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "appveyor",
|
||||||
|
Arguments = $"PushArtifact \"{path}\"",
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true
|
||||||
|
};
|
||||||
|
|
||||||
proc.WaitForExit();
|
var proc = new Process
|
||||||
|
{
|
||||||
|
StartInfo = psi
|
||||||
|
};
|
||||||
|
|
||||||
Console.WriteLine($"Added AppVeyor artifact {path}");
|
proc.Start();
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReplaceLineEndings(string filename)
|
proc.WaitForExit();
|
||||||
{
|
|
||||||
string text = File.ReadAllText(filename);
|
Console.WriteLine($"Added AppVeyor artifact {path}");
|
||||||
File.WriteAllText(filename, text.Replace("\n", "\r\n"));
|
}
|
||||||
|
|
||||||
|
public static void SetAppVeyorVersion(string version)
|
||||||
|
{
|
||||||
|
var psi = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "appveyor",
|
||||||
|
Arguments = $"UpdateBuild -Version \"{version}\"",
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var proc = new Process
|
||||||
|
{
|
||||||
|
StartInfo = psi
|
||||||
|
};
|
||||||
|
|
||||||
|
proc.Start();
|
||||||
|
|
||||||
|
proc.WaitForExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ReplaceLineEndings(string filename)
|
||||||
|
{
|
||||||
|
string text = File.ReadAllText(filename);
|
||||||
|
File.WriteAllText(filename, Regex.Replace(text, @"\r\n|\n\r|\n|\r", "\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SignAssemblies(string password, params string[] fileNames)
|
||||||
|
{
|
||||||
|
SignToolSettings settings = new SignToolSettings()
|
||||||
|
.SetFileDigestAlgorithm("SHA256")
|
||||||
|
.SetFile(CertFileName)
|
||||||
|
.SetFiles(fileNames)
|
||||||
|
.SetPassword(password)
|
||||||
|
.SetTimestampServerDigestAlgorithm("SHA256")
|
||||||
|
.SetRfc3161TimestampServerUrl("http://timestamp.digicert.com");
|
||||||
|
|
||||||
|
SignToolTasks.SignTool(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignAndReZip(string password)
|
||||||
|
{
|
||||||
|
AbsolutePath nupkgFile = ArtifactsDirectory.GlobFiles("*.nupkg").Single();
|
||||||
|
AbsolutePath snupkgFile = ArtifactsDirectory.GlobFiles("*.snupkg").Single();
|
||||||
|
AbsolutePath nupkgDir = TempDirectory / ("sign_" + Path.GetFileName(nupkgFile));
|
||||||
|
AbsolutePath netFxDir = TempDirectory / ("sign_" + Path.GetFileName(CliFrameworkZip));
|
||||||
|
AbsolutePath coreFxDir = TempDirectory / ("sign_" + Path.GetFileName(CliCoreZip));
|
||||||
|
AbsolutePath signedMergedExe = SignedArtifactsDirectory / Path.GetFileName(CliMergedExe);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UnzipFiles(CliFrameworkZip, netFxDir);
|
||||||
|
UnzipFiles(CliCoreZip, coreFxDir);
|
||||||
|
List<string> pkgFileList = UnzipPackage(nupkgFile, nupkgDir);
|
||||||
|
|
||||||
|
var toSign = new List<AbsolutePath>();
|
||||||
|
toSign.AddRange(nupkgDir.GlobFiles("**/LibHac.dll"));
|
||||||
|
toSign.Add(netFxDir / "hactoolnet.exe");
|
||||||
|
toSign.Add(coreFxDir / "hactoolnet.dll");
|
||||||
|
toSign.Add(signedMergedExe);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(SignedArtifactsDirectory);
|
||||||
|
File.Copy(CliMergedExe, signedMergedExe, true);
|
||||||
|
|
||||||
|
SignAssemblies(password, toSign.Select(x => x.ToString()).ToArray());
|
||||||
|
|
||||||
|
// Avoid having multiple signed versions of the same file
|
||||||
|
File.Copy(nupkgDir / "lib" / "net46" / "LibHac.dll", netFxDir / "LibHac.dll", true);
|
||||||
|
File.Copy(nupkgDir / "lib" / "netcoreapp2.1" / "LibHac.dll", coreFxDir / "LibHac.dll", true);
|
||||||
|
|
||||||
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(nupkgFile), nupkgDir, pkgFileList);
|
||||||
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(CliFrameworkZip), netFxDir);
|
||||||
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(CliCoreZip), coreFxDir);
|
||||||
|
|
||||||
|
File.Copy(snupkgFile, SignedArtifactsDirectory / Path.GetFileName(snupkgFile));
|
||||||
|
|
||||||
|
SignNupkg(SignedArtifactsDirectory / Path.GetFileName(nupkgFile), password);
|
||||||
|
SignNupkg(SignedArtifactsDirectory / Path.GetFileName(snupkgFile), password);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Directory.Delete(SignedArtifactsDirectory, true);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Directory.Delete(nupkgDir, true);
|
||||||
|
Directory.Delete(netFxDir, true);
|
||||||
|
Directory.Delete(coreFxDir, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ReadPassword()
|
||||||
|
{
|
||||||
|
var pwd = new StringBuilder();
|
||||||
|
ConsoleKeyInfo key;
|
||||||
|
|
||||||
|
Console.Write("Enter certificate password (Empty password to skip): ");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
key = Console.ReadKey(true);
|
||||||
|
|
||||||
|
// Ignore any key out of range.
|
||||||
|
if (((int)key.Key) >= '!' && ((int)key.Key <= '~'))
|
||||||
|
{
|
||||||
|
// Append the character to the password.
|
||||||
|
pwd.Append(key.KeyChar);
|
||||||
|
Console.Write("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit if Enter key is pressed.
|
||||||
|
} while (key.Key != ConsoleKey.Enter);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
return pwd.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
136
build/RepackNuget.cs
Normal file
136
build/RepackNuget.cs
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
using Nuke.Common.Tools.NuGet;
|
||||||
|
using static Nuke.Common.IO.FileSystemTasks;
|
||||||
|
using static Nuke.Common.IO.PathConstruction;
|
||||||
|
|
||||||
|
namespace LibHacBuild
|
||||||
|
{
|
||||||
|
public partial class Build
|
||||||
|
{
|
||||||
|
public void RepackNugetPackage(string path)
|
||||||
|
{
|
||||||
|
AbsolutePath tempDir = TempDirectory / Path.GetFileName(path);
|
||||||
|
AbsolutePath libDir = tempDir / "lib";
|
||||||
|
AbsolutePath relsFile = tempDir / "_rels" / ".rels";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EnsureCleanDirectory(tempDir);
|
||||||
|
List<string> fileList = UnzipPackage(path, tempDir);
|
||||||
|
|
||||||
|
string newPsmdcpName = CalcPsmdcpName(libDir);
|
||||||
|
string newPsmdcpPath = RenamePsmdcp(tempDir, newPsmdcpName);
|
||||||
|
EditManifestRelationships(relsFile, newPsmdcpPath);
|
||||||
|
|
||||||
|
int index = fileList.FindIndex(x => x.Contains(".psmdcp"));
|
||||||
|
fileList[index] = newPsmdcpPath;
|
||||||
|
|
||||||
|
IEnumerable<string> files = Directory.EnumerateFiles(tempDir, "*.json", SearchOption.AllDirectories)
|
||||||
|
.Concat(Directory.EnumerateFiles(tempDir, "*.xml", SearchOption.AllDirectories))
|
||||||
|
.Concat(Directory.EnumerateFiles(tempDir, "*.rels", SearchOption.AllDirectories))
|
||||||
|
.Concat(Directory.EnumerateFiles(tempDir, "*.psmdcp", SearchOption.AllDirectories))
|
||||||
|
.Concat(Directory.EnumerateFiles(tempDir, "*.nuspec", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
foreach (string filename in files)
|
||||||
|
{
|
||||||
|
Console.WriteLine(filename);
|
||||||
|
ReplaceLineEndings(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipDirectory(path, tempDir, fileList);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Directory.Delete(tempDir, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> UnzipPackage(string package, string dest)
|
||||||
|
{
|
||||||
|
var fileList = new List<string>();
|
||||||
|
|
||||||
|
UnzipFiles(package, dest);
|
||||||
|
|
||||||
|
using (var s = new ZipInputStream(File.OpenRead(package)))
|
||||||
|
{
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = s.GetNextEntry()) != null)
|
||||||
|
{
|
||||||
|
fileList.Add(entry.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CalcPsmdcpName(string libDir)
|
||||||
|
{
|
||||||
|
using (SHA256 sha = SHA256.Create())
|
||||||
|
{
|
||||||
|
foreach (string file in Directory.EnumerateFiles(libDir))
|
||||||
|
{
|
||||||
|
byte[] data = File.ReadAllBytes(file);
|
||||||
|
sha.TransformBlock(data, 0, data.Length, data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sha.TransformFinalBlock(new byte[0], 0, 0);
|
||||||
|
|
||||||
|
return ToHexString(sha.Hash).ToLower().Substring(0, 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RenamePsmdcp(string packageDir, string name)
|
||||||
|
{
|
||||||
|
string fileName = Directory.EnumerateFiles(packageDir, "*.psmdcp", SearchOption.AllDirectories).Single();
|
||||||
|
string newFileName = Path.Combine(Path.GetDirectoryName(fileName), name + ".psmdcp");
|
||||||
|
Directory.Move(fileName, newFileName);
|
||||||
|
|
||||||
|
return Path.GetRelativePath(packageDir, newFileName).Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
|
||||||
|
public void EditManifestRelationships(string path, string psmdcpPath)
|
||||||
|
{
|
||||||
|
XDocument doc = XDocument.Load(path);
|
||||||
|
XNamespace ns = doc.Root.GetDefaultNamespace();
|
||||||
|
|
||||||
|
foreach (XElement rs in doc.Root.Elements(ns + "Relationship"))
|
||||||
|
{
|
||||||
|
using (SHA256 sha = SHA256.Create())
|
||||||
|
{
|
||||||
|
if (rs.Attribute("Target").Value.Contains(".psmdcp"))
|
||||||
|
{
|
||||||
|
rs.Attribute("Target").Value = "/" + psmdcpPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string s = "/" + psmdcpPath + rs.Attribute("Target").Value;
|
||||||
|
byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(s));
|
||||||
|
string id = "R" + ToHexString(hash).Substring(0, 16);
|
||||||
|
rs.Attribute("Id").Value = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.Save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignNupkg(string pkgPath, string password)
|
||||||
|
{
|
||||||
|
NuGetTasks.NuGet(
|
||||||
|
$"sign \"{pkgPath}\" -CertificatePath cert.pfx -CertificatePassword {password} -Timestamper http://timestamp.digicert.com",
|
||||||
|
outputFilter: x => x.Replace(password, "hunter2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToHexString(byte[] arr)
|
||||||
|
{
|
||||||
|
return BitConverter.ToString(arr).ToLower().Replace("-", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,15 +4,17 @@
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<RootNamespace></RootNamespace>
|
<RootNamespace>LibHacBuild</RootNamespace>
|
||||||
<IsPackable>False</IsPackable>
|
<IsPackable>False</IsPackable>
|
||||||
<NoWarn>CS0649;CS0169</NoWarn>
|
<NoWarn>CS0649;CS0169</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Nuke.Common" Version="0.12.0" />
|
<PackageReference Include="GitVersion.CommandLine.DotNetCore" Version="4.0.0" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.0.0" />
|
|
||||||
<PackageReference Include="ILRepack.Lib" Version="2.0.16" NoWarn="NU1701" />
|
<PackageReference Include="ILRepack.Lib" Version="2.0.16" NoWarn="NU1701" />
|
||||||
|
<PackageReference Include="NuGet.CommandLine" Version="4.9.3" />
|
||||||
|
<PackageReference Include="Nuke.Common" Version="0.16.0" />
|
||||||
|
<PackageReference Include="SharpZipLib" Version="1.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -19,8 +19,9 @@
|
||||||
<VersionPrefix>0.2.0</VersionPrefix>
|
<VersionPrefix>0.2.0</VersionPrefix>
|
||||||
<PathMap>$(MSBuildProjectDirectory)=C:/LibHac/</PathMap>
|
<PathMap>$(MSBuildProjectDirectory)=C:/LibHac/</PathMap>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
<IncludeSource>true</IncludeSource>
|
<IncludeSource>true</IncludeSource>
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
<NoWarn>$(NoWarn);1591;NU5105</NoWarn>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue