我最终不得不为此编写两个自定义 phing 任务。其中一个基本上只是为 foreach 任务添加了一个功能,我在 github here 上将其添加为要点。另一个是一个更简单的任务,用于按索引检索分隔列表属性中的项目,我也将其添加为要点here。导入这些任务的工作方式如下:
<includepath classpath="${base.dir}${ds}Tasks${ds}" />
<taskdef name="foreachkey" classname="ForeachKeyTask" />
<taskdef name="listitembykey" classname="ListItemByKeyTask" />
<property name="deploy.targets.production" value="server1,server2,server3" />
<property name="deploy.users.production" value="user1,user2,user3" />
<property name="deploy.privateKeys.production" value=".ssh/key1_rsa,.ssh/key2_rsa,.ssh/key3_rsa" />
<property name="deploy.publicKeys.production" value=".ssh/key1_rsa.pub,.ssh/key2_rsa.pub,.ssh/key3_rsa.pub" />
<property name="deploy.paths.production" value="/path/on/server1,/path/on/server2,/path/on/server3" />
服务器列表的迭代与使用<foreach> 任务类似,只是添加了一个属性名称以跟踪当前索引:
<foreachkey list="deploy.targets" key="currentIndex" param="deploy.server" target="install" />
然后,被调用者有两个可以访问的属性,deploy.server 获取目标服务器列表中的当前值,currentIndex 引用列表中的当前索引。使用它,我现在可以获得其他关联值:
<-- The properties above get aliased to these properties when the target environment is selected -->
<listitembykey key="currentIndex" property="deploy.users" returnval="user" />
<listitembykey key="currentIndex" property="deploy.privateKeys" returnval="privateKey" />
<listitembykey key="currentIndex" property="deploy.publicKeys" returnval="publicKey" />
<listitembykey key="currentIndex" property="deploy.paths" returnval="path" />
<!-- Properties now available that hold the current credential information related to
the current deployment target:
user, privateKey, publicKey, passphrase, path -->
<!-- And they can be used to execute SSH commands... -->
<netssh username="${user}"
pubkeyfile="${publicKey}"
privkeyfile="${privateKey}"
host="${deploy.server}"
sshlib="${deploy.sshlib}"
command="mkdir -p ${path}${ds}${deploy.releasedir}${ds}${deploy.ts}" />
这种方法的缺点是您必须将相关数据保存在相同的索引中。即使 server1 和 server2 之间的用户名(或密钥或路径)相同,您仍然需要列出两次(在我的情况下它们是不同的)。