178 lines
6.0 KiB
YAML
178 lines
6.0 KiB
YAML
trigger: none
|
|
pr: none
|
|
|
|
pool:
|
|
vmImage: 'ubuntu-latest'
|
|
|
|
variables:
|
|
PAC_CLI_VERSION: '2.8.1'
|
|
|
|
stages:
|
|
- stage: BranchGuard
|
|
displayName: Validate Source Branch
|
|
jobs:
|
|
- job: ValidateMaster
|
|
displayName: Ensure run is from master
|
|
steps:
|
|
- script: |
|
|
set -euo pipefail
|
|
echo "Build.SourceBranch=$(Build.SourceBranch)"
|
|
if [ "$(Build.SourceBranch)" != "refs/heads/master" ]; then
|
|
echo "This pipeline can only run from refs/heads/master."
|
|
exit 1
|
|
fi
|
|
displayName: 'Fail if branch is not master'
|
|
|
|
- stage: ExportSolution
|
|
displayName: Export Solution from Source
|
|
dependsOn: BranchGuard
|
|
condition: succeeded()
|
|
jobs:
|
|
- job: Export
|
|
displayName: Export Managed Solution
|
|
steps:
|
|
- task: UseNode@1
|
|
inputs:
|
|
version: '22.x'
|
|
displayName: 'Install Node.js'
|
|
|
|
- script: |
|
|
set -euo pipefail
|
|
|
|
dotnet tool install --global Microsoft.PowerApps.CLI.Tool --version "$(PAC_CLI_VERSION)"
|
|
export PATH="$PATH:$HOME/.dotnet/tools"
|
|
|
|
if [ -z "$(SOLUTION_UNIQUE_NAME)" ]; then
|
|
echo "SOLUTION_UNIQUE_NAME is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(SOURCE_ENVIRONMENT_URL)" ]; then
|
|
echo "SOURCE_ENVIRONMENT_URL is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(SOURCE_USERNAME)" ]; then
|
|
echo "SOURCE_USERNAME is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(SOURCE_PASSWORD)" ]; then
|
|
echo "SOURCE_PASSWORD is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(SOURCE_TENANT_ID)" ]; then
|
|
echo "SOURCE_TENANT_ID is empty."
|
|
exit 1
|
|
fi
|
|
|
|
pac auth clear
|
|
pac auth create --name "Source" --username "$(SOURCE_USERNAME)" --password "$(SOURCE_PASSWORD)" --tenant "$(SOURCE_TENANT_ID)"
|
|
pac org select --environment "$(SOURCE_ENVIRONMENT_URL)"
|
|
|
|
mkdir -p "$(Build.ArtifactStagingDirectory)/solution"
|
|
EXPORT_PATH="$(Build.ArtifactStagingDirectory)/solution/$(SOLUTION_UNIQUE_NAME)_managed.zip"
|
|
|
|
pac solution export \
|
|
--name "$(SOLUTION_UNIQUE_NAME)" \
|
|
--path "$EXPORT_PATH" \
|
|
--managed \
|
|
--overwrite
|
|
|
|
echo "Exported managed solution to: $EXPORT_PATH"
|
|
displayName: 'Export managed solution from source'
|
|
|
|
- task: PublishPipelineArtifact@1
|
|
inputs:
|
|
targetPath: '$(Build.ArtifactStagingDirectory)/solution'
|
|
artifact: 'solution-package'
|
|
publishLocation: 'pipeline'
|
|
displayName: 'Publish exported solution artifact'
|
|
|
|
- stage: Approval
|
|
displayName: Approval Before PROD Import
|
|
dependsOn: ExportSolution
|
|
condition: succeeded()
|
|
jobs:
|
|
- job: WaitForApproval
|
|
displayName: Manual Approval
|
|
pool: server
|
|
timeoutInMinutes: 4320
|
|
steps:
|
|
- task: ManualValidation@0
|
|
timeoutInMinutes: 1440
|
|
inputs:
|
|
notifyUsers: ''
|
|
instructions: |
|
|
Approve to import solution $(SOLUTION_UNIQUE_NAME) into PROD.
|
|
Run context:
|
|
- Source ref: $(Build.SourceBranch)
|
|
- Source ref name: $(Build.SourceBranchName)
|
|
- Commit: $(Build.SourceVersion)
|
|
- Run number: $(Build.BuildNumber)
|
|
Validate change ticket, release notes, and deployment window before approving.
|
|
onTimeout: reject
|
|
|
|
- stage: ImportProd
|
|
displayName: Import Solution into PROD
|
|
dependsOn: Approval
|
|
condition: succeeded()
|
|
jobs:
|
|
- job: Import
|
|
displayName: Import Managed Solution to PROD
|
|
steps:
|
|
- task: UseNode@1
|
|
inputs:
|
|
version: '22.x'
|
|
displayName: 'Install Node.js'
|
|
|
|
- task: DownloadPipelineArtifact@2
|
|
inputs:
|
|
artifact: 'solution-package'
|
|
path: '$(Pipeline.Workspace)/solution-package'
|
|
displayName: 'Download exported solution artifact'
|
|
|
|
- script: |
|
|
set -euo pipefail
|
|
|
|
dotnet tool install --global Microsoft.PowerApps.CLI.Tool --version "$(PAC_CLI_VERSION)"
|
|
export PATH="$PATH:$HOME/.dotnet/tools"
|
|
|
|
IMPORT_PATH="$(Pipeline.Workspace)/solution-package/$(SOLUTION_UNIQUE_NAME)_managed.zip"
|
|
if [ ! -f "$IMPORT_PATH" ]; then
|
|
echo "Managed solution package not found at: $IMPORT_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(PROD_ENVIRONMENT_URL)" ]; then
|
|
echo "PROD_ENVIRONMENT_URL is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(PROD_USERNAME)" ]; then
|
|
echo "PROD_USERNAME is empty."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$(PROD_PASSWORD)" ]; then
|
|
echo "PROD_PASSWORD is empty."
|
|
exit 1
|
|
fi
|
|
|
|
TARGET_TENANT_ID_VALUE="$(TARGET_TENANT_ID)"
|
|
if [ -z "$TARGET_TENANT_ID_VALUE" ]; then
|
|
TARGET_TENANT_ID_VALUE="$(PROD_TENANT_ID)"
|
|
fi
|
|
if [ -z "$TARGET_TENANT_ID_VALUE" ]; then
|
|
echo "TARGET_TENANT_ID is empty. Set TARGET_TENANT_ID (preferred) or PROD_TENANT_ID."
|
|
exit 1
|
|
fi
|
|
|
|
pac auth clear
|
|
pac auth create --name "Prod" --username "$(PROD_USERNAME)" --password "$(PROD_PASSWORD)" --tenant "$TARGET_TENANT_ID_VALUE"
|
|
pac org select --environment "$(PROD_ENVIRONMENT_URL)"
|
|
|
|
pac solution import --path "$IMPORT_PATH" --publish-changes
|
|
echo "Imported solution $(SOLUTION_UNIQUE_NAME) into PROD."
|
|
displayName: 'Import managed solution into PROD' |