Mercurial changegroup hook: repository URL - mercurial

How can I, on a Mercurial repository server, figure out the current repository URL or at least name (subpath) in a changegroup — or somewhat equivalent — hook? I'm running HgWeb on IIS.
$HG_URL returns the pushers URL, not the receiving repository's. $HG_SOURCE only returns serve.
Context: I'm trying to write a changegroup hook for Jenkins using /mercurial/notifyCommit?url=<url> that tells Jenkins to perform an SCM poll, and if I can't get this to work, I have to do about 50 cURL calls (once for every repository on the server) on every changegroup trigger, and then remember to maintain this list in hgweb.config for all eternity.

Your hook will be executed inside the root folder of that specific repository, you can use the following command in bash to get the current folder name:
${PWD##*/}

As per Ton's answer, this is what I ended up doing since I'm on Windows:
changegroup.jenkins.cmd:
#for /f "delims=\" %%a in ("%CD%") do #set TOPMOST=%%~nxa
#curl.exe "http://jenkins/mercurial/notifyCommit?url=http://hgweb/%TOPMOST%" -s -S

Related

How to write mercurial hooks on windows?

I want to add a hook to my repository. I can't work out where i need to put the hook file. The hgrc file is as follows:
[hooks]
precommit.test = precommithook
Location is C:\Code\RepoTest.hg\hgrc
Hook file is:
echo "hello world"
Location is C:\Code\RepoTest.hg\precommithook
When i run
hg commit -m"test"
from the command line i get
running hook precommit.test: precommithook
'precommithook' is not recognized as an internal or external command,
operable program or batch file.
abort: precommit.test hook exited with status 1
I've tried various paths but nothing works.
Most of the examples i googled with regards to Mercurial hooks are Unix based.
Is it possible to write hooks in a powershell?
According to Hooks doc, hook must be executable in given environment program, it haven't predefined location, but have to be found by OS.
Thus:
For pure Windows, hook must be named precommithook.bat
It must be placed into dir in $PATH or full path used in hook definition
As result, with
precommit.test = z:\precommit.bat in hgrc
#echo off
echo Hello World in z:\precommit.bat
I have on commit attempt
>hg commit -m "Edits"
Hello World

How do I tag a specific revision in Mercurial when promoting a build in Jenkins?

I have a Jenkins CI server with the Promoted Builds plug-in and the Mercurial plug-in. What I would like to do when a build gets promoted is tag the revision in Mercurial that corresponds to that build.
The Mercurial plug-in exposes an environment variable called MERCURIAL_REVISION_NUMBER, and this is populated when the build runs, but not when the promotion runs. So when I try do the following in an "Execute a Windows batch command" step in my promotion:
hg tag --rev %MERCURIAL_REVISION_NUMBER% "Promoted-%PROMOTED_NUMBER%-%PROMOTED_ID%"
it fails because %MERCURIAL_REVISION_NUMBER% evaluates to an empty string, so there is no value supplied to the --rev argument.
I do notice that the Mercurial revision is saved in the build.xml file for each build. I'm wondering if there is an easy way to get to it in my promotion step.
That build.xml must be something your Jenkins script is creating -- Mercurial doesn't.
Your Mercurial command looks fine.
One option is to just put the build info into a file as part of your jenkins script:
hg id > $WORKSPACE/built-version
and then include built-version as one of the build's artifacts. Then your promotion script can do:
hg tag --rev $(< built-version) "Promoted-${PROMOTED_NUMBER}-${PROMOTED_ID}"
or whatever the windows equivalent of that is.
I ended up doing it with a Powershell script. This is my first PS script, so I'm certainly open to any suggested improvements.
# Read the appropriate Hg revision from build.xml and tag it
$filename = "..\builds\" + $env:PROMOTED_ID + "\build.xml"
[xml]$build = Get-content $filename
$hg = $build.SelectSingleNode("/build/actions/hudson.plugins.mercurial.MercurialTagAction")
write-host "Tagging revision: " + $hg.rev
hg tag --force --rev $hg.rev "Promoted-$env:PROMOTED_NUMBER-$env:PROMOTED_ID"
hg push --force

Mercurial changegroup hooks not triggered; Linux

I have a server which serves a "central" Mercurial repository; the team clones it and pushes their changes up to it via ssh. Hudson is installed on the same server (RHEL 5.5). I wish to trigger a Hudson build whenever anyone pushes to the central Mercurial repository. I also wish to send a notification email upon a push.
In ProjectName/.hg/.hgrc there is the following:
[hooks]
changegroup.hudson = wget http://Server.Name:8080//job/Project_Name/builds?delay=0sec >&2
If I use putty to ssh to this server and then issue the wget command, a build is successfully triggered, so I don't think it's a permissions issue.
Another hook is:
changegroup.notify = /the/path/.hg/hooks/notify
where notify is:
dest='comma separated list of email addresses'
repo="path/to/repository/"
subject="New changesets in $repo"
hg glog -l 10 -r $HG_NODE: | mail -s "$subject" $dest
When I run ./notify directly from the shell, the mail is sent correctly when I am in the central repository's path; if I execute notify from my home directory, the repository is not found and I get an empty email, but at least I get an email. I assume these hooks are just not being run.
What could be getting in the way? What should I check?
Run cd ProjectName; hg showconfig|grep hooks.
I bet your don't see your hooks, if this is exactly what you have:
In ProjectName/.hg/.hgrc there is the following:
Repository-wide hgrc is .hg/hgrc without dot.

Mercurial auto update problem

We are starting to use Mercurial for source control. We have configured the HGRC configuration file to do an auto update after we push to the "central" repository.
With some PCs we get this error msg:
warning: changegroup hook exited with status -1
HGRC looks like this:
[ui]
username=ADMIN
verbose=true
[hooks]
changegroup = hg update >&2
Later we perform the update manually and everything works right.
I had a very simmilar issue. This finally works now:
changegroup = cmd /c hg update
The bold cmd /c causes cmd.exe to spawn which will execute hg update as we want it to, but now the exit value from cmd.exe will be 0.
Longer Story:
setup: win 2008 server.
mercurial 1.9.3
hgwebdir via plain http, its an internal network
error:
my error was funnily not the -1 as in your case but
"warning: changegroup hook exited with status 1"
Anyway, the update was not performed.
I found out that I can put the hooks into either .hgrc or into hgweb.config the problem was the same here or there. I finally put it into hgweb.config as below, so all repositories are auto commiting, which is way better than having this loose branch all the time. The main reason I wanted auto commit is that the respositories on the vcs & build server hold now the latest version which makes admin tasks often simpler.
[web] push_ssl = False allow_push = *
[collections] c:\Dev\Reps = c:\Dev\Reps
[ui] debug=true
[hooks] changegroup = cmd /c hg update
It might be related with the user actually executing the hook, which might not be the one with the correct privileges.
Do you have a IIS webserver managing your Mercurial repos?
(from the thread:)
From experience with Mercurial/IIS, things I'd recommend trying:
(a) Does running a simple non-HG command work? Permissions on cmd.exe will
affect out-of-process python hooks.
(b) Does a simple hook like 'python -c "import sys; sys.exit(0)"' work?
(c) If you make it this far, can you confirm that the process is running as the
user you think it's running as, with a hook that does something like:
import win32api
username = win32api.GetUserName()
(write username to a file so you can read it)

mercurial automatic push on every commit

Being very familiar with the subversion workflow and that fact that 99.9% of the time my computer is connected to the internet, I don't like doing 'hg ci' and 'hg push' separately.
I remember bzr had a 'checkout' command that would bind subsequent 'commit' commands to automatically commit directly to the server ('push').
Does mercurial have something similar to this?
PS: Writing a shell script or alias that runs 'hg ci $* && hg push' would be the last thing I'd do.
You could add a hook to run push after a successful commit.
EDIT: I just tried it out and it seems to work fine. I added the following to the .hg/hgrc file of the repository I wanted to activate automatic pushing for:
[hooks]
commit.autopush = hg push
EDIT 2: Also, you don't have to worry about something like this:
You're in a repository that you don't want to automatically push.
You use hg -R ~/another-repo-that-autopushes commit to commit in a different repo that does automatically push.
Will the hg push hook end up pushing the changes in the current directory instead of the one you're committing in?
No, it won't. According to the page I linked:
An executable hook is always run with its current directory set to a repository's root directory.
It's an edge case, but Mercurial handles it correctly.