Require auth on all work order QR codes and add top view QR
- StatusBump (GET + POST) now requires authentication; routes by job ID instead of anonymous ShopAccessCode GUID; records actual user name in status history instead of anonymous token string - WorkOrder action generates a second "View Job" QR in the header linking to the authenticated Details page (for verifying specs and seeing catalog images on mobile); status bump QR updated to ID-based URL - WorkOrder view: top QR added to header alongside job number; status bump label updated (removed "no login required" copy) - StatusBump view: updated form routing from asp-route-token to asp-route-id - HelpKnowledgeBase and Jobs help article updated with two-tier QR docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user