The publisher section in CC.Net will be executed regardless if the build is successful or fails. You need to add the 'publish to build server' as a task, under the tasks section - putting it after your last build step.
This will cause CC.Net to only 'publish to build server' when all previous 'tasks' are completed, without raising an error code.
Typically, if you know what is needed in a DOS .bat file to 'publish to build server' you do as follows;
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<workingDirectory>c:\Somewhere</workingDirectory>
<projectFile>Something.sln</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Debug /v:m</buildArgs>
<targets>Build</targets>
<timeout>720</timeout>
<logger>C:\program files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
<exec>
<executable>C:\program files (x86)\CruiseControl.NET\server\PublishToServer.bat</executable>
<baseDirectory>C:\somewhere</baseDirectory>
<buildArgs></buildArgs>
<buildTimeoutSeconds>9000</buildTimeoutSeconds>
</exec>
</tasks>
As slawekg points out, you can use the buildpublisher, which will execute only if the build is successful, however I still find using a batch file to do the copying more configurable than what is available using buildpublisher.