Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
118 changes: 118 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# All files
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

# C# files
[*.cs]
indent_style = space
indent_size = 4
tab_width = 4

# Code style rules
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning

dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning

dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
dotnet_style_readonly_field = true:warning

dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_return = true:warning

dotnet_style_prefer_compound_assignment = true:warning

csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = true:warning

csharp_style_expression_bodied_methods = false:warning
csharp_style_expression_bodied_constructors = false:warning
csharp_style_expression_bodied_operators = false:warning

csharp_style_expression_bodied_properties = true:warning
csharp_style_expression_bodied_indexers = true:warning
csharp_style_expression_bodied_accessors = true:warning

csharp_style_expression_bodied_lambdas = true:warning
csharp_style_expression_bodied_local_functions = false:warning

csharp_style_inlined_variable_declaration = true:warning
csharp_style_deconstructed_variable_declaration = true:warning

csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning

csharp_style_prefer_switch_expression = true:warning
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_not_pattern = true:warning

csharp_style_var_pattern = true:warning
csharp_style_parenthesized_pattern = true:warning

csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning

csharp_style_implicit_object_creation_when_type_is_apparent = true:warning

# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current

# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true

# Spacing preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_opening_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
75 changes: 75 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# GitHub Actions CI/CD

This repository uses GitHub Actions for continuous integration and automated testing.

## Workflows

### CI Pipeline (`ci.yml`)
Runs on every push and pull request to `main` and `develop` branches.

**What it does:**
- ✅ Sets up .NET 9.0 environment
- ✅ Sets up Node.js 20 environment
- ✅ Installs dependencies for both backend and frontend
- ✅ Builds the Svelte client application
- ✅ Builds the .NET solution
- ✅ Runs .NET unit tests (xUnit)
- ✅ Runs client linting (ESLint) — in code-quality.yml
- ✅ Runs client type checking (TypeScript)
- ✅ Runs client unit tests (Vitest)
- 📊 Uploads test results as artifacts

### Code Quality (`code-quality.yml`)
Runs on every push and pull request to `main` and `develop` branches.

**What it does:**
- ✅ Runs ESLint for code style checking
- ✅ Runs TypeScript type checking
- ✅ Runs Prettier format checking

## Local Development

To run tests locally before pushing:

```bash
# Backend tests
dotnet test svelte-NET-Test.sln

# Frontend tests
npm ci --prefix MySvelteApp.Client
npm run test:unit --prefix MySvelteApp.Client

# Frontend linting
npm run lint --prefix MySvelteApp.Client

# Frontend type checking
npm run check --prefix MySvelteApp.Client
```

### Skip Client Build

For faster backend-only development and CI runs, you can skip the client build by setting the `SkipClientBuild=true` environment variable:

```bash
# Build .NET without client
dotnet build svelte-NET-Test.sln /p:SkipClientBuild=true

# Run tests without building client
dotnet test svelte-NET-Test.sln /p:SkipClientBuild=true
```

## Test Results

Test results are automatically uploaded as artifacts when tests fail, allowing you to:
- Download and analyze test results
- View detailed test logs
- Debug failing tests

## Branch Protection

Consider setting up branch protection rules that require:
- ✅ All CI checks to pass
- ✅ Code review approval
- ✅ Up-to-date branches

This ensures code quality and prevents breaking changes from being merged.
83 changes: 83 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CI

permissions:
contents: read

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
test:
name: Test
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
cache: true
cache-dependency-path: |
**/*.csproj
**/packages.lock.json

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: |
package-lock.json
MySvelteApp.Client/package-lock.json

- name: Install root dependencies
if: ${{ hashFiles('package-lock.json') != '' }}
run: npm ci

- name: Install client dependencies
run: npm ci --prefix MySvelteApp.Client

- name: Build client
run: npm run build --prefix MySvelteApp.Client

- name: Restore .NET dependencies
run: dotnet restore svelte-NET-Test.sln

- name: Build .NET solution
run: dotnet build svelte-NET-Test.sln --configuration Release --no-restore
# Note: Set SkipClientBuild=true environment variable to skip client build for faster test-only runs

- name: Run .NET tests
run: dotnet test MySvelteApp.Server/Tests/MySvelteApp.Server.Tests.csproj --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=test-results.trx"

- name: Run ast-grep Svelte 5 compliance scan
uses: ast-grep/action@v1.3
with:
version: latest
config: sgconfig.yml

- name: Run client type checking
run: npm run check --prefix MySvelteApp.Client

- name: Run client linting
run: npm run lint --prefix MySvelteApp.Client

- name: Run client unit tests
run: npm run test:unit --prefix MySvelteApp.Client

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: |
**/test-results.trx
44 changes: 44 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Code Quality
permissions:
contents: read

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
working-directory: MySvelteApp.Client

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: MySvelteApp.Client/package-lock.json

- name: Install client dependencies
run: npm ci

- name: Run ESLint
run: npm run lint

- name: Run TypeScript type checking
run: npm run check

- name: Run Prettier format check
run: npx --no-install prettier --check .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ docker-compose.override.yml
### OS junk ###
.DS_Store
Thumbs.db
TestResults/
9 changes: 9 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env sh

export PATH="$HOME/.dotnet/tools:$PATH"

echo "🔍 Running Prettier formatter..."
(cd MySvelteApp.Client && npm run format)

echo "🔍 Formatting C# code with CSharpier..."
csharpier format --no-cache MySvelteApp.Server
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
{
"name": "Start Observability",
"type": "pwa-node",
"type": "node",
"request": "launch",
"runtimeExecutable": "docker",
"runtimeArgs": [
Expand Down
4 changes: 4 additions & 0 deletions MySvelteApp.Client/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ bun.lockb

# Miscellaneous
/static/

# Generated/OpenAPI and UI library (ignored by formatter)
api/
src/lib/components/ui/
Loading