Question

sitereactor on Wed, 16 Apr 2014 14:08:49


Is it possible to invoke a new deployment for a git repository without doing git push or fetch?

We are running Kudu as part of Azure Pack and have a scenario where changes are committed to the local git repository and we want to be able to invoke a new deployment once this happens.
I know about the deployment options in the REST API, but I assume that "POST /api/deploy" does a fetch on a remote repository, which won't work as the repository is local (similar to mysite.scm.azurewebsites.net/mysite.git) and it can't fetch from iself :)

Are there any other options available through the API or maybe through NodeJs? Something similar to what Kudu adds to the post-receive git hook?

Thanks,

Morten Christensen


Sponsored



Replies

David Ebbo on Thu, 17 Apr 2014 03:06:12


There is a way that's not really documented but that should work. Please try doing a PUT /api/deployments/, passing an empty JSON object.

Here is what the full curl command would look like: 

curl -X PUT -H "Content-Type: application/json" --data "{}" %KUDU_URL%/api/deployments/

Let me know if that does what you want.

thanks,
David

sitereactor on Thu, 17 Apr 2014 14:40:12


Sweet! That worked perfectly :)

Thanks,

Morten Christensen

sitereactor on Fri, 23 May 2014 13:36:07


Hi David,

I have now had a chance to implement the usage of PUT /api/deployments in our solution and it works. But it does seem to take a veeery long time to complete. I'm not sure why a "deploy current" would take longer then a regular git push to the repository.

Any idea why the PUT /api/deployments approach would take longer to complete?

As an example I have two "deploy current" deployments that take around 2 minutes to complete while a "git push" deployment takes less then a minute.

Could it be something around the increment of what is deployed? A git push updates the pushinfo file in the .git folder with the previous and latest commit id. A "deploy current" doesn't do this, so wondering if it deployes everything.

Thanks,

Morten Christensen

David Ebbo on Fri, 23 May 2014 14:14:14


It shouldn't be slower. Can you look at the deployment logs in both cases to compare where the time is spent?

You might also want to look at LogFiles\Git\trace\trace.xml, as that captures the time spent in git operations, while the deployment log doesn't. Look for the /git-receive-pack requests in trace.xml.

sitereactor on Fri, 23 May 2014 14:36:51


Okay, cool. I checked the trace for the latest "deploy current" via PUT.
It started 05/23 13:53:47 and ended 05/23 13:55:17 .. the major ones seems to be (although I'm unsure of the elapsed being for the entry itself or including the nested steps):

Top step for the PUT deployment: title="Incoming Request" date="05/23 13:53:47" url="/deployments" method="PUT" type="request" instance="DEVUWW" pid="5104,4,52" Connection="Keep-Alive" Content-Length="0" Content-Type="text/plain; charset=utf-8" Host="stage-20140523-1438-environment-updates.*.*.net" elapsed="89973"

  • title="DeploymentService.Deploy(id)" date="05/23 13:53:47" elapsed="89961"
  • title="DeploymentManager.Deploy(id)" date="05/23 13:53:48" elapsed="89352"
  • title="Updating to specific changeset" date="05/23 13:53:48" elapsed="35810"
  • title="Executing external process" date="05/23 13:53:48" type="process" path="git.exe" arguments="checkout master --force" elapsed="35786"
  • title="Building" date="05/23 13:54:24" elapsed="53356"
  • title="Executing external process" date="05/23 13:54:24" type="process" path="starter.cmd" arguments="C:\inetpub\temp\DWASFiles\Sites\4b798179-5d91-49d1-a09e-18af267e140a\VirtualDirectory0\site\deployments\tools\deploy.cmd" elapsed="53106"

Anything that stands out?

David Ebbo on Fri, 23 May 2014 14:48:49


How does it compare to the fast one?

The "checkout master --force" step taking 36s second is probably the culprit. Maybe there is something that could be optimized here.

sitereactor on Sat, 24 May 2014 09:23:16


Here is the trace output of a git push I just did. It only had a few changes, but the changes are basically the same as in the PUT /api/deployments

  <step title="Incoming Request" date="05/24 9:14:17" url="/4b798179-5d91-49d1-a09e-18af267e140a.git/git-receive-pack" method="POST" type="request" instance="DEVUWW" pid="5104,4,18" Connection="Keep-Alive" Pragma="no-cache" Content-Length="1738" Content-Type="application/x-git-receive-pack-request" Accept="application/x-git-receive-pack-result" Accept-Encoding="gzip" Expect="100-continue" Host="stage-20140523-1438-environment-updates.scm.*.net" User-Agent="JGit/2.1.0.0" elapsed="18362">
    <step title="RpcService.ReceivePack" date="05/24 9:14:17" elapsed="18356">
      <step title="Executing external process" date="05/24 9:14:17" type="process" path="git.exe" arguments="rev-parse --git-dir" elapsed="45" />
      <step title="Assuming git repository at C:\inetpub\temp\DWASFiles\Sites\4b798179-5d91-49d1-a09e-18af267e140a\VirtualDirectory0\site\repository" date="05/24 9:14:18" elapsed="0" />
      <step title="Executing external process" date="05/24 9:14:18" type="process" path="git.exe" arguments="rev-parse --git-dir" elapsed="39" />
      <step title="Assuming git repository at C:\inetpub\temp\DWASFiles\Sites\4b798179-5d91-49d1-a09e-18af267e140a\VirtualDirectory0\site\repository" date="05/24 9:14:18" elapsed="0" />
      <step title="Creating temporary deployment" date="05/24 9:14:18" elapsed="21" />
      <step title="GitExeServer.Receive" date="05/24 9:14:18" elapsed="17447">
        <step title="Executing external process" date="05/24 9:14:18" type="process" path="git.exe" arguments="receive-pack --stateless-rpc &quot;C:\inetpub\temp\DWASFiles\Sites\4b798179-5d91-49d1-a09e-18af267e140a\VirtualDirectory0\site\repository&quot;" elapsed="17446" />
      </step>
    </step>
    <step title="Outgoing response" date="05/24 9:14:36" type="response" statusCode="200" statusText="OK" Server="Microsoft-IIS/8.5" Expires="Fri, 01 Jan 1980 00:00:00 GMT" Pragma="no-cache" Cache-Control="no-cache, max-age=0, must-revalidate" X-AspNet-Version="4.0.30319" Content-Type="application/x-git-receive-pack-result" elapsed="0" />
  </step>

I've looked for more entries for git push deploys and all of them only takes around 30 seconds, which is much less then the two minutes it takes for a PUT /api/deployments. Another thing is that there is no trace of the deployment manager in the git push. Not sure if that is merely because of what is logged/traced.

Will try to digg through the source and see if there is anything that would explain this difference.

David Ebbo on Sun, 25 May 2014 00:56:46


Indeed, it seems that the code is inefficient in this case, because it always does a 'git checkout --force', which for very large repos can be slow. I think we should be able to optimize this. Could you please open an issue on GitHub to track it? Thanks!

sitereactor on Mon, 26 May 2014 12:59:37


I created an issue for it on github along with some other observations.

Hope this helps and let me know if you need me to supply more details or test out possible fixes.

https://github.com/projectkudu/kudu/issues/1175

Thanks,
Morten Christensen