This is a mobile version, full one is here.
Yegor Bugayenko
29 March 2015
How AppVeyor Helps Me to Validate Pull Requests Before Rultor Merges Them
AppVeyor is a great cloud continuous integration service that builds Windows projects. Rultor is a DevOps assistant, which automates release, merge and deploy operations, using Docker containers. These posts explain how Rultor works and what it’s for: Rultor.com, a Merging Bot and Master Branch Must Be Read-Only.
The problem is that Rultor is running all scripts inside Docker containers and Docker can’t build Windows projects. The only and the best logical solution is to trigger AppVeyor before running all other scripts in Docker. If AppVeyor gives a green light, we continue with our usual in-Docker script. Otherwise, we fail the entire build. Below I explain how this automation was configured in Takes framework.
First, I got a token from my AppVeyor account (at the time
of writing it was here). I created
a text file curl-appveyor.cfg
with this content (it’s not my real token inside,
just an example):
--silent
--header "Authorization: Bearer 1hdmsfbs7xccb9x6g1y4"
--header "Content-Type: application/json"
--header "Accept: application/json"
Then, I encrypted this file, using rultor
command line tool:
$ rultor encrypt -p yegor256/takes curl-appveyor.cfg
The file I created was called
curl-appveyor.cfg.asc
.
I committed and pushed into yegor256/takes
GitHub repository.
$ git add curl-appveyor.cfg.asc
$ git commit -am 'CURL config for Appveyor'
$ git push origin master
Then, I configured AppVeyor “pinging” from Docker script.
This is what I did in .rultor.yml
:
decrypt:
curl-appveyor.cfg: "repo/curl-appveyor.cfg.asc"
merge:
script: |-
ver=$(curl -K ../curl-appveyor.cfg \
--data "{accountName: 'yegor256',
projectSlug: 'takes',
pullRequestId: '${pull_id}'}" \
https://ci.appveyor.com/api/builds | jq -r '.version')
while true; do
status=$(curl -K ../curl-appveyor.cfg \
https://ci.appveyor.com/api/projects/yegor256/takes/build/${ver} \
| jq -r '.build.status')
if [ "${status}" == "success" ]; then break; fi
if [ "${status}" == "failed" ]; then
echo "see https://ci.appveyor.com/project/yegor256/takes/build/${ver}"
exit 1
fi
echo "waiting for AppVeyor build ${ver}: ${status}"
sleep 5s
done
mvn clean install
There is no magic here, it’s very simple. First, I start a new build
using /api/builds
end-point of
AppVeyor REST API.
${pull_id}
is an environment variable that is coming from Rultor,
it contains an integer number of current pull request.
I’m using jq in order to parse AppVeyor JSON output.
Once the build is started, I’m getting its unique version
and start
looping to check its status. I’m waiting for success
or failed
. Anything
else will mean that the build is still in progress and I should keep looping.
You can see how it works in this pull request, for example: yegor256/takes#93.