Rewrite Jenkinsfile for Windows appdev agent (bat, az CLI, EF direct update)
This commit is contained in:
Vendored
+30
-130
@@ -1,154 +1,54 @@
|
||||
pipeline {
|
||||
agent any
|
||||
agent { label 'appdev' }
|
||||
|
||||
// No triggers — start this pipeline manually from the Jenkins UI only.
|
||||
|
||||
environment {
|
||||
DOTNET_CLI_HOME = '/tmp/dotnet_cli_home'
|
||||
WEB_PROJECT = 'src/PowderCoating.Web/PowderCoating.Web.csproj'
|
||||
INFRA_PROJECT = 'src/PowderCoating.Infrastructure/PowderCoating.Infrastructure.csproj'
|
||||
PUBLISH_DIR = "${WORKSPACE}/publish"
|
||||
DEPLOY_ZIP = "${WORKSPACE}/deploy_${BUILD_NUMBER}.zip"
|
||||
MIGRATION_SQL = "${WORKSPACE}/migration_${BUILD_NUMBER}.sql"
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timestamps()
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: 'refs/heads/master']],
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
echo "Building commit: ${GIT_COMMIT}"
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build & Test') {
|
||||
stage('Restore & Build') {
|
||||
steps {
|
||||
sh 'dotnet restore'
|
||||
sh 'dotnet build --no-restore -c Release'
|
||||
sh '''
|
||||
dotnet test --no-build -c Release \
|
||||
--logger "trx;LogFileName=results.trx" \
|
||||
--results-directory TestResults
|
||||
'''
|
||||
bat 'dotnet restore PowderCoatingApp.sln'
|
||||
bat 'dotnet build PowderCoatingApp.sln -c Release --no-restore'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit testResults: 'TestResults/*.trx', allowEmptyResults: true
|
||||
}
|
||||
|
||||
stage('Run Migrations') {
|
||||
steps {
|
||||
bat 'dotnet tool install --global dotnet-ef 2>nul || dotnet tool update --global dotnet-ef 2>nul'
|
||||
withCredentials([string(credentialsId: 'pcl-prod-sql', variable: 'SQL_CONN')]) {
|
||||
bat '"%USERPROFILE%\\.dotnet\\tools\\dotnet-ef.exe" database update --project src\\PowderCoating.Infrastructure --startup-project src\\PowderCoating.Web --configuration Release --no-build --context ApplicationDbContext --connection "%SQL_CONN%"'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Publish') {
|
||||
steps {
|
||||
sh """
|
||||
dotnet publish '${WEB_PROJECT}' \
|
||||
-c Release --no-build \
|
||||
-o '${PUBLISH_DIR}'
|
||||
"""
|
||||
bat 'dotnet publish src\\PowderCoating.Web\\PowderCoating.Web.csproj -c Release --no-build -o publish'
|
||||
}
|
||||
}
|
||||
|
||||
// Generates an idempotent SQL migration script (no live DB connection required).
|
||||
// The script checks which migrations have already been applied before running each one.
|
||||
stage('Generate Migration Script') {
|
||||
stage('Deploy to Azure') {
|
||||
steps {
|
||||
sh """
|
||||
dotnet ef migrations script \
|
||||
--idempotent \
|
||||
--output '${MIGRATION_SQL}' \
|
||||
--project '${INFRA_PROJECT}' \
|
||||
--startup-project '${WEB_PROJECT}' \
|
||||
--context ApplicationDbContext \
|
||||
--no-build
|
||||
"""
|
||||
archiveArtifacts artifacts: "migration_${BUILD_NUMBER}.sql", fingerprint: true
|
||||
echo "Migration script archived — review it in the Jenkins build artifacts before this pipeline runs next time."
|
||||
}
|
||||
}
|
||||
|
||||
stage('Apply Migration to Azure SQL') {
|
||||
steps {
|
||||
withCredentials([
|
||||
string(credentialsId: 'PCL_SQL_SERVER', variable: 'SQL_SERVER'),
|
||||
string(credentialsId: 'PCL_SQL_DATABASE', variable: 'SQL_DATABASE'),
|
||||
string(credentialsId: 'PCL_SQL_USER', variable: 'SQL_USER'),
|
||||
string(credentialsId: 'PCL_SQL_PASSWORD', variable: 'SQL_PASSWORD')
|
||||
]) {
|
||||
sh '''
|
||||
echo "Applying migration to ${SQL_SERVER}/${SQL_DATABASE} ..."
|
||||
/opt/mssql-tools18/bin/sqlcmd \
|
||||
-S "${SQL_SERVER}" \
|
||||
-d "${SQL_DATABASE}" \
|
||||
-U "${SQL_USER}" \
|
||||
-P "${SQL_PASSWORD}" \
|
||||
-C \
|
||||
-b \
|
||||
-i "${MIGRATION_SQL}"
|
||||
echo "Migration applied successfully."
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to Azure App Service') {
|
||||
steps {
|
||||
withCredentials([
|
||||
string(credentialsId: 'PCL_AZURE_CLIENT_ID', variable: 'AZ_CLIENT_ID'),
|
||||
string(credentialsId: 'PCL_AZURE_CLIENT_SECRET', variable: 'AZ_CLIENT_SECRET'),
|
||||
string(credentialsId: 'PCL_AZURE_TENANT_ID', variable: 'AZ_TENANT_ID'),
|
||||
string(credentialsId: 'PCL_AZURE_SUBSCRIPTION_ID', variable: 'AZ_SUBSCRIPTION_ID'),
|
||||
string(credentialsId: 'PCL_AZURE_RESOURCE_GROUP', variable: 'AZ_RG'),
|
||||
string(credentialsId: 'PCL_AZURE_APP_NAME', variable: 'AZ_APP')
|
||||
]) {
|
||||
sh '''
|
||||
az login --service-principal \
|
||||
--username "$AZ_CLIENT_ID" \
|
||||
--password "$AZ_CLIENT_SECRET" \
|
||||
--tenant "$AZ_TENANT_ID" \
|
||||
--output none
|
||||
|
||||
az account set --subscription "$AZ_SUBSCRIPTION_ID"
|
||||
|
||||
echo "Packaging deployment artifact ..."
|
||||
cd "$PUBLISH_DIR"
|
||||
zip -r "$DEPLOY_ZIP" .
|
||||
|
||||
echo "Pushing ZIP to ${AZ_APP} ..."
|
||||
az webapp deployment source config-zip \
|
||||
--resource-group "$AZ_RG" \
|
||||
--name "$AZ_APP" \
|
||||
--src "$DEPLOY_ZIP"
|
||||
|
||||
az logout
|
||||
echo "Deploy complete."
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Smoke Test') {
|
||||
steps {
|
||||
withCredentials([
|
||||
string(credentialsId: 'PCL_AZURE_APP_NAME', variable: 'AZ_APP')
|
||||
]) {
|
||||
sh '''
|
||||
APP_URL="https://${AZ_APP}.azurewebsites.net"
|
||||
echo "Smoke-testing ${APP_URL} ..."
|
||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
--max-time 45 --retry 3 --retry-delay 10 \
|
||||
"${APP_URL}")
|
||||
echo "HTTP status: ${HTTP_STATUS}"
|
||||
# 200 = OK, 302 = redirect to login (both are healthy)
|
||||
if [ "$HTTP_STATUS" != "200" ] && [ "$HTTP_STATUS" != "302" ]; then
|
||||
echo "SMOKE TEST FAILED — got HTTP ${HTTP_STATUS}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Smoke test passed."
|
||||
'''
|
||||
bat 'powershell -Command "Compress-Archive -Path publish\\* -DestinationPath deploy.zip -Force"'
|
||||
withCredentials([azureServicePrincipal(
|
||||
credentialsId: 'azure-pcl',
|
||||
subscriptionIdVariable: 'AZ_SUB_ID',
|
||||
clientIdVariable: 'AZ_CLIENT_ID',
|
||||
clientSecretVariable: 'AZ_CLIENT_SECRET',
|
||||
tenantIdVariable: 'AZ_TENANT_ID'
|
||||
)]) {
|
||||
bat 'az login --service-principal -u "%AZ_CLIENT_ID%" -p "%AZ_CLIENT_SECRET%" --tenant "%AZ_TENANT_ID%" --output none'
|
||||
bat 'az account set --subscription "%AZ_SUB_ID%"'
|
||||
bat 'az webapp deploy --resource-group rg-powdercoatinglogix-prod --name linuxpcl --src-path deploy.zip --type zip'
|
||||
bat 'az logout'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,7 +56,7 @@ pipeline {
|
||||
|
||||
post {
|
||||
success {
|
||||
echo "Production deployment #${BUILD_NUMBER} (${GIT_COMMIT}) completed successfully."
|
||||
echo "Production deployment #${BUILD_NUMBER} completed successfully."
|
||||
}
|
||||
failure {
|
||||
echo "Pipeline #${BUILD_NUMBER} FAILED — review the stage logs above."
|
||||
|
||||
Reference in New Issue
Block a user