Skip to content
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
35 changes: 35 additions & 0 deletions .github/actions/setup-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Setup and Build
description: Setup .NET + Node.js, restore dependencies in parallel, and build frontend + backend

runs:
using: composite
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'

- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ hashFiles('**/*.csproj', 'Directory.Packages.props') }}
restore-keys: nuget-

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'

- name: Restore dependencies
shell: bash
run: npm ci & dotnet restore & wait

- name: Build frontend
shell: bash
run: npm run build

- name: Build .NET
shell: bash
run: dotnet build --no-restore
54 changes: 2 additions & 52 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,7 @@ jobs:
needs: lint
steps:
- uses: actions/checkout@v6

- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'

- name: Download Tailwind CSS
run: bash tools/download-tailwind.sh

- name: Restore .NET
run: dotnet restore

- name: Build .NET
run: dotnet build --no-restore

- name: Install npm dependencies
run: npm ci

- name: Build frontend
run: npm run build
- uses: ./.github/actions/setup-build

- name: Test
run: dotnet test --no-build
Expand All @@ -69,32 +44,7 @@ jobs:
timeout-minutes: 15
steps:
- uses: actions/checkout@v6

- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'

- name: Download Tailwind CSS
run: bash tools/download-tailwind.sh

- name: Restore .NET
run: dotnet restore

- name: Build .NET
run: dotnet build --no-restore

- name: Install npm dependencies
run: npm ci

- name: Build frontend
run: npm run build
- uses: ./.github/actions/setup-build

- name: Install Playwright browsers
run: npx -w tests/e2e playwright install --with-deps
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,14 @@ jobs:
with:
dotnet-version: '10.0.x'

- name: Download Tailwind CSS
run: bash tools/download-tailwind.sh
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'

- name: Install npm dependencies
run: npm ci

- name: Restore
run: dotnet restore
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,6 @@ FodyWeavers.xsd
.idea/
*.sln.iml

# Tailwind CSS standalone CLI
tools/tailwindcss*

