Skip to content

Commit

Permalink
Merge pull request #171 from smallketchup82/velopack
Browse files Browse the repository at this point in the history
Migrate to Velopack
  • Loading branch information
peppy authored Sep 4, 2024
2 parents ccd5e6f + 16ad94b commit ca43ff3
Show file tree
Hide file tree
Showing 20 changed files with 749 additions and 596 deletions.
12 changes: 12 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"vpk": {
"version": "0.0.598-g933b2ab",
"commands": [
"vpk"
]
}
}
}
47 changes: 47 additions & 0 deletions Builders/AndroidBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public class AndroidBuilder : Builder
{
private readonly string? codeSigningPassword;

public AndroidBuilder(string version, string? codeSigningPassword)
: base(version)
{
if (!string.IsNullOrEmpty(Program.AndroidCodeSigningCertPath))
this.codeSigningPassword = codeSigningPassword ?? Program.ReadLineMasked("Enter code signing password: ");
}

protected override string TargetFramework => "net8.0-android";
protected override string RuntimeIdentifier => "android-arm64";

public override Uploader CreateUploader() => new GitHubUploader();

public override void Build()
{
string codeSigningArguments = string.Empty;

if (!string.IsNullOrEmpty(Program.AndroidCodeSigningCertPath))
{
codeSigningArguments +=
$" -p:AndroidKeyStore=true"
+ $" -p:AndroidSigningKeyStore={Program.AndroidCodeSigningCertPath}"
+ $" -p:AndroidSigningKeyAlias={Path.GetFileNameWithoutExtension(Program.AndroidCodeSigningCertPath)}"
+ $" -p:AndroidSigningKeyPass={codeSigningPassword}"
+ $" -p:AndroidSigningKeyStorePass={codeSigningPassword}";
}

string[] versionParts = Version.Split('.');
string versionCode = versionParts[0].PadLeft(4, '0') + versionParts[1].PadLeft(4, '0') + versionParts[2].PadLeft(1, '0');

RunDotnetPublish($"-p:ApplicationVersion={versionCode} {codeSigningArguments}");

File.Move(Path.Combine(Program.StagingPath, "sh.ppy.osulazer-Signed.apk"), Path.Combine(Program.ReleasesPath, "sh.ppy.osulazer.apk"), true);
}
}
}
53 changes: 53 additions & 0 deletions Builders/Builder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public abstract class Builder
{
protected abstract string TargetFramework { get; }
protected abstract string RuntimeIdentifier { get; }

protected string SplashImagePath => Path.Combine(Program.SolutionPath, "assets", "lazer-nuget.png");
protected string IconPath => Path.Combine(Program.SolutionPath, Program.ProjectName, Program.IconName);

protected readonly string Version;

protected Builder(string version)
{
Version = version;

refreshDirectory(Program.STAGING_FOLDER);
}

public abstract Uploader CreateUploader();

public abstract void Build();

protected void RunDotnetPublish(string? extraArgs = null, string? outputDir = null)
{
extraArgs ??= string.Empty;
outputDir ??= Program.StagingPath;

Program.RunCommand("dotnet", $"publish"
+ $" -f {TargetFramework}"
+ $" -r {RuntimeIdentifier}"
+ $" -c Release"
+ $" -o \"{outputDir}\""
+ $" -p:Version={Version}"
+ $" --self-contained"
+ $" {extraArgs}"
+ $" {Program.ProjectName}");
}

private static void refreshDirectory(string directory)
{
if (Directory.Exists(directory))
Directory.Delete(directory, true);
Directory.CreateDirectory(directory);
}
}
}
28 changes: 28 additions & 0 deletions Builders/IOSBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public class IOSBuilder : Builder
{
public IOSBuilder(string version)
: base(version)
{
}

protected override string TargetFramework => "net8.0-ios";
protected override string RuntimeIdentifier => "ios-arm64";

public override Uploader CreateUploader() => new GitHubUploader();

public override void Build()
{
RunDotnetPublish("-p:ApplicationDisplayVersion=1.0");

File.Move(Path.Combine(Program.StagingPath, "osu.iOS.app"), Path.Combine(Program.ReleasesPath, "osu.iOS.app"), true);
}
}
}
44 changes: 44 additions & 0 deletions Builders/LinuxBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public class LinuxBuilder : Builder
{
private const string app_dir = "osu!.AppDir";
private const string app_name = "osu!";
private const string os_name = "linux";

private readonly string stagingTarget;
private readonly string publishTarget;

public LinuxBuilder(string version)
: base(version)
{
stagingTarget = Path.Combine(Program.StagingPath, app_dir);
publishTarget = Path.Combine(stagingTarget, "usr", "bin");
}

protected override string TargetFramework => "net8.0";
protected override string RuntimeIdentifier => $"{os_name}-x64";

public override Uploader CreateUploader() => new LinuxVelopackUploader(app_name, os_name, RuntimeIdentifier, RuntimeIdentifier, stagingPath: stagingTarget);

public override void Build()
{
if (Directory.Exists(stagingTarget))
Directory.Delete(stagingTarget, true);
Directory.CreateDirectory(stagingTarget);

foreach (var file in Directory.GetFiles(Path.Combine(Program.TemplatesPath, app_dir)))
new FileInfo(file).CopyTo(Path.Combine(stagingTarget, Path.GetFileName(file)));

Program.RunCommand("chmod", $"+x {stagingTarget}/AppRun");

RunDotnetPublish(outputDir: publishTarget);
}
}
}
70 changes: 70 additions & 0 deletions Builders/MacOSBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public class MacOSBuilder : Builder
{
private const string app_dir = "osu!.app";
private const string app_name = "osu!";
private const string os_name = "osx";

private readonly string stagingTarget;
private readonly string publishTarget;

public MacOSBuilder(string version, string? arch)
: base(version)
{
if (string.IsNullOrEmpty(arch))
{
Console.Write("Build for which architecture? [x64/arm64]: ");
arch = Console.ReadLine() ?? string.Empty;
}

if (arch != "x64" && arch != "arm64")
Logger.Error($"Invalid Architecture: {arch}");

RuntimeIdentifier = $"{os_name}-{arch}";

stagingTarget = Path.Combine(Program.StagingPath, app_dir);
publishTarget = Path.Combine(stagingTarget, "Contents", "MacOS");
}

protected override string TargetFramework => "net8.0";
protected override string RuntimeIdentifier { get; }

public override Uploader CreateUploader()
{
string extraArgs = $" --signEntitlements=\"{Path.Combine(Environment.CurrentDirectory, "osu.entitlements")}\""
+ $" --noInst";

if (!string.IsNullOrEmpty(Program.AppleCodeSignCertName))
extraArgs += $" --signAppIdentity=\"{Program.AppleCodeSignCertName}\"";
if (!string.IsNullOrEmpty(Program.AppleInstallSignCertName))
extraArgs += $" --signInstallIdentity=\"{Program.AppleInstallSignCertName}\"";
if (!string.IsNullOrEmpty(Program.AppleNotaryProfileName))
extraArgs += $" --notaryProfile=\"{Program.AppleNotaryProfileName}\"";
if (!string.IsNullOrEmpty(Program.AppleKeyChainPath))
extraArgs += $" --keychain=\"{Program.AppleKeyChainPath}\"";

return new MacOSVelopackUploader(app_name, os_name, RuntimeIdentifier, RuntimeIdentifier, extraArgs: extraArgs, stagingPath: stagingTarget);
}

public override void Build()
{
if (Directory.Exists(stagingTarget))
Directory.Delete(stagingTarget, true);

Program.RunCommand("cp", $"-r \"{Path.Combine(Program.TemplatesPath, app_dir)}\" \"{stagingTarget}\"");

RunDotnetPublish(outputDir: publishTarget);

// without touching the app bundle itself, changes to file associations / icons / etc. will be cached at a macOS level and not updated.
Program.RunCommand("touch", $"\"{stagingTarget}\" {Program.StagingPath}", false);
}
}
}
65 changes: 65 additions & 0 deletions Builders/WindowsBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.IO;
using osu.Desktop.Deploy.Uploaders;

