Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split build process per-platform #1

Merged
merged 3 commits into from
Aug 31, 2024
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
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 <[email protected]>. 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 <[email protected]>. 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 <[email protected]>. 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 <[email protected]>. 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 VelopackUploader(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);
}
}
}
48 changes: 48 additions & 0 deletions Builders/MacOSBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

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

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

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}";
}

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

public override Uploader CreateUploader()
{
string extraArgs = $" --icon=\"{IconPath}\"";

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}\"";

return new VelopackUploader(app_name, os_name, RuntimeIdentifier, RuntimeIdentifier, extraArgs);
}

public override void Build() => RunDotnetPublish();
}
}
62 changes: 62 additions & 0 deletions Builders/WindowsBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. 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 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 extraArgs = $" --splashImage=\"{SplashImagePath}\""
+ $" --icon=\"{IconPath}\"";

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

return new VelopackUploader(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");
}
}
}
}
35 changes: 35 additions & 0 deletions Logger.cs
smallketchup82 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Diagnostics;

namespace osu.Desktop.Deploy
{
public static class Logger
{
private static readonly Stopwatch stopwatch = Stopwatch.StartNew();

public static void Error(string message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"FATAL ERROR: {message}");
Console.ResetColor();

Program.PauseIfInteractive();
Environment.Exit(-1);
}

public static void Write(string message, ConsoleColor col = ConsoleColor.Gray)
{
if (stopwatch.ElapsedMilliseconds > 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(stopwatch.ElapsedMilliseconds.ToString().PadRight(8));
}

Console.ForegroundColor = col;
Console.WriteLine(message);
}
}
}
Loading