Skip to content

Commit

Permalink
Allow certain pre-build per-platform actions to optionally configure …
Browse files Browse the repository at this point in the history
…Editor
  • Loading branch information
robinnorth committed May 14, 2021
1 parent eeb0f80 commit 2ee3ff5
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 111 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!-- ## [Unreleased] -->
## [Unreleased]

### Added

- Allow certain pre-build per-platform actions to optionally configure Editor.

### Changed

- Removed pre-Unity 2019.1 code.

## [2.0.0] - 2021-05-13

Expand Down
31 changes: 18 additions & 13 deletions Editor/Build/Action/BuildAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum ActionType
public string actionName = string.Empty;
public string note = string.Empty;
public bool actionEnabled = true;
[Tooltip("BuildAction should run when 'Configure Editor Environment' button is clicked")] public bool configureEditor = false;
public BuildFilter filter = new BuildFilter();

/// <summary>
Expand All @@ -41,25 +42,23 @@ public void Draw(SerializedObject obj)
{
DrawProperties(obj);

System.Type myType = this.GetType();
System.Type myType = GetType();
bool isPreBuildAction = typeof(IPreBuildAction).IsAssignableFrom(myType);
bool isPostBuildAction = typeof(IPostBuildAction).IsAssignableFrom(myType);
bool isPreBuildPerPlatformAction = typeof(IPreBuildPerPlatformAction).IsAssignableFrom(myType);
bool isPostBuildPerPlatformAction = typeof(IPostBuildPerPlatformAction).IsAssignableFrom(myType);
bool isPreBuildActionCanConfigureEditor = typeof(IPreBuildPerPlatformActionCanConfigureEditor).IsAssignableFrom(myType);
bool actionTypeSelectable = false;
if (typeof(IPreBuildAction).IsAssignableFrom(myType) &&
typeof(IPreBuildPerPlatformAction).IsAssignableFrom(myType))
{
actionTypeSelectable = true;
}
else if (typeof(IPostBuildAction).IsAssignableFrom(myType) &&
typeof(IPostBuildPerPlatformAction).IsAssignableFrom(myType))

if ((isPreBuildAction && isPreBuildPerPlatformAction) || (isPostBuildAction && isPostBuildPerPlatformAction))
{
actionTypeSelectable = true;
}
else if (typeof(IPreBuildAction).IsAssignableFrom(myType) ||
typeof(IPostBuildAction).IsAssignableFrom(myType))
else if (isPreBuildAction || isPostBuildAction)
{
actionType = ActionType.SingleRun;
}
else if (typeof(IPreBuildPerPlatformAction).IsAssignableFrom(myType) ||
typeof(IPostBuildPerPlatformAction).IsAssignableFrom(myType))
else if (isPreBuildPerPlatformAction || isPostBuildPerPlatformAction)
{
actionType = ActionType.PerPlatform;
}
Expand All @@ -69,6 +68,11 @@ public void Draw(SerializedObject obj)
actionType = (ActionType)EditorGUILayout.EnumPopup("Action Type", actionType);
}

if (isPreBuildActionCanConfigureEditor)
{
EditorGUILayout.PropertyField(obj.FindProperty("configureEditor"));
}

EditorGUILayout.PropertyField(obj.FindProperty("note"));

// Only Per-Platform actions can be filtered
Expand All @@ -91,7 +95,8 @@ protected virtual void DrawProperties(SerializedObject obj)
prop.name == "actionType" ||
prop.name == "note" ||
prop.name == "actionEnabled" ||
prop.name == "filter")
prop.name == "filter" ||
prop.name == "configureEditor")
{
// Already drawn these. Go to next, don't enter into object.
done = !prop.NextVisible(false);
Expand Down
1 change: 0 additions & 1 deletion Editor/Build/Action/BuildActionListUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace SuperUnityBuild.BuildTool
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

namespace SuperUnityBuild.BuildTool
{
public interface IPreBuildPerPlatformActionCanConfigureEditor { }
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

178 changes: 85 additions & 93 deletions Editor/Build/BuildProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,35 @@ public static void BuildSingle(string keyChain, BuildOptions options)
PerformBuild(buildConfigs, options);
}

public static void ConfigureEnvironment(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime)
public static void ConfigureEditor(string configKey, BuildOptions options = BuildOptions.None)
{
// Switch to target build platform
EditorUserBuildSettings.SwitchActiveBuildTarget(platform.targetGroup, architecture.target);
DateTime configureTime = DateTime.Now;

// Apply defines
string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup);
string buildDefines = GenerateDefaultDefines(releaseType, platform, architecture, distribution);
buildDefines = MergeDefines(preBuildDefines, buildDefines);
// Clear any old notifications
BuildNotificationList.instance.RefreshAll();

PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, buildDefines);
// Report Editor environment configuration
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
"Configuring Editor environment for: ", configKey,
true, null));

