4f976b1332
- 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>
3.5 KiB
3.5 KiB
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:
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):
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):
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, butdb_owneris 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
- New Item → Pipeline — name it "PCL Production Deploy"
- Under Pipeline, set Definition =
Pipeline script from SCM - SCM = Git, repo URL, branch
*/master, Script Path =Jenkinsfile - Do NOT check any triggers (no poll SCM, no build periodically, no webhook)
- 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 |