I am trying to run a pipeline in Azure Devops but the build is always getting failed with the following error Property salesforce.password was circularly defined.
This is the pipeline which I have created:
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- dev
pool:
vmImage: ubuntu-latest
steps:
- task: Ant@1
inputs:
buildFile: 'build/build.xml'
options: '-Dsalesforce.password=${salesforce.password} -Dsalesforce.username=${salesforce.username} -Dsalesforce.loginurl=${salesforce.loginurl} -Dsalesforce.testLevel=${salesforce.testLevel}'
targets: 'deployCheckOnly'
publishJUnitResults: true
testResultsFiles: '**/TEST-*.xml'
javaHomeOption: 'JDKVersion
All the values are added as a variable in Azure
This is the build.xml file:
<project name="Sample usage of Salesforce Ant tasks" default="deploy" basedir="." xmlns:sf="antlib:com.salesforce">
<property file="build.properties"/>
<property environment="env"/>
<property name="ant.jar" value="ant-salesforce.jar"/>
<property name="sf.username" value="${salesforce.username}"/>
<property name="sf.password" value="${salesforce.password}"/>
<property name="sf.serverurl" value="${salesforce.serverurl}"/>
<property name="sf.testlevel" value="${salesforce.testlevel}"/>
<!-- Setting default value for username, password and session id properties to empty string
so unset values are treated as empty. Without this, ant expressions such as ${sf.username}
will be treated literally.
-->
<condition property="sf.username" value=""> <not> <isset property="sf.username"/> </not> </condition>
<condition property="sf.password" value=""> <not> <isset property="sf.password"/> </not> </condition>
<condition property="sf.serverurl" value=""> <not> <isset property="sf.serverurl"/> </not> </condition>
<condition property="sf.testlevel" value=""> <not> <isset property="sf.testlevel"/> </not> </condition>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<taskdef resource="com/salesforce/antlib.xml" uri="antlib:com.salesforce">
<classpath>
<pathelement location="${ant.jar}" />
</classpath>
</taskdef>
<!-- Test out deploy and retrieve verbs for package 'mypkg' -->
<target name="test">
<!-- Upload the contents of the "mypkg" package -->
<sf:deploy username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" deployRoot="mypkg" rollbackOnError="true"/>
<mkdir dir="retrieveOutput"/>
<!-- Retrieve the contents into another directory -->
<sf:retrieve username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" retrieveTarget="retrieveOutput" packageNames="MyPkg"/>
</target>
<!-- Shows deploying code and running tests only within the org namespace -->
<target name="deployCodeRunLocalTests">
<sf:deploy username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" deployRoot="../force-app" rollbackOnError="true" testlevel="RunLocalTests"/>
</target>
</project>`
if you are trying to pass azure devops build variables you have to update this:
options: '-Dsalesforce.password=${salesforce.password} -Dsalesforce.username=${salesforce.username} -Dsalesforce.loginurl=${salesforce.loginurl} -Dsalesforce.testLevel=${salesforce.testLevel}'
to
options: '-Dsalesforce.password=$(salesforce.password) -Dsalesforce.username=$(salesforce.username) -Dsalesforce.loginurl=$(salesforce.loginurl) -Dsalesforce.testLevel=$(salesforce.testLevel)'