Skip to content
Draft
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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## [55.2.2]
## [55.2.3]
- [Build] Improved app build time by running Android, iOS and Library builds in parallel, and ensuring `init` (dotnet restore) runs only once across dependent tasks.


- [iOS26][Tip] Added more padding.

## [55.2.1]
Expand Down
42 changes: 30 additions & 12 deletions build/AwesomeBuildsystem/Core/TaskRunner.csx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class TaskDefinition
public static class TaskRunner
{
private static Dictionary<string, TaskDefinition> tasks = new Dictionary<string, TaskDefinition>();
private static System.Collections.Concurrent.ConcurrentDictionary<string, Task> _executedTasks = new System.Collections.Concurrent.ConcurrentDictionary<string, Task>();

/// <summary>
/// Creates a new async task definition
Expand Down Expand Up @@ -90,27 +91,44 @@ public static class TaskRunner
}

/// <summary>
/// Runs a single task by name or alias
/// Runs a single task by name or alias.
/// Dependencies declared with IsDependentOn are resolved and run first.
/// Each task is guaranteed to run at most once per build session.
/// </summary>
/// <param name="taskNameOrAlias">Name or alias of the task to run</param>
public static async Task RunAsync(string taskNameOrAlias)
public static Task RunAsync(string taskNameOrAlias)
{
var actualTaskName = ResolveTaskName(taskNameOrAlias);

if (actualTaskName != null && tasks.TryGetValue(actualTaskName, out var task))
if (actualTaskName == null || !tasks.TryGetValue(actualTaskName, out var task))
{
Console.WriteLine($"Running task: {actualTaskName}" + (actualTaskName != taskNameOrAlias ? $" (alias: {taskNameOrAlias})" : ""));

if (task.BeforeAction != null) await task.BeforeAction();
if (task.Action != null) await task.Action();
if (task.AfterAction != null) await task.AfterAction();

Console.WriteLine($"Completed task: {actualTaskName}");
Console.WriteLine($"Task '{taskNameOrAlias}' not found");
return Task.CompletedTask;
}
else

// GetOrAdd ensures the task body executes exactly once even when called concurrently.
return _executedTasks.GetOrAdd(actualTaskName, _ => ExecuteTaskAsync(task, actualTaskName, taskNameOrAlias));
}

private static async Task ExecuteTaskAsync(TaskDefinition task, string actualTaskName, string taskNameOrAlias)
{
// Run all dependencies first, in parallel when there are multiple.
if (task.Dependencies.Count == 1)
{
Console.WriteLine($"Task '{taskNameOrAlias}' not found");
await RunAsync(task.Dependencies[0]);
}
else if (task.Dependencies.Count > 1)
{
await Task.WhenAll(task.Dependencies.Select(dep => RunAsync(dep)));
}

Console.WriteLine($"Running task: {actualTaskName}" + (actualTaskName != taskNameOrAlias ? $" (alias: {taskNameOrAlias})" : ""));

if (task.BeforeAction != null) await task.BeforeAction();
if (task.Action != null) await task.Action();
if (task.AfterAction != null) await task.AfterAction();

Console.WriteLine($"Completed task: {actualTaskName}");
}

/// <summary>
Expand Down
8 changes: 6 additions & 2 deletions build/build.csx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ TaskRunner
.Alias("bi")
.IsDependentOn("init")
.DoesBefore(() => { Console.WriteLine("##[group]buildiOS 🛠"); return Task.CompletedTask; })
.Does(() => iOS.Build(LibraryPath, "Debug"))
.Does(() => iOS.Build(ComponentsPath, "Debug"))
.DoesAfter(() => { Console.WriteLine("##[endgroup]"); return Task.CompletedTask; });

TaskRunner
Expand Down Expand Up @@ -332,7 +332,11 @@ TaskRunner
.Alias("ball")
.DoesBefore(() => { Console.WriteLine("##[group]buildAll 🛠"); return Task.CompletedTask; })
.Does(async () => {
await TaskRunner.RunAsync(new[] { "buildAndroid", "buildiOS", "buildLibrary" }, false);
await Task.WhenAll(
TaskRunner.RunAsync("buildAndroid"),
TaskRunner.RunAsync("buildiOS"),
TaskRunner.RunAsync("buildLibrary")
);
})
.DoesAfter(() => { Console.WriteLine("##[endgroup]"); return Task.CompletedTask; });

Expand Down