// Set target settings
PlayerSettings.companyName = releaseType.companyName;
PlayerSettings.productName = releaseType.productName;
// Parse build config
BuildSettings.projectConfigurations.ParseKeychain(configKey, out BuildReleaseType releaseType, out BuildPlatform platform, out BuildArchitecture architecture, out BuildDistribution distribution);

// Set bundle info
PlayerSettings.SetApplicationIdentifier(platform.targetGroup, releaseType.bundleIdentifier);
// Configure environment
ConfigureEnvironment(releaseType, platform, architecture, distribution, configureTime);

// Apply build variant
platform.ApplyVariant();

// Generate BuildConstants
BuildConstantsGenerator.Generate(buildTime, BuildSettings.productParameters.buildVersion, releaseType, platform, architecture, distribution);
// Run pre-build actions that have opted in to configuring the Editor
BuildAction[] buildActions = BuildSettings.preBuildActions.buildActions.Where(item => item.configureEditor).ToArray();

// Refresh scene list to make sure nothing has been deleted or moved
releaseType.sceneList.Refresh();
PerformBuildActions(
releaseType,
platform,
architecture,
distribution,
configureTime, ref options, configKey, null, buildActions, "'Configure Editor' Pre-"
);
}

public static string GenerateDefaultDefines(BuildReleaseType releaseType, BuildPlatform buildPlatform, BuildArchitecture arch, BuildDistribution dist)
Expand Down Expand Up @@ -257,6 +259,35 @@ public static void SetEditorBuildSettingsScenes(BuildReleaseType releaseType)

#region Private Methods

private static void ConfigureEnvironment(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime)
{
// Switch to target build platform
EditorUserBuildSettings.SwitchActiveBuildTarget(platform.targetGroup, architecture.target);

// Apply defines
string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup);
string buildDefines = GenerateDefaultDefines(releaseType, platform, architecture, distribution);
buildDefines = MergeDefines(preBuildDefines, buildDefines);

PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, buildDefines);

// Set target settings
PlayerSettings.companyName = releaseType.companyName;
PlayerSettings.productName = releaseType.productName;

// Set bundle info
PlayerSettings.SetApplicationIdentifier(platform.targetGroup, releaseType.bundleIdentifier);

// Apply build variant
platform.ApplyVariant();

// Generate BuildConstants
BuildConstantsGenerator.Generate(buildTime, BuildSettings.productParameters.buildVersion, releaseType, platform, architecture, distribution);

// Refresh scene list to make sure nothing has been deleted or moved
releaseType.sceneList.Refresh();
}

private static void ReplaceFromFile(StringBuilder sb, string keyString, string filename)
{
if (sb.ToString().IndexOf(keyString) > -1)
Expand Down Expand Up @@ -434,37 +465,7 @@ private static void PerformPreBuild(out DateTime buildTime)
}

// Run pre-build actions.
BuildAction[] buildActions = BuildSettings.preBuildActions.buildActions;

if (buildActions != null)
{
for (int i = 0; i < buildActions.Length; i++)
{
BuildAction action = buildActions[i];

// Check if execute method has been overriden.
MethodInfo m = action.GetType().GetMethod("Execute");
if (m.GetBaseDefinition().DeclaringType != m.DeclaringType && action.actionType == BuildAction.ActionType.SingleRun)
{
if (action.actionEnabled)
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Performing Pre-Build Action ({0}/{1}).", i + 1, buildActions.Length), action.actionName,
true, null));

action.Execute();
}
else
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Skipping Pre-Build Action ({0}/{1}).", i + 1, buildActions.Length), action.actionName,
true, null));
}
}
}
}
PerformBuildActions(BuildSettings.preBuildActions.buildActions, "Pre-");
}