namespace osu.Desktop.Deploy.Builders
{
public class WindowsBuilder : Builder
{
private const string app_name = "osu!.exe";
private const string os_name = "win";
private const string channel = "win";

private readonly string? codeSigningPassword;

public WindowsBuilder(string version, string? codeSigningPassword)
: base(version)
{
if (!string.IsNullOrEmpty(Program.WindowsCodeSigningCertPath))
this.codeSigningPassword = codeSigningPassword ?? Program.ReadLineMasked("Enter code signing password: ");
}

protected override string TargetFramework => "net8.0";
protected override string RuntimeIdentifier => $"{os_name}-x64";

public override Uploader CreateUploader()
{
string installIcon = Path.Combine(Environment.CurrentDirectory, "install.ico");
string extraArgs = $" --splashImage=\"{SplashImagePath}\""
+ $" --icon=\"{installIcon}\""
+ $" --noPortable";

if (!string.IsNullOrEmpty(Program.WindowsCodeSigningCertPath))
extraArgs += $" --signParams=\"/td sha256 /fd sha256 /f {Program.WindowsCodeSigningCertPath} /p {codeSigningPassword} /tr http://timestamp.comodoca.com\"";

return new WindowsVelopackUploader(app_name, os_name, RuntimeIdentifier, channel, extraArgs: extraArgs);
}

public override void Build()
{
RunDotnetPublish();

bool rcEditCommand =
Program.RunCommand("tools/rcedit-x64.exe", $"\"{Path.Combine(Program.StagingPath, "osu!.exe")}\""
+ $" --set-icon \"{IconPath}\"",
exitOnFail: false);

if (!rcEditCommand)
{
// Retry again with wine
// TODO: Should probably change this to use RuntimeInfo.OS checks instead of fail values
bool wineRcEditCommand =
Program.RunCommand("wine", $"\"{Path.GetFullPath("tools/rcedit-x64.exe")}\""
+ $" \"{Path.Combine(Program.StagingPath, "osu!.exe")}\""
+ $" --set-icon \"{IconPath}\"",
exitOnFail: false);

if (!wineRcEditCommand)
Logger.Error("Failed to set icon on osu!.exe");
}
}
}
}
9 changes: 6 additions & 3 deletions GitHubObject.cs → GitHubAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@

