# Jenkins Production Deployment Setup

## What was created

| File | Purpose |
|---|---|
| `Jenkinsfile` | Production pipeline — manual trigger only |
| `jenkins/Dockerfile` | Custom image: Jenkins LTS + .NET 8 + Azure CLI + sqlcmd + dotnet-ef |
| `.config/dotnet-tools.json` | Tool manifest pinning dotnet-ef 8.0.11 |

---

## One-time setup steps

### 1. Build and run your custom Jenkins image

On your Ubuntu Docker host:
```bash
cd /path/to/repo
docker build -t pcl-jenkins ./jenkins
docker run -d -p 8080:8080 -p 50000:50000 \
    -v jenkins_home:/var/jenkins_home \
    --name pcl-jenkins pcl-jenkins
```

If you already have a Jenkins container running, rebuild the image and recreate the container (volume data is preserved).

---

### 2. Create an Azure Service Principal

Run this once from **your machine** (not Jenkins):
```bash
az login
az ad sp create-for-rbac \
    --name "pcl-jenkins-deploy" \
    --role contributor \
    --scopes /subscriptions/<YOUR_SUBSCRIPTION_ID>/resourceGroups/<YOUR_RG>
```

Save the output — you need `appId`, `password`, `tenant`, and your subscription ID.

---

### 3. Create a SQL Server deployment login

In SSMS or Azure portal query editor, run on your Azure SQL server (as admin):
```sql
CREATE LOGIN pcl_deploy WITH PASSWORD = 'ChooseAStrongPassword123!';
USE PowderCoatingDb;
CREATE USER pcl_deploy FOR LOGIN pcl_deploy;
ALTER ROLE db_owner ADD MEMBER pcl_deploy;   -- needs DDL rights for migrations
```

> After migrations are stable you can demote this to `db_datareader`/`db_datawriter` + explicit DDL permissions, but `db_owner` is easiest to start.

---

### 4. Add Jenkins credentials

Go to **Jenkins → Manage Jenkins → Credentials → System → Global** and add 10 **Secret Text** credentials with these exact IDs:

| Credential ID | Value |
|---|---|
| `PCL_AZURE_CLIENT_ID` | `appId` from step 2 |
| `PCL_AZURE_CLIENT_SECRET` | `password` from step 2 |
| `PCL_AZURE_TENANT_ID` | `tenant` from step 2 |
| `PCL_AZURE_SUBSCRIPTION_ID` | Your Azure subscription GUID |
| `PCL_AZURE_RESOURCE_GROUP` | e.g. `powder-coating-prod` |
| `PCL_AZURE_APP_NAME` | Your App Service name (e.g. `pcl-app`) |
| `PCL_SQL_SERVER` | e.g. `pcl-sql.database.windows.net` |
| `PCL_SQL_DATABASE` | e.g. `PowderCoatingDb` |
| `PCL_SQL_USER` | `pcl_deploy` |
| `PCL_SQL_PASSWORD` | The password you set in step 3 |

---

### 5. Create the Jenkins Pipeline job

1. **New Item → Pipeline** — name it "PCL Production Deploy"
2. Under **Pipeline**, set **Definition** = `Pipeline script from SCM`
3. SCM = Git, repo URL, branch `*/master`, Script Path = `Jenkinsfile`
4. **Do NOT** check any triggers (no poll SCM, no build periodically, no webhook)
5. Save

To deploy: open the job → **Build Now**. That's your "Go!" button.

---

## How each stage works

| Stage | What happens |
|---|---|
| **Checkout** | Pulls `master`, logs the commit SHA |
| **Build & Test** | `dotnet restore` → `dotnet build -c Release` → `dotnet test` (results published to Jenkins) |
| **Publish** | `dotnet publish -c Release` → `./publish/` |
| **Generate Migration Script** | `dotnet ef migrations script --idempotent` — no DB connection needed. Script is **archived as a build artifact** so you can inspect it before or after |
| **Apply Migration** | `sqlcmd` runs the idempotent script against Azure SQL. `-b` flag makes it fail-fast on errors |
| **Deploy to Azure** | ZIP the publish folder, `az webapp deployment source config-zip` |
| **Smoke Test** | `curl` the App Service root URL — expects HTTP 200 or 302 |
