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
99 changes: 27 additions & 72 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ on:
pull_request:
branches: [main]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
dotnet-version: '10.0.x'
node-version: '22'
cache: 'npm'

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

- name: Restore
run: dotnet restore
- name: Install npm dependencies
run: npm ci

- name: Build
run: dotnet build --no-restore
- name: Lint and format check
run: npm run check

test-sqlite:
build:
runs-on: ubuntu-latest
needs: build

needs: lint
steps:
- uses: actions/checkout@v4

Expand All @@ -39,68 +39,23 @@ jobs:
with:
dotnet-version: '10.0.x'

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

- name: Test
run: dotnet test --verbosity normal

test-postgresql:
runs-on: ubuntu-latest
needs: build

services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: simplemodule_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
dotnet-version: '10.0.x'
node-version: '22'
cache: 'npm'

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

- name: Test with PostgreSQL
run: dotnet test --verbosity normal
env:
Database__DefaultConnection: "Host=localhost;Database=simplemodule_test;Username=test;Password=test"

- name: Verify migrations are up-to-date
working-directory: template/SimpleModule.Host
env:
Database__DefaultConnection: "Host=localhost;Database=simplemodule_test;Username=test;Password=test"
run: dotnet ef migrations has-pending-model-changes

publish:
runs-on: ubuntu-latest
needs: [test-sqlite, test-postgresql]
if: github.ref == 'refs/heads/main'

steps:
- uses: actions/checkout@v4
- name: Restore .NET
run: dotnet restore

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Build .NET
run: dotnet build --no-restore

- name: Download Tailwind CSS
run: bash tools/download-tailwind.sh
- name: Install npm dependencies
run: npm ci

- name: Publish
run: dotnet publish template/SimpleModule.Host/SimpleModule.Host.csproj -c Release
- name: Build frontend
run: npm run build
160 changes: 160 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
name: Release

on:
workflow_dispatch:
inputs:
bump:
description: 'Version bump type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major

workflow_run:
workflows: [CI]
types: [completed]
branches: [main]

concurrency:
group: release
cancel-in-progress: false

permissions:
contents: write

jobs:
version:
runs-on: ubuntu-latest
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main')
outputs:
version: ${{ steps.bump.outputs.version }}
skip: ${{ steps.check.outputs.skip }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Check if release commit
id: check
run: |
# For workflow_run, check the commit that triggered CI (not current HEAD)
if [ "${{ github.event_name }}" = "workflow_run" ]; then
SHA="${{ github.event.workflow_run.head_sha }}"
else
SHA="HEAD"
fi
MSG=$(git log -1 --pretty=%s "$SHA")
if [[ "$MSG" == release:* ]]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Skipping: commit $SHA is a release commit"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi

- name: Determine bump type
if: steps.check.outputs.skip != 'true'
id: bump-type
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "bump=${{ inputs.bump }}" >> "$GITHUB_OUTPUT"
else
echo "bump=patch" >> "$GITHUB_OUTPUT"
fi

- name: Bump version
if: steps.check.outputs.skip != 'true'
id: bump
run: |
CURRENT=$(jq -r .version version.json)
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"

BUMP="${{ steps.bump-type.outputs.bump }}"
case "$BUMP" in
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
patch) PATCH=$((PATCH + 1)) ;;
esac

NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
jq -n --arg v "$NEW_VERSION" '{"version": $v}' > version.json
echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "Bumped $CURRENT -> $NEW_VERSION ($BUMP)"

- name: Commit and tag
if: steps.check.outputs.skip != 'true'
run: |
VERSION="${{ steps.bump.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add version.json
git commit -m "release: v${VERSION}"
git tag "v${VERSION}"
git push origin main --follow-tags

publish-nuget:
runs-on: ubuntu-latest
needs: version
if: needs.version.outputs.skip != 'true'
steps:
- uses: actions/checkout@v4
with:
ref: v${{ needs.version.outputs.version }}

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

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

- name: Restore
run: dotnet restore

- name: Pack
run: |
VERSION="${{ needs.version.outputs.version }}"
for csproj in framework/*/*.csproj; do
dotnet pack "$csproj" -c Release -p:Version=$VERSION --no-restore -o ./nupkgs
done

- name: Push to NuGet
run: dotnet nuget push ./nupkgs/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate

publish-npm:
runs-on: ubuntu-latest
needs: version
if: needs.version.outputs.skip != 'true'
steps:
- uses: actions/checkout@v4
with:
ref: v${{ needs.version.outputs.version }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci

- name: Build frontend
run: npm run build

- name: Set version and publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
VERSION="${{ needs.version.outputs.version }}"
for pkg in packages/SimpleModule.Client packages/SimpleModule.UI packages/SimpleModule.Theme.Default; do
(cd "$pkg" && npm version "$VERSION" --no-git-tag-version && npm publish --access public)
done
10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@
<!-- Hardlinks instead of file copies where possible -->
<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>
</PropertyGroup>
<!-- NuGet package metadata (version injected by CI via -p:Version) -->
<PropertyGroup>
<Authors>SimpleModule</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/antosubash/SimpleModule</PackageProjectUrl>
<RepositoryUrl>https://github.com/antosubash/SimpleModule</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>modular-monolith;aspnetcore;blazor;react;inertia</PackageTags>
<Copyright>Copyright (c) SimpleModule contributors</Copyright>
</PropertyGroup>
<!-- .NET SDK analyzers only work on net5.0+ -->
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
<AnalysisLevel>latest-all</AnalysisLevel>
Expand Down
25 changes: 8 additions & 17 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,14 @@
}
}
},
"overrides": [
{
"includes": ["modules/*/src/*/types.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
},
"complexity": {
"noBannedTypes": "off",
"noEmptyTypeParameters": "off"
}
}
}
}
],
"files": {
"includes": ["modules/**", "packages/**", "template/**", "tests/**", "!**/wwwroot"]
"includes": [
"modules/**",
"packages/**",
"template/**",
"tests/**",
"!**/wwwroot",
"!**/types.ts"
]
}
}
10 changes: 10 additions & 0 deletions framework/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<PropertyGroup>
<IsPackable>true</IsPackable>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
30 changes: 30 additions & 0 deletions framework/SimpleModule.Blazor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SimpleModule.Blazor

[![NuGet](https://img.shields.io/nuget/v/SimpleModule.Blazor.svg)](https://www.nuget.org/packages/SimpleModule.Blazor)

Blazor SSR integration for SimpleModule, bridging server-side rendering with Inertia.js and React.

## Installation

```bash
dotnet add package SimpleModule.Blazor
```

## Quick Start

The Blazor package is automatically configured when using SimpleModule.Hosting. It provides the SSR shell that renders the initial HTML page with Inertia.js props for React hydration.

```csharp
// In an endpoint:
return Inertia.Render("Products/Browse", new { Products = products });
```

## Key Features

- **Blazor SSR shell** renders the initial HTML with embedded JSON props
- **Inertia.js middleware** bridges ASP.NET responses to React client navigation
- **Razor component discovery** for module-provided Blazor components

## Links

- [GitHub Repository](https://github.com/antosubash/SimpleModule)
3 changes: 1 addition & 2 deletions framework/SimpleModule.Blazor/SimpleModule.Blazor.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<Version>0.1.0-local</Version>
<Description>Blazor SSR integration for SimpleModule. Bridges Blazor server-side rendering with Inertia.js and React frontend.</Description>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
Expand Down
Loading
Loading