namespace osu.Desktop.Deploy
{
public class GitHubObject
public class GitHubAsset
{
[JsonProperty(@"id")]
[JsonProperty("url")]
public string Url = string.Empty;

[JsonProperty("id")]
public int Id;

[JsonProperty(@"name")]
[JsonProperty("name")]
public string Name = string.Empty;
}
}
16 changes: 10 additions & 6 deletions GitHubRelease.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using Newtonsoft.Json;

namespace osu.Desktop.Deploy
{
public class GitHubRelease
{
[JsonProperty(@"id")]
[JsonProperty("id")]
public int Id;

[JsonProperty(@"tag_name")]
[JsonProperty("tag_name")]
public string TagName => $"{Name}";

[JsonProperty(@"name")]
[JsonProperty("name")]
public string Name = string.Empty;

[JsonProperty(@"draft")]
[JsonProperty("draft")]
public bool Draft;

[JsonProperty(@"prerelease")]
[JsonProperty("prerelease")]
public bool PreRelease;

[JsonProperty(@"upload_url")]
[JsonProperty("upload_url")]
public string UploadUrl = string.Empty;

[JsonProperty("assets")]
public GitHubAsset[] Assets = Array.Empty<GitHubAsset>();
}
}
Loading

0 comments on commit ca43ff3

Please sign in to comment.