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.