Use GitHub Releases for official builds
This get ride of AppVeyor for official builds once and for all. As people have been using AppVeyor for custom build and as number might clash with official releases, the minor version of the project was incremented. AppVeyor will still be used for PRs. Also to avoid more confusion between AppVeyor builds and official one, AppVeyor builds are now postfixed with "-prXXX".
This commit is contained in:
parent
8353a1660b
commit
20d2302d9c
23 changed files with 710 additions and 75 deletions
10
.github/actions/scripts/dotnet_publish
vendored
Executable file
10
.github/actions/scripts/dotnet_publish
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ensure the artifacts directory is created
|
||||
mkdir -p $GITHUB_WORKSPACE/artifacts
|
||||
|
||||
dotnet publish "Ryujinx/Ryujinx.csproj" -c "${BUILD_TYPE}" -r "${TARGET_OS}-${TARGET_ARCH}" /p:Version=$BUILD_VERSION
|
||||
|
||||
pushd "$GITHUB_WORKSPACE/Ryujinx/bin/$BUILD_TYPE/netcoreapp3.0/$TARGET_OS-$TARGET_ARCH/publish/"
|
||||
zip -9 -r $GITHUB_WORKSPACE/artifacts/ryujinx-$RELEASE_POSTFIX$BUILD_VERSION-$TARGET_OS\_$TARGET_ARCH.zip .
|
||||
popd
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -16,7 +16,8 @@ jobs:
|
|||
environment: ['Debug', 'Release', 'Profile Debug', 'Profile Release']
|
||||
name: ${{ matrix.environment }} build (Dotnet ${{ matrix.dotnet }}, OS ${{ matrix.os }})
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
|
|
76
.github/workflows/release.yml
vendored
Normal file
76
.github/workflows/release.yml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
name: "Release job"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.100'
|
||||
- name: Determine Build version
|
||||
id: buildVersion
|
||||
run: dotnet run --project "Ryujinx.Actions"
|
||||
env:
|
||||
INPUT_OPERATION: 'get-build-version'
|
||||
INPUT_RELEASE_REPOSITORY: 'Ryujinx/binaries'
|
||||
- name: "Print Build version"
|
||||
run: "echo ${{ steps.buildVersion.outputs.release-version }}"
|
||||
- name: Publish Windows for x64
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
TARGET_OS: win
|
||||
TARGET_ARCH: x64
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish Windows for x64 (Profiled)
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Profile Release
|
||||
TARGET_OS: win
|
||||
TARGET_ARCH: x64
|
||||
RELEASE_POSTFIX: profiled-
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish Linux for x64
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
TARGET_OS: linux
|
||||
TARGET_ARCH: x64
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish Linux for x64 (Profiled)
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Profile Release
|
||||
TARGET_OS: linux
|
||||
TARGET_ARCH: x64
|
||||
RELEASE_POSTFIX: profiled-
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish OSX for x64
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
TARGET_OS: osx
|
||||
TARGET_ARCH: x64
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish OSX for x64 (Profiled)
|
||||
run: ./.github/actions/scripts/dotnet_publish
|
||||
env:
|
||||
BUILD_TYPE: Profile Release
|
||||
TARGET_OS: osx
|
||||
TARGET_ARCH: x64
|
||||
RELEASE_POSTFIX: profiled-
|
||||
BUILD_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
- name: Publish to GitHub Release
|
||||
run: dotnet run --project "Ryujinx.Actions"
|
||||
env:
|
||||
INPUT_OPERATION: 'publish-release'
|
||||
INPUT_RELEASE_REPOSITORY: 'Ryujinx/binaries'
|
||||
INPUT_RELEASE_VERSION: ${{ steps.buildVersion.outputs.release-version }}
|
||||
INPUT_RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -164,3 +164,5 @@ launchSettings.json
|
|||
|
||||
# NetCore Publishing Profiles
|
||||
PublishProfiles/
|
||||
|
||||
artifacts/
|
|
@ -3,25 +3,13 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
|
148
Ryujinx.Actions/Actions/Core.cs
Normal file
148
Ryujinx.Actions/Actions/Core.cs
Normal file
|
@ -0,0 +1,148 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Actions
|
||||
{
|
||||
public class Core
|
||||
{
|
||||
private const string COMMAND_PREFIX = "::";
|
||||
|
||||
private static string EscapeBase(string data)
|
||||
{
|
||||
return data.Replace("%", "%25")
|
||||
.Replace("\r", "%0D")
|
||||
.Replace("\n", "%0A");
|
||||
}
|
||||
|
||||
private static string EscapeMessage(string message)
|
||||
{
|
||||
return EscapeBase(message).Replace(":", "%3A").Replace(",", "%2C");
|
||||
}
|
||||
|
||||
private static string ComputeString(string command, IDictionary<string, string> properties, string message)
|
||||
{
|
||||
string result = $"{COMMAND_PREFIX}{command}";
|
||||
|
||||
if (properties != null && properties.Count > 0)
|
||||
{
|
||||
result += " ";
|
||||
|
||||
bool isFirstProperty = true;
|
||||
|
||||
foreach (KeyValuePair<string, string> property in properties)
|
||||
{
|
||||
if (!isFirstProperty)
|
||||
{
|
||||
result += ",";
|
||||
isFirstProperty = false;
|
||||
}
|
||||
|
||||
result += $"{property.Key}={EscapeBase(property.Value)}";
|
||||
}
|
||||
}
|
||||
|
||||
result += $"{COMMAND_PREFIX}{EscapeMessage(message)}";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Issue(string command, IDictionary<string, string> properties = null, string message = "")
|
||||
{
|
||||
Console.Out.WriteLine(ComputeString(command, properties, message));
|
||||
}
|
||||
|
||||
public static void ExportVariable(string name, string value)
|
||||
{
|
||||
Environment.SetEnvironmentVariable(name, value);
|
||||
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>();
|
||||
properties.Add("name", name);
|
||||
|
||||
Issue("set-env", properties, value);
|
||||
}
|
||||
|
||||
public static void SetSecret(string secret)
|
||||
{
|
||||
Issue("add-mask", message: secret);
|
||||
}
|
||||
|
||||
public static void AddPath(string path)
|
||||
{
|
||||
Issue("add-path", message: path);
|
||||
|
||||
string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
|
||||
|
||||
Environment.SetEnvironmentVariable("Path", $"{path};{systemPath}");
|
||||
}
|
||||
|
||||
public static string GetInput(string name)
|
||||
{
|
||||
string result = Environment.GetEnvironmentVariable($"INPUT_{name.Replace(" ", "_")}".ToUpper());
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result.Trim();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void SetOutput(string name, string value)
|
||||
{
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>();
|
||||
properties.Add("name", name);
|
||||
|
||||
Issue("set-output", properties, value);
|
||||
}
|
||||
|
||||
public static void SetFailed(string message)
|
||||
{
|
||||
Environment.ExitCode = 1;
|
||||
|
||||
Error(message);
|
||||
}
|
||||
|
||||
public static void Debug(string message)
|
||||
{
|
||||
Issue("debug", message: message);
|
||||
}
|
||||
|
||||
public static void Error(string message)
|
||||
{
|
||||
Issue("error", message: message);
|
||||
}
|
||||
|
||||
public static void Warning(string message)
|
||||
{
|
||||
Issue("warning", message: message);
|
||||
}
|
||||
|
||||
public static void Info(string message)
|
||||
{
|
||||
Console.Out.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void StartGroup(string name)
|
||||
{
|
||||
Issue("group", message: name);
|
||||
}
|
||||
|
||||
public static void EndGroup()
|
||||
{
|
||||
Issue("endgroup");
|
||||
}
|
||||
|
||||
public static void SaveState(string name, string value)
|
||||
{
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>();
|
||||
properties.Add("name", name);
|
||||
|
||||
Issue("save-state", properties, value);
|
||||
}
|
||||
|
||||
public static string GetState(string name)
|
||||
{
|
||||
return Environment.GetEnvironmentVariable($"STATE_{name}");
|
||||
}
|
||||
}
|
||||
}
|
9
Ryujinx.Actions/Architecture.cs
Normal file
9
Ryujinx.Actions/Architecture.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Ryujinx.Actions
|
||||
{
|
||||
public enum Architecture
|
||||
{
|
||||
Unknown,
|
||||
X64,
|
||||
AArch64
|
||||
}
|
||||
}
|
111
Ryujinx.Actions/ArtifactInformation.cs
Normal file
111
Ryujinx.Actions/ArtifactInformation.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Ryujinx.Actions
|
||||
{
|
||||
public class ArtifactInformation
|
||||
{
|
||||
public OperatingSystem Os { get; private set; }
|
||||
public Architecture Arch { get; private set; }
|
||||
public BuildType BuildType { get; private set; }
|
||||
public string Url { get; set; }
|
||||
public string FileHash { get; private set; }
|
||||
public string FileName { get; private set; }
|
||||
|
||||
private static OperatingSystem GetOperatingSystemFromNamingPart(string part)
|
||||
{
|
||||
switch (part)
|
||||
{
|
||||
case "win":
|
||||
return OperatingSystem.Windows;
|
||||
case "osx":
|
||||
return OperatingSystem.MacOSX;
|
||||
case "linux":
|
||||
return OperatingSystem.Linux;
|
||||
case "android":
|
||||
return OperatingSystem.Android;
|
||||
case "ios":
|
||||
return OperatingSystem.IOS;
|
||||
default:
|
||||
return OperatingSystem.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static Architecture GetArchitectureFromNamingPart(string part)
|
||||
{
|
||||
switch (part)
|
||||
{
|
||||
case "x64":
|
||||
return Architecture.X64;
|
||||
case "aarch64":
|
||||
return Architecture.AArch64;
|
||||
default:
|
||||
return Architecture.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArtifactInformation FromFileName(string fileName)
|
||||
{
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
string[] fileNameParts = fileNameWithoutExtension.Split("-");
|
||||
|
||||
if (fileNameParts.Length != 3 && fileNameParts.Length != 4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ArtifactInformation artifactInformation = new ArtifactInformation();
|
||||
|
||||
artifactInformation.BuildType = BuildType.Release;
|
||||
|
||||
bool isProfile = fileNameParts.Length == 4;
|
||||
|
||||
if (isProfile)
|
||||
{
|
||||
artifactInformation.BuildType = BuildType.ProfileRelease;
|
||||
}
|
||||
|
||||
string targetConfiguration = isProfile ? fileNameParts[3] : fileNameParts[2];
|
||||
string[] targetConfigurationParts = targetConfiguration.Split("_");
|
||||
|
||||
if (targetConfigurationParts.Length != 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
artifactInformation.Os = GetOperatingSystemFromNamingPart(targetConfigurationParts[0]);
|
||||
artifactInformation.Arch = GetArchitectureFromNamingPart(targetConfigurationParts[1]);
|
||||
|
||||
return artifactInformation;
|
||||
}
|
||||
|
||||
public static ArtifactInformation FromFile(string path)
|
||||
{
|
||||
ArtifactInformation artifactInformation = FromFileName(path);
|
||||
|
||||
if (artifactInformation == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string fileHashString = "";
|
||||
|
||||
using (SHA256 hasher = SHA256.Create())
|
||||
{
|
||||
using (FileStream fileStream = File.OpenRead(path))
|
||||
{
|
||||
byte[] fileHash = hasher.ComputeHash(fileStream);
|
||||
foreach (byte x in fileHash)
|
||||
{
|
||||
fileHashString += string.Format("{0:x2}", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifactInformation.FileName = Path.GetFileName(path);
|
||||
artifactInformation.FileHash = fileHashString;
|
||||
|
||||
return artifactInformation;
|
||||
}
|
||||
}
|
||||
}
|
10
Ryujinx.Actions/BuildType.cs
Normal file
10
Ryujinx.Actions/BuildType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Ryujinx.Actions
|
||||
{
|
||||
public enum BuildType
|
||||
{
|
||||
Debug,
|
||||
Release,
|
||||
ProfileDebug,
|
||||
ProfileRelease
|
||||
}
|
||||
}
|
12
Ryujinx.Actions/OperatingSystem.cs
Normal file
12
Ryujinx.Actions/OperatingSystem.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Actions
|
||||
{
|
||||
public enum OperatingSystem
|
||||
{
|
||||
Unknown,
|
||||
Windows,
|
||||
MacOSX,
|
||||
Linux,
|
||||
Android,
|
||||
IOS
|
||||
}
|
||||
}
|
203
Ryujinx.Actions/Program.cs
Normal file
203
Ryujinx.Actions/Program.cs
Normal file
|
@ -0,0 +1,203 @@
|
|||
using Octokit;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Actions
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private const string GITHUB_USER_CONTENT_BASE_URL = "https://raw.githubusercontent.com/";
|
||||
private const string GITHUB_COMMIT_BASE_URL = "https://github.com/Ryujinx/Ryujinx/commit/";
|
||||
|
||||
private const string TARGET_JSON_NAME = "latest.json";
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string operation = Core.GetInput("operation");
|
||||
|
||||
if (operation == null)
|
||||
{
|
||||
Core.SetFailed("operation must be specified!");
|
||||
}
|
||||
else
|
||||
{
|
||||
string releaseRepository;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case "get-build-version":
|
||||
releaseRepository = Core.GetInput("release_repository");
|
||||
|
||||
string releaseInformationUrl = GITHUB_USER_CONTENT_BASE_URL + releaseRepository + "/master/" + TARGET_JSON_NAME;
|
||||
|
||||
WebClient webClient = new WebClient();
|
||||
|
||||
string latestVersion = webClient.DownloadString(releaseInformationUrl);
|
||||
|
||||
ReleaseInformation releaseInformation = JsonSerializer.Deserialize<ReleaseInformation>(latestVersion, CreateJsonOptions());
|
||||
|
||||
releaseInformation.Version.IncrementPatch();
|
||||
|
||||
Core.SetOutput("release-version", releaseInformation.Version.ToString());
|
||||
break;
|
||||
case "publish-release":
|
||||
string githubWorkspace = Environment.GetEnvironmentVariable("GITHUB_WORKSPACE");
|
||||
string artifactDirectory = Core.GetInput("artifacts_directory");
|
||||
string releaseToken = Core.GetInput("release_token");
|
||||
|
||||
releaseRepository = Core.GetInput("release_repository");
|
||||
|
||||
// Mark the token as secret
|
||||
Core.SetSecret(releaseToken);
|
||||
|
||||
if (artifactDirectory == null)
|
||||
{
|
||||
artifactDirectory = "artifacts";
|
||||
}
|
||||
|
||||
string artifactFullPath = Path.Join(githubWorkspace, artifactDirectory);
|
||||
string releaseVersion = Core.GetInput("release_version");
|
||||
|
||||
PublishRelease(artifactFullPath, VersionCore.FromString(releaseVersion), releaseRepository, releaseToken).Wait();
|
||||
break;
|
||||
default:
|
||||
Core.SetFailed($"Unknown operation {operation} must be specified!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GitHubClient CreateGitHubClientInstance(string releaseToken)
|
||||
{
|
||||
GitHubClient client = new GitHubClient(new ProductHeaderValue("Ryujinx.Actions", "1.0.0"));
|
||||
|
||||
client.Credentials = new Credentials(releaseToken);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
private static JsonSerializerOptions CreateJsonOptions()
|
||||
{
|
||||
JsonSerializerOptions serializeOptions = new JsonSerializerOptions
|
||||
{
|
||||
IgnoreNullValues = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
serializeOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
|
||||
serializeOptions.Converters.Add(new VersionCore.Converter());
|
||||
|
||||
return serializeOptions;
|
||||
}
|
||||
|
||||
private static Task<ReleaseAsset> UploadAsset(GitHubClient client, Release release, Stream stream, string fileName, string contentType)
|
||||
{
|
||||
Core.Info($"Uploading {fileName}");
|
||||
|
||||
ReleaseAssetUpload assetUpload = new ReleaseAssetUpload()
|
||||
{
|
||||
FileName = fileName,
|
||||
ContentType = contentType,
|
||||
RawData = stream,
|
||||
Timeout = TimeSpan.FromMinutes(30)
|
||||
};
|
||||
|
||||
return client.Repository.Release.UploadAsset(release, assetUpload);
|
||||
}
|
||||
|
||||
private static async Task UploadArtifact(GitHubClient client, Release release, string artifactDirectory, ArtifactInformation artifactInformation)
|
||||
{
|
||||
using (FileStream fileStream = File.OpenRead(Path.Combine(artifactDirectory, artifactInformation.FileName)))
|
||||
{
|
||||
await UploadAsset(client, release, fileStream, artifactInformation.FileName, "application/zip");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task PublishRelease(string artifactDirectory, VersionCore releaseVersion, string releaseRepository, string releaseToken)
|
||||
{
|
||||
if (releaseVersion == null)
|
||||
{
|
||||
Core.SetFailed("Invalid release_version!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (releaseToken == null)
|
||||
{
|
||||
Core.SetFailed("Invalid release_token!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (releaseRepository == null)
|
||||
{
|
||||
Core.SetFailed("Invalid release_repository!");
|
||||
return;
|
||||
}
|
||||
|
||||
string commitSha = Environment.GetEnvironmentVariable("GITHUB_SHA");
|
||||
|
||||
if (commitSha == null)
|
||||
{
|
||||
Core.SetFailed("GITHUB_SHA environment variable not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] releaseRepositoryParts = releaseRepository.Split("/");
|
||||
|
||||
if (releaseRepositoryParts.Length != 2)
|
||||
{
|
||||
Core.SetFailed("Invalid release_repository!");
|
||||
return;
|
||||
}
|
||||
|
||||
string releaseRepositoryOwner = releaseRepositoryParts[0];
|
||||
string releaseRepositoryName = releaseRepositoryParts[1];
|
||||
|
||||
ReleaseInformation releaseInformation = new ReleaseInformation(releaseVersion);
|
||||
|
||||
foreach (string file in Directory.GetFiles(artifactDirectory, $"ryujinx*-{releaseVersion}-*.zip"))
|
||||
{
|
||||
ArtifactInformation artifactInformation = ArtifactInformation.FromFile(file);
|
||||
|
||||
releaseInformation.Artifacts.Add(artifactInformation);
|
||||
}
|
||||
|
||||
GitHubClient client = CreateGitHubClientInstance(releaseToken);
|
||||
|
||||
// Create a new release
|
||||
NewRelease newRelease = new NewRelease($"build-{commitSha}");
|
||||
newRelease.Name = releaseVersion.ToString();
|
||||
newRelease.Body = $"Triggered by {GITHUB_COMMIT_BASE_URL}{commitSha}.";
|
||||
newRelease.Draft = true;
|
||||
newRelease.Prerelease = false;
|
||||
|
||||
Release release = await client.Repository.Release.Create(releaseRepositoryOwner, releaseRepositoryName, newRelease);
|
||||
ReleaseUpdate updateRelease = release.ToUpdate();
|
||||
|
||||
// Upload artifacts
|
||||
foreach (ArtifactInformation information in releaseInformation.Artifacts)
|
||||
{
|
||||
await UploadArtifact(client, release, artifactDirectory, information);
|
||||
}
|
||||
|
||||
string releaseInformationJson = JsonSerializer.Serialize(releaseInformation, CreateJsonOptions());
|
||||
|
||||
// Upload release information
|
||||
using (MemoryStream releaseInformationStream = new MemoryStream(Encoding.UTF8.GetBytes(releaseInformationJson)))
|
||||
{
|
||||
await UploadAsset(client, release, releaseInformationStream, "release_information.json", "application/json");
|
||||
}
|
||||
|
||||
updateRelease.Draft = false;
|
||||
|
||||
release = await client.Repository.Release.Edit(releaseRepositoryOwner, releaseRepositoryName, release.Id, updateRelease);
|
||||
|
||||
Core.Info($"Successfully published release {releaseVersion} to {release.HtmlUrl}");
|
||||
}
|
||||
}
|
||||
}
|
23
Ryujinx.Actions/ReleaseInformation.cs
Normal file
23
Ryujinx.Actions/ReleaseInformation.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.Actions
|
||||
{
|
||||
public class ReleaseInformation
|
||||
{
|
||||
public VersionCore Version { get; set; }
|
||||
public List<ArtifactInformation> Artifacts { get; set; }
|
||||
|
||||
private ReleaseInformation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ReleaseInformation(VersionCore version)
|
||||
{
|
||||
Version = version;
|
||||
Artifacts = new List<ArtifactInformation>();
|
||||
}
|
||||
}
|
||||
}
|
13
Ryujinx.Actions/Ryujinx.Actions.csproj
Normal file
13
Ryujinx.Actions/Ryujinx.Actions.csproj
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Octokit" Version="0.40.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
66
Ryujinx.Actions/VersionCore.cs
Normal file
66
Ryujinx.Actions/VersionCore.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Ryujinx.Actions
|
||||
{
|
||||
public class VersionCore
|
||||
{
|
||||
private static readonly Regex REGEX = new Regex(@"^(?<major>\d+)" +
|
||||
@"(?>\.(?<minor>\d+))?" +
|
||||
@"(?>\.(?<patch>\d+))?$",
|
||||
RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
|
||||
|
||||
public uint Major { get; private set; }
|
||||
public uint Minor { get; private set; }
|
||||
public uint Patch { get; private set; }
|
||||
|
||||
public VersionCore(uint major, uint minor, uint patch)
|
||||
{
|
||||
Major = major;
|
||||
Minor = minor;
|
||||
Patch = patch;
|
||||
}
|
||||
|
||||
public void IncrementPatch()
|
||||
{
|
||||
Patch++;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Major}.{Minor}.{Patch}";
|
||||
}
|
||||
|
||||
public static VersionCore FromString(string version)
|
||||
{
|
||||
Match match = REGEX.Match(version);
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
uint major = uint.Parse(match.Groups["major"].Value, CultureInfo.InvariantCulture);
|
||||
uint minor = uint.Parse(match.Groups["minor"].Value, CultureInfo.InvariantCulture);
|
||||
uint patch = uint.Parse(match.Groups["patch"].Value, CultureInfo.InvariantCulture);
|
||||
|
||||
return new VersionCore(major, minor, patch);
|
||||
}
|
||||
|
||||
public class Converter : JsonConverter<VersionCore>
|
||||
{
|
||||
public override VersionCore Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return FromString(reader.GetString());
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, VersionCore value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,24 +4,14 @@
|
|||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
<Configurations>Debug;Release;Profile Debug;Profile Release</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -4,24 +4,14 @@
|
|||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
<Configurations>Debug;Release;Profile Debug;Profile Release</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -11,14 +11,6 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -3,13 +3,6 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -4,24 +4,14 @@
|
|||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||
<Configurations>Debug;Release;Profile Debug;Profile Release</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
22
Ryujinx.sln
22
Ryujinx.sln
|
@ -31,9 +31,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Texture",
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Shader", "Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj", "{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Nvdec", "Ryujinx.Graphics.Nvdec\Ryujinx.Graphics.Nvdec.csproj", "{85A0FA56-DC01-4A42-8808-70DAC76BD66D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec", "Ryujinx.Graphics.Nvdec\Ryujinx.Graphics.Nvdec.csproj", "{85A0FA56-DC01-4A42-8808-70DAC76BD66D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Debugger", "Ryujinx.Debugger\Ryujinx.Debugger.csproj", "{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Debugger", "Ryujinx.Debugger\Ryujinx.Debugger.csproj", "{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Actions", "Ryujinx.Actions\Ryujinx.Actions.csproj", "{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -163,14 +165,6 @@ Global
|
|||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Profile Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Profile Debug|Any CPU.ActiveCfg = Profile Debug|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Profile Debug|Any CPU.Build.0 = Profile Debug|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Profile Release|Any CPU.ActiveCfg = Profile Release|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Profile Release|Any CPU.Build.0 = Profile Release|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E02B7F3-245E-43B1-AE5B-44167A0FDA20}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Profile Debug|Any CPU.ActiveCfg = Profile Debug|Any CPU
|
||||
|
@ -179,6 +173,14 @@ Global
|
|||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Profile Release|Any CPU.Build.0 = Profile Release|Any CPU
|
||||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79E4EE34-9C5F-4BE6-8529-A49D32B5B0CC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Profile Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Profile Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Profile Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Profile Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B4BB6784-3F94-4EEB-AFA1-3D497D2DC0AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Configurations>Debug;Release;Profile Debug;Profile Release</Configurations>
|
||||
<Version>1.0.0-dirty</Version>
|
||||
<Version>1.1.0-dirty</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
|
||||
|
@ -16,7 +16,6 @@
|
|||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;USE_DEBUGGING</DefineConstants>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Due to .net core 3.0 embedded resource loading -->
|
||||
|
|
16
appveyor.yml
16
appveyor.yml
|
@ -1,7 +1,4 @@
|
|||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
version: 1.0.0
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
matrix:
|
||||
|
@ -12,6 +9,17 @@ environment:
|
|||
config_name: '-profiled-'
|
||||
build_script:
|
||||
- ps: >-
|
||||
# Ensure that we are in a PR
|
||||
if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) {
|
||||
throw "This should only be trigger on pull request build!"
|
||||
}
|
||||
|
||||
# change version to contain the PR
|
||||
$version = "$version-pr$env:APPVEYOR_PULL_REQUEST_NUMBER"
|
||||
|
||||
# update AppVeyor build
|
||||
Update-AppveyorBuild -Version $version
|
||||
|
||||
dotnet --version
|
||||
|
||||
dotnet publish -c $env:config -r win-x64 /p:Version=$env:APPVEYOR_BUILD_VERSION
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue