ANT delete task and Windows 7 UAC permissions - file-io

When I do a simple delete of the contents of a folder,
<delete includeemptydirs="true">
<fileset dir="${developmentenvironment.www.dir}" includes="**/*"/>
</delete>
I get an error:
C:\Users\...\build.xml:42: Unable to delete file C:\...\www\appserv\AUTHORS.txt
When, I try to delete the file in the OS, it requires elevated permissions.
I also can't get a UAC prompt by doing this:
<exec executable="cmd">
<arg value="/c del ./*.*"/>
</exec>
Can ANT prompt for elevated UAC permissions when using the delete task?

As Ant is designed to be a platform independent build system, I really doubt it provides this very windows-centric functionality. Can you start your build task as a more appropriate user, for instance, one with permission to modify and delete the files needed to complete the build? Alternatively, can you add the user it is running as, recursively, to the permissions on the directory above the one you are trying to delete?

Ant is just a Java program. No JRE will run it that I'm aware of can mess with UAC.

Related

buildtime.sh “Permission denied” when building in Xcode - Native Project generated by WL Ant Task

Please refer the below post.
IBM Worklight - "Permission denied" when building in Xcode
I am using the Worklight 6.1. I build the environment with Ant Task. Ant task creates my Native folder for android and iPhone environment. I try to build the iPhone native which has been generated by Ant Task is giving the below error. Tried giving read & right permission manually. no fix.
Running a custom build phase script: buildtime.sh
/Users/prasanna/Library/Developer/Xcode/DerivedData/MobileAppIphone-coksdtlrretmihenzyztxxxdcuss/Build/Intermediates/MobileAppIphone.build/Debug-iphonesimulator/MobileAppIphone.build/Script-427B829D1393724500F223DC.sh: line 7: /Volumes/DataHD/ST/Mobile_Client/temp/PROD/iPhone/buildtime.sh: Permission denied
DONE with script: buildtime.sh (exitStatus=126)\n\n
Verify the following:
Create the project in Eclipse
Build it using Worklight Studio
Right-click on the generated iphone\native\buildtime.sh file
Check if it has the required permissions
Do the same with Ant
Check if it has the required permissions
If the result differs then this is a defect in Worklight 6.1.0.x
That said, following one of the options from the answer you've linked to should work, however you do not mention which option did you follow...
Given you are using a command line, I'd opt to following the second option to use CHMOD.
It could be that you have given it the wrong path.
Experiment with the path and come back with results.
you can also change the permission using [CHMOD][3]:
Copy the path to the folder holding the buildtime.sh file
Open the Terminal app
Run the following command (but use your own path from 1 above): chmod 755
/Users/idan/Documents/Worklight/workspace-6001/TestProject/apps/TestApp/iphone/native/buildtime.sh
buildtime.sh is executable file, you need to give it executable permissions, not just r&w
Adding the CHMOD 755 in my Ant Script for all files and folder will solve this permission issue.
<target name="set-permission"> <echo level="info">Setting Read / Write / Execute Permissions to all files and .sh files</echo> <chmod perm="755" includes="/*.sh"> <fileset dir="${basedir}/temp/QA/iphone"> <exclude name="**/trial/"/> </fileset> </chmod> </target>

MsBuild Deploy with PackageLocation drop file permissions

I have an MsBuild Build in TFS that is publishing a web zip package.
This is the command line I am using:
/t:Build;Package
/p:DeployOnBuild=true;Configuration=Release;
DeployTarget=Package;PackageLocation=\\xxx\MyApp.zip
It is working properly and it is also replacing in the web.config the parameters as expected.
The only issue I am facing is the permissions applied to the package file.
Right now the file is deployed into:
* \myshare\myapp\ *
And the folder is set with the permission:
Everyone: full control
The package inside the folder has the permission:
TFSAdmin: full control
and nothing else, so I can't open it or copy it ... Is there any way I can avoid that?
So far it seems that the problem can't be fix if not with a workaround.
I have found an easy and simple workaround by executing in the workflow a batch file at the end of the build process.
In the batch file I use the very old ICACLS to re-set the permissions:
ICACLS \\xxx\MyPackage.zip /GRANT Everyone:F
ICACLS \\xxx\MyPackage.zip /GRANT Users:F
Add in MSBuild .proj file:
<Exec Command="icacls "\\xxx\MyApp.zip" /grant User:F" ContinueOnError="true" />
a sequence of simple rights:
F - full access
M - modify access
RX - read and execute access
R - read-only access
W - write-only access
In case you want to make a folder accessible by your website you can place the following snippet in your "PostBuild" events at the very bottom of your .csproj (you need to edit the .csproj file manually via a text editor):
<Target Name="AfterBuild">
<!-- grant everyone the modify right recursively even for files and folders created dynamically in the future -->
<!-- note the use of (OI) and (CI) flags which stand for object inherit & container inherit these flags -->
<!-- indicate that subordinate containers will inherit the same access control element or ace this means that -->
<!-- files and folders created in the future within the targeted folder will get the same permissions -->
<Exec Command=" icacls ".\Logs" /grant Users:(CI)(OI)M /T " ContinueOnError="true" />σ
<Exec Command=" icacls ".\Logs" /grant IIS_IUSRS:(CI)(OI)M /T " ContinueOnError="true" />
</Target>
Sidenote: If you use publish/deploy-on-remote-server functionality of visual studio to deploy your website, then it goes without saying that the folder permissions will probably NOT be preserved and that you will have to use some sort of post-installation script to re-apply them (probably using the 'icacls' approach again show here). This sort of post-installation script should probably be part of WebDeploy - haven't used WebDeploy myself though so your mileage may vary on this particular aspect.

MSBUILD - block until a file exists on an ftp server?

As part of a build process .. I would like to block the build until a file gets created (exists) remotely at an ftp location, after which I would continue the build. (Preferably with somekind of time out limit).
Suggestions?
Is this even possible using only the standard msbuild task and/or extensionPack/communitytask?
Your best bet is to build a small custom exe (you can even compile it as a build step) that polls for the file you are looking for. Then you use the PreBuild target, or a custom target in a pre-build step to verify that the file exists.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="WaitOnFTP">
<Exec Command="MyFTPWaiter.exe"/>
</Target>
</Project>
Other more MSBuild oriented suggestions are to remake that exe as a custom task, or even an inline task in MSBuild 4.0.
FWIW, I've encountered a similar solution done by a peer who didn't want large binaries used by integration tests in version control and he required the use of a custom downloader in the build to get the files from a SMB share. It worked well enough.
Custom Tasks
Inline Tasks

How do I copy files to a network share that requires a password using MSBuild?

I've created an MSBuild.xml file to automate our ASP.NET project builds. It builds the project, publishes it, zips it and copies the zip to a network share. This all works perfectly, provided that I have already logged in to the network folder previously. After I have accessed the network share the username and password are remembered for until I log out of my machine. If I haven't logged in previously I get a "failure: unknown user name or bad password" error when I run the build file. I would like the build to work all the time regardless of whether I have previously accessed the network share.
Currently I'm using the Copy task to copy the zip file to the network share. I've checked the Copy task documentation and I can't see any way to include credentials. So, how can I copy files to a network share passing the required username and password?
Here is an example of the Copy task I'm using. All the properties are defined at the top of the MSBuild.xml file:
<Target Name="CopyToServer">
<Copy SourceFiles="$(ReleaseFolder)\$(ZipFileName).zip" DestinationFolder="$(WebServerRoot)" />
</Target>
I had the same problem. But I did not want to enter password each time I deploy app using RunAs.
Instead, I use Copy task wrapped by net use via Exec :
<Target Name="CopyOutput">
<ItemGroup>
<PackagedFiles Include="$(ProjectName)\obj\$(Configuration)\Package\PackageTmp\**\*.*"/>
</ItemGroup>
<Exec Command="net use $(DestPath) /user:$(DestLogin) $(DestPass)" ContinueOnError="false"/>
<Copy SourceFiles="#(PackagedFiles)"
DestinationFiles="#(PackagedFiles->'$(DestPath)\%(RecursiveDir)%(Filename)%(Extension)')"
ContinueOnError="true"/>
<Exec Command="net use $(DestPath) /delete" />
</Target>
DestPath, DestLogin and DestPass I set through environment variables.
Thanks to Phil's answer and this one.
I've found one solution. I'm not entirely happy with it, but it'll do until I find a better solution.
If you run the MSBuild command from a batch file it's possible to use the runas command to run MSBuild as the user that has the required permissions to access the network share.
E.g.
runas /user:someWindowsUser "C:\PathToBatchFile"
I would reccoment to create special account, let's say builder, and give read/write access for that account share on remote computer.
Or you can call script on computer start up to open session. See net use /?

How can you publish a ClickOnce application through CruiseControl.NET?

