Automated deployment pipeline for DBmaestro package management with staged environments (DEV → Release Source → QAS → PRD) and scheduled production deployments.
The azure-pipelines.yml implements a comprehensive deployment orchestration with the following stages:
-
ExtractTaskID: Extracts TaskID from commit message
- Regex pattern:
TaskID:\s*([A-Za-z0-9_-]+) - Example commit:
Update schema TaskID: ISSUE-75 - Creates artifact:
taskid-artifact
- Regex pattern:
-
CreatePackage: Creates DBmaestro package
- Uses TaskID as package name
- Runs DBmaestro Build command
- Environment: DEV_USER
-
RunPrecheck: Validates package integrity
- Executes DBmaestro PreCheck
- Ensures package is deployable
-
UpgradeReleaseSource: Deploys to Release Source
- Environment: DEV (Release Source)
- Includes backup and restore behavior
- First production-like environment test
-
ApprovalForQAS: Manual approval gate
- Requires approval before QAS deployment
- Notifies: AdoUser@dbmaestro.local
- Timeout: 24 hours
-
UpgradeQAS: Deploys to QAS
- Environment: QAS
- Full deployment with backup/restore
-
SchedulePRDUpgrade: Schedules production deployment
- Two jobs: environment approval + automated scheduling
- Retrieves deployment schedule from work item associated with TaskID
- Creates dynamic pipeline with calculated cron schedule
- Registers pipeline in "Production Deployments" folder
- Azure DevOps Project with
ado-examplesrepository - Build agent pool:
AdoHosted - DBmaestro agent running on
localhost:8017 - Git Repository Permissions: Build service account must have
ContributeandCreate Branchpermissions
The pipeline needs permission to commit and push the dynamic production pipeline YAML files:
- In Azure DevOps, go to Project Settings (bottom left)
- Navigate to Repositories → ado-examples
- Click the Security tab
- Search for:
[Project]\Build Service ([Organization])- Example:
poc\Build Service (dbmsc)
- Example:
- Set the following permissions to Allow:
- Contribute: Required to commit files
- Create Branch: Required to create main branch if needed
- Click Save changes
Without these permissions, the pipeline will fail at the "Commit Pipeline File to Repository" stage with error:
TF401027: You need the Git 'GenericContribute' permission to perform this action
All commits must include TaskID (and optionally WorkItemId) in the commit message:
git commit -m "Your commit message TaskID: ISSUE-75"
or with explicit WorkItemId reference:
git commit -m "Your commit message TaskID: ISSUE-75 WorkItemId: 12345"
Format: TaskID: [A-Za-z0-9_-]+ anywhere in the commit message
- TaskID is used as the package name
- If WorkItemId is not explicitly provided, the TaskID is used to look up the corresponding work item
- The work item's description is searched for
TargetDeploymentDate: 'YYYY-MM-DD HH:MM:SS'to determine deployment schedule
The pipelines require a Variable Group named DBmaestro-Credentials to store sensitive credentials:
- In Azure DevOps, go to Pipelines → Library
- Click "+ Variable group"
- Enter name:
DBmaestro-Credentials - Add variables:
- DBMUsername: Your DBmaestro service account username
- Click the lock icon to mark as secret
- DBMPassword: Your DBmaestro service account password
- Click the lock icon to mark as secret
- ADO_PAT: Personal Access Token for Azure DevOps API access
- Click the lock icon to mark as secret
- Required for retrieving work item details and deployment dates
- Must have permissions to read work items and create pipelines
- DBMUsername: Your DBmaestro service account username
- Click "Save"
The variable group must be accessible to all pipelines in the project, especially the dynamically generated scheduled pipelines.
To grant access:
- In Pipelines → Library, click on
DBmaestro-Credentials - Click the ⋮ (three dots) menu at the top right
- Select "Open access" to allow all pipelines in the project to use this variable group
- Confirm the permission change
Without this setting, dynamically created scheduled pipelines will fail with a permission error when trying to access the variable group.
- Security: Credentials stored securely in Azure DevOps (not in YAML files)
- Reusability: Automatically available to all pipelines that reference the group
- Dynamic Pipelines: Scheduled production pipelines inherit credentials from the group without manual setup
The dynamically created production deployment scheduled pipelines require permission to access the agent pool.
Option 1: Authorize Individual Pipelines (Recommended for security)
- In Azure DevOps, go to Project Settings → Agent pools (under Pipelines section)
- Click on AdoHosted pool
- Click the Security tab
- Click the + button to add a new pipeline
- Search for and select the newly created production deployment pipeline (e.g., "Deploy-PRD-ISSUE-93")
- Click Save
This grants permission to that specific pipeline to use the agent pool.
Option 2: Allow All Pipelines (Easier for less restricted projects)
If you have project-level permissions:
- In Azure DevOps, go to Project Settings → Agent pools (under Pipelines section)
- Click on AdoHosted pool
- Click the Security tab
- Look for a "Make open" or "Allow all pipelines" option (depending on your Azure DevOps version)
- Enable it to allow all pipelines in the project to use this agent pool
This eliminates the need to authorize each new production deployment pipeline individually.
Without agent pool access, newly created production deployment pipelines will fail with error:
This pipeline needs permission to access a resource before this run can continue to Deploy to Production
DBMUsername: DBmaestro service account username (fromDBmaestro-Credentials)DBMPassword: DBmaestro service account password (fromDBmaestro-Credentials)ADO_PAT: Personal Access Token for Azure DevOps API access (fromDBmaestro-Credentials)
TargetDeploymentDate: Extracted from work item description (parsed fromTargetDeploymentDate: 'YYYY-MM-DD HH:MM:SS'format)- Retrieved via the TaskID and WorkItemId embedded in the commit message
- If not found, defaults to 5 minutes from approval time
- Used to calculate cron expression for scheduled pipeline
When the TaskID is extracted from the commit message, the pipeline automatically:
- Retrieves the WorkItemId from the commit message (TaskID used to link to work item)
- Looks up the work item in Azure DevOps via REST API
- Searches the description for:
TargetDeploymentDate: 'YYYY-MM-DD HH:MM:SS' - Extracts the deployment date from the work item description
- Creates a scheduled pipeline with the calculated cron expression
- Registers and executes the pipeline at the scheduled time
Add this to your Azure DevOps work item description:
Deployment Details:
TargetDeploymentDate: '2025-11-17 14:30:00'
Version: 1.0.0
Approver: John Doe
The pipeline will parse and extract 2025-11-17 14:30:00 as the deployment time.
If the work item doesn't contain TargetDeploymentDate in the description:
- Pipeline proceeds to ApprovalForDeployment stage (environment-based approval)
- After approval, defaults to 5 minutes from approval time
- Creates scheduled pipeline with this default timing
dbmaestroVersion: '2024.1.0'
DBM_JAR_PATH: 'C:\Program Files (x86)\DBmaestro\DOP Server\Agent\DBmaestroAgent.jar'
DBM_AGENT_ENDPOINT: 'localhost:8017'
DBM_PROJECT_NAME: 'Demo-MSSQL'
DBM_ENV_NAME_DEV: 'DEV_USER'
DBM_ENV_NAME_RS: 'DEV' # Release Source
DBM_ENV_NAME_QA: 'QAS'
DBM_ENV_NAME_PROD: 'PRD'For each package, a dynamic production pipeline is created:
- File:
deploy-prd-[PACKAGE_NAME].yml - Location: Repository root
- Schedule: Calculated cron expression
- Folder: "Production Deployments" in Azure DevOps
- Trigger: Scheduled (not manual)
Example: deploy-prd-ISSUE-75.yml scheduled for 2025-11-17 at 14:30:00
The scheduling job performs these operations:
- Generates custom pipeline YAML from template
- Commits to
mainbranch with message:"Add scheduled production deployment for [PACKAGE] [skip ci]" - Pushes to origin
- Registers pipeline via Azure DevOps REST API v7.1
| Stage | Purpose | Timeout | Action |
|---|---|---|---|
| ApprovalForQAS | Review Release Source deployment | 24 hours | Approve/Reject |
| ApprovalForDeployment | Environment-based approval for PRD | 24 hours | Approve (environment checks enforce this) |
The SetDeploymentTime stage automatically retrieves the deployment date from the work item description - no manual variable setting required.
Package name and deployment information is passed between stages via artifacts:
- Published by: ExtractTaskID stage
- Artifact name:
taskid-artifact - File:
taskid.txt - Used by: CreatePackage, RunPrecheck, UpgradeINTEGRACION, UpgradeQAS, ScheduleUpgrade stages
- Published by: ExtractTaskID stage
- Artifact name:
workitemid-artifact - File:
workitemid.txt - Used by: SetDeploymentTime stage to retrieve deployment schedule from work item description
- Published by: SetDeploymentTime stage
- Artifact name:
deploymentdate-artifact - File:
deploymentdate.txt - Used by: ScheduleUpgrade stage to apply the extracted deployment date to cron schedule
Error: error: src refspec main does not match any
Solution: Ensure main branch exists in repository. The pipeline handles detached HEAD state by running:
git fetch origin
git checkout -B main origin/mainSolution: Verify the work item description contains the date in exactly this format: TargetDeploymentDate: 'YYYY-MM-DD HH:MM:SS'
- Correct:
TargetDeploymentDate: '2025-11-17 14:30:00' - Incorrect:
TargetDeploymentDate: 11/17/2025 2:30 PM - Check that the format is surrounded by single quotes
Error: Pipeline defaults to 5 minutes instead of using work item date
Solution:
- Verify
ADO_PATis defined in theDBmaestro-Credentialsvariable group - Ensure the work item description contains:
TargetDeploymentDate: 'YYYY-MM-DD HH:MM:SS' - Check that the Personal Access Token has permissions to read work items
- Verify the work item exists and is linked to the TaskID
Error: Pipeline skips work item lookup and uses default scheduling
Solution: Add ADO_PAT to the DBmaestro-Credentials variable group:
- Go to Pipelines → Library →
DBmaestro-Credentials - Add variable:
ADO_PAT - Set value to your Personal Access Token with work item read permissions
- Mark as secret (click lock icon)
Solution: Check if "Production Deployments" folder exists in Azure DevOps pipelines. If not, create it manually or the REST API will create it automatically on first run.
Run the pipeline with a test commit:
git commit --allow-empty -m "Test pipeline TaskID: TEST-001"
git push origin main
Monitor the pipeline run in Azure DevOps. All stages should complete successfully through SchedulePRDUpgrade.
Old production deployment pipeline files can be safely deleted from the repository after execution if desired. The scheduled pipeline will have already executed before cleanup.
Edit azure-pipelines.yml directly. Changes apply to all future runs.
Edit deploy-prd-template.yml to change production deployment behavior. Placeholders:
CRON_SCHEDULE_PLACEHOLDER: Replaced with calculated cron expressionPACKAGE_NAME_PLACEHOLDER: Replaced with package name
- DBmaestro Agent:
localhost:8017(configurable) - Azure DevOps REST API: Used for pipeline registration
- Git Repository: Source of pipeline files and commit triggers
- Azure DevOps Build Agents: Executes all pipeline jobs