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

Fix inconsistency of plugin code build when packaging for Marketplace/Fab #126

Merged
merged 1 commit into from
Jan 14, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -556,12 +556,25 @@ public virtual async Task<int> ExecuteBuildAsync(
// on the same <Agent> run sequentially one after another and don't need to send their artifacts
// to shared storage. Thus, each <Agent> now maps to one GitLab build job instead of each <Node>.

// Compute reachability from the "End" node, and exclude any nodes that it isn't dependent on.
var endNode = buildGraph.Groups
.SelectMany(x => x.Nodes)
.FirstOrDefault(x => x.Name == "End");
if (endNode == null)
{
throw new InvalidOperationException("Expected BuildGraph export to contain an 'End' node for reachability analysis.");
}
var allNodesRequiredByEnd = new HashSet<string>();
GetFullDependenciesOfNode(
nodeMap,
endNode,
allNodesRequiredByEnd);

// Compute the job names for each group.
IEnumerable<BuildGraphExportNode> FilterNodes(IEnumerable<BuildGraphExportNode> nodes)
{
// This is a special job that we don't actually emit
// because it doesn't do anything.
return nodes.Where(x => x.Name != "End");
// Filter out the "End" node and any nodes that aren't needed by "End".
return nodes.Where(x => x.Name != "End" && allNodesRequiredByEnd.Contains(x.Name));
}
string GetJobName(BuildGraphExportGroup group)
{
Expand All @@ -579,6 +592,7 @@ string GetJobName(BuildGraphExportGroup group)
}

// Now that we have our mappings set up, generate all of the build jobs.
var generatedJobs = new HashSet<string>();
foreach (var group in buildGraph.Groups)
{
var jobName = GetJobName(group);
Expand All @@ -588,6 +602,7 @@ string GetJobName(BuildGraphExportGroup group)
// If this job is only running skipped nodes, ignore it.
continue;
}
generatedJobs.Add(jobName);

// Figure out the aggregate node dependencies of this build job across all nodes.
var nodeNeeds = new HashSet<string>();
Expand Down Expand Up @@ -697,6 +712,19 @@ string GetJobName(BuildGraphExportGroup group)
pipeline.Jobs.Add(job.Name, job);
}

if (generatedJobs.Count == 0)
{
_logger.LogWarning($"No jobs for the build server were generated by this configuration!");
}
else
{
_logger.LogInformation($"Generated {generatedJobs.Count} jobs:");
foreach (var jobName in generatedJobs)
{
_logger.LogInformation($"- {jobName}");
}
}