I have CruiseControl.NET Version 1.4 set up on my development server. Whenever a developer checks in code, it makes a compile.
Now we're at a place where we can start giving our application to the testers. We'd like to use ClickOnce to distribute the application, with the idea being that when a tester goes to test the application, they have the latest build.
I can't find a way to make that happen with CruiseControl.NET. We're using MSBUILD to perform the builds.
We've done this and can give you some pointers to start.
2 things you should be aware of:
MSBuild can generate the necessary deployment files for you.
MSBuild won't deploy the files to the FTP or UNC share. You'll need a separate step for this.
To use MSBuild to generate the ClickOnce manifests, here's the command you'll need to issue:
msbuild /target:publish /p:Configuration=Release /p:Platform=AnyCPU; "c:\yourProject.csproj"
That will tell MSBuild to build your project and generate ClickOnce deployment files inside the bin\Release\YourProject.publish directory.
All that's left is to copy those files to the FTP/UNC share/wherever, and you're all set.
You can tell CruiseControl.NET to build using those MSBuild parameters.
You'll then need a CruiseControl.NET build task to take the generated deployment files and copy them to the FTP or UNC share. We use a custom little C# console program for this, but you could just as easily use a Powershell script.
Thanks for all the help. The final solution we implemented took a bit from every answer.
We found it easier to handle working with multiple environments using simple batch files. I'm not suggesting this is the best way to do this, but for our given scenario and requirements, this worked well. Supplement "Project" with your project name and "Environment" with your environment name (dev, test, stage, production, whatever).
Here is the tasks area of our "ccnet.config" file.
<!-- override settings -->
<exec>
<executable>F:\Source\Project\Environment\CruiseControl\CopySettings.bat</executable>
</exec>
<!-- compile -->
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<workingDirectory>F:\Source\Project\Environment\</workingDirectory>
<projectFile>Project.sln</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
<targets>Rebuild</targets>
<timeout>0</timeout>
<logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
<!-- clickonce publish -->
<exec>
<executable>F:\Source\Project\Environment\CruiseControl\Publish.bat</executable>
</exec>
The first thing you will notice is that CopySettings.bat runs. This copies specific settings for the environment, such as database connections.
Next, the standard MSBUILD task runs. Any compile errors are caught here and handled as normal.
The last thing to execute is Publish.bat. This actually performs a MSBUILD "rebuild" again from command line, and parameters from CruiseControl are automatically passed in and built. Next, MSBUILD is called for the "publish" target. The exact same parameters are given to the publish as the rebuild was issued. This keeps the build numbers in sync. Also, our executables are named differently (i.e. - ProjectDev and ProjectTest). We end up with different version numbers and names, and this allows ClickOnce to do its thing.
The last part of Publish.bat copies the actual files to their new homes. We don't use the publish.htm as all our users are on the network, we just give them a shortcut to the manifest file on their desktop and they can click and always be running the correct executable with a version number that ties out in CruiseControl.
Here is CopySettings.bat
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\app.config" "F:\Source\Project\Environment\Project" /Y /I /R
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.Designer.vb" "F:\Source\Project\Environment\Project\My Project" /Y /I /R
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.settings" "F:\Source\Project\Environment\Project\My Project" /Y /I /R
And lastly, here is Publish.bat
C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:rebuild "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationRevision=%CCNetLabel% /property:AssemblyName="ProjectEnvironment" /property:PublishUrl="\\Server\bin\Project\Environment\\"
C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:publish "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationVersion="1.0.0.%CCNetLabel%" /property:AssemblyVersion="1.0.0.%CCNetLabel%" /property:AssemblyName="ProjectEnvironment"
XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish" "F:\Binary\Project\Environment" /Y /I
XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish\Application Files" "F:\Binary\Project\Environment\Application Files" /Y /I /S
Like I said, it's probably not done the way that CruiseControl and MSBUILD developers had intended things to work, but it does work. If you need to get this working yesterday, it might be the solution you're looking for. Good luck!
I remember doing this last year for a ClickOnce project I was working on. I remember it taking me forever to figure out but here it is. What I wanted my scripts to do was to generate a different installer that pointed to our dev env and a different one for prod. Not only that but i needed it to inject the right versioning information so the existing clients would 'realize' there is a new version out there which is the whole point of clickOnce.
In this script you have to replace with your own server names etc. The trick is to save the publish.htm and project.publish file and inject the new version number based on the version that is provided to you by CC.NET.
Here is what my build script looked like:
<target name="deployProd">
<exec program="<framework_dir>\msbuild.exe" commandline="<project>/<project>.csproj /property:Configuration=PublishProd /property:ApplicationVersion=${build.label}.*;PublishUrl=\\<prod_location>\binups$\;InstallUrl=\\<prod_location>\binups$\;UpdateUrl=\\<prod_location>\binups$\;BootstrapperComponentsUrl=\\<prod_location>\prereqs$\ /target:publish"/>
<copy todir="<project>\bin\PublishProd\<project>.publish">
<fileset basedir=".">
<include name="publish.htm"/>
</fileset>
<filterchain>
<replacetokens>
<token key="CURRENT_VERSION" value="${build.label}"/>
</replacetokens>
</filterchain>
</copy>
</target>
Hope this helps
Just be able passing the ${CCNetLabel} in the CCNET.config msbuild task would be a great improvement.
You want to use the ClickOnce manifest generation tasks in msbuild. The process is a little long winded, so I am just going to point you to a couple of links. Here is the reference on msdn and a sample article to hopefully get you started.