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
9 changes: 8 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@
############################################
# GitHub OAuth / API Authentication (REQUIRED for Azure deployment)
############################################
# Development OAuth App (for local development on localhost:3000)
GITHUB_CLIENT_ID= # OAuth app client ID (create at github.com/settings/developers)
GITHUB_CLIENT_SECRET= # OAuth app client secret
GITHUB_CLIENT_SECRET= # OAuth app client secret

# Production OAuth App (for Azure deployment - falls back to dev credentials if not set)
GITHUB_CLIENT_ID_PROD= # Production OAuth app client ID (optional - uses GITHUB_CLIENT_ID if not set)
GITHUB_CLIENT_SECRET_PROD= # Production OAuth app client secret (optional - uses GITHUB_CLIENT_SECRET if not set)

# GitHub API Tokens
GITHUB_TOKEN= # Personal Access Token (scopes: repo, workflow, read:org)
GH_WORKFLOW_TOKEN= # Workflow dispatch token (can be same as GITHUB_TOKEN)

Expand Down
45 changes: 42 additions & 3 deletions DEPLOYMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,19 @@

4. **Deploy to Azure**
```bash
cd infra
azd up
azd provision
```
- Enter environment name (e.g., "prod")
- Select your Azure subscription
- Choose Azure region (e.g., "eastus")
- Wait 5-10 minutes for deployment
- Wait 5-10 minutes for infrastructure provisioning

Then deploy the application:
```bash
./scripts/deploy.sh
```
- This builds and deploys the container image
- Wait 2-5 minutes for deployment

5. **Done!**
- Azure automatically provisions everything:
Expand All @@ -90,6 +96,25 @@
- Note the URL displayed at the end of deployment
- Navigate to your Template Doctor instance

### Quick Redeploy (Already Configured)

If you already have `.env` configured and just need to redeploy:

```bash
./scripts/full-setup.sh --deploy
```

This command:
- ✅ Skips all configuration prompts
- ✅ Validates existing `.env` file
- ✅ Checks for version updates
- ✅ Installs dependencies and builds packages
- ✅ Runs `azd provision` (infrastructure)
- ✅ Runs `./scripts/deploy.sh` (container build + deploy)
- ✅ Displays your application URL

**When to use**: After initial setup, for quick updates or redeployments.

---

## 📋 What You Need to Prepare
Expand Down Expand Up @@ -162,6 +187,20 @@
**Problem**: "GitHub OAuth not working"
- ✅ Solution: Verify callback URL in GitHub OAuth app matches your deployed URL exactly

**Problem**: "Container App provisioning timeout"
- ✅ Solution: The setup script uses two-step deployment (`azd provision` then `deploy.sh`) to avoid timeout issues

**Problem**: "Deployment stuck or blocking retries"
- ✅ Solution: Cancel stuck deployment:
```bash
az deployment group cancel --resource-group <rg-name> --name container-app
```
Or recreate everything:
```bash
azd down --force --purge
./scripts/full-setup.sh --deploy
```

---

## 💰 Cost Estimate (Azure Production)
Expand Down
25 changes: 25 additions & 0 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ Click "Sign in with GitHub" and you're ready! 🎉

---

## 🔄 Quick Redeploy (Already Configured)

If you already have `.env` configured and just need to redeploy to Azure:

```bash
./scripts/full-setup.sh --deploy
```

This command:
- ✅ Skips all configuration prompts
- ✅ Validates existing `.env` file
- ✅ Checks for Template Doctor updates
- ✅ Installs dependencies and builds packages
- ✅ Deploys to Azure (runs `azd provision` + `deploy.sh`)

**When to use**: After initial setup, for quick updates or redeployments to Azure.

**Input flexibility**: All setup prompts support multiple input methods:
- **Press Enter**: Uses the default (shown in capital letter, e.g., `[Y/n]`)
- **Type 1**: Yes/Option 1
- **Type 2**: No/Option 2
- **Type y/n**: Traditional yes/no input

---

## ⚠️ Common Mistakes (DON'T DO THIS!)

### ❌ WRONG: Setting MONGODB_URI in .env
Expand Down
44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,38 @@ The wizard will ask: **"Are you setting up for local development or Azure deploy

### Azure Production Path (10 minutes)
- ✅ Check prerequisites (Node.js, Azure CLI, azd)
- ✅ Guide you through GitHub OAuth App creation
- ✅ Guide you through GitHub OAuth App creation (if not configured)
- ✅ Create GitHub Personal Access Token
- ✅ Configure Cosmos DB (automatic azd setup)
- ✅ Set up admin users and workflow repository
- ✅ Install npm dependencies
- ✅ Build all packages
- ✅ **Run `azd up` to provision and deploy**
- ✅ **Run `azd provision` and `deploy.sh` to deploy**
- ✅ **Open your Azure app URL**