await EmitBuildServerSpecificFileAsync(
buildSpecification,
pipeline,
Expand Down
79 changes: 37 additions & 42 deletions UET/Redpoint.Uet.BuildPipeline/BuildGraph/BuildGraph_Plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@
<Option Name="ExecuteBuild" Restrict="true|false" DefaultValue="true" Description="If false, no build steps are run (currently ignored)" />

<!-- Package options -->
<Option Name="ExecutePackage" Restrict="true|false" DefaultValue="true" Description="If false, the default Create Package and Zip Plugin steps are not run" />
<Option Name="ExecuteZip" Restrict="true|false" DefaultValue="true" Description="If false, the Create Package step will not generate a .zip file" />
<Option Name="VersionNumber" Restrict="[0-9]+" DefaultValue="10000" Description="The version number to embed in the packaged .uplugin file" />
<Option Name="VersionName" Restrict="[^ ]+" DefaultValue="Unversioned" Description="The version name to embed in the packaged .uplugin file" />
<Option Name="PackageFolder" Restrict="[^ ]+" DefaultValue="Packaged" Description="The folder to place the packaged plugin in" />
<Option Name="PackageInclude" DefaultValue="" Description="Additional include filespec to apply when packaging, separated by semicolons" />
<Option Name="PackageExclude" DefaultValue="" Description="Additional exclude filespec to apply when packaging, separated by semicolons" />
<Option Name="CopyrightHeader" DefaultValue="" Description="Copyright header to apply to all source code files when packaging" />
<Option Name="CopyrightExcludes" DefaultValue="" Description="Relative paths inside the package to exclude from copyright updates, separated with semicolons" />
<Option Name="PackageType" Restrict="Generic|Marketplace|Fab" DefaultValue="Generic" Description="Defines the method of distribution for the produced plugin." />
<Option Name="PackageType" Restrict="None|Generic|Marketplace|Fab" DefaultValue="None" Description="Defines the method of distribution for the produced plugin." />

<!-- Test options -->
<Option Name="GauntletConfigPaths" Restrict="[^ ]*" DefaultValue="" Description="List of the paths to copy files out of into the Config/ folder before building the project for Gauntlet tests."/>
Expand Down Expand Up @@ -366,27 +364,27 @@ $(PackageExclude);
-->

<Agent Name="Compile $(EnginePrefix)Editor Mac (Mac Build Editor)" Type="Mac" If="'$(IsBuildMachine)' == 'true'">
<Node Name="Compile $(EnginePrefix)Editor Mac" Requires="#HostProject" Produces="#EditorBinaries_Mac" If="'$(PackageType)' == 'Generic' and '$(CanBuildEditorMac)' == 'true'">
<Node Name="Compile $(EnginePrefix)Editor Mac" Requires="#HostProject" Produces="#EditorBinaries_Mac" If="'$(CanBuildEditorMac)' == 'true'">
<ForEach Name="MacroName" Values="$(DynamicBeforeCompileMacros)">
<Expand Name="$(MacroName)" TargetType="Editor" TargetName="$(EnginePrefix)Editor" TargetPlatform="Mac" TargetConfiguration="Development" HostPlatform="Mac" />
</ForEach>
<Expand Name="RemoveStalePrecompiledHeaders" ProjectPath="$(TempPath)/$(HostProjectName)" TargetName="$(EnginePrefix)Editor" TargetPlatform="Mac" TargetConfiguration="Development" />
<Compile Target="$(EnginePrefix)Editor" Platform="Mac" Configuration="Development" Tag="#EditorBinaries_Mac" Arguments="-Project=&quot;$(TempPath)/$(HostProjectName)/$(HostProjectName).uproject&quot; -plugin=&quot;$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)/$(PluginName).uplugin&quot; -NoPDB -NoDebugInfo $(AdditionalArguments)"/>
</Node>
<Property Name="EditorBinaries" Value="$(EditorBinaries)#EditorBinaries_Mac;" If="'$(PackageType)' == 'Generic' and '$(CanBuildEditorMac)' == 'true'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(EnginePrefix)Editor Mac;" If="'$(ExecutePackage)' == 'false' and '$(PackageType)' == 'Generic' and '$(CanBuildEditorMac)' == 'true'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(EnginePrefix)Editor Mac;" If="'$(CanBuildEditorMac)' == 'true'" />
</Agent>

<Agent Name="Compile $(EnginePrefix)Editor Win64 (Windows Build Editor)" Type="Win64">
<Node Name="Compile $(EnginePrefix)Editor Win64" Requires="#HostProject" Produces="#EditorBinaries_Win64" If="'$(PackageType)' == 'Generic' and '$(CanBuildEditorWin64)' == 'true'">
<Node Name="Compile $(EnginePrefix)Editor Win64" Requires="#HostProject" Produces="#EditorBinaries_Win64" If="'$(CanBuildEditorWin64)' == 'true'">
<ForEach Name="MacroName" Values="$(DynamicBeforeCompileMacros)">
<Expand Name="$(MacroName)" TargetType="Editor" TargetName="$(EnginePrefix)Editor" TargetPlatform="Win64" TargetConfiguration="Development" HostPlatform="Win64" />
</ForEach>
<Expand Name="RemoveStalePrecompiledHeaders" ProjectPath="$(TempPath)/$(HostProjectName)" TargetName="$(EnginePrefix)Editor" TargetPlatform="Win64" TargetConfiguration="Development" />
<Compile Target="$(EnginePrefix)Editor" Platform="Win64" Configuration="Development" Tag="#EditorBinaries_Win64" Arguments="-Project=&quot;$(TempPath)/$(HostProjectName)/$(HostProjectName).uproject&quot; -plugin=&quot;$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)/$(PluginName).uplugin&quot; $(2017Flag) $(AdditionalArguments)"/>
</Node>
<Property Name="EditorBinaries" Value="$(EditorBinaries)#EditorBinaries_Win64;" If="'$(PackageType)' == 'Generic' and '$(CanBuildEditorWin64)' == 'true'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(EnginePrefix)Editor Win64;" If="'$(ExecutePackage)' == 'false' and '$(PackageType)' == 'Generic' and '$(CanBuildEditorWin64)' == 'true'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(EnginePrefix)Editor Win64;" If="'$(CanBuildEditorWin64)' == 'true'" />
</Agent>

<!--
Expand Down Expand Up @@ -422,7 +420,7 @@ $(PackageExclude);
<ForEach Name="TargetPlatform" Values="$(GameTargetPlatforms)">
<ForEach Name="TargetConfiguration" Values="$(GameConfigurations)">
<Agent Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration) (Mac Build Game)" Type="Mac" If="'$(IsBuildMachine)' == 'true'">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" Produces="#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration)" If="ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" Produces="#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration)" If="ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')">
<ForEach Name="MacroName" Values="$(DynamicBeforeCompileMacros)">
<Expand Name="$(MacroName)" TargetType="Game" TargetName="$(TargetName)" TargetPlatform="$(TargetPlatform)" TargetConfiguration="$(TargetConfiguration)" HostPlatform="Mac" />
</ForEach>
Expand Down Expand Up @@ -456,7 +454,7 @@ $(PackageExclude);
/>
</Node>
<Property Name="GameBinaries" Value="$(GameBinaries)#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration);" If="ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="'$(ExecutePackage)' == 'false' and ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')" />
</Agent>
</ForEach>
</ForEach>
Expand All @@ -471,7 +469,7 @@ $(PackageExclude);
<ForEach Name="TargetPlatform" Values="$(GameTargetPlatforms)">
<ForEach Name="TargetConfiguration" Values="$(GameConfigurations)">
<Agent Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration) (Windows Build Game)" Type="Win64">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" Produces="#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration)" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" Produces="#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration)" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')">
<ForEach Name="MacroName" Values="$(DynamicBeforeCompileMacros)">
<Expand Name="$(MacroName)" TargetType="Game" TargetName="$(TargetName)" TargetPlatform="$(TargetPlatform)" TargetConfiguration="$(TargetConfiguration)" HostPlatform="Win64" />
</ForEach>
Expand Down Expand Up @@ -505,7 +503,7 @@ $(PackageExclude);
/>
</Node>
<Property Name="GameBinaries" Value="$(GameBinaries)#GameBinaries_$(TargetName)_$(TargetPlatform)_$(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'"/>
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="'$(ExecutePackage)' == 'false' and !ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')" />
</Agent>
</ForEach>
</ForEach>
Expand All @@ -515,7 +513,7 @@ $(PackageExclude);
<ForEach Name="TargetPlatform" Values="$(ClientTargetPlatforms)">
<ForEach Name="TargetConfiguration" Values="$(ClientConfigurations)">
<Agent Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration) (Windows Build Client)" Type="Win64">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')">
<WriteTextFile
File="$(TempPath)/$(HostProjectName)/Source/$(HostProjectName)Client.Target.cs"
Text="using UnrealBuildTool; public class $(HostProjectName)ClientTarget : TargetRules { public $(HostProjectName)ClientTarget(TargetInfo Target) : base(Target) { Type = TargetType.Client; DefaultBuildSettings = BuildSettingsVersion.V2; ExtraModuleNames.AddRange(new string[] { &quot;$(HostProjectName)&quot; }); } }"
Expand Down Expand Up @@ -544,7 +542,7 @@ $(PackageExclude);
Arguments="-Project=&quot;$(TempPath)/$(HostProjectName)/$(HostProjectName).uproject&quot; -plugin=&quot;$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)/$(PluginName).uplugin&quot; $(2017Flag) $(AdditionalArguments)"
/>
</Node>
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')" />
</Agent>
</ForEach>
</ForEach>
Expand All @@ -554,7 +552,7 @@ $(PackageExclude);
<ForEach Name="TargetPlatform" Values="$(ServerTargetPlatforms)">
<ForEach Name="TargetConfiguration" Values="$(ServerConfigurations)">
<Agent Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration) (Windows Build Server)" Type="Win64">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'">
<Node Name="Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration)" Requires="#HostProject" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')">
<WriteTextFile
File="$(TempPath)/$(HostProjectName)/Source/$(HostProjectName)Server.Target.cs"
Text="using UnrealBuildTool; public class $(HostProjectName)ServerTarget : TargetRules { public $(HostProjectName)ServerTarget(TargetInfo Target) : base(Target) { Type = TargetType.Server; DefaultBuildSettings = BuildSettingsVersion.V2; ExtraModuleNames.AddRange(new string[] { &quot;$(HostProjectName)&quot; }); } }"
Expand Down Expand Up @@ -583,7 +581,7 @@ $(PackageExclude);
Arguments="-Project=&quot;$(TempPath)/$(HostProjectName)/$(HostProjectName).uproject&quot; -plugin=&quot;$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)/$(PluginName).uplugin&quot; $(2017Flag) $(AdditionalArguments)"
/>
</Node>
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';') and '$(PackageType)' == 'Generic'" />
<Property Name="BuildTasks" Value="$(BuildTasks)Compile $(TargetName) $(TargetPlatform) $(TargetConfiguration);" If="!ContainsItem('$(MacPlatforms)', '$(TargetPlatform)', ';')" />
</Agent>
</ForEach>
</ForEach>
Expand All @@ -594,34 +592,31 @@ $(PackageExclude);
includes custom scripts and Gauntlet tests, which may require game binaries to be present.
-->

