Files
PowderCoatingLogix/CREATE_JENKINS_PROD_DEPLOY.md
spouliot 4f976b1332 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>
2026-04-25 13:27:43 -04:00

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, 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 restoredotnet build -c Releasedotnet 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