Editor utility that drives package publishing for a project. It validates the requested action (inspect_manifest, preflight, publish), prepares a ProjectPublisher, reports files to upload, and triggers publish with change details.
#nullable enable
using System;
using System.Linq;
using System.Threading.Tasks;
using Sandbox;
namespace Editor.Mcp
{
internal static class PackagePublishDriver
{
public static async Task<ToolOutcome<object>> PublishAsync( string action = "inspect_manifest", string? changeTitle = null, string? changeDetail = null )
{
var project = Project.Current;
if ( project == null )
{
return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "publish.no_project", "No active project loaded." );
}
var normAction = (action ?? "").ToLowerInvariant().Trim();
if ( normAction == "status" || string.IsNullOrWhiteSpace( normAction ) )
{
normAction = "inspect_manifest";
}
if ( normAction != "inspect_manifest" && normAction != "preflight" && normAction != "publish" )
{
return ToolOutcome<object>.Failure( null, ToolStatus.Failed, "publish.invalid_action", $"Unsupported action '{action}'. Use inspect_manifest, preflight, or publish." );
}
ProjectPublisher? publisher = null;
try
{
publisher = await ProjectPublisher.FromProject( project );
if ( publisher != null )
{
await publisher.PrePublish();
}
}
catch ( Exception ex )
{
return ToolOutcome<object>.Degraded( new
{
Project = project.Config.Ident,
FullIdent = $"{project.Config.Org}.{project.Config.Ident}",
Action = normAction,
Notice = "Facepunch Cloud publisher pre-flight degraded or offline."
}, "publish.cloud_auth_or_network", "Could not query Facepunch Cloud package status: network or authentication unavailable.", ex.Message );
}
if ( publisher == null )
{
return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "publish.publisher_unavailable", "Could not initialize ProjectPublisher for current project." );
}
var files = publisher.Files.Select( f => new
{
Name = f.Name,
Size = f.Size,
Skip = f.Skip
} ).ToArray();
if ( normAction == "inspect_manifest" || normAction == "preflight" )
{
return ToolOutcome<object>.Ready( new
{
Action = normAction,
Project = project.Config.Ident,
FullIdent = $"{project.Config.Org}.{project.Config.Ident}",
TotalFiles = files.Length,
FilesToUpload = files.Count( f => !f.Skip ),
SampleFiles = files.Take( 20 ).ToArray(),
ReadyToPublish = true
} );
}
if ( normAction == "publish" )
{
var title = string.IsNullOrWhiteSpace( changeTitle ) ? $"Changes on {DateTime.UtcNow:yyyy-MM-dd}" : changeTitle;
publisher.SetChangeDetails( title, changeDetail ?? "" );
await publisher.Publish();
return ToolOutcome<object>.Ready( new
{
Action = "publish",
Project = project.Config.Ident,
ChangeTitle = title,
Published = true
} );
}
return ToolOutcome<object>.Failure( null, ToolStatus.Failed, "publish.invalid_action", $"Unsupported action '{action}'. Use inspect_manifest, preflight, or publish." );
}
}
}