# Playwright
.playwright-cli/
.playwright-mcp/
Expand Down
48 changes: 37 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,47 @@ COPY modules/Tenants/src/SimpleModule.Tenants/*.csproj modules/Tenants/src/Simpl
RUN dotnet restore template/SimpleModule.Host/SimpleModule.Host.csproj

# =============================================================================
# Stage 3: Frontend build + .NET publish
# Stage 3: npm restore (cached unless package.json / lockfile changes)
# =============================================================================
FROM restore AS build
FROM restore AS npm-restore
WORKDIR /src

COPY . .

# Download Tailwind CSS CLI for Linux
RUN ARCH=$(uname -m) && \
case "$ARCH" in x86_64) ARCH="x64" ;; aarch64|arm64) ARCH="arm64" ;; esac && \
curl -sL "https://github.com/tailwindlabs/tailwindcss/releases/download/v4.1.3/tailwindcss-linux-${ARCH}" -o tools/tailwindcss && \
chmod +x tools/tailwindcss
# Root manifest + lockfile
COPY package.json package-lock.json ./

# Workspace package.json files (must exist for npm ci with workspaces)
COPY modules/Admin/src/SimpleModule.Admin/package.json modules/Admin/src/SimpleModule.Admin/
COPY modules/AuditLogs/src/SimpleModule.AuditLogs/package.json modules/AuditLogs/src/SimpleModule.AuditLogs/
COPY modules/Dashboard/src/SimpleModule.Dashboard/package.json modules/Dashboard/src/SimpleModule.Dashboard/
COPY modules/FeatureFlags/src/SimpleModule.FeatureFlags/package.json modules/FeatureFlags/src/SimpleModule.FeatureFlags/
COPY modules/FileStorage/src/SimpleModule.FileStorage/package.json modules/FileStorage/src/SimpleModule.FileStorage/
COPY modules/Marketplace/src/SimpleModule.Marketplace/package.json modules/Marketplace/src/SimpleModule.Marketplace/
COPY modules/OpenIddict/src/SimpleModule.OpenIddict/package.json modules/OpenIddict/src/SimpleModule.OpenIddict/
COPY modules/Orders/src/SimpleModule.Orders/package.json modules/Orders/src/SimpleModule.Orders/
COPY modules/PageBuilder/src/SimpleModule.PageBuilder/package.json modules/PageBuilder/src/SimpleModule.PageBuilder/
COPY modules/Products/src/SimpleModule.Products/package.json modules/Products/src/SimpleModule.Products/
COPY modules/Settings/src/SimpleModule.Settings/package.json modules/Settings/src/SimpleModule.Settings/
COPY modules/Tenants/src/SimpleModule.Tenants/package.json modules/Tenants/src/SimpleModule.Tenants/
COPY modules/Users/src/SimpleModule.Users/package.json modules/Users/src/SimpleModule.Users/
COPY packages/SimpleModule.Client/package.json packages/SimpleModule.Client/
COPY packages/SimpleModule.Theme.Default/package.json packages/SimpleModule.Theme.Default/
COPY packages/SimpleModule.UI/package.json packages/SimpleModule.UI/
COPY template/SimpleModule.Host/ClientApp/package.json template/SimpleModule.Host/ClientApp/
COPY tests/e2e/package.json tests/e2e/
COPY docs/site/package.json docs/site/
COPY website/package.json website/

# Install npm dependencies and build all frontend workspaces
RUN npm ci

# =============================================================================
# Stage 4: Frontend build + .NET publish
# =============================================================================
FROM npm-restore AS build
WORKDIR /src

COPY . .

# Build all frontend workspaces
RUN npm run build

# Publish the .NET application (MSBuild targets detect existing frontend
Expand All @@ -94,7 +120,7 @@ RUN dotnet publish template/SimpleModule.Host/SimpleModule.Host.csproj \
-p:ErrorOnDuplicatePublishOutputFiles=false

# =============================================================================
# Stage 4: Runtime (slim image, non-root user)
# Stage 5: Runtime (slim image, non-root user)
# =============================================================================
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
Expand Down
6 changes: 2 additions & 4 deletions framework/SimpleModule.DevTools/ViteDevWatchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,12 @@ private async Task RunBuild(string name, string command, string workingDir)

private async Task RunTailwindBuild()
{
var tailwindCli = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(_repoRoot, "tools", "tailwindcss.exe")
: Path.Combine(_repoRoot, "tools", "tailwindcss");

var hostDir = environment.ContentRootPath;
var inputPath = Path.Combine(hostDir, "Styles", "app.css");
var outputPath = Path.Combine(hostDir, "wwwroot", "css", "app.css");

var tailwindBin = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "tailwindcss.cmd" : "tailwindcss";
var tailwindCli = Path.Combine(_npmBinPath, tailwindBin);
var command = $"\"{tailwindCli}\" -i \"{inputPath}\" -o \"{outputPath}\"";

await RunBuild("Tailwind", command, hostDir).ConfigureAwait(false);
Expand Down
26 changes: 13 additions & 13 deletions framework/SimpleModule.Hosting/build/SimpleModule.Hosting.targets
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<!-- Tailwind CSS properties -->
<!-- Build configuration -->
<PropertyGroup>
<TailwindCli Condition="'$(OS)' == 'Windows_NT'">$(RepoRoot)tools\tailwindcss.exe</TailwindCli>
<TailwindCli Condition="'$(OS)' != 'Windows_NT'">$(RepoRoot)tools/tailwindcss</TailwindCli>
<TailwindCli Condition="'$(OS)' == 'Windows_NT'">$(RepoRoot)node_modules/.bin/tailwindcss.cmd</TailwindCli>
<TailwindCli Condition="'$(OS)' != 'Windows_NT'">$(RepoRoot)node_modules/.bin/tailwindcss</TailwindCli>
<TailwindInput>$(MSBuildProjectDirectory)/Styles/app.css</TailwindInput>
<TailwindOutput>$(MSBuildProjectDirectory)/wwwroot/css/app.css</TailwindOutput>
<ViteBuildStamp>$(IntermediateOutputPath)vitebuild.stamp</ViteBuildStamp>
Expand Down Expand Up @@ -39,23 +39,23 @@
SkipUnchangedFiles="true"
/>
</Target>
<!-- Warn when Tailwind input exists but node_modules is missing -->
<Target
Name="TailwindBuildCheck"
BeforeTargets="Build"
Condition="Exists('$(TailwindInput)') And !Exists('$(RepoRoot)node_modules')"
>
<Warning Text="node_modules not found. Tailwind CSS will not be compiled. Run 'npm install' in the repository root." />
</Target>
<!-- Tailwind CSS build (incremental: real output file as Outputs) -->
<Target
Name="TailwindBuild"
BeforeTargets="Build"
Condition="Exists('$(TailwindInput)')"
Condition="Exists('$(TailwindInput)') And Exists('$(RepoRoot)node_modules')"
Inputs="@(TailwindSourceFiles)"
Outputs="$(TailwindOutput)"
>
<Warning
Condition="!Exists('$(TailwindCli)')"
Text="Tailwind CSS CLI not found at '$(TailwindCli)'. CSS will not be compiled. Run tools/download-tailwind.sh (or .ps1 on Windows) to install it."
/>
<PropertyGroup>
<_TailwindAvailable>false</_TailwindAvailable>
<_TailwindAvailable Condition="Exists('$(TailwindCli)')">true</_TailwindAvailable>
</PropertyGroup>
<Exec Condition="'$(_TailwindAvailable)' == 'true'" Command="&quot;$(TailwindCli)&quot; -i &quot;$(TailwindInput)&quot; -o &quot;$(TailwindOutput)&quot; --minify" />
<Exec Command="&quot;$(TailwindCli)&quot; -i &quot;$(TailwindInput)&quot; -o &quot;$(TailwindOutput)&quot; --minify" />
</Target>
<!-- Warn when ClientApp exists but node_modules is missing -->
<Target
Expand Down
Loading
Loading