<Do If="'$(ExecutePackage)' == 'true'">
<Expand
Name="Create Package"
AgentStage="Create Final Package"
AgentType="Win64"
NodeName="Create Package"
InputProject="#HostProject"
InputBaseDir="$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)"
InputBinaries="$(EditorBinaries);$(GameBinaries)"
OutputDir="$(TempPath)/$(PackageFolder)"
OutputTag="#PackagedPlugin"
If="'$(ExecutePackage)' == 'true'"
<Expand
Name="Create Package"
AgentStage="Create Final Package"
AgentType="Win64"
NodeName="Create Package"
InputProject="#HostProject"
InputBaseDir="$(TempPath)/$(HostProjectName)/Plugins/$(ShortPluginName)"
InputBinaries="$(EditorBinaries);$(GameBinaries)"
OutputDir="$(TempPath)/$(PackageFolder)"
OutputTag="#PackagedPlugin"
/>
<Property Name="PackageTasks" Value="$(PackageTasks)#PackagedPlugin;" If="'$(PackageType)' != 'None'" />

<Agent Name="Zip Plugin (Create Final Package)" Type="Win64">
<Node Name="Zip Plugin" Requires="#PackagedPlugin" Produces="#PackagedZip">
<Delete Files="$(ProjectRoot)/$(PluginName)-$(Distribution)-$(VersionName).zip" />
<Zip
FromDir="$(TempPath)/$(PackageFolder)/"
Files="#PackagedPlugin"
ZipFile="$(ProjectRoot)/$(PluginName)-$(Distribution)-$(VersionName).zip"
Tag="#PackagedZip"
/>
<Property Name="PackageTasks" Value="$(PackageTasks)#PackagedPlugin;" />

