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
37 changes: 8 additions & 29 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,33 @@

jobs:
build:
runs-on: windows-latest
runs-on: ubuntu-latest
steps:
- name: Setup .NET (With cache)
uses: actions/setup-dotnet@v5.2.0
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
dotnet-quality: 'preview'
dotnet-version: 10.0.x
dotnet-quality: 'preview'

- name: 'Setup Java JDK 11'
uses: actions/setup-java@v5.2.0
with:
distribution: 'microsoft'
java-version: '11'

- name: 'Add MSBuild to PATH'
uses: microsoft/setup-msbuild@v2.0.0
with:
vs-prerelease: true

- name: 'Install DotNet workloads'
shell: bash
run: |
dotnet workload install android ios tvos macos maui maccatalyst

- name: Checkout
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: 'Cache: .nuke/temp, ~/.nuget/packages'
- name: 'Cache: .nuke/temp, NuGet packages'
uses: actions/cache@v5
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
reactiveui/api/cache
key: ${{ runner.os }}-${{ hashFiles('**/global.json', 'nuget-packages.json') }}

- name: 'Restore and Compile ReactiveUI Projects'
run: ./build.cmd Compile

- name: 'Build Website'
run: ./build.cmd BuildWebsite
run: ./build.sh BuildWebsite

- name: 'Deploy netlify'
if: ${{ github.event_name != 'pull_request' }}
run: |
npm install -g netlify-cli
netlify deploy --auth=${{ secrets.NETLIFY_DEPLOY_KEY }} --site=${{ secrets.NETLIFY_SITE_ID }} --prod --dir=reactiveui/_site

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -349,5 +349,12 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

reactiveui/api/lib/
reactiveui/api/cache/
reactiveui/api/refs/
reactiveui/api/reactiveui/
reactiveui/api/reactivemarbles/
reactiveui/api-android/
reactiveui/api-test/
reactiveui/api-windows/
reactiveui/_site/
9 changes: 7 additions & 2 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"enum": [
"BuildWebsite",
"Clean",
"Compile",
"Restore"
"FetchPackages",
"Serve"
]
},
"Verbosity": {
Expand Down Expand Up @@ -108,6 +108,11 @@
"Debug",
"Release"
]
},
"Port": {
"type": "integer",
"description": "Port for the preview server (default: 8080)",
"format": "int32"
}
}
},
Expand Down
Empty file modified build.sh
100644 → 100755
Empty file.
143 changes: 32 additions & 111 deletions build/Build.cs
Original file line number Diff line number Diff line change
@@ -1,149 +1,70 @@
using Nuke.Common;
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tooling;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.MSBuild;
using ReactiveUI.Web;
using System;
using System.IO;
using System.Linq;
using static Nuke.Common.Tools.DotNet.DotNetTasks;