### Quick Redeploy Mode

If you already have `.env` configured and just need to redeploy:

```bash
./scripts/full-setup.sh --deploy
```

This skips all configuration prompts and goes straight to deployment:
- ✅ Validates existing `.env` configuration
- ✅ Checks for version updates
- ✅ Installs dependencies and builds packages
- ✅ Deploys to Azure (runs `azd provision` + `deploy.sh`)

> [!TIP]
> The wizard is interactive, validates configuration at each step, and provides helpful troubleshooting tips. **This is the easiest way to get Template Doctor running!**

**Input Options**: All prompts support multiple input methods:
- **Press Enter**: Uses the default (shown in capital letter)
- **Type 1**: Yes/Option 1
- **Type 2**: No/Option 2
- **Type y/n**: Traditional yes/no input

---

## Manual Setup
Expand Down Expand Up @@ -539,6 +559,26 @@ Access at http://localhost:3000

- **Configuration mismatch**: Verify `config.json` has correct `githubOAuth.clientId` matching `.env`

- **Azure deployment timeout**: If Container App provisioning times out:
- The setup script uses a two-step deployment: `azd provision` (infrastructure) then `deploy.sh` (build + deploy)
- This avoids timeout issues with the placeholder image in `azd up`

- **Stuck deployment blocking retries**:
```bash
# Option 1: Cancel the stuck deployment
az deployment group cancel --resource-group <rg-name> --name container-app

# Option 2: Delete and recreate
azd down --force --purge
./scripts/full-setup.sh --deploy
```

- **Setup script input errors**: The script accepts multiple input formats:
- Press Enter for defaults
- Type `1` for yes, `2` for no
- Type `y` or `n` for yes/no
- If you see "Invalid choice", try using numeric input (1/2)

## Deployments

### GitHub Actions Workflows
Expand Down
14 changes: 2 additions & 12 deletions infra/database.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

param location string = resourceGroup().location
param environmentName string
param logAnalyticsWorkspaceId string

// Generate unique resource name
var resourceToken = toLower(uniqueString(subscription().id, environmentName, location))
Expand Down Expand Up @@ -79,32 +80,21 @@ resource diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-pr
name: 'cosmos-diagnostics'
scope: cosmosAccount
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'MongoRequests'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
{
category: 'QueryRuntimeStatistics'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
]
metrics: [
{
category: 'Requests'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
]
}
Expand Down
4 changes: 4 additions & 0 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ module cosmos './database.bicep' = {
params: {
location: location
environmentName: environmentName
logAnalyticsWorkspaceId: containerAppsEnvironment.outputs.logAnalyticsWorkspaceId
}
dependsOn: [
containerAppsEnvironment
]
}

// Container Apps Environment
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "template-doctor",
"version": "1.0.0",
"version": "2.2.0",
"description": "An Azure template analysis and healing app",
"main": "bin/cli.js",
"private": true,
Expand Down
32 changes: 30 additions & 2 deletions packages/server/src/shared/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,43 @@ export interface AppEnv {

let cached: AppEnv | null = null;

/**
* Determine which GitHub OAuth credentials to use based on environment.
* In production (NODE_ENV=production or Azure), prefer *_PROD variables.
* Falls back to standard GITHUB_CLIENT_ID/SECRET if _PROD variants not set.
*/
function getOAuthCredentials(): { clientId?: string; clientSecret?: string } {
const isProduction =
process.env.NODE_ENV === 'production' ||
process.env.WEBSITE_INSTANCE_ID || // Azure App Service
process.env.CONTAINER_APP_NAME; // Azure Container Apps

if (isProduction) {
// Production: use _PROD if available, fall back to dev
const clientId = process.env.GITHUB_CLIENT_ID_PROD || process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET_PROD || process.env.GITHUB_CLIENT_SECRET;
return { clientId, clientSecret };
} else {
// Development: use standard variables
return {
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
};
}
}

export function loadEnv(): AppEnv {
if (cached) return cached;

const { clientId, clientSecret } = getOAuthCredentials();

const required: Array<[keyof AppEnv, boolean]> = [
['GITHUB_CLIENT_ID', false], // not all endpoints need both at cold start
['GITHUB_CLIENT_SECRET', false],
];
const env: AppEnv = {
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,
GITHUB_CLIENT_ID: clientId,
GITHUB_CLIENT_SECRET: clientSecret,
GH_WORKFLOW_TOKEN: process.env.GH_WORKFLOW_TOKEN,
// Include common dev ports (4000 Vite primary, 5173 Vite default fallback) plus legacy 8080 for backward compatibility
GITHUB_OAUTH_ALLOWED_ORIGINS: (
Expand Down
Loading