<Agent Name="Zip Plugin (Create Final Package)" Type="Win64" If="'$(ExecuteZip)' == 'true'">
<Node Name="Zip Plugin" Requires="#PackagedPlugin" Produces="#PackagedZip">
<Delete Files="$(ProjectRoot)/$(PluginName)-$(Distribution)-$(VersionName).zip" />
<Zip
FromDir="$(TempPath)/$(PackageFolder)/"
Files="#PackagedPlugin"
ZipFile="$(ProjectRoot)/$(PluginName)-$(Distribution)-$(VersionName).zip"
Tag="#PackagedZip"
/>
</Node>
</Agent>
<Property Name="PackageTasks" Value="$(PackageTasks)#PackagedZip;" If="'$(ExecuteZip)' == 'true'" />
</Do>
</Node>
</Agent>
<Property Name="PackageTasks" Value="$(PackageTasks)#PackagedZip;" If="'$(PackageType)' != 'None'" />

<!--
Run all of the tests and deployments (which are dynamically defined by UET).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
public class BuildConfigPluginPackage
{
/// <summary>
/// Defines the package type, such as whether it is being packaged for Marketplace or Fab submission. One of 'Generic', 'Marketplace' or 'Fab'. If not set, defaults to 'Generic'.
/// Defines the package type, such as whether it is being packaged for Marketplace or Fab submission. One of 'None', 'Generic', 'Marketplace' or 'Fab'. If not set, defaults to 'None'.
/// </summary>
[JsonPropertyName("Type"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public BuildConfigPluginPackageType? Type { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
/// </remarks>
public enum BuildConfigPluginPackageType
{
/// <summary>
/// The plugin should not be packaged.
/// </summary>
None,

/// <summary>
/// The plugin is being packaged for a generic store or self-hosted distribution. The plugin package will contain binary files.
/// </summary>
Expand All @@ -18,6 +23,6 @@ public enum BuildConfigPluginPackageType
/// <summary>
/// The plugin is being packaged for submission to Fab. The plugin will not contain binary files.
/// </summary>
Fab
Fab,
}
}
Loading
Loading