Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Robust.Cdn/content.db*
Robust.Cdn/manifest.db*
*.user
testData/
/.vs/**
51 changes: 40 additions & 11 deletions Robust.Cdn/Controllers/ForkPublishController.Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,45 @@ public async Task<IActionResult> MultiPublishStart(
publishManager.AbortMultiPublish(fork, request.Version, tx, commit: false);
}

await dbCon.ExecuteAsync("""
INSERT INTO PublishInProgress (Version, ForkId, StartTime, EngineVersion)
VALUES (@Version, @ForkId, @StartTime, @EngineVersion)
await dbCon.ExecuteAsync(
"""
INSERT INTO PublishInProgress (
Version,
ForkId,
StartTime,
EngineVersion,
SourceUrl,
SourceCommitId,
SourceBranchName,
EngineSourceUrl,
EngineSourceCommitId,
EngineSourceBranchName
)
VALUES (
@Version,
@ForkId,
@StartTime,
@EngineVersion,
@SourceUrl,
@SourceCommitId,
@SourceBranchName,
@EngineSourceUrl,
@EngineSourceCommitId,
@EngineSourceBranchName
)
""",
new
{
request.Version,
request.EngineVersion,
ForkId = forkId,
StartTime = DateTime.UtcNow
StartTime = DateTime.UtcNow,
request.SourceUrl,
request.SourceCommitId,
request.SourceBranchName,
request.EngineSourceUrl,
request.EngineSourceCommitId,
request.EngineSourceBranchName,
});

var versionDir = buildDirectoryManager.GetBuildVersionPath(fork, request.Version);
Expand Down Expand Up @@ -127,8 +156,9 @@ public async Task<IActionResult> MultiPublishFinish(
await using var tx = await dbCon.BeginTransactionAsync(cancel);

var forkId = dbCon.QuerySingle<int>("SELECT Id FROM Fork WHERE Name = @Name", new { Name = fork });
var versionMetadata = dbCon.QuerySingleOrDefault<VersionMetadata>("""
SELECT Version, EngineVersion
var versionMetadata = dbCon.QuerySingleOrDefault<VersionMetadata>(
"""
SELECT Version, EngineVersion, SourceUrl, SourceCommitId, SourceBranchName, EngineSourceUrl, EngineSourceCommitId, EngineSourceBranchName
FROM PublishInProgress
WHERE Version = @Name AND ForkId = @Fork
""",
Expand Down Expand Up @@ -175,11 +205,10 @@ FROM PublishInProgress
return NoContent();
}

public sealed class PublishMultiRequest
{
public required string Version { get; set; }
public required string EngineVersion { get; set; }
}
/// <summary>
/// Request for start of multi-step publishing process of a new version.
/// </summary>
public sealed class PublishMultiRequest : PublishStartRequestBase;

public sealed class PublishFinishRequest
{
Expand Down
9 changes: 7 additions & 2 deletions Robust.Cdn/Controllers/ForkPublishController.OneShot.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO.Compression;
using System.IO.Compression;
using Microsoft.AspNetCore.Mvc;
using Robust.Cdn.Helpers;

Expand Down Expand Up @@ -51,7 +51,12 @@ public async Task<IActionResult> PostPublish(

var versionDir = buildDirectoryManager.GetBuildVersionPath(fork, request.Version);

var metadata = new VersionMetadata { Version = request.Version, EngineVersion = request.EngineVersion };
var metadata = new VersionMetadata(
request.Version,
request.EngineVersion,
new(request.SourceUrl, request.SourceCommitId, request.SourceBranchName),
new(request.EngineSourceUrl, request.EngineSourceCommitId, request.EngineSourceBranchName)
);

try
{
Expand Down
122 changes: 116 additions & 6 deletions Robust.Cdn/Controllers/ForkPublishController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO.Compression;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
Expand Down Expand Up @@ -132,7 +132,7 @@ private MemoryStream GenerateBuildJson(

logger.LogDebug("Client zip hash is {ZipHash}, manifest hash is {ManifestHash}", hash, manifestHash);

var data = new Dictionary<string, string>
var data = new Dictionary<string, string?>
{
{ "download", baseUrlManager.MakeBuildInfoUrl($"fork/{{FORK_ID}}/version/{{FORK_VERSION}}/file/{diskFileName}") },
{ "version", metadata.Version },
Expand All @@ -141,7 +141,13 @@ private MemoryStream GenerateBuildJson(
{ "engine_version", metadata.EngineVersion },
{ "manifest_url", baseUrlManager.MakeBuildInfoUrl("fork/{FORK_ID}/version/{FORK_VERSION}/manifest") },
{ "manifest_download_url", baseUrlManager.MakeBuildInfoUrl("fork/{FORK_ID}/version/{FORK_VERSION}/download") },
{ "manifest_hash", manifestHash }
{ "manifest_hash", manifestHash },
{ "built_on_source_url", metadata.BuildVersionInfo.SourceUrl },
{ "built_on_commit_id", metadata.BuildVersionInfo.CommitId },
{ "built_on_branch_name", metadata.BuildVersionInfo.BranchName},
{ "built_on_engine_url", metadata.EngineSourceVersionInfo.SourceUrl },
{ "built_on_engine_commit_id", metadata.EngineSourceVersionInfo.CommitId },
{ "built_on_engine_branch_name", metadata.EngineSourceVersionInfo.BranchName },
};

var stream = new MemoryStream();
Expand Down Expand Up @@ -290,19 +296,123 @@ private static FileStream CreateTempFile()
FileOptions.DeleteOnClose);
}

public sealed class PublishRequest
/// <summary>
/// Base type with publish start info.
/// </summary>
public abstract class PublishStartRequestBase
{
/// <summary>
/// Human-readable version of the build. This is used to identify the build in the CDN and in the game client.
/// </summary>
public required string Version { get; set; }

/// <summary>
/// Human-readable version of the engine used to build this version.
/// </summary>
public required string EngineVersion { get; set; }

/// <summary>
/// URL of the fork repository. Optional, but useful for debugging.
/// </summary>
public string? SourceUrl { get; set; }

/// <summary>
/// Commit ID on which version was built. Optional, but useful for debugging.
/// </summary>
public string? SourceCommitId { get; set; }

/// <summary>
/// Branch on which version was built. Optional, but useful for debugging.
/// </summary>
public string? SourceBranchName { get; set; }

/// <summary>
/// Url for RobustToolbox repository (or its fork), used for this version. Optional, but useful for debugging.
/// </summary>
public string? EngineSourceUrl { get; set; }

/// <summary>
/// Branch on which RobustToolbox for this version was built. Optional, but useful for debugging.
/// </summary>
public string? EngineSourceBranchName { get; set; }

/// <summary>
/// Commit ID of RobustToolbox, used for this version. Optional, but useful for debugging.
/// </summary>
public string? EngineSourceCommitId { get; set; }
}

/// <summary>
/// Request for one-shot publishing of a new version.
/// </summary>
/// <seealso cref="ForkPublishController.PostPublish"/>
public sealed class PublishRequest : PublishStartRequestBase
{
/// <summary>
/// Uri for new build artifact.
/// </summary>
public required string Archive { get; set; }
}

/// <summary>
/// Build version metadata.
/// </summary>
private sealed class VersionMetadata
{
public required string Version { get; init; }
public required string EngineVersion { get; set; }
public VersionMetadata(string version, string engineVersion, SourceVersionInfo buildVersionInfo, SourceVersionInfo engineSourceVersionInfo)
{
Version = version;
EngineVersion = engineVersion;
BuildVersionInfo = buildVersionInfo;
EngineSourceVersionInfo = engineSourceVersionInfo;
}

public VersionMetadata(
string version,
string engineVersion,
string? sourceUrl,
string? sourceCommitId,
string? sourceBranchName,
string? engineSourceUrl,
string? engineSourceCommitId,
string? engineSourceBranchName
)
{
Version = version;
EngineVersion = engineVersion;
BuildVersionInfo = new SourceVersionInfo(sourceUrl, sourceCommitId, sourceBranchName);
EngineSourceVersionInfo = new SourceVersionInfo(engineSourceUrl, engineSourceCommitId, engineSourceBranchName);
}

/// <summary>
/// Human-readable version of the build. This is used to identify the build in the CDN and in the game client.
/// </summary>
public string Version { get; }

/// <summary>
/// Human-readable version of the engine used to build this version.
/// </summary>
public string EngineVersion { get; }

/// <summary>
/// Version info for sources, used for build.
/// </summary>
public SourceVersionInfo BuildVersionInfo { get; }

/// <summary>
/// Version info for sources of engine, used for build.
/// </summary>
public SourceVersionInfo EngineSourceVersionInfo { get; }
}

/// <summary>
/// Detailed info on sources used for building version.
/// </summary>
/// <param name="SourceUrl">URL for repository that holds sources.</param>
/// <param name="CommitId">Commit ID used for building sources.</param>
/// <param name="BranchName">Branch name or tag, used for building sources.</param>
public record SourceVersionInfo(string? SourceUrl, string? CommitId, string? BranchName);

// File cannot start with a dot but otherwise most shit is fair game.
[GeneratedRegex(@"[a-zA-Z0-9\-_][a-zA-Z0-9\-_.]*")]
private static partial Regex ValidVersionRegexBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Add columns that can represent sources used to build version that should be published
ALTER TABLE PublishInProgress ADD COLUMN SourceUrl TEXT NULL;
ALTER TABLE PublishInProgress ADD COLUMN SourceCommitId TEXT NULL;
ALTER TABLE PublishInProgress ADD COLUMN SourceBranchName TEXT NULL;
ALTER TABLE PublishInProgress ADD COLUMN EngineSourceUrl TEXT NULL;
ALTER TABLE PublishInProgress ADD COLUMN EngineSourceCommitId TEXT NULL;
ALTER TABLE PublishInProgress ADD COLUMN EngineSourceBranchName TEXT NULL;
Loading