private static void PerformPreBuild(
Expand All @@ -474,45 +475,38 @@ private static void PerformPreBuild(
BuildDistribution distribution,
DateTime buildTime, ref BuildOptions options, string configKey, string buildPath)
{
BuildAction[] buildActions = BuildSettings.preBuildActions.buildActions;
if (buildActions != null)
{
for (int i = 0; i < buildActions.Length; i++)
{
BuildAction action = buildActions[i];

// Check if execute method has been overriden.
MethodInfo m = action.GetType().GetMethod("PerBuildExecute");

if (m.GetBaseDefinition().DeclaringType != m.DeclaringType && action.actionType == BuildAction.ActionType.PerPlatform)
{
// Check build filter and execute if true.
if (action.filter == null || action.filter.Evaluate(releaseType, platform, architecture, distribution, configKey) && action.actionEnabled)
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Performing Pre-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
true, null));

action.PerBuildExecute(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);
}
else
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Skipping Pre-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
true, null));
}
}
}
}
PerformBuildActions(
releaseType,
platform,
architecture,
distribution,
buildTime, ref options, configKey, buildPath, BuildSettings.preBuildActions.buildActions, "Pre-"
);
}

private static void PerformPostBuild()
{
// Run post-build actions.
BuildAction[] buildActions = BuildSettings.postBuildActions.buildActions;
PerformBuildActions(BuildSettings.postBuildActions.buildActions, "Post-");
}

private static void PerformPostBuild(
BuildReleaseType releaseType,
BuildPlatform platform,
BuildArchitecture architecture,
BuildDistribution distribution,
DateTime buildTime, ref BuildOptions options, string configKey, string buildPath)
{
PerformBuildActions(
releaseType,
platform,
architecture,
distribution,
buildTime, ref options, configKey, buildPath, BuildSettings.postBuildActions.buildActions, "Post-"
);
}

private static void PerformBuildActions(BuildAction[] buildActions, string notificationLabel)
{
if (buildActions != null)
{
for (int i = 0; i < buildActions.Length; i++)
Expand All @@ -528,7 +522,7 @@ private static void PerformPostBuild()
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Performing Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), action.actionName,
string.Format("Performing {0}Build Action ({1}/{2}):", notificationLabel, i + 1, buildActions.Length), action.actionName,
true, null));

action.Execute();
Expand All @@ -537,23 +531,21 @@ private static void PerformPostBuild()
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Skipping Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), action.actionName,
string.Format("Skipping {0}Build Action ({1}/{2}):", notificationLabel, i + 1, buildActions.Length), action.actionName,
true, null));
}
}
}
}
}

private static void PerformPostBuild(
private static void PerformBuildActions(
BuildReleaseType releaseType,
BuildPlatform platform,
BuildArchitecture architecture,
BuildDistribution distribution,
DateTime buildTime, ref BuildOptions options, string configKey, string buildPath)
DateTime buildTime, ref BuildOptions options, string configKey, string buildPath, BuildAction[] buildActions, string notificationLabel)
{
BuildAction[] buildActions = BuildSettings.postBuildActions.buildActions;

if (buildActions != null)
{
for (int i = 0; i < buildActions.Length; i++)
Expand All @@ -570,7 +562,7 @@ private static void PerformPostBuild(
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Performing Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
string.Format("Performing {0}Build Action ({1}/{2}):", notificationLabel, i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
true, null));

action.PerBuildExecute(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath);
Expand All @@ -579,7 +571,7 @@ private static void PerformPostBuild(
{
BuildNotificationList.instance.AddNotification(new BuildNotification(
BuildNotification.Category.Notification,
string.Format("Skipping Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
string.Format("Skipping {0}Build Action ({1}/{2}):", notificationLabel, i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey),
true, null));
}
}
Expand Down
5 changes: 2 additions & 3 deletions Editor/Build/Settings/UI/ProjectConfigurationsDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
GUI.backgroundColor = Color.green;
if (GUILayout.Button("Build", GUILayout.ExpandWidth(true)))
{
BuildOptions finalBuildOptions = buildOptions;
EditorApplication.delayCall += () =>
BuildProject.BuildSingle(selectedKeyChain.stringValue, finalBuildOptions);
BuildProject.BuildSingle(selectedKeyChain.stringValue, buildOptions);
}
if (GUILayout.Button("Build and Run", GUILayout.ExpandWidth(true)))
{
Expand All @@ -183,7 +182,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
if (GUILayout.Button(new GUIContent("Configure Editor Environment", "Switches platform, refreshes BuildConstants, applies scripting defines and variant settings and sets Build Settings scene list to match the selected build configuration"), GUILayout.ExpandWidth(true)))
{
// Update Editor environment settings to match selected build configuration
BuildProject.ConfigureEnvironment(releaseType, platform, arch, dist, DateTime.Now);
BuildProject.ConfigureEditor(selectedKeyChain.stringValue, buildOptions);

// Apply scene list
BuildProject.SetEditorBuildSettingsScenes(releaseType);
Expand Down

0 comments on commit 2ee3ff5

Please sign in to comment.