diff --git a/.github/workflows/azure-app-service.yml b/.github/workflows/azure-app-service.yml
deleted file mode 100644
index fe000ec..0000000
--- a/.github/workflows/azure-app-service.yml
+++ /dev/null
@@ -1,146 +0,0 @@
-name: Deploy to Azure App Service
-
-on:
- push:
- branches:
- - main
- workflow_dispatch:
- inputs:
- version_bump:
- description: 'Version bump type (major, minor, patch)'
- required: false
- default: 'patch'
- type: choice
- options:
- - major
- - minor
- - patch
-
-env:
- AZURE_WEBAPP_NAME: 'learnstack-prod-001' # Set this to your Azure Web App name
- AZURE_WEBAPP_PACKAGE_PATH: './LearnStack'
- DOTNET_VERSION: '10.0.x'
-
-permissions:
- contents: write # create tags and GitHub releases
-
-jobs:
- build-and-deploy:
- runs-on: ubuntu-latest
-
- steps:
- - name: ๐ Checkout code
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- with:
- fetch-depth: 0 # Fetch all history for version calculation
-
- - name: ๐ท๏ธ Calculate semantic version
- id: version
- run: |
- # Get the latest tag, or start with v0.0.0 if no tags exist
- LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
- echo "Latest tag: $LATEST_TAG"
-
- # Remove 'v' prefix and split into components
- VERSION=${LATEST_TAG#v}
- IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
-
- # Default to patch bump, or use manual input
- BUMP_TYPE="${{ github.event.inputs.version_bump || 'patch' }}"
-
- # Increment version based on bump type
- case $BUMP_TYPE in
- major)
- MAJOR=$((MAJOR + 1))
- MINOR=0
- PATCH=0
- ;;
- minor)
- MINOR=$((MINOR + 1))
- PATCH=0
- ;;
- patch)
- PATCH=$((PATCH + 1))
- ;;
- esac
-
- NEW_VERSION="v${MAJOR}.${MINOR}.${PATCH}"
- echo "New version: $NEW_VERSION"
- echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
- echo "version_number=${MAJOR}.${MINOR}.${PATCH}" >> $GITHUB_OUTPUT
-
- - name: ๐ง Setup .NET
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
- with:
- dotnet-version: ${{ env.DOTNET_VERSION }}
-
- - name: ๐ ๏ธ Restore .NET tools
- run: dotnet tool restore
-
- - name: ๐ฆ Restore dependencies
- run: dotnet restore ./LearnStack/LearnStack.csproj
-
- - name: ๐จ Build application
- run: dotnet build ./LearnStack/LearnStack.csproj --configuration Release --no-restore
-
- - name: ๐๏ธ Verify database migrations
- run: dotnet ef migrations has-pending-model-changes --project ./LearnStack/LearnStack.csproj --startup-project ./LearnStack/LearnStack.csproj --configuration Release --no-build
-
- - name: ๐งช Run tests (if any)
- run: dotnet test --no-build --verbosity normal
- continue-on-error: true
-
- - name: ๐ค Publish application
- run: dotnet publish ./LearnStack/LearnStack.csproj --configuration Release --no-build --output ./publish
-
- - name: ๐ Deploy to Azure Web App
- id: deploy
- uses: azure/webapps-deploy@02a81bead70021f5284939794bcec79c271ab383 # v3.0.8
- with:
- app-name: ${{ env.AZURE_WEBAPP_NAME }}
- publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
- package: ./publish
-
- - name: ๐ Generate release notes
- id: release_notes
- run: |
- cat << EOF > release_notes.md
- ## ๐ LearnStack ${{ steps.version.outputs.version }}
-
- ### โจ What's New
-
- This release has been automatically deployed to Azure App Service.
-
- **Deployment Details:**
- - **Environment:** Production
- - **Version:** ${{ steps.version.outputs.version }}
- - **Deployed:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
- - **Commit:** ${{ github.sha }}
-
- ### ๐ฆ Deployment
- The application is live at: https://${{ env.AZURE_WEBAPP_NAME }}.azurewebsites.net
-
- ### ๐ Links
- - [View Commit](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})
- - [Compare Changes](${{ github.server_url }}/${{ github.repository }}/compare/$(git describe --tags --abbrev=0 2>/dev/null || echo 'initial')...${{ steps.version.outputs.version }})
- EOF
-
- echo "Release notes generated"
-
- - name: ๐ Create GitHub Release
- uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
- with:
- tag_name: ${{ steps.version.outputs.version }}
- name: Release ${{ steps.version.outputs.version }}
- body_path: release_notes.md
- draft: false
- prerelease: false
- generate_release_notes: true
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: โ
Deployment complete
- run: |
- echo "๐ Deployment to Azure App Service completed successfully!"
- echo "๐ฆ Version ${{ steps.version.outputs.version }} is now live!"
- echo "๐ท๏ธ GitHub release created: ${{ steps.version.outputs.version }}"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 21ee96f..f2e4a2c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,7 +23,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
- dotnet-version: '10.0.x'
+ global-json-file: global.json
- name: Restore .NET tools
run: dotnet tool restore
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..11e08f6
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,38 @@
+# Production releases. Run this workflow on main to cut the next version, or publish a
+# GitHub release. The steps live in kasuken/.github; see its RELEASING.md.
+name: Release
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+ inputs:
+ bump:
+ description: Version part to increment
+ type: choice
+ options: [patch, minor, major]
+ default: patch
+ redeploy:
+ description: Existing tag to redeploy instead (rollback), e.g. v1.4.1
+ type: string
+ default: ''
+
+concurrency:
+ group: production
+ cancel-in-progress: false
+
+permissions:
+ contents: write
+ actions: read
+ id-token: write
+
+jobs:
+ release:
+ uses: kasuken/.github/.github/workflows/release-azure-webapp.yml@main
+ with:
+ app-name: learnstack-prod-001
+ web-project: LearnStack/LearnStack.csproj
+ base-url: https://learnstack.cloud
+ bump: ${{ inputs.bump || 'patch' }}
+ redeploy: ${{ inputs.redeploy || '' }}
+ secrets: inherit
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b0e18d..23245f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,12 +10,14 @@ All notable changes to LearnStack will be documented in this file.
- Released as open source under the GNU AGPL v3.0 (`AGPL-3.0-only`), with a Contributor License Agreement for contributions
- "Source code" link in the account menu, configurable with `SourceCodeUrl` (AGPL section 13)
- Issue forms, CODEOWNERS, Dependabot configuration, `.editorconfig`, `.gitattributes` and third-party notices
+- `/health/live` and `/health/ready` endpoints; every release is smoke tested against `/health/ready`
### Changed
-- Deployment, release, pipeline and quick-reference guides moved from `.github/` to `docs/`
+- Pushing to `main` no longer deploys or creates a `v0.1.x` release. Releases use the shared kasuken release workflow (run **Release** with a version bump), which waits for CI, deploys with Azure OIDC instead of a publish profile, smoke tests, and tags the release with the version from this changelog.
### Removed
- Accidentally tracked local files (Claude worktrees, Rider user settings, build error log)
+- The deployment, release, pipeline and quick-reference guides and `version.json`, which described the old push-to-deploy pipeline
---
diff --git a/LearnStack/LearnStack.csproj b/LearnStack/LearnStack.csproj
index b6aa548..1ed267c 100644
--- a/LearnStack/LearnStack.csproj
+++ b/LearnStack/LearnStack.csproj
@@ -15,6 +15,7 @@
+
diff --git a/LearnStack/Program.cs b/LearnStack/Program.cs
index 2c86dfb..63cba6c 100644
--- a/LearnStack/Program.cs
+++ b/LearnStack/Program.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components.Authorization;
+using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
@@ -34,6 +35,8 @@
throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddLearnStackData(connectionString, migrationsAssembly: "LearnStack");
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+builder.Services.AddHealthChecks()
+ .AddDbContextCheck("database", tags: ["ready"]);
// Persist the Data Protection key ring outside the container so that auth cookies and
// antiforgery tokens survive restarts, deployments, slot swaps and scale-out on App
@@ -102,6 +105,15 @@
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection();
+
+// /health/live tells App Service the process is up; /health/ready also checks the database
+// and gates every release (see .github/workflows/release.yml).
+app.MapHealthChecks("/health/live", new HealthCheckOptions { Predicate = _ => false });
+app.MapHealthChecks("/health/ready", new HealthCheckOptions
+{
+ Predicate = check => check.Tags.Contains("ready")
+});
+
app.UseRequestLocalization();
app.UseRouting();
diff --git a/README.md b/README.md
index 1a15e84..f0d8cff 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Blazor Server application for organizing learning resources, turning them into content ideas, and sharing curated knowledge with other learners.
-[](https://github.com/kasuken/LearnStack/actions/workflows/azure-app-service.yml)
+[](https://github.com/kasuken/LearnStack/actions/workflows/ci.yml)



@@ -130,25 +130,16 @@ $env:ConnectionStrings__DefaultConnection="Server=tcp:your-server.database.windo
## Deployment
-LearnStack includes a GitHub Actions workflow that deploys the app to Azure App Service whenever changes are pushed to `main`.
+The hosted service runs on Azure App Service. Merging to `main` only runs CI; production changes when a release is cut with the [Release workflow](.github/workflows/release.yml):
-The workflow:
-
-- builds and publishes the Blazor application,
-- deploys it to Azure App Service,
-- calculates the next semantic version,
-- creates a Git tag,
-- publishes a GitHub release.
-
-Useful docs:
+```bash
+gh workflow run release.yml -R kasuken/LearnStack -f bump=minor # patch | minor | major
+gh workflow run release.yml -R kasuken/LearnStack -f redeploy=v1.4.1 # roll back
+```
-- [Azure deployment guide](./docs/DEPLOYMENT.md)
-- [Release and versioning guide](./docs/RELEASES.md)
-- [CI/CD pipeline overview](./docs/PIPELINE.md)
-- [Quick reference](./docs/QUICK-REFERENCE.md)
+The workflow waits for CI to pass on the commit, builds once, deploys through the `production` environment with Azure OIDC, smoke tests `/health/ready`, and then tags and publishes the GitHub release. The steps are shared with the other kasuken SaaS apps; see [RELEASING.md](https://github.com/kasuken/.github/blob/main/RELEASING.md).
-> [!TIP]
-> The workflow is configured for the `learnstack-prod-001` Azure Web App name by default. If you fork the repository, update `.github/workflows/azure-app-service.yml` and the `AZURE_WEBAPP_PUBLISH_PROFILE` secret for your own environment.
+Hosted-only settings (for example `Billing__Provider=Stripe`) and all secrets are App Service application settings, never committed files.
## Project structure
diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md
deleted file mode 100644
index fc00240..0000000
--- a/docs/DEPLOYMENT.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# ๐ Azure App Service Deployment Guide
-
-This guide will help you deploy LearnStack to Azure App Service using GitHub Actions with automated versioning and releases.
-
-## ๐ Documentation
-
-- **[Release & Versioning Guide](RELEASES.md)** - Semantic versioning and release management
-- **[CI/CD Pipeline Overview](PIPELINE.md)** - Visual workflow diagrams and architecture
-- **[Changelog](../CHANGELOG.md)** - Project history and version notes
-
-## Prerequisites
-
-- Azure subscription
-- Azure App Service created
-- GitHub repository with admin access
-
-## Setup Steps
-
-### 1๏ธโฃ Create Azure App Service
-
-1. Go to [Azure Portal](https://portal.azure.com)
-2. Create a new **App Service**:
- - **Runtime Stack**: .NET 10
- - **Operating System**: Linux (recommended) or Windows
- - **Region**: Choose your preferred region
- - **Pricing Tier**: B1 or higher recommended
-
-### 2๏ธโฃ Configure Database Connection
-
-In your Azure App Service:
-
-1. Go to **Configuration** โ **Connection strings**
-2. Add a new connection string:
- - **Name**: `DefaultConnection`
- - **Value**: Your SQL Database connection string
- - **Type**: SQLServer
-
-Example:
-```
-Server=tcp:your-server.database.windows.net,1433;Initial Catalog=LearnStackDb;Persist Security Info=False;User ID=your-username;Password=your-password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
-```
-
-### 3๏ธโฃ Get Publish Profile
-
-1. In your App Service, click **Get publish profile** (top menu)
-2. Save the downloaded `.PublishSettings` file
-3. Copy the entire contents of this file
-
-### 4๏ธโฃ Configure GitHub Secrets
-
-1. Go to your GitHub repository
-2. Navigate to **Settings** โ **Secrets and variables** โ **Actions**
-3. Click **New repository secret**
-4. Add the following secret:
- - **Name**: `AZURE_WEBAPP_PUBLISH_PROFILE`
- - **Value**: Paste the entire contents of the publish profile file
-
-### 5๏ธโฃ Update Workflow Configuration
-
-Edit `.github/workflows/azure-app-service.yml`:
-
-1. Replace `your-app-name` with your actual Azure App Service name:
- ```yaml
- AZURE_WEBAPP_NAME: 'your-actual-app-name'
- ```
-
-### 6๏ธโฃ Deploy!
-
-1. Commit and push your changes to the `main` branch
-2. GitHub Actions will automatically:
- - Build your application
- - Run tests
- - Publish the app
- - Deploy to Azure App Service
-
-Monitor the deployment in the **Actions** tab of your GitHub repository.
-
-## ๐ท๏ธ Semantic Versioning
-
-### Automatic Version Bumping
-
-Every successful deployment automatically creates a GitHub release with semantic versioning (MAJOR.MINOR.PATCH):
-
-- **Patch** (default): Bug fixes and minor updates โ `v1.0.0` โ `v1.0.1`
-- **Minor**: New features (backward compatible) โ `v1.0.1` โ `v1.1.0`
-- **Major**: Breaking changes โ `v1.1.0` โ `v2.0.0`
-
-### How It Works
-
-1. **Automatic**: Push to `main` โ auto-increments **patch** version
-2. **Manual**: Choose version bump type when triggering manually
-
-### Version History
-
-View all releases in the **Releases** section of your GitHub repository.
-
-Each release includes:
-- ๐ฆ Version number
-- ๐ Deployment date and time
-- ๐ Commit SHA and comparison link
-- ๐ Live deployment URL
-
-## Manual Deployment
-
-You can also trigger deployment manually with custom version bumping:
-
-1. Go to **Actions** tab in GitHub
-2. Select **Deploy to Azure App Service** workflow
-3. Click **Run workflow**
-4. Select the branch
-5. **Choose version bump type**: `major`, `minor`, or `patch`
-6. Click **Run workflow**
-
-## Troubleshooting
-
-### Database Migrations
-
-After first deployment, you may need to run migrations:
-
-1. Go to Azure Portal โ Your App Service
-2. Open **SSH** or **Console**
-3. Run:
- ```bash
- dotnet ef database update --project /home/site/wwwroot/LearnStack.dll
- ```
-
-Alternatively, enable automatic migrations in `Program.cs`.
-
-### Connection String Issues
-
-Ensure your Azure SQL Database:
-- Allows Azure Services to connect
-- Has correct firewall rules
-- Connection string is properly configured in App Service
-
-### Deployment Fails
-
-Check:
-- Publish profile is correctly added to GitHub secrets
-- App Service name matches in the workflow file
-- Sufficient App Service plan tier (B1 or higher)
-
-## Environment Variables
-
-Add these in Azure App Service **Configuration** โ **Application settings**:
-
-| Key | Value | Description |
-|-----|-------|-------------|
-| `ASPNETCORE_ENVIRONMENT` | `Production` | Sets production environment |
-| `WEBSITE_TIME_ZONE` | `UTC` (or your timezone) | Sets application timezone |
-
-## Stripe Billing
-
-Billing is off by default (`Billing__Provider` = `None`), so the app runs without Stripe. To take payments for the Pro plan:
-
-### In the Stripe Dashboard
-
-1. **Product catalog**: create a *Pro* product with two recurring prices, one monthly and one yearly. Copy both price ids (`price_...`).
-2. **Developers โ Webhooks**: add an endpoint at `https:///api/webhooks/billing` that listens for:
- - `checkout.session.completed`
- - `customer.subscription.created`
- - `customer.subscription.updated`
- - `customer.subscription.deleted`
- - `invoice.paid`
- - `invoice.payment_failed`
-
- Copy the endpoint's signing secret (`whsec_...`).
-3. **Settings โ Billing โ Customer portal**: allow customers to update payment methods and cancel subscriptions, and add both Pro prices under *Subscriptions โ Customers can switch plans* so users can move between monthly and yearly.
-4. **Settings โ Billing โ Subscriptions and emails**: choose what happens after all payment retries fail. *Cancel the subscription* or *Mark as unpaid* both downgrade the user to Starter. With *Leave as-is*, the user loses Pro access 7 days after the last failed retry.
-
-### In Azure App Service โ Configuration โ Application settings
-
-Store the secrets as Key Vault references where possible.
-
-| Key | Value |
-|-----|-------|
-| `Billing__Provider` | `Stripe` |
-| `Billing__ApiKey` | Secret key (`sk_live_...`, or `sk_test_...` for a staging slot) |
-| `Billing__WebhookSigningSecret` | Webhook signing secret (`whsec_...`) |
-| `Billing__ProMonthlyPriceId` | Monthly Pro price id |
-| `Billing__ProYearlyPriceId` | Yearly Pro price id |
-| `Billing__CheckoutSuccessUrl` | `https:///Account/Manage/Plan` |
-| `Billing__CheckoutCancelUrl` | `https:///Account/Manage/Plan` |
-| `Billing__PortalReturnUrl` | `https:///Account/Manage/Plan` |
-
-The app adds `session_id={CHECKOUT_SESSION_ID}` to the success URL and `checkout=cancelled` to the cancel URL itself, so the Plan page can confirm an upgrade the moment the user returns. If any Stripe setting is missing, startup fails with an error that lists every missing key.
-
-### Testing locally
-
-```bash
-stripe listen --forward-to http://localhost:5164/api/webhooks/billing
-```
-
-Use the `whsec_...` secret that `stripe listen` prints as `Billing:WebhookSigningSecret` in user secrets, then pay with the test card `4242 4242 4242 4242`.
-
-## SSL/HTTPS
-
-Azure App Service provides free SSL certificates:
-
-1. Go to **Custom domains**
-2. Add your domain
-3. Enable **HTTPS Only** in **TLS/SSL settings**
-
-## Monitoring
-
-Enable Application Insights for monitoring:
-
-1. Go to **Application Insights** in App Service
-2. Turn on Application Insights
-3. View logs, performance, and errors
-
-## Cost Optimization
-
-- Use **B1 Basic** tier for development/testing
-- Scale to **S1 Standard** or higher for production
-- Enable **Always On** for production apps
-- Consider **App Service Plan** sharing across multiple apps
-
----
-
-## ๐ Success!
-
-Your LearnStack application should now be live at:
-`https://your-app-name.azurewebsites.net`
-
-Need help? [Open an issue](https://github.com/kasuken/LearnStack/issues)
diff --git a/docs/PIPELINE.md b/docs/PIPELINE.md
deleted file mode 100644
index edb0bcb..0000000
--- a/docs/PIPELINE.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# ๐ CI/CD Pipeline Overview
-
-## Deployment & Release Flow
-
-```mermaid
-graph TB
- A[๐ Push to main branch] --> B{GitHub Actions Triggered}
- B --> C[๐ฅ Checkout Code]
- C --> D[๐ท๏ธ Calculate Next Version]
- D --> E[๐ฆ Get Latest Tag]
- E --> F{First Release?}
- F -->|Yes| G[Start at v1.0.0]
- F -->|No| H[Increment Version]
- H --> I{Bump Type}
- I -->|Patch| J[v1.0.0 โ v1.0.1]
- I -->|Minor| K[v1.0.0 โ v1.1.0]
- I -->|Major| L[v1.0.0 โ v2.0.0]
- G --> M[๐ง Setup .NET 10]
- J --> M
- K --> M
- L --> M
- M --> N[๐ฆ Restore Dependencies]
- N --> O[๐จ Build Application]
- O --> P[๐งช Run Tests]
- P --> Q[๐ค Publish App]
- Q --> R[โ๏ธ Deploy to Azure]
- R --> S{Deployment Success?}
- S -->|No| T[โ Workflow Failed]
- S -->|Yes| U[๐ Generate Release Notes]
- U --> V[๐ท๏ธ Create Git Tag]
- V --> W[๐ฆ Create GitHub Release]
- W --> X[โ
Success!]
- X --> Y[๐ Live on Azure]
- X --> Z[๐ Release Published]
-
- style A fill:#4CAF50
- style X fill:#4CAF50
- style T fill:#f44336
- style R fill:#2196F3
- style W fill:#FF9800
-```
-
-## Workflow Stages
-
-### 1. ๐ฏ Trigger
-- **Automatic**: Push to `main` branch
-- **Manual**: Workflow dispatch with version bump selection
-
-### 2. ๐ท๏ธ Versioning
-```
-Latest Tag: v1.2.3
-Bump Type: patch
-New Version: v1.2.4
-```
-
-### 3. ๐จ Build
-```bash
-dotnet restore โ dotnet build โ dotnet test โ dotnet publish
-```
-
-### 4. ๐ Deploy
-```
-Artifact โ Azure App Service โ Production Environment
-```
-
-### 5. ๐ฆ Release
-```
-Create Tag โ Generate Notes โ Publish Release โ Notify
-```
-
-## Version Decision Tree
-
-```mermaid
-graph LR
- A[Code Change] --> B{Change Type?}
- B -->|Bug Fix| C[Patch v1.0.X]
- B -->|New Feature| D[Minor v1.X.0]
- B -->|Breaking Change| E[Major vX.0.0]
-
- C --> F[Auto: Push to main]
- D --> G[Manual: Select 'minor']
- E --> H[Manual: Select 'major']
-
- F --> I[v1.0.1]
- G --> J[v1.1.0]
- H --> K[v2.0.0]
-
- style C fill:#90EE90
- style D fill:#87CEEB
- style E fill:#FFB6C1
-```
-
-## Timeline Example
-
-```
-Day 1: v1.0.0 - Initial Release
- โโ feat: Initial app with auth & resources
-
-Day 2: v1.0.1 - Patch
- โโ fix: Login redirect issue
-
-Day 5: v1.0.2 - Patch
- โโ fix: UI alignment bugs
-
-Week 2: v1.1.0 - Minor
- โโ feat: Add export functionality
- โโ feat: Dark mode support
-
-Week 3: v1.1.1 - Patch
- โโ fix: Export CSV formatting
-
-Month 2: v2.0.0 - Major
- โโ BREAKING: New API structure
- โโ feat: Mobile responsive redesign
- โโ feat: Real-time collaboration
-```
-
-## Release Timeline
-
-```mermaid
-gantt
- title LearnStack Release Cycle
- dateFormat YYYY-MM-DD
- section Major Releases
- v1.0.0 Initial Release :milestone, m1, 2026-02-21, 0d
- v2.0.0 Breaking Changes :milestone, m2, 2026-05-21, 0d
-
- section Minor Releases
- v1.1.0 New Features :milestone, m3, 2026-03-07, 0d
- v1.2.0 More Features :milestone, m4, 2026-03-21, 0d
-
- section Patches
- Bug Fixes & Updates :active, 2026-02-21, 90d
-```
-
-## Environment Flow
-
-```mermaid
-graph LR
- A[๐จโ๐ป Developer] -->|Push Code| B[GitHub]
- B -->|Trigger| C[GitHub Actions]
- C -->|Build & Test| D[Build Artifacts]
- D -->|Deploy| E[โ๏ธ Azure App Service]
- E -->|Live| F[๐ Production]
- C -->|Create| G[๐ฆ GitHub Release]
- G -->|Notify| H[๐ง Subscribers]
-
- style A fill:#4CAF50
- style E fill:#2196F3
- style F fill:#FF9800
- style G fill:#9C27B0
-```
-
-## Permissions & Secrets
-
-```mermaid
-graph TB
- A[GitHub Repository] --> B[Settings]
- B --> C[Secrets]
- C --> D[AZURE_WEBAPP_PUBLISH_PROFILE]
- C --> E[GITHUB_TOKEN]
-
- B --> F[Actions]
- F --> G[Permissions]
- G --> H[contents: write]
- G --> I[packages: write]
-
- D --> J[Azure Deployment]
- E --> K[Release Creation]
- H --> K
-
- style D fill:#2196F3
- style E fill:#4CAF50
- style H fill:#FF9800
-```
-
-## Success Metrics
-
-After each deployment, you get:
-
-| Metric | Description |
-|--------|-------------|
-| โ
Build Status | Pass/Fail status of the build |
-| โฑ๏ธ Build Time | Total time from trigger to completion |
-| ๐ฆ Artifact Size | Size of the published application |
-| ๐ท๏ธ Version Tag | New semantic version created |
-| ๐ Deployment URL | Live application endpoint |
-| ๐ Release Notes | Auto-generated changelog |
-
-## Monitoring
-
-Track your deployments:
-
-1. **GitHub Actions**: [Actions Tab](https://github.com/kasuken/LearnStack/actions)
-2. **Releases**: [Releases Page](https://github.com/kasuken/LearnStack/releases)
-3. **Azure Portal**: App Service โ Deployment Center
-4. **Application Insights**: Azure โ App Service โ Application Insights
-
----
-
-## Quick Reference
-
-### Manual Deployment Commands
-
-```bash
-# Trigger from Actions tab, or:
-gh workflow run azure-app-service.yml -f version_bump=patch
-gh workflow run azure-app-service.yml -f version_bump=minor
-gh workflow run azure-app-service.yml -f version_bump=major
-```
-
-### Check Latest Version
-
-```bash
-git describe --tags --abbrev=0
-```
-
-### View All Releases
-
-```bash
-gh release list
-```
-
----
-
-*Powered by GitHub Actions ยท Deployed to Azure App Service*
diff --git a/docs/QUICK-REFERENCE.md b/docs/QUICK-REFERENCE.md
deleted file mode 100644
index a12116e..0000000
--- a/docs/QUICK-REFERENCE.md
+++ /dev/null
@@ -1,282 +0,0 @@
-# ๐ Quick Reference Card
-
-## Common Commands
-
-### Git & Deployment
-
-```bash
-# Deploy with automatic patch version bump
-git add .
-git commit -m "fix: resolve login issue"
-git push origin main
-
-# Deploy with new feature (suggest minor bump)
-git commit -m "feat: add export functionality"
-git push origin main
-
-# Breaking change (suggest major bump - use manual workflow)
-git commit -m "feat!: redesign authentication system
-
-BREAKING CHANGE: New auth requires users to re-login"
-```
-
-### Version Management
-
-```bash
-# Check current version
-git describe --tags --abbrev=0
-
-# List all versions
-git tag -l
-
-# View specific release
-gh release view v1.0.0
-
-# List all releases
-gh release list
-
-# Create manual tag (if needed)
-git tag v1.0.0
-git push origin v1.0.0
-```
-
-### GitHub CLI Workflow
-
-```bash
-# Trigger deployment with patch bump
-gh workflow run azure-app-service.yml -f version_bump=patch
-
-# Trigger deployment with minor bump
-gh workflow run azure-app-service.yml -f version_bump=minor
-
-# Trigger deployment with major bump
-gh workflow run azure-app-service.yml -f version_bump=major
-
-# View workflow runs
-gh run list
-
-# Watch current run
-gh run watch
-```
-
-## Semantic Versioning Quick Guide
-
-| Type | Format | When to Use | Example |
-|------|--------|-------------|---------|
-| ๐ข **Patch** | `v1.0.X` | Bug fixes, small improvements | v1.0.0 โ v1.0.1 |
-| ๐ต **Minor** | `v1.X.0` | New features (backward compatible) | v1.0.1 โ v1.1.0 |
-| ๐ด **Major** | `vX.0.0` | Breaking changes | v1.1.0 โ v2.0.0 |
-
-## Commit Message Conventions
-
-```bash
-# Feature
-git commit -m "feat: add dark mode"
-git commit -m "feat(auth): implement OAuth"
-
-# Bug fix
-git commit -m "fix: resolve login redirect"
-git commit -m "fix(ui): correct button alignment"
-
-# Performance
-git commit -m "perf: optimize database queries"
-
-# Breaking change
-git commit -m "feat!: change API structure
-
-BREAKING CHANGE: Endpoints now use /api/v2/"
-
-# Other types
-docs: # Documentation only changes
-style: # Code style (formatting, missing semi colons, etc)
-refactor: # Code change that neither fixes a bug nor adds a feature
-test: # Adding missing tests
-chore: # Changes to build process or auxiliary tools
-```
-
-## Deployment Checklist
-
-### First-Time Setup
-- [ ] Create Azure App Service (.NET 10)
-- [ ] Create Azure SQL Database
-- [ ] Download publish profile
-- [ ] Add `AZURE_WEBAPP_PUBLISH_PROFILE` to GitHub Secrets
-- [ ] Update `AZURE_WEBAPP_NAME` in workflow file
-- [ ] Configure connection string in Azure
-- [ ] Push to main branch
-- [ ] Verify deployment in GitHub Actions
-- [ ] Check app is live on Azure
-
-### Regular Deployment
-- [ ] Write code and tests
-- [ ] Commit with conventional message
-- [ ] Push to main branch
-- [ ] Monitor GitHub Actions
-- [ ] Verify release created
-- [ ] Test live application
-
-## Troubleshooting
-
-### Issue: Deployment fails
-```bash
-# Check workflow logs
-gh run list --workflow=azure-app-service.yml
-gh run view [RUN_ID]
-
-# Check Azure logs
-az webapp log tail --name your-app-name --resource-group your-rg
-```
-
-### Issue: Version not incrementing
-```bash
-# Check current tags
-git tag -l
-
-# Create initial tag if none exist
-git tag v1.0.0
-git push origin v1.0.0
-
-# Verify tag on remote
-git ls-remote --tags origin
-```
-
-### Issue: Release not created
-```bash
-# Check workflow permissions
-# Go to: Settings โ Actions โ General โ Workflow permissions
-# Ensure "Read and write permissions" is enabled
-
-# Or check workflow file has:
-# permissions:
-# contents: write
-```
-
-### Issue: Database connection fails
-```powershell
-# Test connection string locally
-dotnet ef database update
-
-# Check Azure firewall rules
-az sql server firewall-rule list --resource-group your-rg --server your-server
-
-# Allow Azure services
-az sql server firewall-rule create \
- --resource-group your-rg \
- --server your-server \
- --name AllowAzureServices \
- --start-ip-address 0.0.0.0 \
- --end-ip-address 0.0.0.0
-```
-
-## Environment Variables
-
-### Local Development (.env or appsettings.Development.json)
-```json
-{
- "ConnectionStrings": {
- "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=LearnStackDb;..."
- }
-}
-```
-
-### Azure App Service (Configuration โ Application Settings)
-```
-ASPNETCORE_ENVIRONMENT = Production
-WEBSITE_TIME_ZONE = UTC
-```
-
-### Azure App Service (Configuration โ Connection Strings)
-```
-DefaultConnection = Server=tcp:your-server.database.windows.net,1433;...
-Type = SQLServer
-```
-
-## Useful Links
-
-| Resource | URL |
-|----------|-----|
-| ๐ **Repository** | https://github.com/kasuken/LearnStack |
-| ๐ฆ **Releases** | https://github.com/kasuken/LearnStack/releases |
-| ๐ง **Actions** | https://github.com/kasuken/LearnStack/actions |
-| ๐ **Issues** | https://github.com/kasuken/LearnStack/issues |
-| ๐ **Deployment Guide** | [DEPLOYMENT.md](DEPLOYMENT.md) |
-| ๐ท๏ธ **Release Guide** | [RELEASES.md](RELEASES.md) |
-| ๐ **Pipeline Docs** | [PIPELINE.md](PIPELINE.md) |
-| ๐ **Changelog** | [CHANGELOG.md](../CHANGELOG.md) |
-
-## Azure Portal Quick Links
-
-```bash
-# Open Azure Portal
-open https://portal.azure.com
-
-# Open your App Service
-open https://portal.azure.com/#resource/subscriptions/{subscription-id}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app-name}
-
-# View deployment logs
-open https://{app-name}.scm.azurewebsites.net/api/deployments
-```
-
-## Status Checks
-
-### GitHub Actions Status Badge
-```markdown
-
-```
-
-### Check Live App
-```bash
-curl https://learnstack-prod-001.azurewebsites.net/health
-```
-
-### Check Latest Release
-```bash
-curl -s https://api.github.com/repos/kasuken/LearnStack/releases/latest | jq .tag_name
-```
-
-## Performance Tips
-
-### Local Development
-```bash
-# Use watch mode for hot reload
-dotnet watch run --project LearnStack/LearnStack.csproj
-
-# Build in Release mode
-dotnet build -c Release
-```
-
-### Azure Optimization
-- Enable **Always On** for production
-- Use **Standard** or **Premium** tier for better performance
-- Enable **Application Insights** for monitoring
-- Configure **Autoscaling** based on metrics
-
-## Maintenance Schedule
-
-### Daily
-- โ
Monitor GitHub Actions for failed runs
-- โ
Check Application Insights for errors
-
-### Weekly
-- ๐ Review open issues and PRs
-- ๐ Check application performance metrics
-- ๐ Review security alerts
-
-### Monthly
-- ๐ฆ Update NuGet packages
-- ๐ Review and update dependencies
-- ๐ Update documentation
-- ๐งน Clean up old releases (keep last 10-20)
-
----
-
-## Need Help?
-
-- ๐ Read the [full documentation](./)
-- ๐ [Open an issue](https://github.com/kasuken/LearnStack/issues/new)
-- ๐ฌ [Start a discussion](https://github.com/kasuken/LearnStack/discussions)
-- ๐ง Contact: @kasuken
-
----
-
-*Last Updated: February 21, 2026*
diff --git a/docs/RELEASES.md b/docs/RELEASES.md
deleted file mode 100644
index 19dd5d5..0000000
--- a/docs/RELEASES.md
+++ /dev/null
@@ -1,200 +0,0 @@
-# ๐ท๏ธ Release & Versioning Guide
-
-## Overview
-
-LearnStack uses **Semantic Versioning** (SemVer) for all releases. Every successful deployment to Azure App Service automatically creates a GitHub release with an incremented version.
-
-## Semantic Versioning Format
-
-```
-v{MAJOR}.{MINOR}.{PATCH}
-```
-
-### When to bump each number:
-
-- **MAJOR** (`v2.0.0`): Breaking changes, major rewrites, incompatible API changes
-- **MINOR** (`v1.1.0`): New features, enhancements (backward compatible)
-- **PATCH** (`v1.0.1`): Bug fixes, small improvements, security patches
-
-## Automatic Release Process
-
-### ๐ Automatic Workflow (Default)
-
-When you push to `main` branch:
-
-```bash
-git add .
-git commit -m "feat: add new feature"
-git push origin main
-```
-
-The workflow automatically:
-1. โ
Calculates next **patch** version (e.g., `v1.0.0` โ `v1.0.1`)
-2. ๐จ Builds the application
-3. ๐งช Runs tests
-4. ๐ Deploys to Azure App Service
-5. ๐ท๏ธ Creates a Git tag
-6. ๐ฆ Creates a GitHub release with auto-generated notes
-
-### ๐ฏ Manual Workflow (Custom Version Bump)
-
-For more control over versioning:
-
-1. Go to **Actions** โ **Deploy to Azure App Service**
-2. Click **Run workflow** button
-3. Select **branch**: `main`
-4. Choose **version bump type**:
- - `patch` - Bug fixes (v1.0.0 โ v1.0.1)
- - `minor` - New features (v1.0.0 โ v1.1.0)
- - `major` - Breaking changes (v1.0.0 โ v2.0.0)
-5. Click **Run workflow**
-
-## Release Notes
-
-Each release automatically includes:
-
-- ๐ **Version number** and release name
-- ๐
**Deployment timestamp** (UTC)
-- ๐ **Commit SHA** with link
-- ๐ **Comparison link** (changes since last release)
-- ๐ **Live URL** of the deployed application
-- ๐ **Auto-generated changelog** from commit messages
-
-## Example Releases
-
-### Patch Release (v1.0.1)
-```
-โ
Fix login bug
-โ
Update dependencies
-โ
Improve error messages
-```
-
-### Minor Release (v1.1.0)
-```
-โจ Add export functionality
-โจ Add dark mode support
-โก Improve performance
-๐ Fix minor bugs
-```
-
-### Major Release (v2.0.0)
-```
-๐ฅ BREAKING: New authentication system
-๐ฅ BREAKING: Changed API endpoints
-โจ Complete UI redesign
-โจ Add mobile support
-```
-
-## Commit Message Convention
-
-For better auto-generated release notes, use conventional commits:
-
-```bash
-# Features
-git commit -m "feat: add user profile page"
-git commit -m "feat(auth): implement OAuth login"
-
-# Bug Fixes
-git commit -m "fix: resolve login redirect issue"
-git commit -m "fix(ui): correct button alignment"
-
-# Performance
-git commit -m "perf: optimize database queries"
-
-# Documentation
-git commit -m "docs: update API documentation"
-
-# Chores
-git commit -m "chore: update dependencies"
-```
-
-### Commit Types:
-- `feat:` New feature โ suggests **minor** bump
-- `fix:` Bug fix โ suggests **patch** bump
-- `perf:` Performance improvement โ **patch** bump
-- `docs:` Documentation โ **patch** bump
-- `style:` Code style changes โ **patch** bump
-- `refactor:` Code refactoring โ **patch** bump
-- `test:` Adding tests โ **patch** bump
-- `chore:` Maintenance โ **patch** bump
-- `BREAKING CHANGE:` Breaking change โ requires **major** bump
-
-## Version History
-
-View all releases at:
-```
-https://github.com/kasuken/LearnStack/releases
-```
-
-## Troubleshooting
-
-### Release Creation Failed
-
-**Problem**: GitHub release creation fails
-
-**Solution**:
-- Ensure the workflow has `contents: write` permission (already configured)
-- Check that `GITHUB_TOKEN` has proper permissions
-- Verify no duplicate tags exist
-
-### Version Not Incrementing
-
-**Problem**: Version stays the same
-
-**Solution**:
-- Ensure `fetch-depth: 0` is set in checkout (already configured)
-- Check that tags are being pushed to the repository
-- Manually create the first tag if none exist:
- ```bash
- git tag v1.0.0
- git push origin v1.0.0
- ```
-
-### Creating First Release
-
-If this is your first deployment and no tags exist:
-
-```bash
-# Create initial tag
-git tag v1.0.0
-git push origin v1.0.0
-
-# Next deployment will auto-increment to v1.0.1
-```
-
-## Best Practices
-
-### 1. **Consistent Commit Messages**
-Use conventional commits for better auto-generated changelogs
-
-### 2. **Test Before Merge**
-Always test in a development environment before merging to `main`
-
-### 3. **Plan Major Releases**
-For breaking changes, use manual workflow with `major` bump
-
-### 4. **Document Changes**
-Update `version.json` with notable changes for reference
-
-### 5. **Release Cadence**
-- **Patches**: As needed (bug fixes)
-- **Minor**: Weekly or bi-weekly (new features)
-- **Major**: Quarterly or when necessary (breaking changes)
-
-## Advanced: Pre-releases
-
-To create pre-release versions (beta, alpha):
-
-1. Create a separate branch (e.g., `develop`)
-2. Modify workflow to detect branch and add suffix
-3. Example: `v1.1.0-beta.1`, `v2.0.0-alpha.3`
-
-## Questions?
-
-For questions or issues with versioning and releases:
-- Open an issue: [Create Issue](https://github.com/kasuken/LearnStack/issues/new)
-- Check existing releases: [View Releases](https://github.com/kasuken/LearnStack/releases)
-
----
-
-*Automated with โค๏ธ using GitHub Actions*
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..5269c28
--- /dev/null
+++ b/global.json
@@ -0,0 +1,7 @@
+{
+ "sdk": {
+ "version": "10.0.400",
+ "rollForward": "latestFeature",
+ "allowPrerelease": false
+ }
+}
diff --git a/version.json b/version.json
deleted file mode 100644
index 056f7a6..0000000
--- a/version.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "$schema": "https://json-schema.org/draft-07/schema",
- "version": "1.0.0",
- "description": "LearnStack version tracking",
- "releaseDate": "2026-02-21",
- "changelog": {
- "1.0.0": {
- "date": "2026-02-21",
- "changes": [
- "Initial release",
- "Learning resource management",
- "Content ideas planning",
- "Azure App Service deployment support",
- "Automated GitHub releases with semantic versioning"
- ]
- }
- }
-}