├── .gitattributes
├── samples
├── crypt
│ ├── devops
│ │ ├── storeFor
│ │ ├── crypt
│ │ │ └── AES_CRYPT
│ │ ├── cryptLocal
│ │ │ └── WINDOWS_PASSWORD
│ │ ├── custom
│ │ │ ├── crypt-test.yml
│ │ │ └── properties.varchk
│ │ ├── .gitignore
│ │ ├── properties.cm
│ │ ├── CDAF.solution
│ │ └── tasksRun.tsk
│ └── .gitignore
├── .gitignore
├── all
│ ├── automation-solution
│ │ ├── storeForLocal
│ │ ├── storeForRemote
│ │ ├── crypt
│ │ │ └── secrets.crypt
│ │ ├── cryptLocal
│ │ │ └── WINDOWS_PASSWORD
│ │ ├── propertiesForRemoteTasks
│ │ │ ├── WINDOWS_LOCALHOST_NTLM
│ │ │ ├── USER_PASSWORD_LOCALHOST
│ │ │ └── VAGRANT_CERTIFICATE_DECRYPT
│ │ ├── customLocal
│ │ │ └── properties.varchk
│ │ ├── propertiesForLocalTasks
│ │ │ └── WORKGROUP_LOCAL
│ │ ├── CDAF.solution
│ │ ├── custom
│ │ │ ├── slack.ps1
│ │ │ └── example.yaml
│ │ ├── properties.cm
│ │ ├── tasksRunRemote.tsk
│ │ ├── storeForArtifact.txt
│ │ └── tasksRunLocal.tsk
│ ├── project
│ │ └── build.tsk
│ ├── .gitignore
│ ├── readme.md
│ └── build.tsk
├── custom
│ ├── automation-solution
│ │ ├── storeForLocal
│ │ ├── properties.cm
│ │ ├── CDAF.solution
│ │ ├── tasksRunLocal.tsk
│ │ └── customLocal
│ │ │ └── customDeploy.ps1
│ └── .gitignore
├── minimal-build
│ ├── automation-solution
│ │ ├── storeForLocal
│ │ ├── customLocal
│ │ │ └── properties.varchk
│ │ ├── CDAF.solution
│ │ ├── properties.cm
│ │ ├── build.tsk
│ │ └── tasksRunLocal.tsk
│ ├── solution.properties
│ ├── build.tsk
│ └── .gitignore
├── targetlessCD
│ ├── automation-solution
│ │ ├── storeForLocal
│ │ ├── CDAF.solution
│ │ ├── customLocal
│ │ │ ├── containerTest.tsk
│ │ │ ├── Dockerfile
│ │ │ ├── bootstrapTarget.ps1
│ │ │ └── compose.tsk
│ │ └── properties.cm
│ ├── .gitignore
│ ├── compose
│ │ ├── docker-compose.yml
│ │ └── test
│ │ │ └── Dockerfile
│ └── readme.md
├── containerBuild
│ ├── build.tsk
│ ├── .gitignore
│ └── automation-solution
│ │ └── CDAF.solution
├── containerBuild-custom-image
│ ├── build.tsk
│ ├── .gitignore
│ ├── automation-solution
│ │ ├── CDAF.solution
│ │ └── bootstrapAgent.ps1
│ ├── Readme.md
│ └── Dockerfile
├── log-image
│ ├── solution
│ │ ├── CDAF.solution
│ │ ├── tasksRun.tsk
│ │ └── properties.cm
│ └── .gitignore
├── containerDeploy
│ ├── automation-solution
│ │ ├── storeForRemote
│ │ ├── properties.cm
│ │ ├── customRemote
│ │ │ └── deploy.tsk
│ │ └── CDAF.solution
│ └── .gitignore
├── deliveryEnv.ps1
├── imageBuild
│ ├── automation-solution
│ │ ├── customLocal
│ │ │ └── immutable.tsk
│ │ ├── properties.cm
│ │ └── CDAF.solution
│ └── .gitignore
├── containerDeploy-custom-image
│ ├── automation-solution
│ │ ├── storeForRemote
│ │ ├── storeForLocal
│ │ ├── customRemote
│ │ │ └── deploy.tsk
│ │ ├── properties.cm
│ │ └── CDAF.solution
│ ├── Dockerfile
│ ├── .gitignore
│ └── containerDeploy
│ │ ├── settings.xml
│ │ ├── Dockerfile
│ │ └── bootstrapAgent.ps1
├── minimal
│ ├── .gitignore
│ └── automation-solution
│ │ └── CDAF.solution
├── pre-post-processes
│ ├── automation-solution
│ │ ├── example.yaml
│ │ ├── CDAF.solution
│ │ ├── wrap.tsk
│ │ ├── package.tsk
│ │ ├── postbuild.tsk
│ │ ├── prebuild.tsk
│ │ └── build.tsk
│ └── .gitignore
├── imageBuild-custom-image
│ ├── .gitignore
│ └── automation-solution
│ │ ├── customLocal
│ │ └── Dockerfile
│ │ └── CDAF.solution
├── feature-branch-environments
│ ├── automation-solution
│ │ ├── feature-branch.properties
│ │ ├── CDAF.solution
│ │ ├── properties.cm
│ │ └── tasksRunLocal.tsk
│ └── .gitignore
├── cd.ps1
├── deliveryScript.ps1
└── executeSamples.ps1
├── automation
├── powershell.lnk
├── buildandpackage
│ ├── storeArtifacts.ps1
│ └── loadVSenv.ps1
├── CDAF.windows
├── remote
│ ├── getProperty.ps1
│ ├── extract.ps1
│ ├── deploy.bat
│ ├── push.bat
│ ├── push.ps1
│ ├── fixACLs.ps1
│ ├── logWatch.ps1
│ └── winrmtest.ps1
├── Readme.md
├── .gitignore
├── local
│ ├── push.ps1
│ ├── RemoteTest.ps1
│ ├── deploy.ps1
│ ├── remotePackageManagement.ps1
│ ├── localTasksTarget.ps1
│ ├── copy.ps1
│ ├── copyTemplate.ps1
│ ├── embed.ps1
│ └── remoteTasks.ps1
├── cdEmulate.bat
├── entry.bat
├── processor
│ └── delivery.bat
├── ci.bat
└── badge.svg
├── provisioning
├── ADGroupMember.ps1
├── openFirewallPort.ps1
├── EnableClientRemoting.ps1
├── EnableServerRemoting.ps1
├── readme.md
├── trustedHosts.ps1
├── runner.bat
├── removeFile.ps1
├── EnableFileAndPrintSharing.ps1
├── nextFreePort.ps1
├── setProductKey.ps1
├── setStaticIP.ps1
├── installEXE.ps1
├── sqlLocalDBInstance.ps1
├── applyWindowsUpdates.ps1
├── CredDelegation.ps1
├── encypt.ps1
├── setWinRM.ps1
├── setSPN.ps1
├── addProxy.ps1
├── WIF.ps1
├── SDK.ps1
├── setenv.ps1
├── IISPoolAccount.ps1
├── agent.ps1
├── computerCertificate.ps1
├── sqlAuthMode.ps1
├── addVSTSPackageCred.ps1
├── removeUser.ps1
├── mkdir.ps1
├── addFeature.ps1
├── WIFSDK.ps1
├── sqlCreateDB.ps1
├── GetExecutable.ps1
├── setInternetProxy.ps1
├── addUserToLocalGroup.ps1
├── addPath.ps1
├── installAzureRM.ps1
├── addHOSTS.ps1
├── installMSU.ps1
└── sqlAddUserDB.ps1
├── orchestration
├── ado
│ ├── Multi-stage
│ │ ├── .cdaf
│ │ │ └── CDAF.solution
│ │ ├── templates
│ │ │ ├── azure-pipelines-dockerhub-template.yml
│ │ │ ├── azure-pipelines-terraform-template.yml
│ │ │ ├── azure-pipelines-deployment-template.yml
│ │ │ └── azure-pipelines-build-template.yml
│ │ └── azure-pipelines.yml
│ └── CI-Only
│ │ └── azure-pipelines.yml
├── buildmaster
│ ├── deploy
│ └── build
├── bamboo-specs
│ ├── v1
│ │ └── bamboo.yml
│ └── bamboo.yml
├── vagrant-box
│ └── Vagrantfile
├── jenkins
│ ├── jenkins-scripted-pipeline
│ │ └── Jenkinsfile
│ └── jenkins-declaritive-pipeline
│ │ └── Jenkinsfile
├── vagrant-test
│ └── Vagrantfile
├── gitlab
│ └── .gitlab-ci.yml
└── bitbucket
│ └── bitbucket-pipelines.yml
├── .project
├── .gitignore
├── Readme.md
├── LICENSE.md
└── .github
└── workflows
└── delivery.yml
/.gitattributes:
--------------------------------------------------------------------------------
1 | * -text
2 |
--------------------------------------------------------------------------------
/samples/crypt/devops/storeFor:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples/.gitignore:
--------------------------------------------------------------------------------
1 | /build.binary
2 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/storeForLocal:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/storeForRemote:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples/custom/automation-solution/storeForLocal:
--------------------------------------------------------------------------------
1 | example.yaml
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/storeForLocal:
--------------------------------------------------------------------------------
1 | example.yaml
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/storeForLocal:
--------------------------------------------------------------------------------
1 | # TargetlessCD
2 | compose
3 |
--------------------------------------------------------------------------------
/automation/powershell.lnk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/automation/powershell.lnk
--------------------------------------------------------------------------------
/samples/all/project/build.tsk:
--------------------------------------------------------------------------------
1 | echo "Child Project build verification"
2 |
3 | Get-ChildItem env:
4 |
--------------------------------------------------------------------------------
/samples/containerBuild/build.tsk:
--------------------------------------------------------------------------------
1 | echo "Apply build activity here, which will execute in your container"
--------------------------------------------------------------------------------
/provisioning/ADGroupMember.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/provisioning/ADGroupMember.ps1
--------------------------------------------------------------------------------
/provisioning/openFirewallPort.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/provisioning/openFirewallPort.ps1
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/build.tsk:
--------------------------------------------------------------------------------
1 | echo "Apply build activity here, which will execute in your container"
--------------------------------------------------------------------------------
/provisioning/EnableClientRemoting.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/provisioning/EnableClientRemoting.ps1
--------------------------------------------------------------------------------
/provisioning/EnableServerRemoting.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/provisioning/EnableServerRemoting.ps1
--------------------------------------------------------------------------------
/samples/crypt/devops/crypt/AES_CRYPT:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/samples/crypt/devops/crypt/AES_CRYPT
--------------------------------------------------------------------------------
/samples/log-image/solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=log-image
2 | artifactPrefix=0.0
3 | defaultEnvironment=WINDOWS
4 |
--------------------------------------------------------------------------------
/samples/containerDeploy/automation-solution/storeForRemote:
--------------------------------------------------------------------------------
1 | # The containerDeploy assets are executed in the remote context
2 |
--------------------------------------------------------------------------------
/samples/deliveryEnv.ps1:
--------------------------------------------------------------------------------
1 | # This is an example script which only return WINDOWS, i.e. the on-domain default
2 | return 'WINDOWS'
--------------------------------------------------------------------------------
/samples/imageBuild/automation-solution/customLocal/immutable.tsk:
--------------------------------------------------------------------------------
1 | echo "Deploy your software artefacts into the immutable image."
--------------------------------------------------------------------------------
/samples/imageBuild/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployTaskOverride
2 | local IMMUTABLE immutable.tsk
3 |
--------------------------------------------------------------------------------
/automation/buildandpackage/storeArtifacts.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/automation/buildandpackage/storeArtifacts.ps1
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/.cdaf/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=azuredevops.multistage
2 | artifactPrefix=0.0
3 | # defaultBranch=main
4 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/automation-solution/storeForRemote:
--------------------------------------------------------------------------------
1 | # The containerDeploy assets are executed in the remote context
2 |
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/.gitignore:
--------------------------------------------------------------------------------
1 | /automation/
2 | /container-build/
3 | /TasksLocal/
4 | /container-build-*.zip
5 | /release.ps1
6 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/automation-solution/storeForLocal:
--------------------------------------------------------------------------------
1 | # Store containerDeploy if constructing a custom image
2 | containerDeploy
--------------------------------------------------------------------------------
/samples/crypt/devops/cryptLocal/WINDOWS_PASSWORD:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/samples/crypt/devops/cryptLocal/WINDOWS_PASSWORD
--------------------------------------------------------------------------------
/samples/log-image/solution/tasksRun.tsk:
--------------------------------------------------------------------------------
1 | echo "Download an image"
2 | curl.exe -s -O $uri
3 |
4 | echo "Write image to Log"
5 | IMGTXT $filename
6 |
--------------------------------------------------------------------------------
/samples/all/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /myProduct-*.zip
3 | /bin.bat
4 | /propertiesForLocalTasks/
5 | /propertiesForRemoteTasks/
6 | /release.ps1
7 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/crypt/secrets.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/samples/all/automation-solution/crypt/secrets.crypt
--------------------------------------------------------------------------------
/samples/containerBuild/.gitignore:
--------------------------------------------------------------------------------
1 | /automation/
2 | /container-build/
3 | /TasksLocal/
4 | /container-build-*.zip
5 | /release.ps1
6 | /Dockerfile
7 |
--------------------------------------------------------------------------------
/samples/minimal/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /minimal-package-*.zip
3 | /minimal-package-*.tar.gz
4 | /bin.bat
5 | /release.ps1
6 | /minimal-package-*/
7 |
--------------------------------------------------------------------------------
/samples/imageBuild/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /index.html
3 | /manifest.txt
4 | /storeForLocal_manifest.txt
5 | /app/
6 | /imagebuild-*.zip
7 | /release.ps1
8 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/cryptLocal/WINDOWS_PASSWORD:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/samples/all/automation-solution/cryptLocal/WINDOWS_PASSWORD
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/example.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdaf/windows/HEAD/samples/pre-post-processes/automation-solution/example.yaml
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/automation-solution/customRemote/deploy.tsk:
--------------------------------------------------------------------------------
1 | echo "Here we execute the CLI or REST deployment steps"
2 |
3 | anypoint-cli-v4 --version
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=targetless-cd
2 | artifactPrefix=0.0
3 |
4 | buildImage=cdaf/iis
5 | runtimeImage=cdaf/windows
6 |
--------------------------------------------------------------------------------
/samples/custom/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployScriptOverride
2 | local WINDOWS customDeploy.ps1
3 | local WORKGROUP customDeploy.ps1
4 |
--------------------------------------------------------------------------------
/samples/imageBuild-custom-image/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /index.html
3 | /manifest.txt
4 | /storeForLocal_manifest.txt
5 | /app/
6 | /imagebuild-*.zip
7 | /release.ps1
8 |
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/customLocal/properties.varchk:
--------------------------------------------------------------------------------
1 | NON_EXIST=optional
2 |
3 | # Verify variable is populated and log the checksum value
4 | HOME=secret
5 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/propertiesForRemoteTasks/WINDOWS_LOCALHOST_NTLM:
--------------------------------------------------------------------------------
1 | # Mandatory properties to land package on host
2 | deployHost=localhost
3 | deployLand=c:\deploy
4 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/customLocal/properties.varchk:
--------------------------------------------------------------------------------
1 | env:NON_EXIST=optional
2 |
3 | # Verify variable is populated and log the checksum value
4 | env:COMPUTERNAME=secret
5 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployTaskOverride
2 | container WINDOWS deploy.tsk
3 | container WORKGROUP deploy.tsk
4 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/propertiesForLocalTasks/WORKGROUP_LOCAL:
--------------------------------------------------------------------------------
1 | # Use the same process as loop-back connection (WINDOWS) but on the localhost
2 | deployTaskOverride=tasksRunRemote.tsk
3 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/propertiesForRemoteTasks/USER_PASSWORD_LOCALHOST:
--------------------------------------------------------------------------------
1 | # Mandatory properties to land package on host
2 | deployHost=localhost
3 | remoteUser=vagrant
4 | remotePass=vagrant
--------------------------------------------------------------------------------
/samples/log-image/solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target filename uri
2 | local WORKGROUP JPEG_example_flower.jpg https://upload.wikimedia.org/wikipedia/commons/3/3f/JPEG_example_flower.jpg
3 |
--------------------------------------------------------------------------------
/samples/minimal-build/solution.properties:
--------------------------------------------------------------------------------
1 | PROJECT=
2 | REVISION=feature
3 | AUTOMATIONROOT=/mnt/c/Users/jules/git/linux/automation
4 | SOLUTIONROOT=/mnt/c/Users/jules/git/linux/samples/minimal-build/automation-solution
5 |
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/customLocal/containerTest.tsk:
--------------------------------------------------------------------------------
1 | curl.exe --silent target
2 |
3 | $status = curl.exe --silent -w '%{http_code}' target -o output.log
4 | if ( $status -ne '200' ) { exit $status }
--------------------------------------------------------------------------------
/samples/containerBuild/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Container Build Sample
2 | solutionName=container-build-minimal
3 | artifactPrefix=0.0
4 |
5 | containerImage=cdaf/windows
6 | CDAF_DOCKER_REQUIRED=yes
7 |
--------------------------------------------------------------------------------
/samples/feature-branch-environments/automation-solution/feature-branch.properties:
--------------------------------------------------------------------------------
1 | # Separate environments for features and bugs
2 | feature=DEV1
3 | bugfix=DEV2
4 |
5 | # Hotfixes deploy to all environments
6 | hotfix=DEV1
7 | hotfix=DEV2
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Sample of Optional Processes
2 | solutionName=pre-post-processes
3 |
4 | artifactPrefix=0.0
5 | packageFeatures=minimal
6 |
7 | processSequence=localTasks.ps1
8 |
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Simple Build and Minimal Release Package Process
2 | solutionName=minimal-build
3 |
4 | artifactPrefix=0.0
5 | packageFeatures=minimal
6 |
7 | processSequence=localTasks.ps1
8 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | # Template Solution Properties file
2 | # If using symantic versioning, append build number at the end of version
3 | artifactPrefix=0.1
4 | productName=My Product Name
5 | solutionName=myProduct
6 |
--------------------------------------------------------------------------------
/samples/minimal/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Minimal Release Package
2 | solutionName=minimal-package
3 |
4 | artifactPrefix=0.0
5 | packageFeatures=minimal
6 | packageMethod=tarball
7 |
8 | processSequence=localTasks.ps1
9 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/wrap.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Post-package Tasks"
7 |
--------------------------------------------------------------------------------
/samples/custom/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Custom Build and Deployment Scripts
2 | solutionName=custom
3 |
4 | artifactPrefix=0.0
5 | packageFeatures=minimal
6 | packageMethod=tarball
7 |
8 | processSequence=localTasks.ps1
9 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/package.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Pre-package Tasks"
7 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/postbuild.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Post Build Tasks"
7 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/prebuild.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Pre-Build Tasks"
7 |
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployTaskOverride
2 | local DOCKER compose.tsk
3 | local WINDOWS compose.tsk
4 | local WORKGROUP compose.tsk
5 |
6 | local AUTO_TEST containerTest.tsk
7 |
--------------------------------------------------------------------------------
/orchestration/buildmaster/deploy:
--------------------------------------------------------------------------------
1 | ##AH:UseTextMode
2 |
3 |
4 | Deploy-Artifact TasksLocal
5 | (
6 | To: $WorkingDirectory
7 | );
8 |
9 | Execute-PowerShell >>cd $WorkingDirectory
10 | .\TasksLocal\delivery.bat $EnvironmentName >>;
11 |
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target literal zero integer var_load
2 | local WINDOWS "Hello WINDOWS" '0' 1 $env:USERNAME
3 | local WORKGROUP "Hello WORKGROUP" '0' 2 $env:USERNAME
4 |
--------------------------------------------------------------------------------
/samples/crypt/devops/custom/crypt-test.yml:
--------------------------------------------------------------------------------
1 | ---
2 | application:
3 | admin-password: "%secret1%"
4 | user-password: "@dbuserpassword@"
5 | database:
6 | target: "%deployHost%"
7 | user: "%dbreaderwriter%"
8 | password: "%secret2%"
9 |
--------------------------------------------------------------------------------
/samples/feature-branch-environments/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Deploying from Feature Branch Based on Branch Name
2 | solutionName=feature-branch-environments
3 |
4 | artifactPrefix=0.0
5 | packageFeatures=minimal
6 |
7 | processSequence=localTasks.ps1
8 |
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/build.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "PROJECT = $PROJECT"
3 | echo "SOLUTIONROOT = $SOLUTIONROOT"
4 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
5 | echo "CDAF_CORE = $CDAF_CORE"
6 |
7 | echo "Project Level Build"
8 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | _CDAF Github PowerShell
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/samples/feature-branch-environments/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target usage
2 | local LINUX "Default environment"
3 | local DEV1 "Feature branch environment for feature or hotfix branch"
4 | local DEV2 "Feature branch environment for bugfix or hotfix branch"
5 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/propertiesForRemoteTasks/VAGRANT_CERTIFICATE_DECRYPT:
--------------------------------------------------------------------------------
1 | # Mandatory properties to land package on host
2 | deployHost=windows-1.mshome.net
3 | deployLand=c:\deploy
4 | remoteUser=vagrant
5 | remoteCred=WINDOWS_PASSWORD
6 | decryptThb=1C5A22D1DA540F210122BB63EB8F38ABBBB9009A
7 |
--------------------------------------------------------------------------------
/automation/CDAF.windows:
--------------------------------------------------------------------------------
1 | # Do not make customisation or configuration changes in these folders, copy the solution folder
2 | # and apply configuration changes that are specific to your solution.
3 | productVersion=3.0.0.b
4 | productName=Continuous Delivery Automation Framework
5 | solutionName=WU-CDM
6 |
--------------------------------------------------------------------------------
/samples/feature-branch-environments/automation-solution/tasksRunLocal.tsk:
--------------------------------------------------------------------------------
1 | echo "In this example, only branch names containing 'feature', 'bugfix' or 'hotfix' will execute from etnry.sh,"
2 | echo "This configuration has no affect on cdEmulate execution."
3 |
4 | PROPLD manifest.txt
5 |
6 | echo "deploying branch name $REVISION to $TARGET"
7 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/Dockerfile:
--------------------------------------------------------------------------------
1 | # DOCKER-VERSION 1.2.0
2 | ARG CONTAINER_IMAGE
3 | FROM ${CONTAINER_IMAGE}
4 |
5 | WORKDIR /solution/workspace
6 |
7 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference = 'Continue';"]
8 |
9 | CMD ["Wait-Event"]
10 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
--------------------------------------------------------------------------------
/samples/crypt/devops/custom/properties.varchk:
--------------------------------------------------------------------------------
1 | env:NON_EXIST=optional
2 |
3 | # Verify variable is populated and log the checksum value
4 | env:AES_KEY=secret
5 |
6 | # Verify variable is populated, and the SHA256 matches, support literal or variable
7 | env:AES_KEY=90BF7460FFDFE121C41AAFDF6B7D33EB08ACD0736D8B0A0B461E595E32DE26F5
8 | env:AES_KEY=$env:AES_KEY_MASK
--------------------------------------------------------------------------------
/samples/log-image/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
--------------------------------------------------------------------------------
/samples/targetlessCD/.gitignore:
--------------------------------------------------------------------------------
1 | /cdaf/
2 | /TasksLocal/
3 | /TasksRemote/
4 | /projectDirectories.txt
5 | /manifest.txt
6 | /storeFor_manifest.txt
7 | /storeForLocal_manifest.txt
8 | /storeForRemote_manifest.txt
9 | /projectsToBuild.txt
10 | /propertiesForLocalTasks/
11 | /propertiesForRemoteTasks/
12 | /propertiesForContainerTasks/
13 | /release.ps1
14 | /*.zip
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
14 | /*.tar.gz
15 |
--------------------------------------------------------------------------------
/samples/containerDeploy/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
14 | /*.tar.gz
15 |
--------------------------------------------------------------------------------
/automation/remote/getProperty.ps1:
--------------------------------------------------------------------------------
1 | $PROP_FILE = $args[0]
2 | $PROP_NAME = $args[1]
3 |
4 | # Brute force property retrieval, comment lines are not explicitely ignored, simply omitted as they won't match the property name sought
5 | Foreach ($ROW in get-content $PROP_FILE) {
6 | $test = $ROW -split '=', 2
7 | if ( $test[0] -eq $PROP_NAME ) {
8 | return $test[1]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/samples/custom/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
14 | /*.tar.gz
15 | /runtime.ps1
16 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
14 | /*.tar.gz
15 |
--------------------------------------------------------------------------------
/automation/Readme.md:
--------------------------------------------------------------------------------
1 | # Continuous Delivery Automation Framework (CDAF)
2 |
3 | For principles and usage guidance see [https://cdaf.io](https://cdaf.io/10-cdaf/index.html).
4 |
5 | For the complete set of samples and provisioning helpers, see [GitHub](https://github.com/cdaf/windows).
6 |
7 | For related blog, see [LinkedIn articles](https://www.linkedin.com/in/jules-clements-842b589/recent-activity/articles/).
8 |
--------------------------------------------------------------------------------
/samples/feature-branch-environments/.gitignore:
--------------------------------------------------------------------------------
1 | /TasksLocal/
2 | /TasksRemote/
3 | /projectDirectories.txt
4 | /manifest.txt
5 | /storeFor_manifest.txt
6 | /storeForLocal_manifest.txt
7 | /storeForRemote_manifest.txt
8 | /projectsToBuild.txt
9 | /propertiesForLocalTasks/
10 | /propertiesForRemoteTasks/
11 | /propertiesForContainerTasks/
12 | /release.ps1
13 | /*.zip
14 | /*.tar.gz
15 | /runtime.ps1
16 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/custom/slack.ps1:
--------------------------------------------------------------------------------
1 | Add-Type -AssemblyName System.Net.Http
2 | $http = New-Object -TypeName System.Net.Http.Httpclient
3 | $message = "Hello world."
4 | $httpMessage = "{""text"": """ + $message + """}";
5 | $content = New-Object -TypeName System.Net.Http.StringContent($httpMessage)
6 | $httpResult = $http.PostAsync("https://hooks.slack.com/services/your_channel_url_here", $content).Result
7 |
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Container Build Sample
2 | solutionName=container-build
3 | artifactPrefix=0.0
4 |
5 | containerBuild=& ${AUTOMATIONROOT}/processor/containerBuild.ps1 $SOLUTION $BUILDNUMBER $REVISION $ACTION
6 | containerImage=cdaf/windows
7 | CDAF_DOCKER_REQUIRED=yes
8 |
9 | packageFeatures=minimal
10 |
11 | processSequence=localTasks.ps1
12 |
--------------------------------------------------------------------------------
/samples/minimal-build/build.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Solution Level Build"
7 |
8 | echo '---' > example.yaml
9 | echo ' application:' >> example.yaml
10 | echo ' message: "%literal%"' >> example.yaml
11 | echo ' secret: "@secret@"' >> example.yaml
12 | cat example.yaml
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | [](https://www.gnu.org/licenses/lgpl-3.0)
2 | [](http://cdaf.io)
3 |
4 | # Continuous Delivery Automation Framework for Windows
5 |
6 | For published documentation see https://docs.cdaf.io/
7 |
8 | For core product see automation directory and see also samples directory for some patterns.
9 |
10 |
--------------------------------------------------------------------------------
/orchestration/buildmaster/build:
--------------------------------------------------------------------------------
1 | ##AH:UseTextMode
2 |
3 |
4 | Git::Get-Source
5 | (
6 | Credentials: Bonobo,
7 | DiskPath: $WorkingDirectory
8 | );
9 |
10 | Execute-PowerShell >>cd $WorkingDirectory
11 | .\automation\ci.bat $BuildNumber>>;
12 |
13 | Create-Artifact Package
14 | (
15 | Include: *.zip
16 | );
17 |
18 | Create-Artifact TasksLocal
19 | (
20 | Include: "TasksLocal/**"
21 | );
22 |
--------------------------------------------------------------------------------
/samples/minimal-build/.gitignore:
--------------------------------------------------------------------------------
1 | /buildnumber.counter
2 | /TasksLocal/
3 | /TasksRemote/
4 | /targetList
5 | /projectDirectories.txt
6 | /manifest.txt
7 | /storeFor_manifest.txt
8 | /storeForLocal_manifest.txt
9 | /storeForRemote_manifest.txt
10 | /projectsToBuild.txt
11 | /propertiesForLocalTasks/
12 | /propertiesForRemoteTasks/
13 | /propertiesForContainerTasks/
14 | /*.gz
15 | /release.ps1
16 | /example.yaml
17 |
18 | /minimal-build-*
19 |
--------------------------------------------------------------------------------
/samples/pre-post-processes/automation-solution/build.tsk:
--------------------------------------------------------------------------------
1 | echo "REVISION = $REVISION"
2 | echo "SOLUTIONROOT = $SOLUTIONROOT"
3 | echo "AUTOMATIONROOT = $AUTOMATIONROOT"
4 | echo "CDAF_CORE = $CDAF_CORE"
5 |
6 | echo "Solution Level Build"
7 |
8 | echo '---' > example.yaml
9 | echo ' application:' >> example.yaml
10 | echo ' message: "%literal%"' >> example.yaml
11 | echo ' secret: "@secret@"' >> example.yaml
12 | cat example.yaml
--------------------------------------------------------------------------------
/samples/all/readme.md:
--------------------------------------------------------------------------------
1 | # All CDAF Core Features
2 |
3 | To avoid execution of Remote Tasks
4 |
5 | $env:CDAF_DELIVERY='WORKGROUP'
6 |
7 | To execute Remote Tasks, configure remote loop-back access to teh localhost.
8 |
9 | ..\..\automation\provisioning\mkdir.ps1 C:\deploy
10 | ..\..\automation\provisioning\CredSSP.ps1 server
11 |
12 | ..\..\automation\provisioning\trustedHosts.ps1 *
13 | ..\..\automation\provisioning\CredSSP.ps1 client
--------------------------------------------------------------------------------
/automation/.gitignore:
--------------------------------------------------------------------------------
1 | # CDAF Working Files
2 | /TasksLocal/
3 | /TasksRemote/
4 | /projectDirectories.txt
5 | /manifest.txt
6 | /storeFor_manifest.txt
7 | /storeForLocal_manifest.txt
8 | /storeForRemote_manifest.txt
9 | /projectsToBuild.txt
10 | /propertiesForLocalTasks/
11 | /propertiesForRemoteTasks/
12 | /propertiesForContainerTasks/
13 | /release.ps1
14 | /*.zip
15 | /*.tar.gz
16 | /bin/
17 |
18 | # Exclude CDAF Copy for containerBuild process
19 | # /automation/
--------------------------------------------------------------------------------
/samples/containerDeploy/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployTaskOverride filename uri
2 | container WINDOWS deploy.tsk JPEG_example_flower.jpg https://upload.wikimedia.org/wikipedia/commons/3/3f/JPEG_example_flower.jpg
3 | container WORKGROUP deploy.tsk JPEG_example_flower.jpg https://upload.wikimedia.org/wikipedia/commons/3/3f/JPEG_example_flower.jpg
4 |
--------------------------------------------------------------------------------
/samples/crypt/.gitignore:
--------------------------------------------------------------------------------
1 | # CDAF Working Files
2 | /TasksLocal/
3 | /TasksRemote/
4 | /projectDirectories.txt
5 | /manifest.txt
6 | /storeFor_manifest.txt
7 | /storeForLocal_manifest.txt
8 | /storeForRemote_manifest.txt
9 | /projectsToBuild.txt
10 | /propertiesForLocalTasks/
11 | /propertiesForRemoteTasks/
12 | /propertiesForContainerTasks/
13 | /release.ps1
14 | /*.zip
15 | /*.tar.gz
16 | /bin/
17 |
18 | # Exclude CDAF Copy for containerBuild process
19 | # /automation/
--------------------------------------------------------------------------------
/samples/crypt/devops/.gitignore:
--------------------------------------------------------------------------------
1 | # CDAF Working Files
2 | /TasksLocal/
3 | /TasksRemote/
4 | /projectDirectories.txt
5 | /manifest.txt
6 | /storeFor_manifest.txt
7 | /storeForLocal_manifest.txt
8 | /storeForRemote_manifest.txt
9 | /projectsToBuild.txt
10 | /propertiesForLocalTasks/
11 | /propertiesForRemoteTasks/
12 | /propertiesForContainerTasks/
13 | /release.ps1
14 | /*.zip
15 | /*.tar.gz
16 | /bin/
17 |
18 | # Exclude CDAF Copy for containerBuild process
19 | # /automation/
--------------------------------------------------------------------------------
/samples/minimal-build/automation-solution/tasksRunLocal.tsk:
--------------------------------------------------------------------------------
1 | echo "Minimum function checklist"
2 | VARCHK
3 |
4 | echo "Load a property file to memory"
5 | PROPLD manifest.txt
6 |
7 | echo "Display a resolved variable"
8 | ASSIGN $username = "$var_load"
9 |
10 | echo "Detokenise a setting file"
11 | DETOKN example.yaml
12 |
13 | echo "Detokenise setting file using environment variable"
14 | REPLAC example.yaml @secret@ $HOME
15 |
16 | echo "In a real pipeline, can rely on secret masking"
17 | cat example.yaml
18 |
--------------------------------------------------------------------------------
/provisioning/readme.md:
--------------------------------------------------------------------------------
1 | Atomic Provisioning
2 | ===================
3 | The intention of these provisioning scripts is that they are self container with minimal dependancies, i.e. can be executed on a clean OS.
4 |
5 | Interactive Provisioning
6 | ------------------------
7 |
8 | Role Installers cannot be run via remote powershell without spawning a new window. If running on the local machine and logging capture is desired, set the following environment variable.
9 |
10 | [Environment]::SetEnvironmentVariable('interactive', 'true')
--------------------------------------------------------------------------------
/samples/targetlessCD/compose/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | target:
4 | image: "${TARGET_TAG}"
5 | environment:
6 | - MICRO_LISTEN_PORT=${MICRO_LISTEN_PORT}
7 |
8 | test:
9 | image: "${TEST_TAG}"
10 | volumes:
11 | - ${WORK_SPACE}:c:/solution/workspace
12 | depends_on:
13 | - target
14 |
15 | # For binding to existing networks by name, without this a default NAT will be created
16 | #networks:
17 | # default:
18 | # name: nat
19 | # external: true
20 |
--------------------------------------------------------------------------------
/samples/custom/automation-solution/tasksRunLocal.tsk:
--------------------------------------------------------------------------------
1 | echo "Minimum function checklist"
2 | VARCHK
3 |
4 | echo "Load a property file to memory`n"
5 | PROPLD manifest.txt
6 |
7 | echo "Display a resolved variable`n"
8 | ASSIGN $username = "$var_load"
9 |
10 | echo "Detokenise a setting file`n"
11 | DETOKN example.yaml
12 |
13 | echo "Detokenise setting file using environment variable`n"
14 | REPLAC example.yaml @secret@ $env:COMPUTERNAME
15 |
16 | echo "In a real pipeline, can rely on secret masking`n"
17 | cat example.yaml
18 |
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/customLocal/Dockerfile:
--------------------------------------------------------------------------------
1 | # DOCKER-VERSION 1.2.0
2 | ARG CONTAINER_IMAGE
3 | FROM ${CONTAINER_IMAGE}
4 |
5 | # Create root, i.e. C:\solution
6 | WORKDIR /solution
7 |
8 | # Shared bootstrap between Docker and Vagrant
9 | COPY bootstrapTarget.ps1 .
10 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
11 | RUN ./bootstrapTarget.ps1
12 |
13 | # Change workdir to an new (empty) folder for volume mount to work
14 | WORKDIR /solution/workspace
15 |
--------------------------------------------------------------------------------
/samples/targetlessCD/compose/test/Dockerfile:
--------------------------------------------------------------------------------
1 | # DOCKER-VERSION 1.2.0
2 | ARG CONTAINER_IMAGE
3 | FROM ${CONTAINER_IMAGE}
4 |
5 | # Create root, i.e. C:\solution
6 | WORKDIR /solution
7 |
8 | # Place entry script
9 | COPY executeTest.ps1 .
10 |
11 | # Change workdir to an new (empty) folder for volume mount to work
12 | WORKDIR /solution/workspace
13 |
14 | # Unlike the web server, this container is transient, and does not build the wrapper into the image, instead this relies of the volume mount
15 | CMD ["powershell", "-Command", "../executeTest.ps1", "AUTO_TEST"]
--------------------------------------------------------------------------------
/orchestration/bamboo-specs/v1/bamboo.yml:
--------------------------------------------------------------------------------
1 | ---
2 | project:
3 | key: YOUREXISTINGPROJECTKEY
4 | plan:
5 | key: NEW
6 | name: The New Key Must be 3 characters
7 | stages:
8 | - jobs:
9 | - scripts:
10 | - "automation\\processor\\buildPackage.bat ${bamboo.buildNumber} ${bamboo.repository.branch.name}"
11 | interpreter: cmd.exe
12 | # requirements:
13 | # - container
14 | artifacts:
15 | - name: Package
16 | path: '*.zip'
17 | - name: TasksLocal
18 | path: 'TasksLocal/**'
19 |
--------------------------------------------------------------------------------
/samples/imageBuild/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=imagebuild-minimal
2 | artifactPrefix=0.1
3 |
4 | buildImage=cdaf/windows
5 | CDAF_DOCKER_REQUIRED=yes
6 |
7 | # Base Image from Private Registry
8 | # CDAF_PULL_REGISTRY_URL=registry.gitlab.com
9 | # CDAF_PULL_REGISTRY_USER=.
10 | # CDAF_PULL_REGISTRY_TOKEN=$env:GITLAB_REGISTRY_PAT
11 |
12 | # push to registry (exclude URL for DockerHub)
13 | # CDAF_REGISTRY_URL=myregistry.io/repo
14 | # CDAF_REGISTRY_TAG=latest ${CDAF_REGISTRY_URL}/${SOLUTION}:$BUILDNUMBER
15 | # CDAF_REGISTRY_USER=.
16 | # CDAF_REGISTRY_TOKEN=${ACCESS_TOKEN}
17 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/containerDeploy/settings.xml:
--------------------------------------------------------------------------------
1 |
5 | /solution/home/.m2/repository
6 |
7 |
8 | apis
9 | datacom-group
10 | ${ado.pat}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/samples/containerDeploy/automation-solution/customRemote/deploy.tsk:
--------------------------------------------------------------------------------
1 | echo "Here we execute the CLI or REST deployment steps, or perhaps execute tests."
2 | echo "Note: the user home is mounted to deployment container."
3 |
4 | echo "`$RELEASE = $RELEASE"
5 | echo "`$OPT_ARG = $OPT_ARG"
6 | echo "`$env:ENVIRONMENT = $env:ENVIRONMENT"
7 |
8 | echo "Download an image"
9 | curl.exe -s -O "$uri"
10 |
11 | echo "Write image to Log"
12 | IMGTXT $filename
13 |
14 | echo "Do not exit as variable not set"
15 | EXITIF $NOT_SET
16 |
17 | echo "`nControlled Exit"
18 | EXITIF $RELEASE Release
19 |
20 | echo "THIS LINE SHOULD NOT EXECUTE"
21 | exit 666
22 |
--------------------------------------------------------------------------------
/samples/imageBuild-custom-image/automation-solution/customLocal/Dockerfile:
--------------------------------------------------------------------------------
1 | # escape=`
2 | ARG CONTAINER_IMAGE
3 | FROM ${CONTAINER_IMAGE}
4 |
5 | # Shared bootstrap between Docker and Vagrant
6 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
7 | RUN base.ps1 netfx-4.8-devpack
8 |
9 | # If not using the CDAF base image
10 | # RUN curl.exe -fsO "https://raw.githubusercontent.com/cdaf/windows/refs/heads/master/provisioning/base.ps1"
11 | # RUN ./base.ps1 netfx-4.8-devpack
12 |
13 | # Normal containers run a console application, this is just keeps the container from stopping
14 | CMD ["Wait-Event"]
15 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/properties.cm:
--------------------------------------------------------------------------------
1 | context target literal zero integer var_load csv list null_var empty_var
2 | local WINDOWS "Hello World" '0' 3 $env:EXAMPLE_SECRET_2 value1,value2,value3 $csv $null ''
3 | local WORKGROUP "Hello World" '0' 4 $env:EXAMPLE_SECRET_2 valueA,valueB,valueC $csv $null ''
4 | remote VAGRANT_CERTIFICATE_DECRYPT "Hello World" '0' 5 $env:EXAMPLE_SECRET_2 valueA,valueB,valueC $csv $null ''
5 | local VAGRANT_LOCAL "Hello World" '0' 6 $env:EXAMPLE_SECRET_2 valueA,valueB,valueC $csv $null ''
6 |
--------------------------------------------------------------------------------
/provisioning/trustedHosts.ps1:
--------------------------------------------------------------------------------
1 |
2 | $scriptName = 'trustedHosts.ps1'
3 | Write-Host "`n[$scriptName] ---------- start ----------"
4 | $trustedHosts = $args[0]
5 |
6 | # Output File (plain text or XML depending on method) must be supplioed
7 | if ($trustedHosts) {
8 | Write-Host "[$scriptName] trustedHosts : $trustedHosts"
9 | } else {
10 | Write-Host "[$scriptName] trustedHosts not passed! Exiting"; exit 100
11 | }
12 |
13 | Write-Host "`n[$scriptName] Add the trustedHosts ($trustedHosts) as a trusted hosts for Remote Powershell"
14 | Set-WSManInstance -ResourceURI winrm/config/client -ValueSet @{TrustedHosts=$trustedHosts}
15 |
16 | Write-Host "`n[$scriptName] ---------- stop -----------`n"
17 | exit 0
--------------------------------------------------------------------------------
/samples/crypt/devops/properties.cm:
--------------------------------------------------------------------------------
1 | context target deployHost zero integer dbreaderwriter dbuserpassword remoteUser remotePass
2 | remote VAGRANT windows-1.mshome.net '0' 1 databaseuser $env:USERNAME $env:CDAF_PS_USERNAME $env:CDAF_PS_USERPASS
3 | local VAGRANT $env:COMPUTERNAME '0' 2 databaseuser $env:USERNAME
4 | local WINDOWS $env:COMPUTERNAME '0' 3 databaseuser $env:USERNAME
5 | local WORKGROUP $env:COMPUTERNAME '0' 4 databaseuser $env:USERNAME
6 | local TEST test.mshome.net '0' 5 databaseuser $env:USERNAME
7 | local PROD prod.mshome.net '0' 6 databaseuser $env:USERNAME
--------------------------------------------------------------------------------
/samples/imageBuild-custom-image/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=imagebuild
2 | artifactPrefix=0.1
3 |
4 | buildImage=docker.io/cdaf/windows:latest
5 | imageBuild=& "$AUTOMATIONROOT/remote/imageBuild.ps1" ${SOLUTION}_${REVISION} ${BUILDNUMBER} ${buildImage} ${LOCAL_WORK_DIR}
6 | CDAF_DOCKER_REQUIRED=yes
7 |
8 | # Base Image from Private Registry
9 | # CDAF_PULL_REGISTRY_URL=registry.gitlab.com
10 | # CDAF_PULL_REGISTRY_USER=.
11 | # CDAF_PULL_REGISTRY_TOKEN=$env:GITLAB_REGISTRY_PAT
12 |
13 | # push to registry (exclude URL for DockerHub)
14 | # CDAF_REGISTRY_URL=myregistry.io/repo
15 | # CDAF_REGISTRY_TAG=${CDAF_REGISTRY_URL}/${SOLUTION}:$BUILDNUMBER
16 | # CDAF_REGISTRY_USER=.
17 | # CDAF_REGISTRY_TOKEN=${ACCESS_TOKEN}
18 |
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/Readme.md:
--------------------------------------------------------------------------------
1 | # Container Build
2 |
3 | This example highlights how a self-hosted build server can use containers to perform isolated builds. This method supports mutually exclusive requirements such as .NET, Java or NodeJS.
4 |
5 | This also enables the developer to codify their build dependencies, via the provisioning script (bootstrapAgent.ps1).
6 |
7 | ## Image Build
8 |
9 | An image is built each time CDAF is run and tagged with build number, the previous version(s) are deleted.
10 |
11 | ## Container Run
12 |
13 | A container is instantiated from the image, with two volume mounts, one for the workspace and another for the user home. The user home mount allows for persisting data between builds, such as Maven cache or dotnet packages.
14 |
--------------------------------------------------------------------------------
/provisioning/runner.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo.
3 | echo [%~nx0] ------------------------
4 | echo [%~nx0] PowerShell Script Runner
5 | echo [%~nx0] ------------------------
6 |
7 | rem Launcher script that overides execution policy
8 | rem cannot elevate powershell
9 |
10 | set "back=\"
11 | set "command=%cd%%back%%1"
12 |
13 | echo %command% %2 %3 %4 %5 %6 %7 %8 %9
14 |
15 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%command%'" "'%2'" "'%3'" "'%4'" "'%5'" "'%6'" "'%7'" "'%8'" "'%9'"
16 | set result=%errorlevel%
17 | if %result% NEQ 0 (
18 | echo.
19 | echo [%~nx0] call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command & %command% %2 %3 %4 %5 %6 %7 %8 %9 failed!
20 | echo [%~nx0] Errorlevel = %result%
21 | exit /b %result%
22 | )
23 |
--------------------------------------------------------------------------------
/automation/local/push.ps1:
--------------------------------------------------------------------------------
1 | # The API Key needs to be obtained from the NuGet server to all package push without prompting for credentials
2 | $PACK_LOC = $args[0]
3 | $API_KEY_FILE = $args[1]
4 | $NUGET_URL = $args[2]
5 |
6 | $exitStatus = 0
7 |
8 | $scriptName = $MyInvocation.MyCommand.Name
9 | $userName = [Environment]::UserName
10 |
11 | Write-Host " PACK_LOC = $PACK_LOC"
12 | Write-Host " API_KEY_FILE = $API_KEY_FILE"
13 | Write-Host " NUGET_URL = $NUGET_URL"
14 |
15 | $secure = Get-Content $API_KEY_FILE | ConvertTo-SecureString
16 | $plain = (New-Object System.Management.Automation.PSCredential 'N/A', $secure).GetNetworkCredential().Password
17 |
18 | # Assumes the package location is cleaned and there will be only one eligable
19 | NuGet.exe push $PACK_LOC\*.nupkg -ApiKey $plain -Source $NUGET_URL
20 |
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/Dockerfile:
--------------------------------------------------------------------------------
1 | # escape=`
2 | # Allow override of image as environment variable
3 | ARG CONTAINER_IMAGE=docker.io/cdaf/linux:windows
4 | FROM ${CONTAINER_IMAGE}
5 |
6 | # Create root, i.e. C:\solution
7 | WORKDIR /solution
8 |
9 | # Shared bootstrap between Docker and Vagrant
10 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
11 | RUN base.ps1 netfx-4.8-devpack
12 |
13 | # If not using the CDAF base image
14 | # RUN curl.exe -fsO "https://raw.githubusercontent.com/cdaf/windows/refs/heads/master/provisioning/base.ps1"
15 | # RUN ./base.ps1 netfx-4.8-devpack
16 |
17 | # Change workdir to the mapped folder so that the build artefacts are available on the host
18 | WORKDIR /solution/workspace
19 |
20 | CMD ci
21 |
--------------------------------------------------------------------------------
/samples/containerDeploy/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Container Deployment
2 | solutionName=container-deploy
3 | artifactPrefix=0.0
4 |
5 | # containerImage used for both containerBuild and containerDeploy if runtimeImage not specified
6 | # containerImage=mcr.microsoft.com/windows/server:ltsc2022
7 | runtimeImage=cdaf/windows
8 |
9 | processSequence=containerTasks.ps1
10 |
11 | # Use non-default image build location, compose/test instead of containerDeploy, note when using a custom directory, this must be included in the storeFor or storeForLocal definition
12 | # containerDeploy=& ${WORK_DIR_DEFAULT}/containerDeploy.ps1 "${TARGET}" "${RELEASE}" "${SOLUTION}" "${BUILDNUMBER}" "${REVISION}" -imageDir compose/test
13 |
14 | # containerDeploy files, can be space separated list
15 | # runtimeFiles=$WORKSPACE_ROOT\release.ps1
16 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/automation-solution/CDAF.solution:
--------------------------------------------------------------------------------
1 | productName=Container Deployment
2 | solutionName=container-deploy
3 | artifactPrefix=0.0
4 |
5 | # containerImage used for both containerBuild and containerDeploy if runtimeImage not specified
6 | # containerImage=mcr.microsoft.com/windows/server:ltsc2022
7 | runtimeImage=cdaf/windows
8 |
9 | processSequence=containerTasks.ps1
10 |
11 | # Use non-default image build location, compose/test instead of containerDeploy, note when using a custom directory, this must be included in the storeFor or storeForLocal definition
12 | # containerDeploy=& ${WORK_DIR_DEFAULT}/containerDeploy.ps1 "${TARGET}" "${RELEASE}" "${SOLUTION}" "${BUILDNUMBER}" "${REVISION}" -imageDir compose/test
13 |
14 | # Include deployable release for feedback loop
15 | runtimeFiles=$WORKSPACE_ROOT\release.ps1
16 |
--------------------------------------------------------------------------------
/provisioning/removeFile.ps1:
--------------------------------------------------------------------------------
1 |
2 | $scriptName = 'removeFile.ps1'
3 | Write-Host "`n[$scriptName] Primarily for removing large media files after install"
4 | Write-Host "`n[$scriptName] ---------- start ----------"
5 | $fileToRemove = $args[0]
6 | if ($fileToRemove) {
7 | Write-Host "[$scriptName] fileToRemove : $fileToRemove"
8 | } else {
9 | Write-Host "[$scriptName] fileToRemove not supplied! Exit with `$LASTEXITCODE 1"
10 | exit 1
11 | }
12 |
13 | if ( Test-Path $fileToRemove ) {
14 | write-host "[itemRemove] Delete $fileToRemove"
15 | Remove-Item $fileToRemove -Recurse -Force
16 | if(!$?) {
17 | Write-Host "[$scriptName] DELETE_EXCEPTION Remove-Item $fileToRemove -Recurse -Force"
18 | Write-Host "[$scriptName] Exit with `$LASTEXITCODE 2"
19 | exit 2
20 | }
21 | }
22 |
23 | Write-Host "`n[$scriptName] ---------- stop ----------"
24 |
--------------------------------------------------------------------------------
/automation/remote/extract.ps1:
--------------------------------------------------------------------------------
1 | Add-Type -AssemblyName System.IO.Compression.FileSystem
2 |
3 | $packagePath = $args[0]
4 | $packageFile = $args[1]
5 |
6 | $scriptName = "extract.ps1"
7 |
8 | [System.IO.Compression.ZipFile]::ExtractToDirectory("$packagePath\$packageFile.zip", "$packagePath\$packageFile")
9 | $exitcode = $LASTEXITCODE
10 | if ( $exitcode -gt 0 ) {
11 |
12 | Write-Host
13 | Write-Host "[$scriptName (remote)] Package Extraction (Zip) failed with exit code = $exitcode" -ForegroundColor Red
14 | throw "Package Extraction (Zip) failed with exit code = $exitcode"
15 |
16 | } else {
17 |
18 | foreach ($item in (Get-ChildItem -Path $packagePath\$packageFile)) {
19 | Write-Host "[$scriptName (remote)] --> $item"
20 | }
21 |
22 | Write-Host
23 | Write-Host "[$scriptName (remote)] Package Extraction Successful" -ForegroundColor Green
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/samples/targetlessCD/readme.md:
--------------------------------------------------------------------------------
1 | # Targetless CD
2 |
3 | > Can only be executed on Windows Server 2022 or Windows 11
4 |
5 | Execute function test without deploying a target, instead, perform test in docker-compose environment.
6 |
7 | This leverages two key featues of imageBuild
8 |
9 | ## Post Build & Package Image Build
10 |
11 | Triggered from the CDAF.solution property
12 |
13 | buildImage=docker.io/library/python:latest
14 |
15 | This launches the default construction process. After the Build and Package is complete, the customer Dockerfile is placed in Taskslocal, this is used to construct the deliverable image.
16 |
17 | ## Build All Images
18 |
19 | At deploy time, the `compose.tsk` calls imageBuild without specifying an image or constructor, this triggers a build of each subdirectory
20 |
21 | ### Default Image
22 |
23 | A base image is not supplied, so `dockerBuild` will attempt to derive from the `runtimeImage` property.
24 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/containerDeploy/Dockerfile:
--------------------------------------------------------------------------------
1 | # DOCKER-VERSION 1.2.0
2 | ARG CONTAINER_IMAGE
3 | FROM ${CONTAINER_IMAGE}
4 |
5 | # Copy solution, provision and then build
6 | WORKDIR /solution
7 |
8 | ENV CDAF_INSTALL_PATH 'c:\cdaf'
9 |
10 | # Provision Build Dependancies, configure Maven cache to use host user profile volume mount
11 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
12 | COPY bootstrapAgent.ps1 .
13 | RUN .\bootstrapAgent.ps1 anypoint-cli-v4
14 |
15 | COPY properties/* /solution/deploy/
16 | COPY release.ps1 .
17 | COPY deploy.zip .
18 | RUN powershell -Command Expand-Archive deploy.zip
19 |
20 | # Unlike containerBuild the workspace is not volume mounted, this replicates what the remote deploy process does leaving the image ready to run
21 | WORKDIR /solution/deploy
22 | CMD ["./deploy.ps1", "${ENVIRONMENT}"]
23 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Continuous Delivery Automation Framework (CDAF)
2 | ===============================================
3 |
4 | License for use and distribution
5 | --------------------------------
6 |
7 | CDAF is distributed under the GNU LGPL license
8 |
9 | GNU LGPL information
10 | --------------------
11 |
12 | This library is free software; you can redistribute it and/or
13 | modify it under the terms of the GNU Lesser General Public
14 | License as published by the Free Software Foundation; either
15 | version 2.1 of the License, or (at your option) any later version.
16 |
17 | This library is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 | Lesser General Public License for more details.
21 |
22 | You can receive a copy of the GNU Lesser General Public License from
23 | http://www.gnu.org/
24 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/custom/example.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | application:
3 | message: "%literal%"
4 | zero: "%zero%"
5 | integer: "%integer%"
6 | var: "%var_load%"
7 | list_var: "%list%"
8 | list_csv: "%csv%"
9 | empty_var: "%empty_var%"
10 | null_var: "%null_var%"
11 |
12 | ad_hoc_resolved: "@secret@"
13 |
14 | message_resolved: "@literal@"
15 | zero_resolved: "@zero@"
16 | integer_resolved: "@integer@"
17 | var_resolved: "@var_load@"
18 | list_var_resolved: "@list@"
19 | list_csv_resolved: "@csv@"
20 | empty_var_resolved: "@empty_var@"
21 | null_var_resolved: "@null_var@"
22 |
23 | message_revealed: "!literal!"
24 | zero_revealed: "!zero!"
25 | integer_revealed: "!integer!"
26 | var_revealed: "!var_load!"
27 | list_var_revealed: "!list!"
28 | list_csv_revealed: "!csv!"
29 | empty_var_revealed: "!empty_var!"
30 | null_var_revealed: "!null_var!"
31 |
--------------------------------------------------------------------------------
/automation/cdEmulate.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | cmd /c "exit 0"
3 |
4 | rem Too complicated to derive automation root from Batch runner, so hard coded for windows.
5 | set ACTION=%1
6 |
7 | echo.
8 | echo [%~nx0] --------------------
9 | echo [%~nx0] Initialise Emulation
10 | echo [%~nx0] --------------------
11 |
12 | for %%Q in ("%~dp0\.") DO set "AUTOMATIONROOT=%%~fQ"
13 |
14 | rem Launcher script that overides execution policy
15 | rem cannot elevate powershell
16 |
17 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%AUTOMATIONROOT%\processor\cdEmulate.ps1'" "'%ACTION%'"
18 | set result=%errorlevel%
19 | if %result% NEQ 0 (
20 | echo [%~nx0] ERROR call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %AUTOMATIONROOT%\processor\cdEmulate.ps1 %ACTION%
21 | echo [%~nx0] Return LASTEXITCODE %result%
22 | echo.
23 | echo [%~nx0] --- End Emulation Error Handling ---
24 | echo.
25 | exit /b %result%
26 | )
27 |
--------------------------------------------------------------------------------
/automation/remote/deploy.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo [%~nx0] ExecutionPolicy ByPass ...
3 |
4 | echo.
5 | echo [%~nx0] ------------------------------------
6 | echo [%~nx0] Remote Execution Policy Override
7 | echo [%~nx0] ------------------------------------
8 |
9 | rem Launcher script that overides execution policy
10 | rem cannot elevate powershell
11 |
12 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%cd%\%WORK_DIR_DEFAULT%\executeTasks.ps1'" "'%1'" "'%2'" "'%3'"
13 | set result=%errorlevel%
14 | if %result% NEQ 0 (
15 | echo.
16 | echo [%~nx0] CDAF_DELIVERY_FAILURE call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %cd%\%WORK_DIR_DEFAULT%\executeTasks.ps1 %1 %2 %3
17 | echo [%~nx0] Return LASTEXITCODE %result%
18 | exit /b %result%
19 | )
20 |
21 | echo.
22 | echo [%~nx0] ------------------------------------
23 | echo [%~nx0] Deployment Complete
24 | echo [%~nx0] ------------------------------------
25 |
--------------------------------------------------------------------------------
/automation/remote/push.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo [%0] Push to NuGet URL ...
3 |
4 | set PACKAGE_LOC=%1
5 | set KEY_FILE=%2
6 | set URL=%3
7 | echo.
8 | echo [%~nx0] ------------------
9 | echo [%~nx0] Local Process
10 | echo [%~nx0] ------------------
11 | echo [%~nx0] PACKAGE_LOC : %PACKAGE_LOC%
12 | echo [%~nx0] KEY_FILE : %KEY_FILE%
13 | echo [%~nx0] URL : %URL%
14 |
15 | rem Launcher script that overides execution policy
16 | rem cannot elevate powershell
17 |
18 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%cd%\%WORK_DIR_DEFAULT%\automation\local\push.ps1'" "'%PACKAGE_LOC%'" "'%KEY_FILE%'" "'%URL%'"
19 | set result=%errorlevel%
20 | if %result% NEQ 0 (
21 | echo.
22 | echo [%~nx0] Error %result% returned from ...
23 | echo [%~nx0] call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %cd%\%WORK_DIR_DEFAULT%\automation\local\push.ps1 %PACKAGE_LOC% %KEY_FILE% %URL%
24 | echo [%~nx0] Errorlevel = %result%
25 | exit /b %result%
26 | )
27 |
--------------------------------------------------------------------------------
/provisioning/EnableFileAndPrintSharing.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "$expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
11 | }
12 |
13 | $scriptName = 'EnableFileAndPrintSharing.ps1'
14 | Write-Host "`n[$scriptName] ---------- start ----------"
15 |
16 | executeExpression "DISM /Online /Enable-Feature /FeatureName:File-Services /All"
17 | executeExpression "netsh advfirewall firewall set rule group='File and Printer Sharing' new enable=Yes"
18 |
19 | Write-Host "`n[$scriptName] ---------- stop ----------"
20 | exit 0
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/templates/azure-pipelines-dockerhub-template.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - deployment: Deploy
3 | displayName: ${{ parameters.displayName }}
4 | environment: ${{ parameters.environment }}
5 | pool:
6 | vmImage: windows-latest
7 | # pool:
8 | # name: Self-hosted Pool Name
9 | strategy:
10 | runOnce:
11 | deploy:
12 | steps:
13 | - task: DownloadBuildArtifacts@0
14 | displayName: Download the build artifacts
15 | inputs:
16 | buildType: current
17 | downloadType: single
18 | artifactName: drop
19 |
20 | - task: PowerShell@2
21 | displayName: CDAF Release Package
22 | env:
23 | DOCKERHUB_TOKEN: $(DOCKERHUB_TOKEN)
24 | inputs:
25 | workingDirectory: $(System.ArtifactsDirectory)/drop
26 | targetType: filePath
27 | filePath: ./release.sh
28 | arguments: ${{ parameters.environment }}
29 |
--------------------------------------------------------------------------------
/provisioning/nextFreePort.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [int]$localPort
3 | )
4 |
5 | $scriptName = 'nextFreePort.ps1'
6 | cmd /c "exit 0"
7 |
8 | # Use the CDAF provisioning helpers
9 | Write-Host "`n[$scriptName] ---------- start ----------"
10 | Write-Host "[$scriptName] localPort : $localPort`n"
11 |
12 | while ($localPort -lt 65535) {
13 | if ( Get-NetUDPEndpoint | Where LocalPort -eq $localPort ) {
14 | Write-Host "[$scriptName] $localPort is use for UDP"
15 | $localPort += 1
16 | } else {
17 | if (Get-NetTCPConnection | Where LocalPort -eq $localPort ) {
18 | Write-Host "[$scriptName] $localPort is use for TCP"
19 | $localPort += 1
20 | } else {
21 | Write-Host "[$scriptName] free port is $localPort"
22 | Write-Host "`n[$scriptName] ---------- finish ----------"
23 | return $localPort
24 | }
25 | Write-Host "[$scriptName] free port is $localPort"
26 | Write-Host "`n[$scriptName] ---------- finish ----------"
27 | return $localPort
28 | }
29 | }
30 |
31 | Write-Host "`n[$scriptName] Failed to find a free port!"
32 | $error.clear()
33 | exit 1
--------------------------------------------------------------------------------
/provisioning/setProductKey.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'setProductKey.ps1'
2 | Write-Host
3 | Write-Host "[$scriptName] Install Windows Product key in preparation for activation"
4 | Write-Host
5 | Write-Host "[$scriptName] ---------- start ----------"
6 | $fileFile = $args[0]
7 | if ($fileFile) {
8 | Write-Host "[$scriptName] fileFile : $fileFile"
9 | } else {
10 | $fileFile = "$env:TEMP\productkey.txt"
11 | Write-Host "[$scriptName] fileFile : $fileFile (default)"
12 | }
13 |
14 | Write-Host
15 | if (Test-Path $fileFile ) {
16 | Write-Host "[$scriptName] $fileFile found"
17 | } else {
18 | Write-Host "[$scriptName] $fileFile not found!"
19 | exit 200
20 | }
21 | $key = [IO.File]::ReadAllText($fileFile)
22 | $computer = gc env:computername
23 | $service = get-wmiObject -query "select * from SoftwareLicensingService" -computername $computer
24 |
25 | Write-Host "[$scriptName] Install key and refresh status"
26 | $service.InstallProductKey($key)
27 | $service.RefreshLicenseStatus()
28 |
29 | Write-Host
30 | Write-Host "[$scriptName] ---------- stop -----------"
31 | Write-Host
--------------------------------------------------------------------------------
/samples/all/build.tsk:
--------------------------------------------------------------------------------
1 | Write-Host "CDAF Version : $(& $CDAF_CORE/capabilities.ps1 cdaf)"
2 |
3 | Write-Host "Am I an Administrator?`n" -ForegroundColor Magenta
4 | IFADMN "whoami"
5 |
6 | Write-Host "Clean Build workspace (not solution)`n" -ForegroundColor Magenta
7 | REMOVE *.binary
8 |
9 | Write-Host "If ACTION (emulation only) is clean, do not perform any further action`n" -ForegroundColor Magenta
10 | EXITIF $terminate = $ACTION
11 |
12 | Write-Host "artifactPrefix is automatically loaded from CDAF.solution, combine with build number to create symantic (http://semver.org/) version`n" -ForegroundColor Magenta
13 | ASSIGN $symver = "${artifactPrefix}.${BUILDNUMBER}"
14 |
15 | Write-Host "Perform build in DOS Command`n" -ForegroundColor Magenta
16 | EXECMD "echo @echo off > bin.bat"
17 | EXECMD "echo echo Artefact symantic version : $symver >> bin.bat"
18 | .\bin.bat
19 |
20 | Write-Host "Robust URL Check`n" -ForegroundColor Magenta
21 | EXERTY "curl.exe --silent -L -w '%{http_code}' google.com -o NUL"
22 |
23 | Write-Host "Execute outside of WORKSPACE"
24 | cd $TMPDIR
25 | PROPLD $AUTOMATIONROOT\CDAF.windows
26 |
--------------------------------------------------------------------------------
/provisioning/setStaticIP.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'setStaticIP.ps1'
2 | Write-Host
3 | Write-Host "[$scriptName] ---------- start ----------"
4 | $staticIP = $args[0]
5 | if ($staticIP) {
6 | Write-Host "[$scriptName] staticIP : $staticIP"
7 | } else {
8 | Write-Host "[$scriptName] staticIP not supplied, exiting with exit code 100"
9 | exit 100
10 | }
11 |
12 | foreach ($interface in (Get-DnsClient -InterfaceAlias 'Ethernet*')) {
13 | if ($staticIP -eq (Get-NetIPAddress -InterfaceIndex $interface.InterfaceIndex -AddressFamily 'IPv4').IPAddress ) {
14 |
15 | $PrefixLength = (Get-NetIPAddress -InterfaceIndex $interface.InterfaceIndex -AddressFamily 'IPv4').PrefixLength
16 | $InterfaceIndex = (Get-NetIPAddress -InterfaceIndex $interface.InterfaceIndex -AddressFamily 'IPv4').InterfaceIndex
17 | Set-NetIPAddress -IPAddress $staticIP -PrefixLength $PrefixLength -InterfaceIndex $InterfaceIndex
18 |
19 | # List the setting value
20 | Get-NetIPAddress -InterfaceIndex $interface.InterfaceIndex -AddressFamily 'IPv4'
21 | }
22 | }
23 |
24 | Write-Host
25 | Write-Host "[$scriptName] ---------- stop ----------"
26 |
--------------------------------------------------------------------------------
/automation/entry.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | cmd /c "exit 0"
3 |
4 | rem This script is for use with Git only and is dependent on "master" branch naming convention
5 |
6 | rem Action can be used to pass staging directory with staging@ prefix or
7 | rem housekeeping with remoteURL@
8 |
9 | set CDAF_COMMAND_SHELL=yes
10 |
11 | for %%Q in ("%~dp0\.") DO set "AUTOMATIONROOT=%%~fQ"
12 |
13 | echo.
14 | echo [%~nx0] ----------------------------------
15 | echo [%~nx0] PowerShell Execution Policy ByPass
16 |
17 | rem Launcher script that overides execution policy
18 | rem cannot elevate powershell
19 |
20 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%AUTOMATIONROOT%\entry.ps1'" "'%1'" "'%2'" "'%3'" "'%4'"
21 | set result=%errorlevel%
22 | if %result% NEQ 0 (
23 | echo [%~nx0] DELIVERY_ERROR call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %AUTOMATIONROOT%\entry.ps1 %1 %2 %3 %4
24 | echo [%~nx0] Return LASTEXITCODE %result%
25 | exit /b %result%
26 | )
27 |
28 | echo [%~nx0] PowerShell Policy ByPass Complete
29 | echo [%~nx0] ----------------------------------
30 | echo.
31 | exit 0
--------------------------------------------------------------------------------
/samples/cd.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$buildNumber,
3 | [string]$branchName
4 | )
5 |
6 | $scriptName = 'ci.ps1'
7 | cmd /c "exit 0"
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | $error.clear()
12 | Write-Host "$expression"
13 | try {
14 | $result = Invoke-Expression $expression
15 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
16 | } catch { echo $_.Exception|format-list -force; exit 2 }
17 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
18 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
19 | return $result
20 | }
21 |
22 |
23 | Write-Host "`n[$scriptName] ---------- start ----------`n"
24 | Write-Host "[$scriptName] buildNumber : $buildNumber"
25 | Write-Host "[$scriptName] branchName : $branchName"
26 |
27 |
28 | executeExpression "hostname"
29 | executeExpression "whoami"
30 |
31 | Write-Host "`n[$scriptName] ---------- stop ----------"
32 | $error.clear()
33 | exit 0
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/customLocal/bootstrapTarget.ps1:
--------------------------------------------------------------------------------
1 |
2 | cmd /c "exit 0"
3 | $scriptName = 'bootstrapTarget.ps1'
4 |
5 | function executeExpression ($expression) {
6 | $error.clear()
7 | Write-Host "$expression"
8 | try {
9 | $output = Invoke-Expression $expression
10 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
11 | } catch { echo $_.Exception|format-list -force; exit 2 }
12 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
13 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
14 | return $output
15 | }
16 |
17 | Write-Host "`n[$scriptName] ---------- start ----------`n"
18 |
19 | Write-Host "[$scriptName] Download latest from GitHub`n"
20 | executeExpression '$env:CDAF_INSTALL_PATH = "c:\cdaf"'
21 | executeExpression '. { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex'
22 |
23 | Write-Host "[$scriptName] Add any provisioning needed here`n"
24 | executeExpression "capabilities.ps1"
25 |
26 | Write-Host "`n[$scriptName] ---------- stop ----------"
27 |
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | name: $(Rev:r)
2 |
3 | trigger:
4 | branches:
5 | include:
6 | - '*'
7 |
8 | stages:
9 | - stage: DEV
10 | displayName: CI
11 | # variables:
12 | # - group: Git Reader
13 | jobs:
14 | - template: templates/azure-pipelines-build-template.yml
15 | parameters:
16 | displayName: CI
17 |
18 | - stage: TEST
19 | displayName: User Acceptence Test
20 | condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master'))
21 | dependsOn: DEV
22 | # variables:
23 | # - group: Test Library Group
24 | jobs:
25 | - template: templates/azure-pipelines-deployment-template.yml
26 | parameters:
27 | displayName: CD
28 | environment: TEST
29 |
30 | - stage: PROD
31 | displayName: Production Gated Deployment
32 | condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master'))
33 | dependsOn: TEST
34 | # variables:
35 | # - group: Production Library Group
36 | jobs:
37 | - template: templates/azure-pipelines-deployment-template.yml
38 | parameters:
39 | displayName: CD
40 | environment: PROD
41 |
--------------------------------------------------------------------------------
/automation/processor/delivery.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | cmd /c "exit 0"
3 | echo.
4 | echo [%~nx0] =========================================
5 | echo [%~nx0] Continuous Delivery (CD) Process Starting
6 | echo [%~nx0] =========================================
7 |
8 | set ENVIRONMENT=%1
9 | set RELEASE=%2
10 | set OPT_ARG=%3
11 | set WORK_DIR_DEFAULT=%4
12 | set SOLUTION=%5
13 | set BUILDNUMBER=%6
14 |
15 | rem Launcher script that overides execution policy
16 | rem cannot elevate powershell
17 |
18 | IF [%WORK_DIR_DEFAULT%] == [] (
19 | set workDirLocal=TasksLocal
20 | ) ELSE (
21 | set workDirLocal=%WORK_DIR_DEFAULT%
22 | )
23 |
24 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%cd%\%workDirLocal%\delivery.ps1'" "'%ENVIRONMENT%'" "'%RELEASE%'" "'%OPT_ARG%'" "'%WORK_DIR_DEFAULT%'"
25 | set result=%errorlevel%
26 | if %result% NEQ 0 (
27 | echo [%~nx0] CDAF_DELIVERY_FAILURE call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %cd%\%workDirLocal%\delivery.ps1 %ENVIRONMENT% %RELEASE% %OPT_ARG% %WORK_DIR_DEFAULT%
28 | echo [%~nx0] Return LASTEXITCODE %result%
29 | exit /b %result%
30 | )
31 |
32 | echo [%~nx0] =========================================
33 | echo.
34 | exit 0
35 |
--------------------------------------------------------------------------------
/automation/ci.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | cmd /c "exit 0"
3 |
4 | rem This script is a simple lauch script
5 |
6 | set BUILDNUMBER=%1
7 | set REVISION=%2
8 | set ACTION=%3
9 | set LOCAL_WORK_DIR=%4
10 | set REMOTE_WORK_DIR=%5
11 |
12 | set CDAF_COMMAND_SHELL=yes
13 |
14 | for %%Q in ("%~dp0\.") do set "AUTOMATIONROOT=%%~fQ"
15 |
16 | echo.
17 | echo [ %~nx0 ] ============================================
18 | echo [ %~nx0 ] Continuous Integration (CI) Process Starting
19 | echo [ %~nx0 ] ============================================
20 |
21 | rem Launcher script that overides execution policy
22 | rem cannot elevate powershell
23 |
24 | call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command "& '%AUTOMATIONROOT%\processor\buildPackage.ps1'" "'%BUILDNUMBER%'" "'%REVISION%'" "'%ACTION%'" "'%LOCAL_WORK_DIR%'" "'%REMOTE_WORK_DIR%'"
25 | set result=%errorlevel%
26 | if %result% NEQ 0 (
27 | echo [%~nx0] BUILD_PACKAGE_ERROR call powershell -NoProfile -NonInteractive -ExecutionPolicy ByPass -command %AUTOMATIONROOT%\processor\buildPackage.ps1 %BUILDNUMBER% %REVISION% %ACTION% %AUTOMATION_ROOT% %LOCAL_WORK_DIR% %REMOTE_WORK_DIR%
28 | echo [%~nx0] Return LASTEXITCODE %result%
29 | exit /b %result%
30 | )
31 |
--------------------------------------------------------------------------------
/orchestration/vagrant-box/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure
5 | # configures the configuration version (we support older styles for
6 | # backwards compatibility). Please don't change it unless you know what
7 | # you're doing.
8 | Vagrant.configure(2) do |config|
9 | config.vm.guest = :windows
10 | config.vm.communicator = "winrm"
11 | config.vm.boot_timeout = 1200 # 20 minutes
12 | config.winrm.timeout = 1800 # 30 minutes
13 | config.winrm.max_tries = 20
14 | config.winrm.retry_limit = 200 # from https://github.com/mitchellh/vagrant/issues/6430
15 | config.winrm.retry_delay = 10 # from https://github.com/mitchellh/vagrant/issues/6430
16 | config.vm.graceful_halt_timeout = 600
17 | #hyper-v: config.vm.provider 'hyperv' do |hyperv, override|
18 | #hyper-v: hyperv.ip_address_timeout = 600 # 10 minutes
19 | #hyper-v: hyperv.auto_start_action = 'Start'
20 | #hyper-v: hyperv.linked_clone = true
21 | #hyper-v: end
22 | #virtbox: config.vm.provider 'virtualbox' do |virtualbox, override|
23 | #virtbox: virtualbox.linked_clone = true
24 | #virtbox: virtualbox.gui = false
25 | #virtbox: end
26 | end
27 |
--------------------------------------------------------------------------------
/automation/local/RemoteTest.ps1:
--------------------------------------------------------------------------------
1 | $callingPID = $args[0]
2 | $listPSVer = $args[1]
3 |
4 | $scriptName = 'RemoteTest.ps1'
5 |
6 | Write-Host
7 | Write-Host "[$scriptName] ---------- Start ----------"
8 | Write-Host "[$scriptName] callingPID : $callingPID"
9 | Write-Host "[$scriptName] listPSVer : $listPSVer"
10 | Write-Host "[$scriptName] pwd : $(Get-Location)"
11 | Write-Host "[$scriptName] hostname : $(hostname)"
12 | Write-Host "[$scriptName] whoami : $(whoami)"
13 | Write-Host
14 | if ($listPSVer) {
15 | Write-Host "[$scriptName] PSVersionTable details (`$listPSVer set to $listPSVer):"
16 | $PSVersionTable
17 | } else {
18 | Write-Host "[$scriptName] Computer architecture and Service Pack version (`$listPSVer not set):"
19 | $computer = "."
20 | $sOS =Get-WmiObject -class Win32_OperatingSystem -computername $computer
21 | foreach($sProperty in $sOS) {
22 | write-host " Caption : $($sProperty.Caption)"
23 | write-host " Description : $($sProperty.Description)"
24 | write-host " OSArchitecture : $($sProperty.OSArchitecture)"
25 | write-host " ServicePackMajorVersion : $($sProperty.ServicePackMajorVersion)"
26 | }
27 | }
28 | Write-Host
29 | Write-Host "[$scriptName] ---------- Finish ----------"
30 | Write-Host
31 |
--------------------------------------------------------------------------------
/samples/containerBuild-custom-image/automation-solution/bootstrapAgent.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'bootstrapAgent.ps1'
2 |
3 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
4 | function executeExpression ($expression) {
5 | $error.clear()
6 | Write-Host "[$scriptName] $expression"
7 | try {
8 | Invoke-Expression $expression
9 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
10 | } catch { echo $_.Exception|format-list -force; exit 2 }
11 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
12 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
13 | }
14 |
15 | cmd /c "exit 0"
16 | # Use the CDAF provisioning helpers
17 | Write-Host "`n[$scriptName] ---------- start ----------`n"
18 |
19 | Write-Host "[$scriptName] Download latest from GitHub`n"
20 | executeExpression '$env:CDAF_INSTALL_PATH = "c:\cdaf"'
21 | executeExpression '. { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex'
22 |
23 | Write-Host "[$scriptName] Add any provisioning needed here`n"
24 | executeExpression "capabilities.ps1"
25 |
26 | Write-Host "`n[$scriptName] ---------- stop ----------"
27 | $error.clear()
28 | exit 0
--------------------------------------------------------------------------------
/automation/remote/push.ps1:
--------------------------------------------------------------------------------
1 | function executeExpression ($expression) {
2 | $error.clear()
3 | Write-Host "[$scriptName] $expression"
4 | try {
5 | Invoke-Expression $expression
6 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
7 | } catch { echo $_.Exception|format-list -force; exit 2 }
8 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
9 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
10 | }
11 |
12 | # The API Key needs to be obtained from the NuGet server to all package push without prompting for credentials
13 | $PACK_LOC = $args[0]
14 | $API_KEY_FILE = $args[1]
15 | $NUGET_URL = $args[2]
16 |
17 | $scriptName = 'push.ps1'
18 |
19 | Write-Host "[$scriptName] PACK_LOC : $PACK_LOC"
20 | Write-Host "[$scriptName] API_KEY_FILE : $API_KEY_FILE"
21 | Write-Host "[$scriptName] NUGET_URL : $NUGET_URL"
22 |
23 | $secure = Get-Content $API_KEY_FILE | ConvertTo-SecureString
24 | $plain = (New-Object System.Management.Automation.PSCredential 'N/A', $secure).GetNetworkCredential().Password
25 |
26 | # Assumes the package location is cleaned and there will be only one eligable
27 | executeExpression "NuGet.exe push $PACK_LOC\*.nupkg -ApiKey `$plain -Source $NUGET_URL"
28 |
--------------------------------------------------------------------------------
/automation/local/deploy.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$TARGET,
3 | [string]$WORKSPACE,
4 | [string]$warnondeployerror,
5 | [string]$OPT_ARG
6 | )
7 |
8 | function throwErrorlevel ($trappedExit) {
9 | write-host "[$scriptName] Trapped DOS exit code $trappedExit, throwing as exception`n" -ForegroundColor Red
10 | throw "$trappedExit"
11 | }
12 |
13 | # Dummy script to transition from remote powershell to local power shell via DOS batch execution override
14 | $scriptName = "deploy.ps1"
15 |
16 | write-host "[$scriptName] cd $WORKSPACE"
17 | Set-Location $WORKSPACE
18 | write-host
19 | & .\deploy.bat $TARGET $ENVIRONMENT $OPT_ARG
20 | if ( !$? ) {
21 | $exitCode = $LASTEXITCODE
22 | if ( $exitCode -ne 0 ) {
23 | if ( $warnondeployerror ) {
24 | Write-host "[$scriptName] deploy.bat did not complete normally, however `$warnondeployerror set ($warnondeployerror) so proceeding normally." -ForegroundColor Yellow
25 | cmd /c "exit 0"
26 | & Write-Output "[$scriptName] Reset call operator : ";$?
27 | } else {
28 | throwErrorlevel $exitCode
29 | }
30 | } else {
31 | Write-host "[$scriptName][WARN] `$LASTEXITCODE = $LASTEXITCODE`n `$Error[] = $Error`n" -ForegroundColor Yellow
32 | $Error.clear()
33 | Write-host "[$scriptName] Exit normally ..." -ForegroundColor Yellow
34 | }
35 | }
36 | exit 0
37 |
--------------------------------------------------------------------------------
/automation/remote/fixACLs.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$path
3 | )
4 | $scriptName = 'fixACLs.ps1'
5 |
6 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
7 | function executeExpression ($expression) {
8 | $error.clear()
9 | Write-Host "[$scriptName] $expression"
10 | try {
11 | Invoke-Expression $expression
12 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
13 | } catch { Write-Host $_.Exception|format-list -force; exit 2 }
14 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
15 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
16 | }
17 |
18 | Write-Host "`n[$scriptName] ---------- start ----------"
19 | if ($path) {
20 | Write-Host "[$scriptName] path : $path"
21 | } else {
22 | $path = 'C:\inetpub\wwwroot\'
23 | Write-Host "[$scriptName] path : $path (not passed so set to default)"
24 | }
25 |
26 | if ( ! ( Test-Path $path )) {
27 | Write-Host "`n[$scriptName] Created directory $(mkdir $path)"
28 | }
29 |
30 | Write-Host "`n[$scriptName] `$acl = Get-Acl $path"
31 | $acl = Get-Acl $path
32 | executeExpression "Set-Acl '$path' `$acl"
33 |
34 | Write-Host "`n[$scriptName] --- end ---"
35 | $error.clear()
36 | exit 0
37 |
--------------------------------------------------------------------------------
/automation/local/remotePackageManagement.ps1:
--------------------------------------------------------------------------------
1 | $packagePath = $args[0]
2 | $packageFile = $args[1]
3 |
4 | $scriptName = "remotePackageManagement.ps1"
5 |
6 | # If this script has started, then the PowerShell session is valid
7 | Write-Host "[$scriptName (remote)] Connection test Successfull" -ForegroundColor Green
8 |
9 | if ( ! ( Test-Path $packagePath )) {
10 | Write-Host "[$scriptName (remote)] Target path does not exit, create $(New-Item -Path $packagePath -ItemType directory)"
11 | }
12 |
13 | cd $packagePath
14 | $timeStamp = $(get-date -f yyyy-MM-dd-hhmmss)
15 | $packageFileName = $packageFile + ".zip"
16 |
17 | if ( Test-Path $packageFileName ) {
18 |
19 | Write-Host "`n[$scriptName (remote)] Package file ($packageFile.zip) exists rename:"
20 | Write-Host "[$scriptName (remote)] $packageFileName --> $packageFile-$timeStamp.zip"
21 | Move-Item $packageFileName $packageFile-$timeStamp.zip
22 |
23 | } else {
24 |
25 | Write-Host "`n[$scriptName (remote)] Not a re-run, purge landing directory ($(pwd))."
26 | Remove-Item * -Recurse -Force
27 |
28 | }
29 |
30 | if ( Test-Path $packageFile ) {
31 | Write-Host "`n[$scriptName (remote)] Extracted Package directory ($packageFile) exists rename:"
32 | Write-Host "[$scriptName (remote)] $packageFile --> $packageFile-$timeStamp"
33 | Move-Item $packageFile $packageFile-$timeStamp
34 | }
35 |
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/templates/azure-pipelines-terraform-template.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - deployment: Deploy
3 | displayName: ${{ parameters.displayName }}
4 | environment: ${{ parameters.environment }}
5 | pool:
6 | vmImage: windows-latest
7 | # pool:
8 | # name: Self-hosted Pool Name
9 |
10 | strategy:
11 | runOnce:
12 | deploy:
13 | steps:
14 | - task: DownloadBuildArtifacts@0
15 | displayName: Download the build artifacts
16 | inputs:
17 | buildType: current
18 | downloadType: single
19 | artifactName: drop
20 |
21 | - task: PowerShell@2
22 | displayName: ${{ parameters.environment }} "${{ parameters.action }}"
23 | env:
24 | # Use for deploy (state management) only
25 | TERRAFORM_TOKEN: $(TERRAFORM_TOKEN)
26 | inputs:
27 | workingDirectory: $(System.ArtifactsDirectory)/drop
28 | targetType: 'inline' # Use latest published version
29 | script: |
30 | . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
31 | .\automation\provisioning\base.ps1 terraform
32 | ./release.ps1 ${{ parameters.environment }} $(Build.BuildNumber) "${{ parameters.action }}"
33 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/tasksRunRemote.tsk:
--------------------------------------------------------------------------------
1 | Write-Host "CDAF Version : $(& $CDAF_CORE/capabilities.ps1 cdaf)"
2 |
3 | Write-Host "Create a temp directory & copy content to it, then add another file`n" -ForegroundColor Magenta
4 | REFRSH manifest.txt .cdaf-regression-temp-dir
5 | VECOPY example.yaml .cdaf-regression-temp-dir
6 |
7 | Write-Host "Create a zip file from the directory, then extract it to directory with the same name`n" -ForegroundColor Magenta
8 | CMPRSS zipPackage .cdaf-regression-temp-dir
9 | DCMPRS zipPackage
10 |
11 | Write-Host "Remove the temp directory`n" -ForegroundColor Magenta
12 | REMOVE .cdaf-regression-temp-dir
13 |
14 | Write-Host "List host capabilities`n" -ForegroundColor Magenta
15 | & $CDAF_CORE\capabilities.ps1
16 |
17 | Write-Host "Supply by pipeline as an environment variable, see provisioning/encrypt.ps1 to create file`n" -ForegroundColor Magenta
18 | $env:AES_KEY = '29-240-88-121-33-64-150-226-136-160-144-115-127-74-74-30'
19 |
20 | Write-Host "Capture output to file or it will simply be logged and discarded`n" -ForegroundColor Magenta
21 | DECRYP ./crypt/secrets.crypt $env:AES_KEY | Out-File secrets
22 | cat secrets
23 |
24 | Write-Host "Robust URL Check`n" -ForegroundColor Magenta
25 | EXERTY "curl.exe --silent -L -w '%{http_code}' google.com -o NUL"
26 |
27 | Write-Host "Execute outside of WORKSPACE"
28 | cd $TMPDIR
29 | PROPLD $WORKSPACE\manifest.txt
30 |
--------------------------------------------------------------------------------
/provisioning/installEXE.ps1:
--------------------------------------------------------------------------------
1 | # Cannot use parameters as opt_arg may contain parameters itself
2 |
3 | $scriptName = 'installEXE.ps1'
4 |
5 | Write-Host "`n[$scriptName] ---------- start ----------"
6 | $exeFile = $args[0]
7 | if ($exeFile) {
8 | Write-Host "[$scriptName] exeFile : $exeFile"
9 | } else {
10 | Write-Host "[$scriptName] Executable file not passed, exiting with code 1";exit 1
11 | }
12 | if (!(Test-Path $exeFile)) {
13 | Write-Host "[$scriptName] $exeFile not found, exiting with code 2";exit 2
14 | }
15 |
16 | $opt_arg = $args[1]
17 | if ($opt_arg) {
18 | Write-Host "[$scriptName] opt_arg : $opt_arg"
19 | } else {
20 | Write-Host "[$scriptName] opt_arg : (not supplied)"
21 | }
22 |
23 | if ($opt_arg) {
24 | Write-Host "`n[$scriptName] `$proc = Start-Process -FilePath `"$exeFile`" -ArgumentList `"$opt_arg`" -PassThru -Wait -NoNewWindow"
25 | $proc = Start-Process -FilePath "$exeFile" -ArgumentList "$opt_arg" -PassThru -Wait -NoNewWindow
26 | } else {
27 | Write-Host "`n[$scriptName] `$proc = Start-Process -FilePath `"$exeFile`" -PassThru -Wait -NoNewWindow"
28 | $proc = Start-Process -FilePath "$exeFile" -PassThru -Wait -NoNewWindow
29 | }
30 | if ( $proc.ExitCode -ne 0 ) {
31 | Write-Host "`n[$scriptName] Exit with `$LASTEXITCODE = $($proc.ExitCode)`n"
32 | exit $proc.ExitCode
33 | }
34 |
35 | Write-Host "`n[$scriptName] ---------- stop ----------"
36 |
--------------------------------------------------------------------------------
/provisioning/sqlLocalDBInstance.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "$expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
11 | }
12 |
13 | $scriptName = 'sqlLocalDBInstance.ps1'
14 |
15 | Write-Host
16 | Write-Host "[$scriptName] ---------- start ----------"
17 | $instanceName = $args[0]
18 | if ($instanceName) {
19 | Write-Host "[$scriptName] instanceName : $instanceName"
20 | } else {
21 | $instanceName = 'MSSQLLocalDB'
22 | Write-Host "[$scriptName] instanceName : $instanceName (not supplied, so default used)"
23 | }
24 |
25 | $exists = SqlLocalDB.exe info | findstr.exe $instanceName
26 |
27 | Write-Host
28 | if ( $exists ) {
29 | executeExpression "SqlLocalDB.exe start $instanceName"
30 | } else {
31 | executeExpression "SqlLocalDB.exe create $instanceName"
32 | executeExpression "SqlLocalDB.exe start $instanceName"
33 | }
34 |
35 | Write-Host
36 | executeExpression "foreach (`$instance in SqlLocalDB.exe info ) { SqlLocalDB.exe info `$instance }"
37 |
38 | Write-Host
39 | Write-Host "[$scriptName] ---------- stop ----------"
40 |
--------------------------------------------------------------------------------
/provisioning/applyWindowsUpdates.ps1:
--------------------------------------------------------------------------------
1 | # Only for Windows Server 2016 and above
2 | $scriptName = 'applyWindowsUpdates.ps1'
3 | Write-Host "`n[$scriptName] ---------- start ----------"
4 | $autoRestart = $args[0]
5 | if ($autoRestart) {
6 | Write-Host "[$scriptName] autoRestart : $autoRestart"
7 | } else {
8 | $autoRestart = 'yes'
9 | Write-Host "[$scriptName] autoRestart : $autoRestart (default)"
10 | }
11 |
12 | try {
13 | Write-Host "[$scriptName] Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force"
14 | Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
15 |
16 | Write-Host "[$scriptName] Set-PSRepository -Name PSGallery -InstallationPolicy Trusted"
17 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
18 |
19 | Write-Host "[$scriptName] Install-Module -Name PSWindowsUpdate -Confirm:`$False"
20 | Install-Module -Name PSWindowsUpdate -Confirm:$False
21 |
22 | Write-Host "[$scriptName] Import-Module PSWindowsUpdate"
23 | Import-Module PSWindowsUpdate
24 |
25 | if ($autoRestart -eq 'yes') {
26 | Write-Host "[$scriptName] Get-WUInstall -Verbose -AcceptAll -AutoReboot:`$True -Confirm:`$False"
27 | Get-WUInstall -Verbose -AcceptAll -AutoReboot:$True -Confirm:$False
28 | } else {
29 | Write-Host "[$scriptName] Get-WUInstall -Verbose -AcceptAll -AutoReboot:`$False -Confirm:`$False"
30 | Get-WUInstall -Verbose -AcceptAll -AutoReboot:$False -Confirm:$False
31 | }
32 |
33 | } catch { Write-Host $_.Exception|format-list -force; exit 5 }
34 |
35 | Write-Host "`n[$scriptName] ---------- stop ----------"
36 |
--------------------------------------------------------------------------------
/orchestration/jenkins/jenkins-scripted-pipeline/Jenkinsfile:
--------------------------------------------------------------------------------
1 | node {
2 | properties(
3 | [
4 | [
5 | $class: 'BuildDiscarderProperty',
6 | strategy: [$class: 'LogRotator', numToKeepStr: '10']
7 | ],
8 | pipelineTriggers(
9 | [
10 | [$class: "SCMTrigger", scmpoll_spec: "H/3 * * * *"],
11 | ]
12 | )
13 | ]
14 | )
15 | }
16 |
17 | node {
18 | try {
19 | withEnv(["BRANCH_NAME=${env.BRANCH_NAME}"]) {
20 | stage ('Application Build and Test') {
21 | checkout scm
22 | bat "automation\\ci.bat ${BUILD_NUMBER} ${BRANCH_NAME}"
23 | }
24 | }
25 |
26 | if ( env.BRANCH_NAME == 'master' ) {
27 |
28 | stage ('Automated Test') {
29 | bat "TasksLocal\\delivery.bat CD"
30 | }
31 |
32 | stage ('Acceptance Test') {
33 | bat "TasksLocal\\delivery.bat TEST"
34 | }
35 |
36 | stage ('Product Owner Approval') { input "Deploy to Production?" }
37 |
38 | stage ('Production') {
39 | bat "TasksLocal\\delivery.bat PROD"
40 | }
41 | }
42 | }
43 |
44 | catch (e) {
45 | currentBuild.result = "FAILED"
46 | println currentBuild.result
47 | notifyFailed()
48 | throw e
49 | }
50 |
51 | finally {
52 | junit '**/test-results/*.xml'
53 | }
54 | }
55 |
56 | def notifyFailed() {
57 |
58 | emailext (
59 | recipientProviders: [[$class: 'DevelopersRecipientProvider']],
60 | subject: "Jenkins Job [${env.JOB_NAME}] Build [${env.BUILD_NUMBER}] failure",
61 | body: "Check console output at ${env.BUILD_URL}"
62 | )
63 | }
--------------------------------------------------------------------------------
/provisioning/CredDelegation.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "$expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
11 | }
12 |
13 | $scriptName = 'CredDelegation.ps1'
14 | Write-Host
15 | Write-Host "Applies Windows Domain : Allow a user or computer to delegate, i.e. `"double hop`""
16 | Write-Host
17 | Write-Host "[$scriptName] ---------- start ----------"
18 | $identity = $args[0]
19 | if ($identity) {
20 | Write-Host "[$scriptName] identity : $identity"
21 | } else {
22 | $identity = 'deployer'
23 | Write-Host "[$scriptName] identity : $identity (default)"
24 | }
25 |
26 | $entity = $args[1]
27 | if ($entity) {
28 | Write-Host "[$scriptName] entity : $entity (choices user or computer)"
29 | } else {
30 | $entity = 'user'
31 | Write-Host "[$scriptName] entity : $entity (default, choices user or computer)"
32 | }
33 |
34 | if ($entity -eq 'user') {
35 | executeExpression "Set-ADUser -Identity $identity -TrustedForDelegation `$True"
36 | } else {
37 | executeExpression "Set-ADComputer -Identity $passthruHost -TrustedForDelegation `$True"
38 | }
39 |
40 | Write-Host
41 | Write-Host "[$scriptName] ---------- stop ----------"
42 |
--------------------------------------------------------------------------------
/orchestration/vagrant-test/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure
5 | # configures the configuration version (we support older styles for
6 | # backwards compatibility). Please don't change it unless you know what
7 | # you're doing.
8 |
9 | # This file is used by AtlasPackage.ps1 for verifying CDAF base boxes
10 | if ENV['OVERRIDE_IMAGE']
11 | vagrantBox = ENV['OVERRIDE_IMAGE']
12 | else
13 | puts "OVERRIDE_IMAGE not specified! Set environment variable and retry"
14 | exit 7724
15 | end
16 |
17 | Vagrant.configure(2) do |config|
18 |
19 | # Build Server, fills the role of the build agent and delivers to the host above
20 | config.vm.define 'test' do |test|
21 | test.vm.box = "#{vagrantBox}"
22 | test.vm.provision 'shell', inline: 'Write-Host "pwd = $(pwd)"'
23 | test.vm.provision 'shell', inline: 'Write-Host "whoami = $(whoami)"'
24 | test.vm.provision 'shell', inline: 'systeminfo'
25 |
26 | # Oracle VirtualBox with private NAT has insecure deployer keys for desktop testing
27 | test.vm.provider 'virtualbox' do |virtualbox, override|
28 | override.vm.network 'private_network', ip: '172.16.17.100'
29 | end
30 |
31 | # Microsoft Hyper-V does not support NAT or setting hostname. vagrant up build --provider hyperv
32 | test.vm.provider 'hyperv' do |hyperv, override|
33 | hyperv.vmname = "windows-test"
34 | if ENV['VAGRANT_SMB_PASS']
35 | override.vm.synced_folder ".", "/vagrant", type: "smb", smb_username: "#{ENV['VAGRANT_SMB_USER']}", smb_password: "#{ENV['VAGRANT_SMB_PASS']}", mount_options: ["vers=2.1"]
36 | end
37 | end
38 | end
39 |
40 | end
--------------------------------------------------------------------------------
/provisioning/encypt.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$inputFile,
3 | [string]$encryptedFile,
4 | [string]$stringKeyIn
5 | )
6 |
7 | cmd /c "exit 0"
8 |
9 | $scriptName = 'encrypt.ps1'
10 |
11 | Write-Host "`n[$scriptName] Create an encrypted file using AES key "
12 | Write-Host "`n[$scriptName] ---------- start ----------"
13 | if ($inputFile) {
14 | Write-Host "[$scriptName] inputFile : $inputFile"
15 | } else {
16 | Write-Host "[$scriptName] inputFile not suppplied!"; exit 101
17 | }
18 |
19 | if ($encryptedFile) {
20 | Write-Host "[$scriptName] encryptedFile : $encryptedFile"
21 | } else {
22 | $encryptedFile = $inputFile
23 | Write-Host "[$scriptName] encryptedFile : (not suppplied, existing file will be replaced)"
24 | }
25 |
26 | if ($stringKeyIn) {
27 | Write-Host "[$scriptName] stringKeyIn : `$stringKeyIn (example format 29-240-88-121-33-64-150-226-136-160-144-115-127-74-74-30)"
28 | $key = @()
29 | $key = $stringKeyIn.Split('-')
30 | } else {
31 | Write-Host "[$scriptName] stringKeyIn : (not supplied, new key will be generated, example format 29-240-88-121-33-64-150-226-136-160-144-115-127-74-74-30)"
32 | $Key = New-Object Byte[] 16 # You can use 16, 24, or 32 for AES
33 | [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
34 | $stringKeyOut = ""
35 | foreach ($element in $key) { $stringKeyOut += "-$element" }
36 | $stringKeyOut = $stringKeyOut.Substring(1)
37 | }
38 |
39 | Get-Content $inputFile -Raw | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString -key $Key | Out-File $encryptedFile
40 | if ( $stringKeyOut ) {
41 | $stringKeyOut
42 | }
43 | Write-Host "`n[$scriptName] ---------- stop ----------"
44 |
--------------------------------------------------------------------------------
/samples/custom/automation-solution/customLocal/customDeploy.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$SOLUTION,
3 | [string]$BUILD,
4 | [string]$ENVIRONMENT
5 | )
6 |
7 | $Error.Clear()
8 | cmd /c "exit 0"
9 | $scriptName = 'customDeploy.ps1'
10 |
11 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
12 | function executeExpression ($expression) {
13 | Write-Host "[$(Get-Date)] $expression"
14 | try {
15 | Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
17 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
18 | if ( $LASTEXITCODE ) {
19 | if ( $LASTEXITCODE -ne 0 ) {
20 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
21 | } else {
22 | if ( $error ) {
23 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE, $error[] =`n" -ForegroundColor Yellow
24 | $error
25 | }
26 | }
27 | } else {
28 | if ( $error ) {
29 | Write-Host "[$scriptName][WARN] $Error array populated but LASTEXITCODE not set, $error[] =`n" -ForegroundColor Yellow
30 | $error
31 | }
32 | }
33 | }
34 |
35 | Write-Host "`n[$scriptName] ---------- start ----------"
36 | Write-Host "[$scriptName] SOLUTION : $SOLUTION"
37 | Write-Host "[$scriptName] BUILD : $BUILD"
38 | Write-Host "[$scriptName] ENVIRONMENT : $ENVIRONMENT"
39 | Write-Host "[$scriptName] TARGET : $TARGET"
40 |
41 | & ./Transform.ps1 $TARGET | ForEach-Object { invoke-expression $_ }
42 |
43 | executeExpression "dir"
44 |
45 | Write-Host "`n[$scriptName] ---------- stop ----------"
46 |
--------------------------------------------------------------------------------
/provisioning/setWinRM.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "$expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
11 | }
12 |
13 |
14 | $scriptName = 'setStaticIP.ps1'
15 | Write-Host
16 | Write-Host "[$scriptName] ---------- start ----------"
17 | $URI = $args[0]
18 | if ($URI) {
19 | Write-Host "[$scriptName] URI : $URI"
20 | } else {
21 | Write-Host "[$scriptName] URI not supplied, valid example winrm/config/winrs"
22 | Write-Host "[$scriptName] Exiting with exit code 100"
23 | exit 100
24 | }
25 |
26 | $name = $args[1]
27 | if ($name) {
28 | Write-Host "[$scriptName] name : $name"
29 | } else {
30 | Write-Host "[$scriptName] name not supplied, valid example MaxShellsPerUser"
31 | Write-Host "[$scriptName] Exiting with exit code 101"
32 | exit 101
33 | }
34 |
35 | $value = $args[2]
36 | if ($value) {
37 | Write-Host "[$scriptName] value : $value"
38 | } else {
39 | Write-Host "[$scriptName] value not supplied, valid example 30"
40 | Write-Host "[$scriptName] Exiting with exit code 102"
41 | exit 102
42 | }
43 |
44 | Write-Host
45 | # Build the command in a format that is supported in PowerShell
46 | executeExpression "winrm set $URI `'@{$name=`"$value`"}`'"
47 |
48 | Write-Host
49 | Write-Host "[$scriptName] ---------- stop ----------"
50 |
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/templates/azure-pipelines-deployment-template.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | # Environment of Virtual Machines, replaces legacy "Deployment Groups"
3 | - deployment: Release # do not use "Deploy" or job will get stuck at "Job is pending..."
4 | displayName: ${{ parameters.displayName }}
5 | environment:
6 | name: ${{ parameters.environment }}
7 | resourceType: VirtualMachine
8 |
9 | # Deploy to agent pool, either Microsoft hosted or Self-hosted
10 | # - deployment: Deploy
11 | # displayName: ${{ parameters.displayName }}
12 | # environment: ${{ parameters.environment }}
13 | # pool:
14 | # vmImage: windows-latest
15 | # pool:
16 | # name: Self-hosted Pool Name
17 |
18 | strategy:
19 | runOnce:
20 | deploy:
21 | steps:
22 | - task: DownloadBuildArtifacts@0
23 | displayName: Download the build artifacts
24 | inputs:
25 | buildType: current
26 | downloadType: single
27 | artifactName: drop
28 |
29 | # - task: PowerShell@2
30 | # displayName: Diag
31 | # inputs:
32 | # workingDirectory: $(System.ArtifactsDirectory)/drop
33 | # targetType: inline
34 | # script: dir ; systeminfo
35 |
36 | - task: PowerShell@2
37 | displayName: CDAF Release Package
38 | # env:
39 | # CONNECTION_STRING: $(CONNECTION_STRING)
40 | # DATABASE_PASSWORD: $(DATABASE_PASSWORD)
41 | inputs:
42 | workingDirectory: $(System.ArtifactsDirectory)/drop
43 | targetType: filePath
44 | filePath: $(System.ArtifactsDirectory)/drop/release.ps1
45 | arguments: ${{ parameters.environment }}
46 |
--------------------------------------------------------------------------------
/orchestration/gitlab/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # If stages is not defined in the .gitlab-ci.yml file, the default pipeline stages are:
2 | #stages:
3 | # - .pre
4 | # - build
5 | # - test
6 | # - deploy
7 | # - .post
8 |
9 | CI:
10 | stage: build
11 |
12 | # To use native container runner with CDAF pre-installed
13 | image: cdaf/windows
14 | script: entry.ps1 ${CI_PIPELINE_IID} ${CI_COMMIT_BRANCH}
15 |
16 | # Self-hosted Runner
17 | # tags:
18 | # - batch
19 |
20 | # Install Edge Version
21 | # script: |
22 | # . { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex
23 | # .\automation\entry.ps1 ${CI_PIPELINE_IID} ${CI_COMMIT_BRANCH}
24 |
25 | # Install Latest Version
26 | # script: |
27 | # . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
28 | # .\automation\entry.bat ${CI_PIPELINE_IID} ${CI_COMMIT_BRANCH}
29 |
30 | artifacts:
31 | paths:
32 | - release.ps1
33 |
34 | TEST:
35 | stage: test
36 | tags:
37 | - batch
38 | script: "./release.ps1 ${CI_JOB_NAME} ${CI_PIPELINE_ID}"
39 | environment: "${CI_JOB_STAGE}"
40 | dependencies:
41 | - CI
42 | only:
43 | - master
44 |
45 | PROD:
46 | stage: deploy
47 | tags:
48 | - batch
49 | script: "./release.ps1 ${CI_JOB_NAME} ${CI_PIPELINE_ID}"
50 | environment: "${CI_JOB_STAGE}"
51 | dependencies:
52 | - TEST
53 | only:
54 | - master
55 | when: manual
56 |
57 | # To apply a hard-dependency on the manual gate, use "needs"
58 | #VERIFY:
59 | # stage: publish
60 | # image: cdaf/linux
61 | # script: |
62 | # ./release.sh ${CI_JOB_NAME} ${CI_PIPELINE_ID}
63 | # dependencies:
64 | # - CI
65 | # - PROD
66 | # needs:
67 | # - CI
68 | # - PROD
69 | # only:
70 | # - main
71 |
--------------------------------------------------------------------------------
/automation/local/localTasksTarget.ps1:
--------------------------------------------------------------------------------
1 |
2 | function getProp ($propName) {
3 | try {
4 | $propValue=$(& ${CDAF_CORE}\getProperty.ps1 $propertiesFile $propName)
5 | if(!$?){ taskWarning }
6 | } catch { exceptionExit "LOCAL_TASKS_TARGET_getProp" $_ }
7 |
8 | return $propValue
9 | }
10 |
11 | $ENVIRONMENT = $args[0]
12 | $SOLUTION = $args[1]
13 | $BUILD = $args[2]
14 | $TARGET = $args[3]
15 | $OPT_ARG = $args[4]
16 |
17 | $scriptName = $myInvocation.MyCommand.Name
18 | $propertiesFile = "propertiesForLocalTasks\$TARGET"
19 |
20 | write-host
21 | write-host "[$scriptName] propertiesFile : $propertiesFile"
22 |
23 | $scriptOverride = getProp ("deployScriptOverride")
24 | if ($scriptOverride ) {
25 | $taskList = $scriptOverride
26 | write-host "[$scriptName] deployScriptOverride : $scriptOverride"
27 | Write-Host
28 | $expression=".\$scriptOverride $SOLUTION $BUILD $TARGET"
29 | write-host $expression
30 | try {
31 | Invoke-Expression $expression
32 | if(!$?){ taskFailure "LOCAL_OVERRIDESCRIPT_TRAP" }
33 | } catch { exceptionExit "LOCAL_OVERRIDESCRIPT_EXCEPTION" $_ }
34 |
35 |
36 | } else {
37 |
38 | $taskOverride = getProp ("deployTaskOverride")
39 | if ($taskOverride ) {
40 | $taskList = $taskOverride
41 | } else {
42 | $taskList = "tasksRunLocal.tsk"
43 | }
44 |
45 | Write-Host
46 | foreach ( $taskItem in $taskList.Split() ) {
47 | write-host "`n[$scriptName] --- Executing $taskItem ---`n" -ForegroundColor Green
48 | & ${CDAF_CORE}\execute.ps1 $SOLUTION $BUILD $TARGET $taskItem $OPT_ARG
49 | if($LASTEXITCODE -ne 0){ ERRMSG "LOCAL_TASKS_TARGET_EXECUTE_NON_ZERO_EXIT ${CDAF_CORE}\execute.ps1 $SOLUTION $BUILD $TARGET $taskItem" $LASTEXITCODE }
50 | if(!$?){ taskFailure "LOCAL_TASKS_TARGET_EXECUTE_TRAP" }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/automation/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
37 |
--------------------------------------------------------------------------------
/provisioning/setSPN.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$spn,
3 | [string]$targetAccount
4 | )
5 |
6 | cmd /c "exit 0"
7 | $Error.Clear()
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | Write-Host "[$(Get-Date)] $expression"
12 | try {
13 | Invoke-Expression $expression
14 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
15 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
16 | if ( $LASTEXITCODE ) {
17 | if ( $LASTEXITCODE -ne 0 ) {
18 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
19 | } else {
20 | if ( $error ) {
21 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE, $error[] = $error`n" -ForegroundColor Yellow
22 | $error.clear()
23 | }
24 | }
25 | } else {
26 | if ( $error ) {
27 | Write-Host "[$scriptName][WARN] $Error array populated but LASTEXITCODE not set, $error[] = $error`n" -ForegroundColor Yellow
28 | $error.clear()
29 | }
30 | }
31 | }
32 |
33 | $scriptName = 'setSPN.ps1'
34 | Write-Host "`nConfigure SPN for double hop authentication. Perform on Domain Controller."
35 | Write-Host "`n[$scriptName] ---------- start ----------"
36 | if ($spn) {
37 | Write-Host "[$scriptName] spn : $spn"
38 | } else {
39 | $spn = 'MSSQLSvc/DB:1433'
40 | Write-Host "[$scriptName] spn : $spn (default)"
41 | }
42 |
43 | if ($targetAccount) {
44 | Write-Host "[$scriptName] targetAccount : $targetAccount"
45 | } else {
46 | $targetAccount = 'MSHOME\SQLSA'
47 | Write-Host "[$scriptName] targetAccount : $targetAccount (default)"
48 | }
49 |
50 | executeExpression "setspn.exe -a $spn $targetAccount"
51 |
52 | Write-Host "`n[$scriptName] ---------- stop ----------`n"
53 |
--------------------------------------------------------------------------------
/automation/local/copy.ps1:
--------------------------------------------------------------------------------
1 | function taskException ($taskName, $exit, $exception) {
2 | write-host "[$scriptName] Caught an exception excuting $taskName :" -ForegroundColor Red
3 | write-host " Exception Type: $($exception.Exception.GetType().FullName)" -ForegroundColor Red
4 | write-host " Exception Message: $($exception.Exception.Message)" -ForegroundColor Red
5 | exit $exit
6 | }
7 |
8 | function getFilename ($FullPathName) {
9 |
10 | $PIECES=$FullPathName.split('\')
11 | $NUMBEROFPIECES=$PIECES.Count
12 | $FILENAME=$PIECES[$NumberOfPieces-1]
13 | $DIRECTORYPATH=$FullPathName.Trim($FILENAME)
14 | return $FILENAME
15 |
16 | }
17 |
18 | $copyFile = $args[0]
19 | $deployLand = $args[1]
20 | $WORK_DIR_DEFAULT = $args[2]
21 |
22 | $fileName = getFilename($copyFile)
23 |
24 | $scriptName = $myInvocation.MyCommand.Name
25 | $deployPath = "$deployLand\$fileName"
26 |
27 | if ( Test-Path $WORK_DIR_DEFAULT\copyLand.ps1 ) {
28 | Remove-Item $WORK_DIR_DEFAULT\copyLand.ps1 -Recurse
29 | if(!$?){ taskWarning "Remove-Item $WORK_DIR_DEFAULT\copyLand.ps1"}
30 | }
31 |
32 | # The copy method loads the file contents into an argument and streams to a remote writer, to get this to work,
33 | # the target location needs to be a literal and cannot be substituted at runtime, to overcome this the script
34 | # file itself is hardcoded with the desired target location.
35 | $templateFile = @(Get-Content "$WORK_DIR_DEFAULT\copyTemplate.ps1")
36 | $outputFile = "$WORK_DIR_DEFAULT\copyLand.ps1"
37 | $stream = [System.IO.StreamWriter] $outputFile
38 | foreach ($line in $templateFile) {
39 | $line = $line -replace "deployLand", $deployPath
40 | $line = $line -replace "copy.ps1", "copyLand.ps1"
41 | $stream.WriteLine($line)
42 | }
43 | $stream.close()
44 |
45 | try {
46 | & $WORK_DIR_DEFAULT\copyLand.ps1 $copyFile
47 | if(!$?){ taskWarning }
48 | } catch { taskException "$copyFile" 2491 $_ }
49 |
--------------------------------------------------------------------------------
/provisioning/addProxy.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$proxyURI
3 | )
4 |
5 | function executeExpression ($expression) {
6 | $error.clear()
7 | Write-Host "$expression"
8 | try {
9 | $output = Invoke-Expression $expression
10 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
11 | } catch { echo $_.Exception|format-list -force; exit 2 }
12 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
13 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
14 | return $output
15 | }
16 |
17 | $scriptName = 'addDISM.ps1'
18 |
19 | Write-Host "`n[$scriptName] ---------- start ----------`n"
20 | if ($proxyURI) {
21 | Write-Host "[$scriptName] proxyURI : $proxyURI"
22 | } else {
23 | Write-Host "[$scriptName] ERROR: proxyURI not passed, halting with LASTEXITCODE=110"; exit 110
24 | }
25 |
26 | if ($DefaultNetworkCredentials) {
27 | Write-Host "[$scriptName] DefaultNetworkCredentials : $DefaultNetworkCredentials"
28 | } else {
29 | $DefaultNetworkCredentials = 'no'
30 | Write-Host "[$scriptName] DefaultNetworkCredentials : $DefaultNetworkCredentials (default)"
31 | }
32 |
33 | executeExpression "Add-Content $PROFILE `"[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('$proxyURI')`""
34 |
35 | if ($DefaultNetworkCredentials -eq 'yes') {
36 | executeExpression "Add-Content $PROFILE `"[system.net.webrequest]::defaultwebproxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials`""
37 | }
38 | executeExpression "Add-Content $PROFILE `"[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = `$true`""
39 |
40 | executeExpression "$PROFILE"
41 |
42 | Write-Host "`n[$scriptName] List the resulting configuration ..."
43 | [system.net.webrequest]::defaultwebproxy
44 |
45 | Write-Host "`n[$scriptName] ---------- stop ----------"
46 | exit 0
--------------------------------------------------------------------------------
/samples/deliveryScript.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$SOLUTION,
3 | [string]$BUILDNUMBER,
4 | [string]$TARGET
5 | )
6 |
7 | $scriptName = 'deliveryScript.ps1'
8 | cmd /c "exit 0"
9 |
10 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
11 | function executeExpression ($expression) {
12 | $error.clear()
13 | Write-Host "[$scriptName] $expression"
14 | try {
15 | Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName][CDAF_DELIVERY_FAILURE.failure] `$? = $?"; exit 1 }
17 | } catch { Write-Host "[$scriptName][CDAF_DELIVERY_FAILURE.exception] ..."; echo $_.Exception|format-list -force; exit 2 }
18 | if ( $error[0] ) { Write-Host "[$scriptName][CDAF_DELIVERY_FAILURE.error] `$error[0] = $error"; exit 3 }
19 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName][CDAF_DELIVERY_FAILURE.exit] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
20 | }
21 |
22 | Write-Host "`n[$scriptName] ---------- start ----------"
23 | Write-Host "[$scriptName] SOLUTION : $SOLUTION"
24 | Write-Host "[$scriptName] BUILDNUMBER : $BUILDNUMBER"
25 | Write-Host "[$scriptName] TARGET : $TARGET"
26 |
27 | & ./Transform.ps1 $TARGET | ForEach-Object { invoke-expression $_ }
28 |
29 | if ( Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels' ) {
30 |
31 | Write-Host "Compatibility setting`n"
32 | [Console]::OutputEncoding = [System.Text.Encoding]::Default
33 |
34 | Write-Host "Cleanup from previously failed builds`n"
35 | executeExpression "docker-compose down"
36 | executeExpression "docker-compose rm"
37 |
38 | Write-Host "Create Test SQL Server Container`n"
39 | executeExpression "docker-compose up -d"
40 |
41 | } else {
42 |
43 | Write-Host "This operating system is not a server, please ensure SQL Server is running with sa account and password of Passw0rd!`n"
44 |
45 | }
46 |
47 | Write-Host "`n[$scriptName] ---------- stop ----------"
48 | $error.clear()
49 | exit 0
--------------------------------------------------------------------------------
/provisioning/WIF.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'WIF.ps1'
2 | $versionChoices = '4'
3 | Write-Host
4 | Write-Host "[$scriptName] --------------------------"
5 | Write-Host "[$scriptName] Windows Identity Framework"
6 | Write-Host "[$scriptName] --------------------------"
7 | $version = $args[0]
8 | if ($version) {
9 | Write-Host "[$scriptName] version : $version"
10 | } else {
11 | $version = '4'
12 | Write-Host "[$scriptName] version : $version (default, choices $versionChoices)"
13 | }
14 |
15 | $mediaDir = $args[1]
16 | if ($mediaDir) {
17 | Write-Host "[$scriptName] mediaDir : $mediaDir"
18 | } else {
19 | $mediaDir = "$env:TEMP"
20 | Write-Host "[$scriptName] mediaDir : $mediaDir (default)"
21 | }
22 |
23 | if (!( Test-Path $mediaDir )) {
24 | Write-Host "[$scriptName] mkdir $mediaDir"
25 | mkdir $mediaDir
26 | }
27 |
28 | Write-Host
29 |
30 | switch ($version) {
31 | '4' {
32 | $file = 'Windows6.1-KB974405-x64.msu'
33 | $uri = 'https://download.microsoft.com/download/D/7/2/D72FD747-69B6-40B7-875B-C2B40A6B2BDD/' + $file
34 | }
35 | default {
36 | Write-Host "[$scriptName] version not supported, choices are $versionChoices"
37 | }
38 | }
39 |
40 | Write-Host
41 | $fullpath = $mediaDir + '\' + $file
42 | if ( Test-Path $fullpath ) {
43 | Write-Host "[$scriptName] $fullpath exists, download not required"
44 | } else {
45 |
46 | $webclient = new-object system.net.webclient
47 | Write-Host "[$scriptName] $webclient.DownloadFile($uri, $fullpath)"
48 | $webclient.DownloadFile($uri, $fullpath)
49 | }
50 |
51 | try {
52 | $argList = @("$fullpath", '/quiet', '/norestart')
53 | Write-Host "[$scriptName] Start-Process -FilePath `'wusa.exe`' -ArgumentList $argList -PassThru -Wait"
54 | $proc = Start-Process -FilePath 'wusa.exe' -ArgumentList $argList -PassThru -Wait
55 | } catch {
56 | Write-Host "[$scriptName] PowerShell Install Exception : $_" -ForegroundColor Red
57 | exit 200
58 | }
59 |
60 | Write-Host
61 | Write-Host "[$scriptName] ---------- stop -----------"
62 | Write-Host
--------------------------------------------------------------------------------
/.github/workflows/delivery.yml:
--------------------------------------------------------------------------------
1 | name: CDAF Targetless CD using hosted agent
2 | # This workflow is triggered on pushes to the repository.
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | name: Continuous Integration & Feature Branch Testing
8 | runs-on: windows-latest
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v4
12 |
13 | - name: Fetch all history for all tags and branches
14 | run: |
15 | git config remote.origin.url https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
16 | git fetch --prune --unshallow
17 |
18 | - name: CDAF
19 | shell: powershell # pwsh for PowerShell Core
20 | run: |
21 | cd ${env:GITHUB_WORKSPACE}
22 | cp -Recurse ./samples/crypt/devops solution
23 | .\automation\entry.ps1 ${env:GITHUB_RUN_NUMBER} ${env:GITHUB_REF}
24 |
25 | - name: Artifact Retention
26 | uses: actions/upload-artifact@v4
27 | with:
28 | name: deploy
29 | path: release.ps1
30 |
31 | NO_PROP:
32 | name: Verify nothing attempted when unknown Environment supplied
33 | needs: build
34 | runs-on: windows-latest
35 | steps:
36 | - name: Download Artifacts
37 | uses: actions/download-artifact@v4
38 | with:
39 | name: deploy
40 | path: drop
41 |
42 | - name: NO_PROP
43 | shell: powershell # pwsh for PowerShell Core
44 | run: |
45 | cd ${env:GITHUB_WORKSPACE}\drop
46 | .\release.ps1 NO_PROP
47 |
48 | WINDOWS:
49 | name: Decryption Test from Sample
50 | needs: [build, NO_PROP]
51 | runs-on: windows-latest
52 | steps:
53 | - name: Download Artifacts
54 | uses: actions/download-artifact@v4
55 | with:
56 | name: deploy
57 | path: drop
58 |
59 | - name: WINDOWS
60 | shell: powershell # pwsh for PowerShell Core
61 | run: |
62 | cd ${env:GITHUB_WORKSPACE}\drop
63 | .\release.ps1 WINDOWS
64 |
--------------------------------------------------------------------------------
/automation/local/copyTemplate.ps1:
--------------------------------------------------------------------------------
1 | # Emulate Linux SCP transferring file via WinRM
2 |
3 | function taskException ($taskName, $exit, $exception) {
4 | write-host "[$scriptName] Caught an exception excuting $taskName :" -ForegroundColor Red
5 | write-host " Exception Type: $($exception.Exception.GetType().FullName)" -ForegroundColor Red
6 | write-host " Exception Message: $($exception.Exception.Message)" -ForegroundColor Red
7 | exit $exit
8 | }
9 |
10 | $srcPath = $args[0]
11 |
12 | $scriptName = $myInvocation.MyCommand.Name
13 | if (-not(Test-Path $srcPath)) {
14 | write-host "`n[$scriptName] Source file not found! Throwing exception : $srcPath`n" -ForegroundColor Red
15 | throw "$srcPath"
16 | }
17 |
18 | Write-Host "`n[$scriptName] Copy $srcPath to 'deployLand'`n"
19 | try {
20 | [System.IO.FileStream]$srcStream = New-Object IO.FileStream $srcPath, Open
21 | [Byte[]]$readBuffer = New-Object Byte[] 1048576 # 1MB
22 |
23 | do {
24 |
25 | # Read from the input file and create a resulting buffer to the exact length of the stream
26 | $streamLength = $srcStream.Read($readBuffer, 0, $readBuffer.Length)
27 | [Byte[]] $buffer = New-Object Byte[] $streamLength
28 | for ($index = 0; $index -lt $streamLength; $index += 1) {
29 | $buffer[$index] = $readBuffer[$index]
30 | }
31 |
32 | # Process each buffer on the target host
33 | Invoke-Command -Session $session `
34 | -ScriptBlock {
35 | param(
36 | [Byte[]] $inBuffer
37 | )
38 |
39 | try {
40 | [System.IO.FileStream]$dstStream = New-Object IO.FileStream 'deployLand', Append
41 | $dstStream.Write($inBuffer, 0, $inBuffer.length)
42 | } catch {
43 | taskException "BUFFER_WRITE" 201 $_
44 | } finally {
45 | $dstStream.Dispose()
46 | $dstStream = $null
47 | }
48 | } `
49 | -ArgumentList @( ,$buffer )
50 |
51 | } while ($streamLength -gt 0)
52 |
53 | } catch {
54 | taskException "BUFFER_READ" 200 $_
55 | } finally {
56 |
57 | $srcStream.Dispose()
58 | $srcStream = $null
59 |
60 | [System.GC]::Collect()
61 | }
62 |
--------------------------------------------------------------------------------
/provisioning/SDK.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'SDK.ps1'
2 | $versionChoices = '4.5.2'
3 | Write-Host
4 | Write-Host "[$scriptName] ---------- start ----------"
5 | $version = $args[0]
6 | if ($version) {
7 | Write-Host "[$scriptName] version : $version"
8 | } else {
9 | $version = '4.5.2'
10 | Write-Host "[$scriptName] version : $version (default, choices $versionChoices)"
11 | }
12 |
13 | $mediaDir = $args[1]
14 | if ($mediaDir) {
15 | Write-Host "[$scriptName] mediaDir : $mediaDir"
16 | } else {
17 | $mediaDir = "$env:TEMP"
18 | Write-Host "[$scriptName] mediaDir : $mediaDir (default)"
19 | }
20 |
21 | if (!( Test-Path $mediaDir )) {
22 | Write-Host "[$scriptName] mkdir $mediaDir"
23 | mkdir $mediaDir
24 | }
25 |
26 | switch ($version) {
27 | '4.5.2' {
28 | $file = 'NDP452-KB2901951-x86-x64-DevPack.exe'
29 | $uri = 'http://download.microsoft.com/download/4/3/B/43B61315-B2CE-4F5B-9E32-34CCA07B2F0E/' + $file
30 | }
31 | default {
32 | Write-Host "[$scriptName] version not supported, choices are $versionChoices"
33 | }
34 | }
35 |
36 | $installFile = $mediaDir + '\' + $file
37 | Write-Host "[$scriptName] installFile : $installFile"
38 |
39 | $logFile = $installDir = [Environment]::GetEnvironmentVariable('TEMP', 'user') + '\' + $file + '.log'
40 | Write-Host "[$scriptName] logFile : $logFile"
41 |
42 | Write-Host
43 | if ( Test-Path $installFile ) {
44 | Write-Host "[$scriptName] $installFile exists, download not required"
45 | } else {
46 |
47 | $webclient = new-object system.net.webclient
48 | Write-Host "[$scriptName] $webclient.DownloadFile($uri, $installFile)"
49 | $webclient.DownloadFile($uri, $installFile)
50 | }
51 |
52 | Write-Host
53 | $argList = @('/q', '/norestart')
54 | Write-Host "[$scriptName] Start-Process -FilePath $installFile -ArgumentList $argList -PassThru -Wait"
55 | try {
56 | $proc = Start-Process -FilePath $installFile -ArgumentList $argList -PassThru -Wait
57 | } catch {
58 | Write-Host "[$scriptName] $installFile Exception : $_" -ForegroundColor Red
59 | exit 200
60 | }
61 |
62 | Write-Host
63 | Write-Host "[$scriptName] ---------- stop ----------"
64 |
--------------------------------------------------------------------------------
/samples/crypt/devops/CDAF.solution:
--------------------------------------------------------------------------------
1 | solutionName=crypt
2 | # productName=Cryptography Solution
3 |
4 | # Custom Diagnostics on error
5 | # CDAF_ERROR_DIAG=foreach ( $item in ( Get-WmiObject Win32_LogicalDisk )) { get-volume -DriveLetter ($item.DeviceID).split(":")[0] }
6 |
7 | # containerBuild minimum configuration, if a Dockerfile is not found, a default file will be used
8 | # containerImage=cdaf/windows
9 |
10 | # containerBuild default process
11 | # containerBuild=& "${AUTOMATIONROOT}\processor\containerBuild.ps1" "$SOLUTION" "$BUILDNUMBER" "$REVISION" "$ACTION"
12 |
13 | artifactPrefix=0.0
14 | # productVersion=0.0.0
15 | # packageFeatures=minimal
16 | # packageMethod=tarball
17 |
18 | # imageBuild minimum configuration, if a Dockerfile is not found, a default file will be created
19 | # buildImage=cdaf/windows
20 |
21 | # imageBuild default process
22 | # imageBuild=& "$CDAF_CORE\imageBuild.ps1" "${SOLUTION}_${REVISION}" "${BUILDNUMBER}" "${buildImage}" "${LOCAL_WORK_DIR}"
23 | # CDAF_DOCKER_REQUIRED=yes
24 |
25 | # imageBuild integrated push to registry
26 | # CDAF_REGISTRY_URL=${env:CI_REGISTRY}
27 | # CDAF_REGISTRY_TAG=latest ${env:CI_REGISTRY}/linux/${env:SOLUTION}:$BUILDNUMBER
28 | # CDAF_REGISTRY_USER=${env:CI_REGISTRY_USER}
29 | # CDAF_REGISTRY_TOKEN=${env:CI_JOB_TOKEN}
30 |
31 | # defaultBranch=master
32 | # defaultEnvironment=DESKTOP
33 |
34 | # gitRemoteURL=https://github.com/cdaf/${SOLUTION}.git
35 | # gitUserNameEnvVar=${env:GIT_USER}
36 | # gitUserPassEnvVar=${env:GIT_PASS}
37 | # gitCustomCleanup=& $AUTOMATIONROOT\buildandpackage\clean.ps1
38 |
39 | # processSequence=localTasks.ps1 remoteTasks.ps1 containerTasks.ps1
40 |
41 | # containerDeploy minimal config, if directory containerDeploy is found, a customer image build will be attempted
42 | # runtimeImage=cdaf/windows
43 |
44 | # containerDeploy default process
45 | # containerDeploy=& "$CDAF_CORE\containerDeploy.ps1" "${TARGET}" "${RELEASE}" "${SOLUTION}" "${BUILDNUMBER}" "${REVISION}"
46 |
47 | # containerDeploy including additional files in image, and retain the resulting image
48 | # runtimeFiles=$WORKSPACE_ROOT\release.ps1 $CDAF_CORE\embed.ps1
49 | # runtimeRetain=yes
50 |
--------------------------------------------------------------------------------
/provisioning/setenv.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$variable,
3 | [string]$value,
4 | [string]$target,
5 | [string]$secret
6 | )
7 |
8 | cmd /c "exit 0"
9 | $scriptName = 'setenv.ps1'
10 |
11 | function mask ($value) {
12 | return (Get-FileHash -InputStream $([IO.MemoryStream]::new([byte[]][char[]]$value)) -Algorithm MD5).Hash
13 | }
14 |
15 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
16 | function executeExpression ($expression) {
17 | $error.clear()
18 | Write-Host "$expression"
19 | try {
20 | Invoke-Expression $expression
21 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
22 | } catch { Write-Output $_.Exception|format-list -force; exit 2 }
23 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
24 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
25 | }
26 |
27 | Write-Host "`n[$scriptName] ---------- start ----------"
28 | if ( $variable ) {
29 | Write-Host "[$scriptName] variable : $variable"
30 | } else {
31 | $mediaDir = "$env:TEMP"
32 | Write-Host "[$scriptName] mediaDir : $mediaDir (default)"
33 | }
34 |
35 | if ( $value ) {
36 | if (( $secret ) -or ( $variable -like '*key*' ) -or ( $variable -like '*secret*' ) -or ( $variable -like '*password*' ) -or ( $variable -like '*pat*' )) {
37 | Write-Host "[$scriptName] value : $(mask $value) (MD5 mask)"
38 | } else {
39 | Write-Host "[$scriptName] value : $value"
40 | }
41 | } else {
42 | Write-Host "[$scriptName] value required, exiting!"
43 | exit 101
44 | }
45 |
46 | if ( $target ) {
47 | Write-Host "[$scriptName] target : $target (choices user or machine)"
48 | } else {
49 | $target = 'user'
50 | Write-Host "[$scriptName] target : $target (default, choices user or machine)"
51 | }
52 |
53 | Write-Host
54 | executeExpression "[Environment]::SetEnvironmentVariable(`'$variable`', `$value, `'$target`')"
55 | executeExpression "`$env:$variable = [Environment]::GetEnvironmentVariable(`'$variable`', `'$target`')"
56 |
57 | Write-Host "`n[$scriptName] ---------- stop -----------`n"
--------------------------------------------------------------------------------
/automation/local/embed.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "[$scriptName] $expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | }
11 |
12 | $scriptName = 'embed.ps1'
13 | Write-Host
14 | Write-Host "[$scriptName] Turn a file into an embedded string"
15 | Write-Host
16 | Write-Host "[$scriptName] ---------- start ----------"
17 | $fileIn = $args[0]
18 | if ($fileIn) {
19 | Write-Host "[$scriptName] fileIn : $fileIn (choices $configChoices)"
20 | } else {
21 | Write-Host "[$scriptName] Input file not supplied, exiting!"
22 | exit 100
23 | }
24 |
25 | $fileOut = $args[1]
26 | if ($fileOut) {
27 | Write-Host "[$scriptName] fileOut : $fileOut"
28 | } else {
29 | $fileOut = 'embedded.ps1'
30 | Write-Host "[$scriptName] fileOut : $fileOut (default)"
31 | }
32 |
33 | Write-Host
34 | Write-Host "[$scriptName] Test input file ($fileIn) exists"
35 | $extension = [System.IO.Path]::GetExtension("$fileIn")
36 | $verificationFile = 'testfile' + $extension
37 |
38 | Write-Host
39 | Write-Host "[$scriptName] Load input file ($fileIn)"
40 | $ByteArray = [System.IO.File]::ReadAllBytes($fileIn)
41 | $EncodedText = [System.Convert]::ToBase64String($ByteArray)
42 |
43 | if (Test-Path $fileOut) {
44 | Write-Host
45 | Write-Host "[$scriptName] Delete Existing $fileOut"
46 | Remove-Item $fileOut
47 | }
48 |
49 | Write-Host
50 | Write-Host "[$scriptName] Create script ($fileOut) which will generated the embedded file"
51 | Add-Content $fileOut "`$EncodedText = `'$EncodedText`'"
52 | Add-Content $fileOut "`$ByteArray = [System.Convert]::FromBase64String(`$EncodedText)"
53 | Add-Content $fileOut "[System.IO.File]::WriteAllBytes(`'$verificationFile`', `$ByteArray)"
54 |
55 | Write-Host
56 | Write-Host "[$scriptName] Execute scipt ($fileOut) to recreate input file as $verificationFile"
57 | executeExpression "./$fileOut"
58 |
59 | Write-Host
60 | Write-Host "[$scriptName] ---------- stop ----------"
61 |
--------------------------------------------------------------------------------
/provisioning/IISPoolAccount.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$poolid,
3 | [string]$poolPassword,
4 | [string]$poolName
5 | )
6 |
7 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
8 | function executeExpression ($expression) {
9 | $error.clear()
10 | Write-Host "$expression"
11 | try {
12 | Invoke-Expression $expression
13 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
14 | } catch { $_.Exception|format-list -force; exit 2 }
15 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
16 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
17 | }
18 |
19 | $scriptName = 'IISPoolAccount.ps1'
20 |
21 | Write-Host
22 | Write-Host "[$scriptName] ---------- start ----------"
23 | if ($poolid) {
24 | Write-Host "[$scriptName] poolid : $poolid"
25 | } else {
26 | Write-Host "[$scriptName] poolid not supplied! Exit with code 100"; exit 100
27 | }
28 |
29 | if ($poolPassword) {
30 | Write-Host "[$scriptName] poolPassword : *********************"
31 | } else {
32 | Write-Host "[$scriptName] poolPassword : not supplied (assuming Managed Service Account)"
33 | }
34 |
35 | if ($poolName) {
36 | Write-Host "[$scriptName] poolName : $poolName"
37 | } else {
38 | $poolName = 'DefaultAppPool'
39 | Write-Host "[$scriptName] poolName : $poolName (default)"
40 | }
41 |
42 | executeExpression 'Import-Module ServerManager'
43 | executeExpression 'Import-Module WebAdministration'
44 |
45 | try {
46 | $appPool = get-item iis:\apppools\$poolName
47 | } catch {
48 | Write-Host "[$scriptName] Sleep to ensure any previous provisioning is complete"
49 | Start-Sleep 5
50 | $appPool = get-item iis:\apppools\$poolName
51 | }
52 |
53 | Write-Host "`n[$scriptName] Set ID for iis:\apppools\$poolName to $poolid"
54 | $appPool.processModel.userName = $poolid
55 | if ($poolPassword) {
56 | $appPool.processModel.password = $poolPassword
57 | }
58 | $appPool.processModel.identityType = 'SpecificUser'
59 | $appPool | Set-Item
60 | $appPool.Stop()
61 | $appPool.Start()
62 |
63 | Write-Host "[$scriptName] IIS Recycled"
64 |
65 | Write-Host "`n[$scriptName] ---------- stop ----------"
66 |
--------------------------------------------------------------------------------
/provisioning/agent.ps1:
--------------------------------------------------------------------------------
1 | function exceptionExit {
2 | param ($exitcode)
3 | write-host
4 | $host.SetShouldExit($exitCode)
5 | exit
6 | }
7 |
8 | function taskComplete { param ($taskName)
9 | write-host
10 | write-host "[$scriptName] Remote Task ($taskName) Successfull " -ForegroundColor Green
11 | write-host
12 | }
13 |
14 | $scriptName = 'agent.ps1'
15 |
16 | Write-Host
17 | Write-Host "[$scriptName] Create an encrypted password file (outfile) for the current user and test against address (targethost)"
18 | Write-Host
19 | Write-Host "[$scriptName] ---------- start ----------"
20 | $targetHost = $args[0]
21 | if ($targetHost) {
22 | Write-Host "[$scriptName] Target Host : $targetHost"
23 | } else {
24 | $targetHost = $(hostname)
25 | Write-Host "[$scriptName] Target Host not passed, default to local host ($targetHost)"
26 | }
27 |
28 | $userID = $args[1]
29 | if ($userID) {
30 | Write-Host "[$scriptName] Target User : $userID"
31 | } else {
32 | $userID = $(whoami)
33 | Write-Host "[$scriptName] Target Host not passed, default to current user ($userID)"
34 | }
35 |
36 | $outputFile = $args[2]
37 | if ($outputFile) {
38 | Write-Host "[$scriptName] Output File : $outputFile"
39 | } else {
40 | $outputFile = "$(hostname)-${targetHost}.crypt"
41 | Write-Host "[$scriptName] Output File not passed, default to $outputFile"
42 | }
43 |
44 | Write-Host
45 | Write-Host "[$scriptName] Pipe password into an encrypted file, enter password : " -NoNewline
46 | read-host -assecurestring | convertfrom-securestring | out-file $outputFile
47 |
48 | Write-Host
49 | Write-Host "[$scriptName] Read the password into a variable (don't print the content of this variable)"
50 | $password = get-content $outputFile | convertto-securestring
51 |
52 | Write-Host
53 | Write-Host "[$scriptName] Create a credential object with the user ID and password"
54 | $cred = New-Object System.Management.Automation.PSCredential ($userID, $password )
55 | Write-Host
56 | try {
57 | Invoke-Command -credential $cred -ComputerName $targetHost { Write-Host "Running as $(whoami) on $(hostname), test successful" }
58 | if(!$?){ exceptionExit 1 }
59 | } catch { exceptionExit 2 }
60 |
61 | Write-Host
62 | Write-Host "[$scriptName] ---------- stop ----------"
63 |
--------------------------------------------------------------------------------
/provisioning/computerCertificate.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$certificateName
3 | )
4 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
5 | function executeExpression ($expression) {
6 | $error.clear()
7 | $LASTEXITCODE = 0
8 | Write-Host "$expression"
9 | try {
10 | $output = Invoke-Expression $expression
11 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
12 | } catch { echo $_.Exception|format-list -force; exit 2 }
13 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
14 | if ( $LASTEXITCODE -ne 0 ) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
15 | return $output
16 | }
17 |
18 | $scriptName = 'computerCertificate.ps1'
19 | Write-Host "`n[$scriptName] ---------- start ----------"
20 | if ($certificateName) {
21 | Write-Host "[$scriptName] certificateName : $certificateName"
22 | } else {
23 | $certificateName = 'localhost'
24 | Write-Host "[$scriptName] certificateName : $certificateName (not passed, set to default)"
25 | }
26 |
27 | foreach ( $certificate in get-childitem "cert:\localmachine\my" ) {
28 | if ($certificate.DnsNameList -eq "$certificateName") {
29 | if ( $certificate.NotAfter -lt (Get-Date) ) {
30 | Write-Host "[$scriptName] Thumbprint found ($returnValue) but expired $($certificate.NotAfter)"
31 | } else {
32 | $count = $count + 1
33 | $returnValue = $certificate.Thumbprint
34 | Write-Host "[$scriptName] Thumbprint found $returnValue"
35 | }
36 | }
37 | }
38 |
39 | if ( $returnValue ) {
40 | if ( $count -gt 1 ) {
41 | Write-Host "`n[$scriptName] Multiple certificates found for $certificateName, returning last = $returnValue"
42 | } else {
43 | Write-Host "`n[$scriptName] $certificateName certificate exists with thumbprint = $returnValue"
44 | }
45 | } else {
46 | $certificate = executeExpression "New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname $certificateName"
47 | $returnValue = $certificate.Thumbprint
48 | Write-Host "`n[$scriptName] Created self-signed certificate for $certificateName with thumbprint = $returnValue"
49 | }
50 |
51 | Write-Host "`n[$scriptName] ---------- stop ----------"
52 | $error.clear()
53 | return $returnValue
54 | exit 0
--------------------------------------------------------------------------------
/provisioning/sqlAuthMode.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$mode,
3 | [string]$instance
4 | )
5 | $scriptName = 'sqlAuthMode.ps1'
6 | cmd /c "exit 0"
7 |
8 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
9 | function executeExpression ($expression) {
10 | $error.clear()
11 | Write-Host "$expression"
12 | try {
13 | $output = Invoke-Expression $expression
14 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
15 | } catch { echo $_.Exception|format-list -force; exit 2 }
16 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
17 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
18 | return $output
19 | }
20 |
21 | Write-Host "`n[$scriptName] Because the instance service has to be restarted, this script only supports execution on the SQL host itself"
22 | Write-Host "`n[$scriptName] ---------- start ----------"
23 | if ($mode) {
24 | Write-Host "[$scriptName] mode : $mode"
25 | } else {
26 | $mode = 'Mixed'
27 | Write-Host "[$scriptName] mode : $mode (default)"
28 | }
29 |
30 | if ($instance) {
31 | $sqlinstance = 'MSSQL$' + $instance
32 | Write-Host "[$scriptName] instance : $sqlinstance"
33 | } else {
34 | $sqlinstance = 'MSSQLSERVER'
35 | Write-Host "[$scriptName] instance : $sqlinstance (default)"
36 | }
37 |
38 | # SMO installed as part of Standard, connect to the local default instance
39 | executeExpression '[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")'
40 | if ($instance) {
41 | $srv = executeExpression 'new-Object Microsoft.SqlServer.Management.Smo.Server(".\$instance")'
42 | } else {
43 | $srv = executeExpression 'new-Object Microsoft.SqlServer.Management.Smo.Server(".")'
44 | }
45 |
46 | executeExpression '$srv.Databases | Select name' # Establish connection
47 |
48 | # Change the mode and restart the instance
49 | executeExpression "`$srv.Settings.LoginMode = [Microsoft.SqlServer.Management.SMO.ServerLoginMode]::$mode"
50 | executeExpression '$srv.Alter()'
51 | executeExpression '$srv.Settings.LoginMode'
52 | executeExpression "Restart-Service '$sqlinstance'"
53 |
54 | Write-Host "`n[$scriptName] ---------- stop ----------"
55 | exit 0
--------------------------------------------------------------------------------
/provisioning/addVSTSPackageCred.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$feedName,
3 | [string]$uri,
4 | [string]$feedPass,
5 | [string]$feedUser,
6 | [string]$nugetPath
7 | )
8 | $scriptName = 'addVSTSPackageCred.ps1'
9 |
10 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
11 | function executeExpression ($expression) {
12 | $error.clear()
13 | Write-Host "$expression"
14 | try {
15 | Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
17 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
18 | } catch { echo $_.Exception|format-list -force; exit 2 }
19 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
20 | }
21 |
22 | Write-Host "`n[$scriptName] Add VSTS Package Management credentials to allow non interactive authentication for NuGet."
23 | Write-Host "`n[$scriptName] ---------- start ----------"
24 | if ($feedName) {
25 | Write-Host "[$scriptName] feedName : $feedName"
26 | } else {
27 | Write-Host "[$scriptName] feedName is required"; exit 100
28 | }
29 |
30 | if ($uri) {
31 | Write-Host "[$scriptName] uri : $uri"
32 | } else {
33 | Write-Host "[$scriptName] uri is required"; exit 101
34 | }
35 |
36 | if ($feedPass) {
37 | Write-Host "[$scriptName] feedPass : `$feedPass"
38 | } else {
39 | Write-Host "[$scriptName] feedPass is required"; exit 102
40 | }
41 |
42 | if ($feedUser) {
43 | Write-Host "[$scriptName] feedUser : $feedUser"
44 | } else {
45 | $feedUser = 'usingPAT'
46 | Write-Host "[$scriptName] feedUser : $feedUser (default)"
47 | }
48 |
49 | if ($nugetPath) {
50 | Write-Host "[$scriptName] nugetPath : $nugetPath"
51 | } else {
52 | $nugetPath = 'C:/agent/externals/nuget/nuget.exe'
53 | Write-Host "[$scriptName] nugetPath : $nugetPath (default)"
54 | }
55 |
56 | Write-Host "[$scriptName] whoami : $(whoami)"
57 |
58 | Write-Host "`n[$scriptName] Add Source`n"
59 | executeExpression "$nugetPath sources add -name $feedName -Source $uri -username $feedUser -password `$feedPass"
60 |
61 | Write-Host "`n[$scriptName] List resulting sources`n"
62 | executeExpression "$nugetPath sources"
63 |
64 | Write-Host "`n[$scriptName] ---------- stop ----------"
65 | exit 0
66 |
--------------------------------------------------------------------------------
/samples/targetlessCD/automation-solution/customLocal/compose.tsk:
--------------------------------------------------------------------------------
1 | Write-Host "`nLoad the branch (REVISION) and container image from the manifest, placed here by package.tsk`n"
2 | PROPLD manifest.txt
3 |
4 | ASSIGN $id = $("${SOLUTION}_${REVISION}").ToLower()
5 |
6 | cd compose
7 | ..\imageBuild.ps1 ${id} ${BUILDNUMBER} ${containerImage}
8 | cd ..
9 |
10 | ASSIGN $env:TARGET_TAG = "${id}_taskslocal"
11 | ASSIGN $env:TEST_TAG = "${id}_test"
12 | & $WORKSPACE\dockerClean.ps1 $env:TARGET_TAG ${BUILDNUMBER}
13 | & $WORKSPACE\dockerClean.ps1 $env:TEST_TAG ${BUILDNUMBER}
14 |
15 | Write-Host "List containers current state`n"
16 | docker ps
17 |
18 | Write-Host "Load desired state to persistent store`n"
19 | ASSIGN $composePersist = "${env:TEMP}\${id}"
20 | MAKDIR $composePersist
21 | cd $composePersist
22 | $env:WORK_SPACE = $(pwd)
23 |
24 | Write-Host "Cleanup from previously test`n"
25 | if ( Test-Path docker-compose.yml ) { EXECMD "docker-compose down --remove-orphans" }
26 |
27 | Write-Host "Load Release to WORK_SPACE ($env:WORK_SPACE)`n"
28 | $parent = Split-Path -parent $WORKSPACE
29 | Write-Host "`nLoad current artefact set from $parent`n"
30 | VECOPY $WORKSPACE\compose\docker-compose.yml $composePersist
31 | REFRSH $parent\TasksLocal $composePersist\TasksLocal
32 |
33 | Write-Host "Set the build number to use`n"
34 | ASSIGN $env:TARGET_TAG = "${env:TARGET_TAG}:${BUILDNUMBER}"
35 | ASSIGN $env:TEST_TAG = "${env:TEST_TAG}:${BUILDNUMBER}"
36 |
37 | Write-Host "Start target [${env:TARGET_TAG}]`n"
38 | EXECMD "docker-compose up -d target"
39 | $containerID = $(docker ps -aq --filter "ancestor=$env:TARGET_TAG")
40 | & $WORKSPACE\dockerLog.ps1 $containerID 'IIS logging started'
41 |
42 | Write-Host "Execute tests [${env:TEST_TAG}] (allow 5 minutes to complete)`n"
43 | EXECMD "docker-compose up -d test"
44 | $containerID = $(docker ps -aq --filter "ancestor=$env:TEST_TAG")
45 | & $WORKSPACE\dockerLog.ps1 $containerID 'Automated Test Execution completed successfully.' 300
46 |
47 | Write-Host "`nTear down if `$env:COMPOSE_KEEP ($env:COMPOSE_KEEP) not set`n"
48 | if ( $env:COMPOSE_KEEP ) { docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq) } else { EXECMD "docker-compose down" }
49 |
50 | cd $WORKSPACE
51 |
52 | echo "Clean-up Transient Directory Created by imageBuild.sh"
53 | REMOVE $env:TEMP/${SOLUTION}
54 |
--------------------------------------------------------------------------------
/automation/buildandpackage/loadVSenv.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "[$scriptName] $expression"
5 | try {
6 | Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | }
11 |
12 | $scriptName = 'loadVSenv.ps1'
13 | Write-Host "[$scriptName] ---------- start ----------"
14 | Write-Host
15 | $version = $args[0]
16 | if ($version) {
17 | Write-Host "[$scriptName] version : $version"
18 | } else {
19 | $version = '2015'
20 | Write-Host "[$scriptName] version : not supplied, defaulted to $version"
21 | }
22 |
23 | # from http://stackoverflow.com/questions/2124753/how-i-can-use-powershell-with-the-visual-studio-command-prompt
24 | switch ($version) {
25 | 2017 {
26 | pushd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools"
27 | cmd /c "VsDevCmd.bat&set" |
28 | foreach {
29 | if ($_ -match "=") {
30 | Write-Host "[$scriptName] $_";$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
31 | }
32 | }
33 | popd
34 | Write-Host "`nVisual Studio 2017 Command Prompt variables set." -ForegroundColor Yellow
35 | }
36 | 2015 {
37 | pushd 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools'
38 | cmd /c "vsvars32.bat&set" |
39 | foreach {
40 | if ($_ -match "=") {
41 | Write-Host "[$scriptName] $_";$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
42 | }
43 | }
44 | popd
45 | write-host "`nVisual Studio 2015 Command Prompt variables set." -ForegroundColor Yellow
46 | }
47 | default {
48 | pushd 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC'
49 | cmd /c "vcvarsall.bat&set" |
50 | foreach {
51 | if ($_ -match "=") {
52 | Write-Host "[$scriptName] $_";$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
53 | }
54 | }
55 | popd
56 | write-host "`nVisual Studio 2010 Command Prompt variables set." -ForegroundColor Yellow
57 | }
58 | }
59 |
60 | Write-Host
61 | Write-Host "[$scriptName] ---------- stop ----------"
62 |
--------------------------------------------------------------------------------
/provisioning/removeUser.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$userName
3 | )
4 |
5 | cmd /c "exit 0"
6 | $Error.Clear()
7 |
8 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
9 | function executeExpression ($expression) {
10 | Write-Host "[$(Get-Date)] $expression"
11 | try {
12 | Invoke-Expression $expression
13 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
14 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
15 | if ( $LASTEXITCODE ) {
16 | if ( $LASTEXITCODE -ne 0 ) {
17 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
18 | } else {
19 | if ( $error ) {
20 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE, $error[] = $error`n" -ForegroundColor Yellow
21 | $error.clear()
22 | }
23 | }
24 | } else {
25 | if ( $error ) {
26 | Write-Host "[$scriptName][WARN] $Error array populated but LASTEXITCODE not set, $error[] = $error`n" -ForegroundColor Yellow
27 | $error.clear()
28 | }
29 | }
30 | }
31 |
32 | function removeLocal ($userName) {
33 | Write-Host "`n[$scriptName] Workgroup Host, delete local user ($userName).`n"
34 | $ADSIComp = executeExpression "[ADSI]`"WinNT://$Env:COMPUTERNAME,Computer`""
35 | executeExpression "`$ADSIComp.Delete('User', `"$userName`")"
36 | executeExpression "net user"
37 | }
38 |
39 | $scriptName = 'removeUser.ps1'
40 | Write-Host "`n[$scriptName] Remove User from Domain or Workgroup, Windows Server 2012 and above. Pass .\ prefix for local user.`n"
41 | Write-Host "`n[$scriptName] ---------- start ----------"
42 | if ($userName) {
43 | Write-Host "[$scriptName] userName : $userName"
44 | } else {
45 | $userName = 'vagrant'
46 | Write-Host "[$scriptName] userName : $userName (default)"
47 | }
48 |
49 | if ( $userName.StartsWith('.\')) {
50 |
51 | $prefix, $userName = $userName.Split('\')
52 | removeLocal $userName
53 |
54 | } else {
55 |
56 | if ((gwmi win32_computersystem).partofdomain -eq $true) {
57 |
58 | Write-Host "`n[$scriptName] Remove the new user`n"
59 | executeExpression "Remove-ADUser -Name $userName"
60 |
61 | } else {
62 |
63 | removeLocal $userName
64 |
65 | }
66 | }
67 |
68 | Write-Host "`n[$scriptName] ---------- stop ----------`n"
69 | exit 0
--------------------------------------------------------------------------------
/provisioning/mkdir.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$directoryName,
3 | [string]$userName
4 | )
5 |
6 | cmd /c "exit 0"
7 | $Error.Clear()
8 | $scriptName = 'mkdir.ps1'
9 |
10 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
11 | function executeExpression ($expression) {
12 | $error.clear()
13 | Write-Host "$expression"
14 | try {
15 | $output = Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 10 }
17 | } catch { echo $_.Exception|format-list -force; exit 11 }
18 | if ( $error[0] ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 12 }
19 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
20 | return $output
21 | }
22 |
23 | function setACL ($objectName, $userName) {
24 | Write-Host "[$scriptName] List ACL before changes"
25 | Get-Acl $objectName | Format-List
26 | $acl = Get-Acl $objectName
27 | $permission = $userName,"FullControl","Allow"
28 | $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
29 | $acl.SetAccessRule($accessRule)
30 | $acl | Set-Acl $objectName
31 | Write-Host "[$scriptName] List ACL after changes"
32 | Get-Acl $objectName | Format-List
33 | }
34 |
35 | Write-Host "`n[$scriptName] ---------- start ----------"
36 | if ($directoryName) {
37 | Write-Host "[$scriptName] directoryName : $directoryName"
38 | } else {
39 | Write-Host "[$scriptName] directoryName not supplied, exiting!"
40 | exit 100
41 | }
42 |
43 | if ($userName) {
44 | Write-Host "[$scriptName] userName : $userName"
45 | } else {
46 | Write-Host "[$scriptName] userName : (not supplied, ACL changes will not be attempted)"
47 | }
48 |
49 | if ( Test-Path $directoryName ) {
50 | Write-Host "[$scriptName] Directory $directoryName already exists, no action attempted."
51 | } else {
52 | executeExpression "New-Item -ItemType Directory -Force -Path `'$directoryName`'"
53 | }
54 | $newDir = executeExpression "New-Item -ItemType Directory -Force -Path `'$directoryName`'"
55 | Write-Host "Created $($newDir.FullName)"
56 |
57 | if ($userName) {
58 | Write-Host
59 | foreach ($item in Get-ChildItem -Recurse $directoryName) {
60 | setACL $item.FullName $userName
61 | }
62 | }
63 |
64 | Write-Host "`n[$scriptName] ---------- stop -----------"
65 |
--------------------------------------------------------------------------------
/samples/crypt/devops/tasksRun.tsk:
--------------------------------------------------------------------------------
1 | echo "Some basic functions"
2 | REFRSH . $TMPDIR/workspacecopy
3 | REMOVE TMPDIR/workspacecopy
4 |
5 | Write-Host "Resolve and reveal property, then assign to a named variable`n" -ForegroundColor Green
6 | ASSIGN $HOSTNAME = $deployHost
7 |
8 | Write-Host "Load Propertes as variables and reveal their values`n" -ForegroundColor Green
9 | PROPLD $TARGET reveal
10 |
11 | Write-Host "The following is an example of secrets management" -ForegroundColor Green
12 | Write-Host "DO NOT log the AES key, this is supplied by CD tool as environment variable`n" -ForegroundColor Yellow
13 | $env:AES_KEY = '29-240-88-121-33-64-150-226-136-160-144-115-127-74-74-30'
14 |
15 | Write-Host "A sensitive value can be logged using non-reversable mask" -ForegroundColor Green
16 | $env:AES_KEY_MASK = (MASKED $env:AES_KEY)
17 |
18 | VARCHK properties.varchk
19 |
20 | Write-Host "DO NOT Decrypt without capturing return value or secrets will be disclosed`n" -ForegroundColor Yellow
21 | DECRYP .\crypt\AES_CRYPT $env:AES_KEY
22 |
23 | Write-Host "Either capture Decrypt output to a variable`n" -ForegroundColor Cyan
24 | $secrets = DECRYP .\crypt\AES_CRYPT $env:AES_KEY
25 |
26 | Write-Host "Or stream Decrypt function to reconstruct an encrypted file`n" -ForegroundColor Cyan
27 | DECRYP .\crypt\AES_CRYPT $env:AES_KEY > unencypted.txt
28 |
29 | Write-Host "List content of tokenised properties file`n" -ForegroundColor Green
30 | cat crypt-test.yml
31 |
32 | Write-Host "Detokenise plain text with embedded variable`n" -ForegroundColor Cyan
33 | DETOKN crypt-test.yml $TARGET reveal
34 |
35 | Write-Host "Safe to list as no sensitive values have been transformed`n" -ForegroundColor Green
36 | cat crypt-test.yml
37 |
38 | Write-Host "Detokenise secrets with embedded variable, using non-default token, i.e. @remoteUser@`n" -ForegroundColor Cyan
39 | $env:CDAF_OVERRIDE_TOKEN = '@'
40 | DETOKN crypt-test.yml $TARGET resolve
41 |
42 | Write-Host "If resolved secrets are known CD tool, listing should result in masked values`n" -ForegroundColor Yellow
43 | cat crypt-test.yml
44 |
45 | Write-Host "Detokenise with masked secrets, only supports encrypted name/value files, in-memory, i.e. unencrypted file is never on disk`n" -ForegroundColor Cyan
46 | ASSIGN $env:CDAF_OVERRIDE_TOKEN
47 | DETOKN crypt-test.yml .\crypt\AES_CRYPT $env:AES_KEY
48 |
49 | Write-Host "DO NOT list the contents of the AES detokenised file because CD tool does not know to mask these values`n" -ForegroundColor Red
50 | cat crypt-test.yml
--------------------------------------------------------------------------------
/orchestration/jenkins/jenkins-declaritive-pipeline/Jenkinsfile:
--------------------------------------------------------------------------------
1 | pipeline {
2 | agent none
3 | options {
4 | buildDiscarder(logRotator(numToKeepStr: '10'))
5 | }
6 | triggers {
7 | pollSCM 'H/3 * * * *'
8 | }
9 | stages {
10 | stage('Application Build and Test') {
11 | agent any
12 | steps {
13 | checkout scm
14 | bat "automation\\ci.bat ${BUILD_NUMBER} ${BRANCH_NAME}"
15 | }
16 | }
17 | stage('Packer Image') {
18 | when { branch 'master'}
19 | agent any
20 | steps {
21 | sh "TasksLocal/delivery.sh PACKER"
22 | }
23 | }
24 | stage('CD') {
25 | when { branch 'master'}
26 | agent any
27 | steps {
28 | bat "TasksLocal\\delivery.bat ${env.STAGE_NAME}"
29 | }
30 | }
31 |
32 | stage ('Test Manager Approval') {
33 | when { branch 'master'}
34 | steps {
35 | timeout(time:1, unit:'DAYS') {
36 | input message:'Deploy to Acceptence Test?'
37 | }
38 | }
39 | }
40 |
41 | stage('TEST') {
42 | when { branch 'master'}
43 | agent any
44 | steps {
45 | bat "TasksLocal\\delivery.bat ${env.STAGE_NAME}"
46 | }
47 | }
48 |
49 | stage ('Product Owner Approval') {
50 | when { branch 'master'}
51 | steps {
52 | timeout(time:2, unit:'DAYS') {
53 | input message:'Deploy to Production?'
54 | }
55 | }
56 | }
57 |
58 | stage('PROD') {
59 | when { branch 'master'}
60 | agent any
61 | steps {
62 | bat "TasksLocal\\delivery.bat ${env.STAGE_NAME}"
63 | }
64 | }
65 | }
66 | post {
67 | success {
68 | echo 'I succeeeded!'
69 | }
70 | unstable {
71 | echo 'I am unstable :/'
72 | emailext (
73 | subject: "Jenkins Job Unstable : Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
74 | body: "${env.BUILD_URL}",
75 | compressLog: true,
76 | recipientProviders: [[$class: 'DevelopersRecipientProvider']]
77 | )
78 | }
79 | failure {
80 | echo 'I failed :('
81 | emailext (
82 | subject: "Jenkins Job Failed : Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
83 | body: "${env.BUILD_URL}",
84 | attachLog: true,
85 | recipientProviders: [[$class: 'DevelopersRecipientProvider']]
86 | )
87 | }
88 | changed {
89 | echo 'Things were different before...'
90 | }
91 | always {
92 | junit '**/target/surefire-reports/*.xml'
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/provisioning/addFeature.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$feature,
3 | [string]$options,
4 | [string]$media,
5 | [string]$wimIndex
6 | )
7 | $scriptName = 'addFeature.ps1'
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | $error.clear()
12 | Write-Host "$expression"
13 | try {
14 | Invoke-Expression $expression
15 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
16 | } catch { echo $_.Exception|format-list -force; exit 2 }
17 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
18 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
19 | }
20 |
21 | Write-Host "`n[$scriptName] Add Windows Feature using DIM source if provided."
22 | Write-Host "`n[$scriptName] ---------- start ----------"
23 | if ($feature) {
24 | Write-Host "[$scriptName] feature : $feature"
25 | } else {
26 | $feature = 'Web-Scripting-Tools'
27 | Write-Host "[$scriptName] feature : $feature (default)"
28 | }
29 |
30 | if ($options) {
31 | Write-Host "[$scriptName] options : $options"
32 | } else {
33 | Write-Host "[$scriptName] options : not supplied"
34 | }
35 |
36 | if ($media) {
37 | Write-Host "[$scriptName] media : $media"
38 | } else {
39 | $media = "$env:TEMP\install.wim"
40 | Write-Host "[$scriptName] media : $media (default)"
41 | }
42 |
43 | if ($wimIndex) {
44 | Write-Host "[$scriptName] wimIndex : $wimIndex"
45 | } else {
46 | $wimIndex = '2'
47 | Write-Host "[$scriptName] wimIndex : $wimIndex (default, Standard Edition)"
48 | }
49 |
50 | # If media is not found, install will attempt to download from windows update
51 | if ( Test-Path $media ) {
52 | if ( $media -match ':' ) {
53 | $sourceOption = '-Source wim:' + $media + ":$wimIndex"
54 | Write-Host "[$scriptName] Media path found, using source option $sourceOption"
55 | } else {
56 | $sourceOption = '-Source ' + $media
57 | Write-Host "[$scriptName] Media path found, using source option $sourceOption"
58 | }
59 | } else {
60 | Write-Host "[$scriptName] media path not found, will attempt to download from windows update."
61 | }
62 |
63 | Write-Host "`n[$scriptName] Install $feature"
64 | executeExpression "Install-WindowsFeature -Name `'$feature`' $options $sourceOption"
65 |
66 | Write-Host "`n[$scriptName] ---------- stop ----------"
67 | exit 0
68 |
--------------------------------------------------------------------------------
/provisioning/WIFSDK.ps1:
--------------------------------------------------------------------------------
1 | $scriptName = 'WIFSDK.ps1'
2 | $versionChoices = '4'
3 | Write-Host
4 | Write-Host "[$scriptName] Windows Identity Framework Software Development Kit"
5 | Write-Host
6 | Write-Host "[$scriptName] ---------- start ----------"
7 | $version = $args[0]
8 | if ($version) {
9 | Write-Host "[$scriptName] version : $version"
10 | } else {
11 | $version = '4'
12 | Write-Host "[$scriptName] version : $version (default, choices $versionChoices)"
13 | }
14 |
15 | $mediaDir = $args[1]
16 | if ($mediaDir) {
17 | Write-Host "[$scriptName] mediaDir : $mediaDir"
18 | } else {
19 | $mediaDir = "$env:TEMP"
20 | Write-Host "[$scriptName] mediaDir : $mediaDir (default)"
21 | }
22 |
23 | if (!( Test-Path $mediaDir )) {
24 | Write-Host "[$scriptName] mkdir $mediaDir"
25 | mkdir $mediaDir
26 | }
27 |
28 | Write-Host
29 |
30 | switch ($version) {
31 | '4' {
32 | $file = 'WindowsIdentityFoundation-SDK-4.0.msi'
33 | $uri = 'https://download.microsoft.com/download/7/0/1/70118832-3749-4C75-B860-456FC0712870/' + $file
34 | }
35 | '3.5' {
36 | $file = 'WindowsIdentityFoundation-SDK-3.5.msi'
37 | $uri = 'https://download.microsoft.com/download/7/0/1/70118832-3749-4C75-B860-456FC0712870/' + $file
38 | }
39 | default {
40 | Write-Host "[$scriptName] version not supported, choices are $versionChoices"
41 | }
42 | }
43 |
44 | $installFile = $mediaDir + '\' + $file
45 | Write-Host "[$scriptName] installFile : $installFile"
46 |
47 | $logFile = $installDir = [Environment]::GetEnvironmentVariable('TEMP', 'user') + '\' + $file + '.log'
48 | Write-Host "[$scriptName] logFile : $logFile"
49 |
50 | Write-Host
51 | $fullpath = $mediaDir + '\' + $file
52 | if ( Test-Path $fullpath ) {
53 | Write-Host "[$scriptName] $fullpath exists, download not required"
54 | } else {
55 | $webclient = new-object system.net.webclient
56 | Write-Host "[$scriptName] $webclient.DownloadFile($uri, $fullpath)"
57 | $webclient.DownloadFile($uri, $fullpath)
58 | }
59 |
60 | $argList = @(
61 | "/qn",
62 | "/l*",
63 | "$logFile",
64 | "/i",
65 | "$installFile"
66 | )
67 |
68 | Write-Host "[$scriptName] Start-Process -FilePath msiexec -ArgumentList $argList -PassThru -Wait"
69 | try {
70 | $proc = Start-Process -FilePath msiexec -ArgumentList $argList -PassThru -Wait
71 | } catch {
72 | Write-Host "[$scriptName] $media Install Exception : $_" -ForegroundColor Red
73 | exit 200
74 | }
75 |
76 | Write-Host
77 | Write-Host "[$scriptName] ---------- stop -----------"
78 | Write-Host
--------------------------------------------------------------------------------
/orchestration/bitbucket/bitbucket-pipelines.yml:
--------------------------------------------------------------------------------
1 | pipelines:
2 | default:
3 | - step:
4 | name: Build and test
5 | runs-on:
6 | - windows
7 |
8 | # Custom tags must be ADDITIONAL to the inbuild tags
9 | # - docker.2019
10 |
11 | script:
12 |
13 | # Using CDAF Edge
14 | # - . { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex
15 |
16 | # Use Latest Stable
17 | - . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
18 |
19 | - $env:DOCKER_HOST = ''
20 | - .\automation\entry.ps1 $env:BITBUCKET_BUILD_NUMBER $env:BITBUCKET_BRANCH
21 |
22 | branches:
23 | 'master':
24 | - step:
25 | name: Build and test
26 | runs-on:
27 | - windows
28 | script:
29 | - . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
30 | - $env:DOCKER_HOST = ''
31 | - .\automation\ci.bat $env:BITBUCKET_BUILD_NUMBER $env:BITBUCKET_BRANCH
32 | artifacts:
33 | - "release.ps1"
34 |
35 | # Legacy artefacts
36 | # artifacts:
37 | # - "TasksLocal/**"
38 | # - "*.zip"
39 |
40 | - step:
41 | name: Deploy to test
42 | runs-on:
43 | - windows
44 | deployment: Test
45 | script:
46 | - $env:DOCKER_HOST = ''
47 | - ./release.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
48 |
49 | # Legacy Delivery
50 | # - ./TasksLocal/delivery.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
51 |
52 | - step:
53 | name: Deploy to staging
54 | deployment: Staging
55 | script:
56 | - $env:DOCKER_HOST = ''
57 | - ./release.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
58 |
59 | # Legacy Delivery
60 | # - ./TasksLocal/delivery.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
61 |
62 | runs-on:
63 | - windows
64 |
65 | - step:
66 | name: Deploy to production
67 | runs-on:
68 | - windows
69 | deployment: Production
70 | trigger: manual
71 | script:
72 | - $env:DOCKER_HOST = ''
73 | - ./release.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
74 |
75 | # Legacy Delivery
76 | # - ./TasksLocal/delivery.ps1 $env:BITBUCKET_DEPLOYMENT_ENVIRONMENT
77 |
--------------------------------------------------------------------------------
/orchestration/ado/CI-Only/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started-yaml
2 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables
3 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=vsts&tabs=yaml
4 |
5 | name: $(Rev:r)
6 | # name: $(TeamProject)_$(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
7 |
8 | pool:
9 | vmImage: 'windows-latest'
10 | # vmImage: 'windows-2019'
11 |
12 | trigger:
13 | branches:
14 | include:
15 | - '*'
16 |
17 | # For a private pool, in this example, named Private requiring the capability of PowerShell
18 | #pool:
19 | # name: Azure
20 | # demands: PowerShell
21 |
22 | # or pool with no demands
23 | #pool: Default
24 |
25 | variables:
26 | - group: Git-Reader-for-Branch-Clean-up
27 | # Must explicitely load secrets into a variable that is NOT the same as the variable itself, i.e. name cannot be GIT_PASSWORD
28 | - name: gitPass
29 | value: $[variables.GIT_PASSWORD]
30 |
31 | steps:
32 | - script: automation\entry.bat "$(Build.BuildNumber)" "$env:Build_SourceBranchName" "staging@$env:Build_ArtifactStagingDirectory"
33 | env:
34 | GIT_USERNAME: $[variables.GIT_USERNAME]
35 | GIT_PASSWORD: $(gitPass)
36 |
37 | # For installed instance of CDAF, in the agents user profile in this example
38 | # - script: "%USERPROFILE%\\.cdaf\\entry.bat \"$(Build.BuildNumber)\" \"$(Build.SourceBranchName)\" \"staging@$(Build.ArtifactStagingDirectory)\""
39 |
40 | # Require explicit exit code if using a multi-line script
41 | # - script: |
42 | # $env:READ_ONLY_PAT=$(READ_ONLY_PAT)
43 | # ~/cdaf/processor/entry.ps1 "$env:Build_BuildNumber" "$env:Build_SourceBranchName" "staging@$env:Build_ArtifactStagingDirectory"
44 | # $LASTEXITCODE=$?
45 | # if ( $LASTEXITCODE != "0" ) { exit $$LASTEXITCODE }
46 |
47 | # env:
48 | # MAVEN_ARTIFACT_TOKEN: $(MAVEN_ARTIFACT_TOKEN)
49 |
50 | #- task: PublishTestResults@2
51 | # inputs:
52 | #testResultsFormat: 'JUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
53 | #testResultsFiles: '**/TEST-*.xml'
54 | #searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
55 | #mergeTestResults: true # Optional
56 | #failTaskOnFailedTests: true # Optional
57 | #testRunTitle: # Optional
58 | #buildPlatform: # Optional
59 | #buildConfiguration: # Optional
60 | #publishRunAttachments: true # Optional
61 |
62 | - task: PublishBuildArtifacts@1
63 | #ArtifactName: 'drop'
64 | #publishLocation: 'Container'
--------------------------------------------------------------------------------
/provisioning/sqlCreateDB.ps1:
--------------------------------------------------------------------------------
1 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
2 | function executeExpression ($expression) {
3 | $error.clear()
4 | Write-Host "$expression"
5 | try {
6 | $output = Invoke-Expression $expression
7 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
8 | } catch { echo $_.Exception|format-list -force; exit 2 }
9 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
10 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
11 | return $output
12 | }
13 |
14 | # Reset $LASTEXITCODE
15 | cmd /c exit 0
16 |
17 | $scriptName = 'sqlCreateDB.ps1'
18 |
19 | Write-Host; Write-Host "[$scriptName] ---------- start ----------"
20 | $dbName = $args[0]
21 | if ($dbName) {
22 | Write-Host "[$scriptName] dbName : $dbName"
23 | } else {
24 | Write-Host "[$scriptName] dbName not supplied, exiting with code 100"
25 | exit 100
26 | }
27 |
28 | $dbOwner = $args[1]
29 | if ($dbOwner) {
30 | Write-Host "[$scriptName] dbOwner : $dbOwner"
31 | } else {
32 | Write-Host "[$scriptName] dbOwner : (not supplied)"
33 | }
34 |
35 | $dbhost = $args[2]
36 | if ($dbhost) {
37 | Write-Host "[$scriptName] dbhost : $dbhost"
38 | } else {
39 | $dbhost = '.'
40 | Write-Host "[$scriptName] dbhost : $dbhost (default)"
41 | }
42 |
43 | Write-Host
44 | # Load the assemblies
45 | executeExpression '[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")'
46 | executeExpression '[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement")'
47 |
48 | Write-Host
49 | $srv = executeExpression "new-Object Microsoft.SqlServer.Management.Smo.Server(`"$dbhost`")"
50 | if ( $srv ) {
51 | executeExpression "`$srv | select Urn"
52 | } else {
53 | Write-Host "[$scriptName] Server $dbhost not found!, Exit with code 103"; exit 103
54 | }
55 |
56 | Write-Host
57 |
58 | $db = executeExpression "New-Object Microsoft.SqlServer.Management.Smo.Database(`$srv, `"$dbName`")"
59 | executeExpression "`$db | select name"
60 | executeExpression "`$db.Create()"
61 | if ($dbOwner) {
62 | if ($dbOwner -eq $env:UserName) {
63 | Write-Host "[$scriptName] Requested owner is current user, no action taken."
64 | } else {
65 | executeExpression "`$db.SetOwner(`"$dbOwner`", `$True)"
66 | }
67 | }
68 |
69 | Write-Host
70 | executeExpression "`$srv.databases | select name"
71 |
72 | Write-Host
73 | Write-Host "[$scriptName] ---------- stop ----------"
74 |
--------------------------------------------------------------------------------
/provisioning/GetExecutable.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$url,
3 | [string]$mediaDir,
4 | [string]$runTime,
5 | [string]$proxy
6 | )
7 | $scriptName = 'GetExecutable.ps1'
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | $error.clear()
12 | Write-Host "$expression"
13 | try {
14 | Invoke-Expression $expression
15 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
16 | } catch { echo $_.Exception|format-list -force; exit 2 }
17 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
18 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
19 | }
20 |
21 | Write-Host "`n[$scriptName] ---------- start ----------"
22 | if ($url) {
23 | Write-Host "[$scriptName] url : $url"
24 | } else {
25 | $url = 'http://cdaf.io/static/app/downloads/Database.exe'
26 | Write-Host "[$scriptName] url : $url (default)"
27 | }
28 |
29 | if ($mediaDir) {
30 | Write-Host "[$scriptName] mediaDir : $mediaDir"
31 | } else {
32 | $mediaDir = "$env:TEMP"
33 | Write-Host "[$scriptName] mediaDir : $mediaDir (default)"
34 | }
35 |
36 | if ($runTime) {
37 | Write-Host "[$scriptName] runTime : $runTime"
38 | } else {
39 | $runTime = '$env:windir'
40 | Write-Host "[$scriptName] runTime : $runTime (default)"
41 | }
42 |
43 | if ($proxy) {
44 | Write-Host "[$scriptName] proxy : $proxy`n"
45 | executeExpression "[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('$proxy')"
46 | } else {
47 | Write-Host "[$scriptName] proxy : (not supplied)"
48 | }
49 |
50 | $file = Split-Path -Path $url -Leaf
51 |
52 | if (!( Test-Path $mediaDir )) {
53 | Write-Host "[$scriptName] mkdir $mediaDir"
54 | mkdir $mediaDir
55 | }
56 |
57 | Write-Host
58 | $fullpath = $mediaDir + '\' + $file
59 | if ( Test-Path $fullpath ) {
60 | Write-Host "[$scriptName] $fullpath exists, download not required"
61 | } else {
62 | Write-Host "[$scriptName] $file does not exist in $mediaDir, listing contents"
63 | try {
64 | Get-ChildItem $mediaDir | Format-Table name
65 | if(!$?) { $fullpath = listAndContinue }
66 | } catch { $fullpath = listAndContinue }
67 |
68 | Write-Host "[$scriptName] Attempt download"
69 | executeExpression "(New-Object System.Net.WebClient).DownloadFile('$url', '$fullpath')"
70 | }
71 |
72 | executeExpression "Copy-Item `"$fullpath`" `"$runTime`""
73 |
74 | Write-Host "`n[$scriptName] ---------- stop ----------"
75 |
--------------------------------------------------------------------------------
/orchestration/bamboo-specs/bamboo.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: 2
3 |
4 | plan:
5 | project-key: REF
6 | key: WUC
7 | name: CDAf Windows Publication
8 |
9 | stages:
10 | - Build Stage:
11 | - Build Job
12 |
13 | Build Job:
14 | tasks:
15 | - script:
16 | interpreter: powershell
17 | scripts: | # Use latest Published CDAF
18 | . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
19 | .\\automation\\entry.bat ${bamboo.buildNumber} ${bamboo.repository.branch.name}
20 |
21 | # scripts: | # Edge version from GitHub
22 | # $env:CDAF_PATH = '.\automation'
23 | # . { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex
24 | # .\\automation\\entry.bat ${bamboo.buildNumber} ${bamboo.repository.branch.name}
25 |
26 | # scripts: | # "In-source" implemenation
27 | # .\\automation\\entry.bat ${bamboo.buildNumber} ${bamboo.repository.branch.name}
28 |
29 | artifacts:
30 | - name: Package
31 | pattern: 'release.ps1'
32 | shared: true
33 |
34 | ---
35 | version: 2
36 |
37 | deployment:
38 | name: WU-CDM
39 | source-plan: REF-WUC
40 |
41 | release-naming:
42 | next-version-name: ${bamboo.buildNumber}
43 |
44 | environments:
45 | - TEST
46 | - UAT
47 | - PROD
48 |
49 | TEST:
50 | triggers:
51 | - build-success
52 | tasks:
53 | - clean
54 | - artifact-download:
55 | destination: ${bamboo.working.directory}
56 | - script:
57 | interpreter: powershell
58 | scripts:
59 | - ${bamboo.build.working.directory}\\release.ps1 ${bamboo.deploy.environment} ${bamboo.deploy.release}
60 | - if ( $LASTEXITCODE -ne 0 ) { throw "Script failed with LASTEXITCODE = $LASTEXITCODE" }
61 |
62 | UAT:
63 | triggers:
64 | - environment-success: TEST
65 | tasks:
66 | - clean
67 | - artifact-download:
68 | destination: ${bamboo.working.directory}
69 | - script:
70 | interpreter: powershell
71 | scripts:
72 | - ${bamboo.build.working.directory}\\release.ps1 ${bamboo.deploy.environment} ${bamboo.deploy.release}
73 | - if ( $LASTEXITCODE -ne 0 ) { throw "Script failed with LASTEXITCODE = $LASTEXITCODE" }
74 |
75 | PROD:
76 | tasks:
77 | - clean
78 | - artifact-download:
79 | destination: ${bamboo.working.directory}
80 | - script:
81 | interpreter: powershell
82 | scripts:
83 | - ${bamboo.build.working.directory}\\release.ps1 ${bamboo.deploy.environment} ${bamboo.deploy.release}
84 | - if ( $LASTEXITCODE -ne 0 ) { throw "Script failed with LASTEXITCODE = $LASTEXITCODE" }
85 |
--------------------------------------------------------------------------------
/provisioning/setInternetProxy.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$httpProxy,
3 | [string]$automaticeConfigurationScript
4 | )
5 |
6 | cmd /c "exit 0"
7 | $scriptName = 'setInternetProxy.ps1'
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | $error.clear()
12 | Write-Host "[$scriptName] $expression"
13 | try {
14 | Invoke-Expression $expression
15 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
16 | } catch { echo $_.Exception|format-list -force; exit 2 }
17 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
18 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
19 | }
20 |
21 | Write-Host "`n[$scriptName] ---------- start ----------`n"
22 | if ($httpProxy) {
23 | Write-Host "[$scriptName] httpProxy : $httpProxy (can be space separated list)"
24 | } else {
25 | if ($env:http_proxy) {
26 | $httpProxy = $env:http_proxy
27 | Write-Host "[$scriptName] httpProxy : $httpProxy (not passed, but derived from `$env:http_proxy)"
28 | }
29 | }
30 |
31 | if ($automaticeConfigurationScript) {
32 | Write-Host "[$scriptName] automaticeConfigurationScript : $automaticeConfigurationScript"
33 | } else {
34 | Write-Host "[$scriptName] automaticeConfigurationScript : (not supplied)"
35 | }
36 |
37 | if ($httpProxy) {
38 | Write-Host "[$scriptName] httpProxy : $httpProxy (can be space separated list)"
39 | executeExpression "[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('$httpProxy')"
40 |
41 | $protocol,$prefix,$port = $httpProxy.split(':')
42 | $address = $prefix.Replace('/', '')
43 | $regKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
44 | executeExpression "Set-ItemProperty -path '$regKey' ProxyEnable -value 1"
45 | executeExpression "Set-ItemProperty -path '$regKey' ProxyServer -value '${address}:${port}'"
46 |
47 | Write-Host "`n[$scriptName] List current settings before changing`n"
48 | executeExpression "netsh winhttp show proxy"
49 | executeExpression "netsh winhttp set proxy '${address}:${port}'"
50 |
51 | if ($automaticeConfigurationScript) {
52 | executeExpression "Set-ItemProperty -path $regKey AutoConfigURL -Value $automaticeConfigurationScript"
53 | }
54 | } else {
55 | Write-Host "[$scriptName] httpProxy not passed and unable to derive from `$env:http_proxy, exit without attempting any changes" -ForegroundColor 'Yellow'
56 | }
57 |
58 | Write-Host "`n[$scriptName] ---------- stop ----------"
59 | $error.clear()
60 | exit 0
--------------------------------------------------------------------------------
/provisioning/addUserToLocalGroup.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$group,
3 | [string]$userName,
4 | [string]$domain
5 | )
6 |
7 | cmd /c "exit 0"
8 | $Error.Clear()
9 |
10 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
11 | function executeExpression ($expression) {
12 | Write-Host "[$(Get-Date)] $expression"
13 | try {
14 | Invoke-Expression $expression
15 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
16 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
17 | if ( $LASTEXITCODE ) {
18 | if ( $LASTEXITCODE -ne 0 ) {
19 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
20 | } else {
21 | if ( $error ) {
22 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE error follows...`n" -ForegroundColor Yellow
23 | $error
24 | }
25 | }
26 | } else {
27 | if ( $error ) {
28 | Write-Host "[$scriptName] `$error[] = $error"; exit 1113
29 | }
30 | }
31 | }
32 |
33 | $scriptName = 'addUserToLocalGroup.ps1'
34 |
35 | Write-Host "`n[$scriptName] ---------- start ----------"
36 | if ($group) {
37 | Write-Host "[$scriptName] group : $group"
38 | } else {
39 | $group = 'Remote Management Users'
40 | Write-Host "[$scriptName] group : $group (default)"
41 | }
42 |
43 | if ($userName) {
44 | Write-Host "[$scriptName] userName : $userName"
45 | } else {
46 | $userName = 'Deployer'
47 | Write-Host "[$scriptName] userName : $userName (default)"
48 | }
49 |
50 | if ($domain) {
51 | Write-Host "[$scriptName] domain : $domain"
52 | } else {
53 | Write-Host "[$scriptName] domain : not supplied, will treat as local machine (workgroup)"
54 | }
55 |
56 | if ($domain) {
57 | Write-Host
58 | Write-Host "[$scriptName] Add $domain/$userName to local group $group."
59 | $de = executeExpression "[ADSI]`"WinNT://$env:computername/$group,group`""
60 | executeExpression "`$de.psbase.Invoke(`"Add`",([ADSI]`"WinNT://$domain/$userName`").path)"
61 | } else {
62 | if ( $userName.StartsWith('.\')) {
63 | $userName = $userName.Substring(2) # Remove the .\ prefix
64 | }
65 | Write-Host "[$scriptName] Add $userName to local group $group."
66 | $argList = "localgroup `"$group`" $userName /add"
67 | Write-Host "[$scriptName] Start-Process net -ArgumentList $argList -PassThru -Wait"
68 | $proc = Start-Process net -ArgumentList $argList -PassThru -Wait
69 | if ( $proc.ExitCode -ne 0 ) {
70 | Write-Host "`n[$scriptName] Exit with `$LASTEXITCODE $($proc.ExitCode)`n"
71 | exit $proc.ExitCode
72 | }
73 | }
74 |
75 | Write-Host "`n[$scriptName] ---------- stop ----------"
76 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/storeForArtifact.txt:
--------------------------------------------------------------------------------
1 | # StoreForArtifact
2 | # Comments begin with # and will be ignored.
3 | # Section Labels begin with [ and will be ignored.
4 | # Empty lines will be ignored.
5 | #
6 | # To copy an artifact to the artifacts root directory, simply list it as follows:
7 | # \bin\Release\MyArtifactFile.exe
8 | #
9 | # To copy an artifact to the artifacts root directory and perform a rename, include the
10 | # filename after the pipe.
11 | # \bin\Release\MyArtifactFile.exe | MyRenamedFile.exe
12 | #
13 | # To copy an artifact to a specific sub-directory under the artifacts root directory,
14 | # use a pipe seperator to indicate the sub-directory.
15 | # \bin\Release\MyArtifactFile.exe | binaries
16 | #
17 | # To copy an artifact to a specific sub-directory under the artifacts root directory
18 | # AND perform a rename, include the filename after the sub-directory.
19 | # \bin\Release\MyArtifactFile.exe | binaries\MyRenamedFile.exe
20 | #
21 | # Wildcards may be used when copying files. To copy files from a target directory based
22 | # on wildcards, just specify the pattern in the source side.
23 | # \bin\Release\* | binaries\Release
24 | # \bin\Release\*.dll | binaries\ReleaseDLLs
25 | #
26 | # To zip a directory under the artifact workbench (or the workbench itself) simply pass
27 | # in that value as below. This will place a bin.zip under ARTIFACT_WORKBENCH
28 | # \bin
29 | #
30 | # To zip a directory under the artifact workbench (or the workbench itself) and specify
31 | # an output directory (and optionally, a filename) use the following entry format.
32 | # \bin | zips\binaries.zip
33 | #
34 | # By default, the filename will be analyzed to determine if the submitted name should be
35 | # handled as a directory or as a file based on the presence of a period in the name. In
36 | # the case of a directory that has periods, or a file that lacks an extension, this default
37 | # behavior will fail. To override the default and explicitly state whether or not a file
38 | # is a directory or a file, add a suffix of -d or -f to the end of the path.
39 | # \obj\Release\Package\PackageTmp\* -d | -d
40 | # \ -d | zips\.zip -f
41 | #
42 | # All values will be trimmed before being used in the application, so use whitespace as desired.
43 |
44 | [PROJECT_LABEL]
45 | \obj\Release\Package\PackageTmp\* -d | -d
46 |
47 | [zips]
48 | artifacts\ -d | zips\.zip -f
--------------------------------------------------------------------------------
/provisioning/addPath.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$directoryName,
3 | [string]$level
4 | )
5 |
6 | cmd /c "exit 0"
7 | $Error.Clear()
8 |
9 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
10 | function executeExpression ($expression) {
11 | Write-Host "[$(Get-Date)] $expression"
12 | try {
13 | Invoke-Expression $expression
14 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
15 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
16 | if ( $LASTEXITCODE ) {
17 | if ( $LASTEXITCODE -ne 0 ) {
18 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
19 | } else {
20 | if ( $error ) {
21 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE error follows...`n" -ForegroundColor Yellow
22 | $error
23 | }
24 | }
25 | } else {
26 | if ( $error ) {
27 | Write-Host "[$scriptName] `$error[] = $error"; exit 1113
28 | }
29 | }
30 | }
31 |
32 | $scriptName = 'addPath.ps1'
33 | Write-Host "`n[$scriptName] ---------- start ----------"
34 | if ($directoryName) {
35 | Write-Host "[$scriptName] directoryName : $directoryName"
36 | } else {
37 | Write-Host "[$scriptName] directoryName not supplied, exiting!"
38 | exit 2365
39 | }
40 |
41 | if ($level) {
42 | Write-Host "[$scriptName] level : $level (Choices are Machine or User)"
43 | } else {
44 | $level = 'Machine'
45 | Write-Host "[$scriptName] level : $level (Default, choices are Machine or User)"
46 | }
47 |
48 | $elementInPath = $false
49 | # Append Directory to PATH if it is not already in the path
50 | $currentPath = [Environment]::GetEnvironmentVariable('Path', $level)
51 | if ( $currentPath ) {
52 | foreach ( $item in $currentPath.split(';') ) {
53 | if ( $item -eq $directoryName ) {
54 | $elementInPath = $true
55 | }
56 | }
57 | if ( $elementInPath ) {
58 | Write-Host "`n[$scriptName] directoryName $directoryName already exists in $level path`n"
59 | } else {
60 | Write-Host
61 | executeExpression "[Environment]::SetEnvironmentVariable(`'Path`', `$currentPath + `";$directoryName`", `'$level`')"
62 | Write-Host
63 | }
64 | }else {
65 | Write-Host
66 | executeExpression "[Environment]::SetEnvironmentVariable(`'Path`', `"$directoryName`", `'$level`')"
67 | Write-Host
68 | }
69 |
70 | # Reload the path (without logging off and back on)
71 | $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
72 |
73 | Write-Host "[$scriptName] Complete path (User and Machine) is now ..."
74 | foreach ($item in ($env:PATH).split(';')) {
75 | Write-Host "[$scriptName] $item"
76 | }
77 |
78 | Write-Host "`n[$scriptName] ---------- stop -----------`n"
79 |
--------------------------------------------------------------------------------
/samples/all/automation-solution/tasksRunLocal.tsk:
--------------------------------------------------------------------------------
1 | Write-Host "CDAF Version : $(& $CDAF_CORE/capabilities.ps1 cdaf)"
2 |
3 | Write-Host "12-factor approach uses environment variables, these would be set by the CI/CD tooling`n" -ForegroundColor Magenta
4 | ASSIGN $env:EXAMPLE_SECRET_1 = 'Shhh,Passw0Rd!'
5 | ASSIGN $env:EXAMPLE_SECRET_2 = 'Shhh,secret'
6 |
7 | Write-Host "Variable checklist" -ForegroundColor Magenta
8 | VARCHK
9 |
10 | Write-Host "Load a property file to memory`n" -ForegroundColor Magenta
11 | PROPLD manifest.txt
12 |
13 | Write-Host "Reveal values when assigning to variable`n" -ForegroundColor Magenta
14 | Write-Host " `$var_load = $var_load"
15 | Write-Host " `$list = $list"
16 | Write-Host " `$empty_var = $empty_var"
17 | Write-Host " `$null_var = $null_var"
18 | Write-Host " `$null = $null"
19 |
20 | ASSIGN $resolvedVarInVar = $var_load
21 | ASSIGN $resolvedStringInVar = $list
22 | ASSIGN $resolvedEmptyInVar = $empty_var
23 | ASSIGN $resolvedNullInVar = $null_var
24 | ASSIGN $resolvedNullVar = $null
25 |
26 | Write-Host "Keep a copy of the tokenised file`n" -ForegroundColor Magenta
27 | MAKDIR check
28 | VECOPY example.yaml check
29 |
30 | Write-Host "Detokenise a setting file`n" -ForegroundColor Magenta
31 | DETOKN example.yaml
32 |
33 | Write-Host "empty_var token is preserved because no match will be found, while null_var contains a reference to `$null" -ForegroundColor Magenta
34 | cat example.yaml
35 |
36 | Write-Host "Detokenise setting file using ad-hoc environment variable, only using where variable manipulation is required.`n" -ForegroundColor Magenta
37 | REPLAC example.yaml @secret@ $env:EXAMPLE_SECRET_1
38 | cat example.yaml
39 |
40 | Write-Host "Detokenise setting file using environment variable as defined in CM, this is the recommended method for applying secrets.`n" -ForegroundColor Magenta
41 | $env:CDAF_OVERRIDE_TOKEN = '@'
42 | DETOKN example.yaml $TARGET resolve
43 |
44 | Write-Host "empty_var token is preserved because no match will be found, while null_var will result in an empty property" -ForegroundColor Magenta
45 | cat example.yaml
46 |
47 | Write-Host "Detokenise setting file, revealing resolved property list = $list, csv = $csv`n" -ForegroundColor Magenta
48 | $env:CDAF_OVERRIDE_TOKEN = '!'
49 | DETOKN example.yaml $TARGET reveal
50 |
51 | Write-Host "empty_var token is preserved because no match will be found, while null_var will result in an empty property" -ForegroundColor Magenta
52 | cat example.yaml
53 |
54 | Write-Host "Process a comma separated list as array`n" -ForegroundColor Magenta
55 | Write-Host "`$csv = $csv"
56 | foreach ($item in $csv.Split(',')) { Write-Host " [ $item ]" }
57 |
58 | Write-Host "Detokenise file outside of workspace`n" -ForegroundColor Magenta
59 | cd check
60 | DETOKN example.yaml
61 |
62 | Write-Host "Execute outside of WORKSPACE"
63 | cd $TMPDIR
64 | PROPLD $WORKSPACE\manifest.txt
65 |
--------------------------------------------------------------------------------
/orchestration/ado/Multi-stage/templates/azure-pipelines-build-template.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - job: Build
3 | displayName: ${{ parameters.displayName }}
4 | pool:
5 | vmImage: windows-latest
6 | # vmImage: windows-2019
7 |
8 | # pool: # Self-hosted Pool Name
9 | # name: Default
10 | # demands: Agent.OS -equals Windows_NT
11 |
12 | steps:
13 | # - task: PowerShell@2
14 | # displayName: Diag
15 | # inputs:
16 | # workingDirectory: $(System.ArtifactsDirectory)/drop
17 | # targetType: inline
18 | # script: dir ; systeminfo
19 |
20 | - task: PowerShell@2
21 | displayName: CDAF Release Build
22 | # URL and user are not likely to be set as secret, so an explicit mapping is not required, but included for reference
23 | # env:
24 | # GIT_URL: $(GIT_URL)
25 | # GIT_USER: $(GIT_USER)
26 | # GIT_PASS: $(GIT_PASS)
27 | inputs:
28 |
29 | targetType: 'inline' # Use latest published version
30 | script: |
31 | . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
32 | .\automation\entry.ps1 $(Build.BuildNumber) $(Build.SourceBranch) staging@$(Build.ArtifactStagingDirectory)
33 |
34 | # targetType: 'inline' # Use edge CDAF version from GitHub
35 | # script: |
36 | # . { iwr -useb https://raw.githubusercontent.com/cdaf/windows/master/install.ps1 } | iex
37 | # .\automation\entry.ps1 $(Build.BuildNumber) $(Build.SourceBranch) staging@$(Build.ArtifactStagingDirectory)
38 |
39 | # targetType: 'inline' # Use a specific CDAF version
40 | # script: |
41 | # iwr -useb http://cdaf.io/static/app/downloads/WU-CDAF-2.5.3.zip -OutFile WU_CDAF.zip
42 | # Expand-Archive WU_CDAF.zip
43 | # .\WU_CDAF\automation\entry.ps1 $(Build.BuildNumber) $(Build.SourceBranch) staging@$(Build.ArtifactStagingDirectory)
44 |
45 | # "In-source" implemenation
46 | # targetType: filePath
47 | # filePath: ./automation/entry.ps1
48 | # arguments: $(Build.BuildNumber) $(Build.SourceBranch) staging@$(Build.ArtifactStagingDirectory)
49 |
50 | # - task: PublishTestResults@2
51 | # condition: succeededOrFailed()
52 | # inputs:
53 | # testResultsFormat: 'JUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
54 | # testResultsFiles: '**/test-results/*.xml'
55 | # searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
56 | # mergeTestResults: true # Optional
57 | # failTaskOnFailedTests: true # Optional
58 | # testRunTitle: Checkov Results # Optional
59 | # buildPlatform: # Optional
60 | # buildConfiguration: # Optional
61 | # publishRunAttachments: true # Optional
62 |
63 | - task: PublishBuildArtifacts@1
64 |
--------------------------------------------------------------------------------
/provisioning/installAzureRM.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [String]$interface
3 | )
4 | $scriptName = 'installAzureRM.ps1'
5 |
6 | # Retry logic for connection issues, i.e. "Cannot retrieve the dynamic parameters for the cmdlet. PowerShell Gallery is currently unavailable. Please try again later."
7 | # Includes warning for "Cannot find a variable with the name 'PackageManagementProvider'. Cannot find a variable with the name 'SourceLocation'."
8 | function executeRetry ($expression) {
9 | $exitCode = 1
10 | $wait = 10
11 | $retryMax = 5
12 | $retryCount = 0
13 | while (( $retryCount -le $retryMax ) -and ($exitCode -ne 0)) {
14 | $exitCode = 0
15 | $error.clear()
16 | Write-Host "[$retryCount] $expression"
17 | try {
18 | Invoke-Expression $expression
19 | if(!$?) { Write-Host "[$scriptName] `$? = $?" -ForegroundColor Red; $exitCode = 1 }
20 | } catch { Write-Host "[$scriptName] $_" -ForegroundColor Red; $exitCode = 2 }
21 | if ( $error[0] ) { Write-Host "[$scriptName] Warning, message in `$error[0] = $error" -ForegroundColor Yellow; $error.clear() } # do not treat messages in error array as failure
22 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { $exitCode = $LASTEXITCODE; Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red; cmd /c "exit 0" }
23 | if ($exitCode -ne 0) {
24 | if ($retryCount -ge $retryMax ) {
25 | Write-Host "[$scriptName] Retry maximum ($retryCount) reached, exiting with `$LASTEXITCODE = $exitCode.`n"
26 | exit $exitCode
27 | } else {
28 | $retryCount += 1
29 | Write-Host "[$scriptName] Wait $wait seconds, then retry $retryCount of $retryMax"
30 | sleep $wait
31 | }
32 | }
33 | }
34 | }
35 |
36 | cmd /c "exit 0"
37 | # Use the CDAF provisioning helpers
38 | Write-Host "`n[$scriptName] ---------- start ----------"
39 | if ($interface) {
40 | Write-Host "[$scriptName] interface : $interface"
41 | } else {
42 | $interface = 'powershell'
43 | Write-Host "[$scriptName] interface : $interface (default)"
44 | }
45 |
46 | switch($interface){
47 | 'powershell' {
48 | Write-Host "`n[$scriptName] Install Azure PowerShell commandlets`n"
49 | executeRetry 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Verbose -Force'
50 | executeRetry 'Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted'
51 | executeRetry 'Install-PackageProvider -Name NuGet -Confirm:$False'
52 | executeRetry 'Install-Module NuGet -Confirm:$False'
53 | executeRetry 'Install-Module AzureRM -Confirm:$False'
54 | executeRetry 'Install-Module Azure -Confirm:$False'
55 | }
56 | 'cli' {
57 | Write-Host "[$scriptName] Interface $interface is not yet implemented."
58 | }
59 |
60 | default {
61 | Write-Host "[$scriptName] Interface $interface is not supported! Exit with LASTEXITCODE 3657"
62 | exit 3657
63 | }
64 | }
65 |
66 | Write-Host "`n[$scriptName] ---------- stop ----------"
67 | exit 0
--------------------------------------------------------------------------------
/provisioning/addHOSTS.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$ipAddress,
3 | [string]$hostEntry
4 | )
5 |
6 | # Initialise
7 | cmd /c "exit 0"
8 | $Error.Clear()
9 | $scriptName = 'addHOSTS.ps1'
10 |
11 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
12 | function executeExpression ($expression) {
13 | Write-Host "[$(Get-Date)] $expression"
14 | try {
15 | Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; $error ; exit 1111 }
17 | } catch { Write-Output $_.Exception|format-list -force; $error ; exit 1112 }
18 | if ( $LASTEXITCODE ) {
19 | if ( $LASTEXITCODE -ne 0 ) {
20 | Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE " -ForegroundColor Red ; $error ; exit $LASTEXITCODE
21 | } else {
22 | if ( $error ) {
23 | Write-Host "[$scriptName][WARN] $Error array populated by `$LASTEXITCODE = $LASTEXITCODE error follows...`n" -ForegroundColor Yellow
24 | $error
25 | }
26 | }
27 | } else {
28 | if ( $error ) {
29 | Write-Host "[$scriptName] `$error[] = $error"; exit 1113
30 | }
31 | }
32 | }
33 |
34 | # In memory replacement performed to avoid dead-lock scenario when trying to use Get-Content / Set-Content commandlets
35 | Write-Host "`n[$scriptName] ---------- start ----------`n"
36 | if ($ipAddress) {
37 | Write-Host "[$scriptName] ipAddress : $ipAddress"
38 | } else {
39 | Write-Host "[$scriptName] ipAddress not supplied!" ; exit 777
40 | }
41 |
42 | if ($hostEntry) {
43 | Write-Host "[$scriptName] hostEntry : $hostEntry"
44 | } else {
45 | Write-Host "[$scriptName] hostEntry not supplied!" ; exit 776
46 | }
47 |
48 | $stringTest = $ipAddress.Split('.')
49 | $isFQDN = foreach ($item in $stringTest) { if (! ( $item -match "^\d+$" )) { Write-Output $item } }
50 | if ( $isFQDN ) {
51 | $ipAddress = ([System.Net.Dns]::GetHostAddresses($ipAddress))[0].IPAddressToString
52 | Write-Host "[$scriptName] Converted from FQDN to $ipAddress"
53 | }
54 |
55 |
56 | $hostsfile = 'C:\Windows\System32\drivers\etc\hosts'
57 | $transformed = @(Get-Content $hostsfile)
58 | $addEntry = $True
59 | $i = 0
60 | foreach ($record in $transformed) {
61 | if ($record -match " ${hostEntry}") {
62 | write-host "[$scriptName] Replacing $($transformed[$i]) with $ipAddress ${hostEntry}"
63 | $transformed[$i] = "$ipAddress ${hostEntry}"
64 | $addEntry = $False
65 | break
66 | }
67 | $i++
68 | }
69 |
70 | if ( $addEntry ) {
71 | Write-Host "[$scriptName] Existing entry not found, create $ipAddress ${hostEntry}"
72 | $transformed += "$ipAddress ${hostEntry}"
73 | }
74 |
75 | Write-Host "[$scriptName] Replace $hostsfile"
76 | $stream = [System.IO.StreamWriter] $hostsfile
77 | foreach ($record in $transformed) {
78 | $stream.WriteLine($record)
79 | }
80 | $stream.close()
81 |
82 | executeExpression "Get-Content $hostsfile"
83 |
84 | Write-Host "`n[$scriptName] ---------- finish ----------`n"
85 |
--------------------------------------------------------------------------------
/automation/remote/logWatch.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$logFile,
3 | [string]$stringMatch,
4 | [string]$waitTime
5 | )
6 |
7 | cmd /c "exit 0"
8 | $scriptName = 'logWatch.ps1'
9 |
10 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
11 | function executeExpression ($expression) {
12 | $error.clear()
13 | Write-Host "$expression"
14 | try {
15 | Invoke-Expression $expression
16 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
17 | } catch { Write-Host $_.Exception|format-list -force; exit 2 }
18 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
19 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
20 | }
21 |
22 | Write-Host "`n[$scriptName] --- start ---"
23 | if ($logFile) {
24 | Write-Host "[$scriptName] logFile : $logFile"
25 | } else {
26 | Write-Host "[$scriptName] logFile not supplied, exit with `$LASTEXITCODE = 101"; exit 101
27 | }
28 |
29 | if ($stringMatch) {
30 | Write-Host "[$scriptName] stringMatch : $stringMatch"
31 | } else {
32 | Write-Host "[$scriptName] stringMatch not supplied, exit with `$LASTEXITCODE = 102"; exit 102
33 | }
34 |
35 | if ($waitTime) {
36 | Write-Host "[$scriptName] waitTime : $waitTime`n"
37 | } else {
38 | $waitTime = '60'
39 | Write-Host "[$scriptName] waitTime : $waitTime (default)`n"
40 | }
41 |
42 | $wait = 5
43 | $retryMax = [int]( $waitTime / $wait )
44 | $retryCount = 0
45 | $lastLineNumber = 0
46 | $exitCode = 4365
47 | while (( $retryCount -le $retryMax ) -and ($exitCode -ne 0)) {
48 | sleep $wait
49 | if ( Test-Path $logFile ) {
50 | $output = $(cat $logFile)
51 | if ( $output ) {
52 | $lineCount = 1
53 | foreach ($line in $output -split "`r`n") {
54 | if ( $lineCount -gt $lastLineNumber ) {
55 | Write-Host "> $line"
56 | $lastLineNumber = $lineCount
57 | }
58 | $lineCount += 1
59 | }
60 |
61 | if ( Select-String -Pattern $stringMatch -InputObject $output ) {
62 | Write-Host "`n[$scriptName] stringMatch ($stringMatch) found."
63 | $exitCode = 0
64 | }
65 | if ( Select-String -Pattern 'CDAF_DELIVERY_FAILURE.' -InputObject $output ) {
66 | Write-Host "[$scriptName] Error Detected (CDAF_DELIVERY_FAILURE.) exit with error code 335"
67 | $exitCode = 335
68 | $retryCount = $retryMax
69 | }
70 | } else {
71 | Write-Host "[$scriptName] no output ..."
72 | }
73 | } else {
74 | Write-Host "[$scriptName] no output (log file does not exist) ..."
75 | }
76 |
77 | if ( $retryCount -ge $retryMax ) {
78 | Write-Host "[$scriptName] Maximum wait time ($waitTime) reached after $retryMax retries, exiting with code $waitTime (waitTime)"
79 | $exitCode = $waitTime
80 | }
81 | $retryCount += 1
82 | }
83 |
84 | Write-Host "`n[$scriptName] --- end ---"
85 | $error.clear()
86 | exit $exitCode
87 |
--------------------------------------------------------------------------------
/samples/containerDeploy-custom-image/containerDeploy/bootstrapAgent.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$npmPackages
3 | )
4 |
5 | cmd /c "exit 0"
6 | $scriptName = 'bootstrapAgent.ps1'
7 |
8 |
9 | # Consolidated Error processing function
10 | # required : error message
11 | # optional : exit code, if not supplied only error message is written
12 | function ERRMSG ($message, $exitcode) {
13 | if ( $exitcode ) {
14 | Write-Host "`n[$scriptName]$message" -ForegroundColor Red
15 | } else {
16 | Write-Warning "`n[$scriptName]$message"
17 | }
18 | if ( $error ) {
19 | $i = 0
20 | foreach ( $item in $Error )
21 | {
22 | Write-Host "`$Error[$i] $item"
23 | $i++
24 | }
25 | $Error.clear()
26 | }
27 | if ( $exitcode ) {
28 | if ( $env:CDAF_ERROR_DIAG ) {
29 | Write-Host "`n[$scriptName] Invoke custom diag `$env:CDAF_ERROR_DIAG = $env:CDAF_ERROR_DIAG`n"
30 | Invoke-Expression $env:CDAF_ERROR_DIAG
31 | }
32 | Write-Host "`n[$scriptName] Exit with LASTEXITCODE = $exitcode`n" -ForegroundColor Red
33 | exit $exitcode
34 | }
35 | }
36 |
37 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
38 | function executeExpression ($expression) {
39 | Write-Host "[$(Get-Date)] $expression"
40 | try {
41 | Invoke-Expression $expression
42 | if(!$?) { ERRMSG "[TRAP] `$? = $?" 1211 }
43 | } catch {
44 | $message = $_.Exception.Message
45 | $_.Exception | format-list -force
46 | $_.Exception.StackTrace
47 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) {
48 | ERRMSG "[EXEC][EXCEPTION] $message" $LASTEXITCODE
49 | } else {
50 | ERRMSG "[EXEC][EXCEPTION] $message" 1212
51 | }
52 | }
53 | if ( $LASTEXITCODE ) {
54 | if ( $LASTEXITCODE -ne 0 ) {
55 | ERRMSG "[EXEC][EXIT] `$LASTEXITCODE is $LASTEXITCODE" $LASTEXITCODE
56 | } else {
57 | if ( $error ) {
58 | ERRMSG "[EXEC][WARN] `$LASTEXITCODE is $LASTEXITCODE, but standard error populated"
59 | }
60 | }
61 | } else {
62 | if ( $error ) {
63 | if ( $env:CDAF_IGNORE_WARNING -eq 'no' ) {
64 | ERRMSG "[EXEC][ERROR] `$env:CDAF_IGNORE_WARNING is 'no' so exiting" 1213
65 | } else {
66 | ERRMSG "[EXEC][WARN] `$LASTEXITCODE not set, but standard error populated"
67 | }
68 | }
69 | }
70 | }
71 |
72 | # Windows Command Execution combining standard error and standard out, with only non-zero exit code triggering error
73 | function EXECMD ($expression) {
74 | Write-Host "[$(Get-Date)] $expression"
75 | cmd /c "$expression 2>&1"
76 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) {
77 | ERRMSG "[EXECMD][EXIT] `$LASTEXITCODE is $LASTEXITCODE" $LASTEXITCODE
78 | }
79 | }
80 |
81 | # This is a trivial example when could be just built in-line within Dockerfile, however, it is a example for more complex provisioning
82 | Write-Host "`n[$scriptName] ---------- start ----------"
83 | if ($npmPackages) {
84 | Write-Host "[$scriptName] npmPackages : $npmPackages"
85 | EXECMD "npm install -g $npmPackages"
86 | } else {
87 | Write-Host "[$scriptName] npmPackages : (not supplied, no action attempted)"
88 | }
89 |
90 | Write-Host "`n[$scriptName] ---------- stop ----------"
91 |
--------------------------------------------------------------------------------
/automation/remote/winrmtest.ps1:
--------------------------------------------------------------------------------
1 |
2 | $scriptName = 'winrmtest.ps1'
3 | Write-Host
4 | Write-Host "[$scriptName] ---------- start ----------"
5 | Write-Host
6 |
7 | $vmHost = $args[0]
8 | if ( $vmHost ) {
9 | Write-Host "[$scriptName] vmHost : $vmHost"
10 | } else {
11 | Write-Host "[$scriptName] VM host not passed, exit with error code 100."; exit 100
12 | }
13 |
14 | $username = $args[1]
15 | if ( $username ) {
16 | Write-Host "[$scriptName] username : $username"
17 | } else {
18 | Write-Host "[$scriptName] Username not passed, exit with error code 101."; exit 101
19 | }
20 |
21 | $userpass = $args[2]
22 | if ( $userpass ) {
23 | Write-Host "[$scriptName] userpass : ***********"
24 | } else {
25 | Write-Host "[$scriptName] Password not passed, exit with error code 102."; exit 102
26 | }
27 |
28 | $successRequired = $args[3]
29 | if ( $successRequired ) {
30 | Write-Host "[$scriptName] successRequired : $successRequired"
31 | } else {
32 | $successRequired = 2
33 | Write-Host "[$scriptName] successRequired : $successRequired (default)"
34 | }
35 |
36 | $retries = $args[4]
37 | if ( $retries ) {
38 | Write-Host "[$scriptName] retries : $retries"
39 | } else {
40 | $retries = 5
41 | Write-Host "[$scriptName] retries : $retries (default)"
42 | }
43 | Write-Host
44 |
45 | # Add target host to trusted hosts list
46 | try {
47 | Set-WSManInstance -ResourceURI winrm/config/client -ValueSet @{TrustedHosts=$vmHost}
48 | } catch {
49 | Write-Host "[$scriptName] unable to add target as trusted host, assuming on domain, proceeding ..."
50 | }
51 |
52 | # Create a credential object with the user ID and userpass
53 | $securePassword = ConvertTo-SecureString $userpass -asplaintext -force
54 | $cred = New-Object System.Management.Automation.PSCredential ($username, $securePassword)
55 | $i = 0
56 | $timeout = 60
57 | $successCount = 0
58 | do {
59 | # Test connection and echo basic target details
60 | try {
61 | Invoke-Command -ComputerName $vmHost -credential $cred -SessionOption (New-PSSessionOption -SkipRevocationCheck -SkipCACheck -SkipCNCheck) {
62 | Write-Host
63 | Write-Host " RemotePowershell user : $(whoami)"
64 | Write-Host " RemotePowershell hostname : $(hostname)"
65 | }
66 | if($?) { $successCount ++ }
67 | } catch { Write-Host "[$scriptName] Invoke Exception thrown, $_"; exit 200 }
68 |
69 | if ($successCount -lt $successRequired) {
70 | $i++
71 | if ( $i -le $retries) {
72 | Write-Host "[$scriptName] Success count $successCount/$successRequired, retry WinRM ($i/$retries) wait $timeout seconds before retry ..."
73 | sleep $timeout
74 | } else {
75 | Write-Host "[$scriptName] WinRM Connection failed after $retries tries, exit with error code 201"
76 | exit 201
77 | }
78 | }
79 | } # End of 'Do'
80 | until (( $i -gt $retries) -or ($successCount -ge $successRequired))
81 | if ($successCount -ge $successRequired) {
82 | Write-Host "[$scriptName] Success count $successCount/$successRequired."
83 | }
84 |
85 | Write-Host
86 | Write-Host "[$scriptName] ---------- finish ----------"
87 | Write-Host
88 |
89 | # Clear the error array from any failed attempts
90 | $error.clear()
91 |
--------------------------------------------------------------------------------
/automation/local/remoteTasks.ps1:
--------------------------------------------------------------------------------
1 | # executeExpression and ERRMSG inherited from delivery.ps1
2 |
3 | $scriptName = $myInvocation.MyCommand.Name
4 |
5 | Write-Host "`n[$scriptName] +---------------------------------+"
6 | Write-Host "[$scriptName] | Process Remotely Executed Tasks |"
7 | Write-Host "[$scriptName] +---------------------------------+"
8 |
9 | $ENVIRONMENT = $args[0]
10 | Write-Host "[$scriptName] ENVIRONMENT : $ENVIRONMENT"
11 | $BUILDNUMBER = $args[1]
12 | Write-Host "[$scriptName] BUILDNUMBER : $BUILDNUMBER"
13 | $SOLUTION = $args[2]
14 | Write-Host "[$scriptName] SOLUTION : $SOLUTION"
15 | $WORK_DIR_DEFAULT = $args[3]
16 | Write-Host "[$scriptName] WORK_DIR_DEFAULT : $WORK_DIR_DEFAULT"
17 | $OPT_ARG = $args[4]
18 | Write-Host "[$scriptName] OPT_ARG : $OPT_ARG"
19 |
20 | $propertiesFile = "CDAF.properties"
21 | $propName = "productVersion"
22 | try {
23 | $cdafVersion=$(& $WORK_DIR_DEFAULT\getProperty.ps1 $WORK_DIR_DEFAULT\$propertiesFile $propName)
24 | if(!$?){ taskWarning }
25 | } catch { exceptionExit 'GET_CDAF_VERSION_104' $_ }
26 |
27 | Write-Host "[$scriptName] CDAF Version : $cdafVersion"
28 |
29 | $WORKSPACE = (Get-Location).Path
30 | Write-Host "[$scriptName] WORKSPACE : $WORKSPACE"
31 | # list system info
32 | Write-Host "[$scriptName] Hostname : $(hostname)"
33 | Write-Host "[$scriptName] Whoami : $(whoami)"
34 | Write-Host "[$scriptName] pwd : $(pwd)"
35 |
36 | $propertiesFilter = 'propertiesForRemoteTasks\' + "$ENVIRONMENT*"
37 |
38 | $exitStatus = 0
39 |
40 | # Perform Remote Tasks for each environment defintion file
41 |
42 | if (-not(Test-Path $WORK_DIR_DEFAULT\$propertiesFilter)) {
43 |
44 | Write-Host "`n[$scriptName][WARN] Properties not found ($propertiesFilter) alter processSequence property to skip" -ForegroundColor Yellow
45 |
46 | } else {
47 |
48 | Write-Host "`n[$scriptName] Preparing to process deploy targets :`n"
49 | foreach ($propFile in (Get-ChildItem -Path $WORK_DIR_DEFAULT\$propertiesFilter)) {
50 | $propFilename = getFilename($propFile.ToString())
51 | Write-Host "[$scriptName] $propFilename"
52 | }
53 |
54 | foreach ($propFile in (Get-ChildItem -Path $WORK_DIR_DEFAULT\$propertiesFilter)) {
55 | $propFilename = getFilename($propFile.ToString())
56 |
57 | write-host "`n[$scriptName] --- Process Target $propFilename ---`n" -ForegroundColor Green
58 | executeExpression "& '$WORK_DIR_DEFAULT\remoteTasksTarget.ps1' '$ENVIRONMENT' '$SOLUTION' '$BUILDNUMBER' '$propFilename' '$WORK_DIR_DEFAULT' '$OPT_ARG'"
59 | if ( "$(pwd)" -ne $WORKSPACE ){
60 | Write-Host "`n[$scriptName] Return to WORKSPACE"
61 | executeExpression " cd $WORKSPACE"
62 | }
63 |
64 | write-host "`n[$scriptName] --- Completed Target $propFilename ---`n" -ForegroundColor Green
65 | }
66 |
67 | if ( "$(pwd)" -ne $WORKSPACE ){
68 | Write-Host "`n[$scriptName] Return to WORKSPACE"
69 | executeExpression " cd $WORKSPACE"
70 | }
71 |
72 | Write-Host "[$scriptName] +----------------------------------+"
73 | Write-Host "[$scriptName] | Competed Remotely Executed Tasks |"
74 | Write-Host "[$scriptName] +----------------------------------+"
75 | }
76 |
77 | exit 0
--------------------------------------------------------------------------------
/provisioning/installMSU.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$msuFile,
3 | [string]$opt_arg,
4 | [string]$reboot
5 | )
6 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
7 | function executeExpression ($expression) {
8 | $error.clear()
9 | Write-Host "$expression"
10 | try {
11 | $output = Invoke-Expression $expression
12 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
13 | } catch { echo $_.Exception|format-list -force; exit 2 }
14 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
15 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
16 | return $output
17 | }
18 |
19 | $scriptName = 'installMSU.ps1'
20 | Write-Host "`n[$scriptName] Generic MSU installer"
21 | Write-Host "`n[$scriptName] ---------- start ----------"
22 | if ($msuFile) {
23 | Write-Host "[$scriptName] msuFile : $msuFile"
24 | } else {
25 | Write-Host "[$scriptName] MSI file not supplied, exiting with error code 1"; exit 1
26 | }
27 | Write-Host
28 | if ( Test-Path $msuFile ) {
29 | $fileName = Split-Path $msuFile -leaf
30 | } else {
31 | Write-Host "[$scriptName] $msuFile not found, exiting with error code 2"; exit 2
32 | }
33 |
34 | if ($opt_arg) {
35 | Write-Host "[$scriptName] opt_arg : $opt_arg"
36 | } else {
37 | Write-Host "[$scriptName] opt_arg : (not supplied)"
38 | }
39 |
40 | if ($reboot) {
41 | Write-Host "[$scriptName] reboot : $reboot"
42 | $optParm += "-reboot $reboot"
43 | $argList = @('/quiet')
44 | } else {
45 | $reboot = 'no'
46 | Write-Host "[$scriptName] reboot : $reboot (default)"
47 | $argList = @('/quiet', '/norestart')
48 | }
49 |
50 | if ($env:interactive) {
51 | Write-Host "[$scriptName] `$env:interactive : $env:interactive, run in current window"
52 | $sessionControl = '-PassThru -Wait -NoNewWindow'
53 | } else {
54 | $sessionControl = '-PassThru -Wait'
55 | }
56 |
57 | Write-Host
58 |
59 | try {
60 |
61 | $proc = executeExpression "Start-Process -FilePath `'$msuFile`' -ArgumentList `'$argList`' $sessionControl"
62 |
63 | if ( $proc.ExitCode -ne 0 ) {
64 | switch ($proc.ExitCode) {
65 | 2359302 {
66 | Write-Host "`n[$scriptName] Exit 2359302 MSU alreay installed, reboot maybe required.`n"
67 | }
68 | -2145124329 {
69 | Write-Host "`n[$scriptName] Exit -2145124329 MSU alreay installed.`n"
70 | }
71 | 3010 {
72 | Write-Host "`n[$scriptName] Exit 3010 The requested operation is successful. Changes will not be effective until the system is rebooted.`n"
73 | }
74 | default {
75 | Write-Host "`n[$scriptName] Install Failed, see log file (c:\windows\logs\CBS\CBS.log) for details, listing last 40 lines`n"
76 | executeExpression "Get-Content 'c:\windows\logs\CBS\CBS.log' | select -Last 40"
77 | Write-Host "`n[$scriptName] Exit with `$LASTEXITCODE $($proc.ExitCode)`n"
78 | exit $proc.ExitCode
79 | }
80 | }
81 | }
82 | } catch {
83 | Write-Host "[$scriptName] PowerShell Install Exception : $_" -ForegroundColor Red
84 | exit 200
85 | }
86 |
87 | Write-Host
88 | Write-Host "[$scriptName] ---------- stop -----------"
89 | Write-Host
--------------------------------------------------------------------------------
/provisioning/sqlAddUserDB.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$dbName,
3 | [string]$dbUser,
4 | [string]$dbhost
5 | )
6 |
7 | # Reset $LASTEXITCODE
8 | cmd /c exit 0
9 |
10 | $scriptName = 'sqlAddUserDB.ps1'
11 |
12 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
13 | function executeExpression ($expression) {
14 | $error.clear()
15 | Write-Host "$expression"
16 | try {
17 | $output = Invoke-Expression $expression
18 | if(!$?) { Write-Host "[$scriptName] `$? = $?"; exit 1 }
19 | } catch { echo $_.Exception|format-list -force; exit 2 }
20 | if ( $error ) { Write-Host "[$scriptName] `$error[0] = $error"; exit 3 }
21 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) { Write-Host "[$scriptName] `$LASTEXITCODE = $LASTEXITCODE "; exit $LASTEXITCODE }
22 | return $output
23 | }
24 |
25 | Write-Host "`n[$scriptName] ---------- start ----------"
26 | if ($dbName) {
27 | Write-Host "[$scriptName] dbName : $dbName"
28 | } else {
29 | Write-Host "[$scriptName] dbName not supplied, exiting with code 100"; exit 100
30 | }
31 |
32 | if ($dbUser) {
33 | Write-Host "[$scriptName] dbUser : $dbUser"
34 | } else {
35 | Write-Host "[$scriptName] dbUser not supplied, exiting with code 101"; exit 101
36 | }
37 |
38 | if ($dbhost) {
39 | Write-Host "[$scriptName] dbhost : $dbhost"
40 | } else {
41 | $dbhost = '.'
42 | Write-Host "[$scriptName] dbhost : $dbhost (default)"
43 | }
44 |
45 | Write-Host "`n[$scriptName] Load the assemblies ...`n"
46 | executeExpression '[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")'
47 | executeExpression '[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement")'
48 |
49 | # Rely on caller passing host or host\instance as they desire
50 | Write-Host "`n[$scriptName] Connect to the SQL Server instance ($dbhost) ...`n"
51 | $srv = executeExpression "new-Object Microsoft.SqlServer.Management.Smo.Server(`"$dbhost`")"
52 | if ( $srv ) {
53 | executeExpression "`$srv | select Urn"
54 | } else {
55 | Write-Host "[$scriptName] Server $dbhost not found!, Exit with code 103"; exit 103
56 | }
57 |
58 | Write-Host "`n[$scriptName] List current permissions for database ($dbName) ...`n"
59 | $db = executeExpression "`$srv.Databases[`"$dbName`"]"
60 | if ( $db ) {
61 | executeExpression "`$db | select Urn"
62 | executeExpression "`$db.EnumDatabasePermissions() | select Grantee, PermissionState"
63 | } else {
64 | Write-Host "[$scriptName] Database $dbName not found!, Exit with code 104"; exit 104
65 | }
66 |
67 | Write-Host "`n[$scriptName] List user permission before update ...`n"
68 | $usr = executeExpression "New-Object ('Microsoft.SqlServer.Management.Smo.User') (`$db, `"$dbUser`")"
69 | if ( $usr ) {
70 | executeExpression "`$usr | select Urn"
71 | executeExpression "`$usr.EnumObjectPermissions()"
72 | } else {
73 | Write-Host "[$scriptName] User $dbUser not found!, Exit with code 105"; exit 105
74 | }
75 | executeExpression "`$usr.Login = `$dbUser"
76 | executeExpression "`$usr.Create()"
77 |
78 | Write-Host "`n[$scriptName] List user and database permissions after update ...`n"
79 | executeExpression "`$usr.EnumObjectPermissions()"
80 | executeExpression "`$db.EnumDatabasePermissions() | select Grantee, PermissionState"
81 |
82 | Write-Host "`n[$scriptName] ---------- stop ----------"
83 |
--------------------------------------------------------------------------------
/samples/executeSamples.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$ACTION
3 | )
4 |
5 | $scriptName = 'executeSamples.ps1'
6 | cmd /c "exit 0"
7 |
8 |
9 | # Consolidated Error processing function
10 | # required : error message
11 | # optional : exit code, if not supplied only error message is written
12 | function ERRMSG ($message, $exitcode) {
13 | if ( $exitcode ) {
14 | Write-Host "`n[$scriptName]$message" -ForegroundColor Red
15 | } else {
16 | Write-Warning "`n[$scriptName]$message"
17 | }
18 | if ( $error ) {
19 | $i = 0
20 | foreach ( $item in $Error )
21 | {
22 | Write-Host "`$Error[$i] $item"
23 | $i++
24 | }
25 | $Error.clear()
26 | }
27 | if ( $exitcode ) {
28 | if ( $env:CDAF_ERROR_DIAG ) {
29 | Write-Host "`n[$scriptName] Invoke custom diag `$env:CDAF_ERROR_DIAG = $env:CDAF_ERROR_DIAG`n"
30 | Invoke-Expression $env:CDAF_ERROR_DIAG
31 | }
32 | Write-Host "`n[$scriptName] Exit with LASTEXITCODE = $exitcode`n" -ForegroundColor Red
33 | exit $exitcode
34 | }
35 | }
36 |
37 | # Common expression logging and error handling function, copied, not referenced to ensure atomic process
38 | function executeExpression ($expression) {
39 | Write-Host "[$(Get-Date)] $expression"
40 | try {
41 | Invoke-Expression $expression
42 | if(!$?) { ERRMSG "[TRAP] `$? = $?" 1211 }
43 | } catch {
44 | $message = $_.Exception.Message
45 | $_.Exception | format-list -force
46 | $_.Exception.StackTrace
47 | if (( $LASTEXITCODE ) -and ( $LASTEXITCODE -ne 0 )) {
48 | ERRMSG "[EXEC][EXCEPTION] $message" $LASTEXITCODE
49 | } else {
50 | ERRMSG "[EXEC][EXCEPTION] $message" 1212
51 | }
52 | }
53 | if ( $LASTEXITCODE ) {
54 | if ( $LASTEXITCODE -ne 0 ) {
55 | ERRMSG "[EXEC][EXIT] `$LASTEXITCODE is $LASTEXITCODE" $LASTEXITCODE
56 | } else {
57 | if ( $error ) {
58 | ERRMSG "[EXEC][WARN] `$LASTEXITCODE is $LASTEXITCODE, but standard error populated"
59 | }
60 | }
61 | } else {
62 | if ( $error ) {
63 | if ( $env:CDAF_IGNORE_WARNING -eq 'no' ) {
64 | ERRMSG "[EXEC][ERROR] `$env:CDAF_IGNORE_WARNING is 'no' so exiting" 1213
65 | } else {
66 | ERRMSG "[EXEC][WARN] `$LASTEXITCODE not set, but standard error populated"
67 | }
68 | }
69 | }
70 | }
71 |
72 | Write-Host "`n[$scriptName] ---------- start ----------`n"
73 | Write-Host "[$scriptName] ACTION : $ACTION`n"
74 |
75 | if ( $ACTION -eq 'native' ) {
76 | $list = @('all', 'custom', 'feature-branch-environments', 'minimal', 'pre-post-processes')
77 | Write-Host "[$scriptName] ACTION = $ACTION, execute custom list:`n"
78 | } else {
79 | $list = Get-ChildItem -Directory
80 | Write-Host "[$scriptName] ACTION not set, execute default list:`n"
81 | }
82 |
83 | foreach ($dirName in $list) {
84 | Write-Host "[$scriptName] $dirName"
85 | }
86 |
87 | foreach ($dirName in $list) {
88 | Write-Host "`n[$scriptName] ---------- begin $dirName ----------`n"
89 | executeExpression "cd $dirName"
90 | executeExpression "..\..\automation\cdEmulate.bat"
91 | executeExpression "cd .."
92 | Write-Host "`n[$scriptName] ---------- end $dirName ----------"
93 | }
94 |
95 | Write-Host "`n[$scriptName] Sample test complete for:"
96 | foreach ($dirName in $list) {
97 | Write-Host " $dirName"
98 | }
99 |
100 | Write-Host "`n[$scriptName] ---------- stop ----------"
101 | $error.clear()
102 | exit 0
--------------------------------------------------------------------------------