Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ for:
secure: QWdxOY0xIK4XR50AYb77TKCmMd2k00iEBfrYYxzhwM+pDyvSjQXO6Oqg1epfe0KRpZNc+a9cGwCJ8qMyCEQxsA==
init:
- curl -sSL https://dot.net/v1/dotnet-install.sh | /bin/bash -s -- --channel 8.0
- brew install create-dmg
build_script:
- dotnet tool install Cake.Tool --create-manifest-if-needed
- dotnet tool run dotnet-cake ./build-macos.cake --settings_skippackageversioncheck=true
artifacts:
- path: 'artifacts\StructuredLogViewer-*.zip'
- path: 'artifacts\StructuredLogViewer-*.dmg'
name: 'Structured Log Viewer macOS app'
on_failure:
- appveyor PushArtifact msbuild.binlog
135 changes: 121 additions & 14 deletions build-macos.cake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var netCoreProject = new {

var certIsSet = !string.IsNullOrEmpty(EnvironmentVariable("P12_BASE64"));
var certNameIsSet = !string.IsNullOrEmpty(EnvironmentVariable("APPLE_CERT_NAME"));
var appleIdSet = !string.IsNullOrEmpty(EnvironmentVariable("APPLE_ID_EMAIL"));

var keychainPath = "app-signing.keychain";
var keychainPassword = Guid.NewGuid().ToString("N");
Expand Down Expand Up @@ -321,34 +322,140 @@ Task("Install-Certificate")
}
});

Task("Compress-Bundle")
Task("Create-Dmg")
.IsDependentOn("Sign-Bundle")
.Does(() =>
{
var runtimeIdentifiers = netCoreProject.Runtimes.Where(r => r.StartsWith("osx"));
foreach(var runtime in runtimeIdentifiers)
{
Information($"Compressing {runtime} macOS bundle");
var appBundlePath = artifactsDir.Combine(runtime).Combine($"{macAppName}.app");
Information($"Creating {runtime} macOS dmg");
var architecture = runtime[(runtime.IndexOf("-")+1)..];
var sourceDirectory = artifactsDir.Combine(runtime);
var appBundleFileName = $"{macAppName}.app";
var volumeName = $"{macAppName}.{architecture}";

var dmgPath = artifactsDir.Combine(runtime).CombineWithFilePath($"../{macAppName}-{architecture}.dmg");

var args = new ProcessArgumentBuilder();
args.Append("--volname");
args.AppendQuoted(volumeName);
// Necessary to disable AppleScript and other GUI dependent operations.
// On the CI we don't have it as an option.
args.Append("--skip-jenkins");
args.Append("--window-pos 200 120");
args.Append("--window-size 800 400");
args.Append("--icon-size 100");

// AppBundle icon
args.Append("--icon");
args.AppendQuoted(appBundleFileName);
args.Append("200 190");

// `/Applications` folder icon
args.Append("--icon");
args.AppendQuoted("Applications");
args.Append("200 190");

args.Append("--hide-extension");
args.AppendQuoted(appBundleFileName);
args.Append("--app-drop-link 600 185");

args.AppendQuoted(dmgPath.ToString());
args.AppendQuoted(sourceDirectory.ToString());

RunToolWithOutput("create-dmg", new ProcessSettings
{
Arguments = args.RenderSafe()
});
}
});

Task("Sign-Dmg")
.WithCriteria(certNameIsSet)
.IsDependentOn("Create-Dmg")
.Does(() =>
{
var runtimeIdentifiers = netCoreProject.Runtimes.Where(r => r.StartsWith("osx"));
foreach(var runtime in runtimeIdentifiers)
{
Information($"Signing {runtime} macOS dmg");
var architecture = runtime[(runtime.IndexOf("-")+1)..];
var zippedPath = artifactsDir.Combine(runtime).CombineWithFilePath($"../{macAppName}-{architecture}.zip");
var dmgPath = artifactsDir.Combine(runtime).CombineWithFilePath($"../{macAppName}-{architecture}.dmg");
var signingIdentity = EnvironmentVariable("APPLE_CERT_NAME");

var args = new ProcessArgumentBuilder();
args.Append("-c");
args.Append("-k");
args.Append("--keepParent");
args.AppendQuoted(appBundlePath.ToString());
args.AppendQuoted(zippedPath.ToString());

// "Ditto" is absolutely necessary instead of "zip" command.
// Otherwise no symlinks are saved, and notarize process would fail.
RunToolWithOutput("ditto", new ProcessSettings
args.Append("--options runtime");
args.Append("--sign");
args.AppendQuoted(signingIdentity);
args.AppendQuoted(dmgPath.ToString());

RunToolWithOutput("codesign", new ProcessSettings
{
Arguments = args.RenderSafe()
});
}
});

Task("Notarize-And-Staple-Dmg")
.WithCriteria(appleIdSet)
.IsDependentOn("Sign-Dmg")
.Does(() =>
{
var runtimeIdentifiers = netCoreProject.Runtimes.Where(r => r.StartsWith("osx"));
foreach(var runtime in runtimeIdentifiers)
{
var architecture = runtime[(runtime.IndexOf("-")+1)..];
var dmgPath = artifactsDir.Combine(runtime).CombineWithFilePath($"../{macAppName}-{architecture}.dmg");
var appBundlePath = artifactsDir.Combine(runtime).Combine($"{macAppName}.app");

Information($"Notarizing {runtime} macOS dmg");
{
var appleIdEmail = EnvironmentVariable("APPLE_ID_EMAIL");
var appleIdPass = EnvironmentVariable("APPLE_ID_PASSWORD");
var appleTeamId = EnvironmentVariable("APPLE_TEAM_ID");

var args = new ProcessArgumentBuilder();
args.Append("submit");
args.AppendQuoted(dmgPath.ToString());
args.Append("--apple-id");
args.AppendQuoted(appleIdEmail);
args.Append("--password");
args.AppendQuoted(appleIdPass);
args.Append("--team-id");
args.AppendQuoted(appleTeamId);
args.Append("--wait");
RunToolWithOutput("notarytool", new ProcessSettings
{
Arguments = args.RenderSafe()
});
}

Information($"Stapling {runtime} macOS dmg");
{
var args = new ProcessArgumentBuilder();
args.Append("staple");
args.AppendQuoted(dmgPath.ToString());
RunToolWithOutput("stapler", new ProcessSettings
{
Arguments = args.RenderSafe()
});
}

// It's not necessary to staple .app alone, unless we will distribute it zipped for auto-update. But it also doesn't harm.
Information($"Stapling {runtime} macOS app");
{
var args = new ProcessArgumentBuilder();
args.Append("staple");
args.AppendQuoted(appBundlePath.ToString());
RunToolWithOutput("stapler", new ProcessSettings
{
Arguments = args.RenderSafe()
});
}
}
});

Task("Cleanup-After-Sign")
.WithCriteria(certIsSet)
.IsDependentOn("Sign-Bundle")
Expand All @@ -366,7 +473,7 @@ Task("Package-Mac")
.IsDependentOn("Create-Bundle")
.IsDependentOn("Sign-Bundle")
.IsDependentOn("Cleanup-After-Sign")
.IsDependentOn("Compress-Bundle");
.IsDependentOn("Notarize-And-Staple-Dmg");

Task("Default")
.IsDependentOn("Restore-NetCore")
Expand Down
6 changes: 0 additions & 6 deletions notarize.sh

This file was deleted.

14 changes: 0 additions & 14 deletions staple.sh

This file was deleted.