class Build : NukeBuild
{
/// Support plugins are available for:
/// - JetBrains ReSharper https://nuke.build/resharper
/// - JetBrains Rider https://nuke.build/rider
/// - Microsoft VisualStudio https://nuke.build/visualstudio
/// - Microsoft VSCode https://nuke.build/vscode

public static int Main() => Execute<Build>(x => x.Compile);
public static int Main() => Execute<Build>(x => x.BuildWebsite);

[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;

private static readonly string reactiveui = nameof(reactiveui);
private static readonly string akavache = nameof(akavache);
private static readonly string fusillade = nameof(fusillade);
private static readonly string punchclock = nameof(punchclock);
private static readonly string splat = nameof(splat);
private static readonly string DynamicData = nameof(DynamicData);
private static readonly string reactivemarbles = nameof(reactivemarbles);
private static readonly string extensions = nameof(extensions);
private static readonly string[] RxUIProjects = [akavache, fusillade, punchclock, splat, extensions]; ////, reactiveui, "ReactiveUI.Validation", "ReactiveUI.Avalonia", "Maui.Plugins.Popup"];

private AbsolutePath RxUIAPIDirectory => RootDirectory / reactiveui / "api" / reactiveui;
private AbsolutePath RxMAPIDirectory => RootDirectory / reactiveui / "api" / reactivemarbles;

private static readonly string api = nameof(api);
private AbsolutePath WebRootPath => RootDirectory / reactiveui;
private AbsolutePath ApiPath => WebRootPath / api;
private AbsolutePath ApiLibDirectory => ApiPath / "lib";
private AbsolutePath ApiRefsDirectory => ApiPath / "refs";
private AbsolutePath ApiCacheDirectory => ApiPath / "cache";
private AbsolutePath DocfxConfigPath => WebRootPath / "docfx.json";
private AbsolutePath SiteOutputPath => WebRootPath / "_site";

Target Clean => _ => _
.Before(Restore)
.Before(FetchPackages)
.Executes(() =>
{
RxUIAPIDirectory.DeleteDirectory();
RxMAPIDirectory.DeleteDirectory();
ApiLibDirectory.DeleteDirectory();
ApiRefsDirectory.DeleteDirectory();
// Install docfx
ProcessTasks.StartShell("dotnet tool update -g docfx").AssertZeroExitCode();
});

Target Restore => _ => _
Target FetchPackages => _ => _
.DependsOn(Clean)
.Executes(() =>
{
// Restore ReactiveUI Projects
RxUIAPIDirectory.GetSources(RootDirectory, reactiveui, RxUIProjects);

// Restore Reactive Marbles Projects
RxMAPIDirectory.GetSources(RootDirectory, reactivemarbles, DynamicData);
NuGetFetcher.FetchPackages(RootDirectory, ApiPath);
});

Target Compile => _ => _
.DependsOn(Restore)
Target BuildWebsite => _ => _
.DependsOn(FetchPackages)
.Produces(SiteOutputPath)
.Executes(() =>
{
foreach (var project in RxUIProjects)
{
try
{
var dirRx = RxUIAPIDirectory / "external" / project / $"{project}-main" / "src";
File.Copy(RootDirectory / "global.json", dirRx / "global.json", true);
var solutionFile = dirRx / $"{project}.sln";

// Find any .sln or .slnx file as a fallback
var solutionFileSearch = Directory.EnumerateFiles(dirRx, "*.sln*").FirstOrDefault();
if (File.Exists(solutionFile) == false)
{
solutionFile += "x";
if (File.Exists(solutionFile) == false)
{
if (File.Exists(solutionFileSearch))
{
solutionFile = solutionFileSearch;
}
else
{
SourceFetcher.LogRepositoryError(reactiveui, project, $"Solution file not found: {dirRx / $"{project}.sln(x)"}");
continue;
}
}
}

SourceFetcher.LogInfo($"Restoring {solutionFile}...");
DotNetRestore(s => s.SetProjectFile(solutionFile));
SourceFetcher.LogInfo($"Building {solutionFile}...");
DotNetBuild(s => s
.SetProjectFile(solutionFile)
.SetConfiguration(Configuration)
.EnableNoRestore());
SourceFetcher.LogInfo($"{project} build complete");
}
catch (Exception ex)
{
SourceFetcher.LogRepositoryError(reactiveui, project, ex.ToString());
}
}

try
{
var dirDd = RxMAPIDirectory / "external" / DynamicData / $"{DynamicData}-main" / "src";
File.Copy(RootDirectory / "global.json", dirDd / "global.json", true);
var solutionFile = dirDd / $"{DynamicData}.sln";
if (File.Exists(solutionFile) == false)
{
solutionFile += "x";
if (File.Exists(solutionFile) == false)
{
SourceFetcher.LogRepositoryError(reactivemarbles, DynamicData, $"Solution file not found: {dirDd / $"{DynamicData}.sln(x)"}");
return;
}
}

SourceFetcher.LogInfo($"Building {solutionFile}...");
MSBuildTasks.MSBuild(s => s
.SetProjectFile(solutionFile)
.SetConfiguration(Configuration)
.SetRestore(true));
SourceFetcher.LogInfo($"{DynamicData} build complete");
NuGetFetcher.PatchDocfxJson(RootDirectory);
ProcessTasks.StartProcess("docfx", $"\"{DocfxConfigPath}\"", workingDirectory: RootDirectory)
.AssertZeroExitCode();
NuGetFetcher.LogInfo("Web Site build complete");
}
catch (Exception ex)
{
SourceFetcher.LogRepositoryError(reactivemarbles, DynamicData, ex.ToString());
NuGetFetcher.LogError(ex.ToString());
}
});

Target BuildWebsite => _ => _
.Produces(RootDirectory / reactiveui / "_site")
.Executes(() =>
{
try
{
ProcessTasks.StartShell("docfx reactiveui/docfx.json").AssertZeroExitCode();
SourceFetcher.LogInfo("Web Site build complete");
}
catch (Exception ex)
[Parameter("Port for the preview server (default: 8080)")]
readonly int Port = 8080;

Target Serve => _ => _
.DependsOn(BuildWebsite)
.Executes(() =>
{
SourceFetcher.LogError(ex.ToString());
}
});
NuGetFetcher.LogInfo($"Serving website at http://localhost:{Port}");
ProcessTasks.StartProcess("docfx", $"serve \"{SiteOutputPath}\" -p {Port}", workingDirectory: RootDirectory)
.AssertZeroExitCode();
});
}
Loading
Loading