GSOC Project : Improving RubyBench

Currently I am using rubybench/ruby:initial (‘initial’ is just a random tag) in FROM to use the previous image as the base for the next build. initial tag is the docker tag I gave on dockerhub. At present, every image has the tag initial. So base image just picks up the previous image to build. However I am unable to figure out how to make this tag variable to point it to commit’s sha1. In this case for the base image I have to use the previous commit’s sha1 and tag the latest build with current commit’s sha1. Do you have any ideas?

Hmm I’m not sure yet. I’ll try to have a look this weekend. In the mean time, try reading the documentation? :stuck_out_tongue:

I will also try to find it out. And I did not follow you, which documentation?

1 Like

@shahsaurabh0605 @system Sorry. I was travelling for few days and could not reply. Do we want to setup some chat for the ongoing discussion or we are fine discussing here?

1 Like

On my side, It’s perfectly fine discussing here.

I tried to find a lot on how we can tag our images with commit’s sha1, but I don’t think docker provides any such provision for now. You can follow my question on stackoverflow. So can we keep a fixed tag for our images for now? I think this will also be easier to work with.

We don’t have to stick with dockerhub. You can try writing a script which listens for an incoming hook from Github. Then just sed the Dockerfile and build the new image with the right tag.

I have tried to write a script to trigger the builds here :
This script must listen an incoming hook from your ruby repo and run. This will first substitute the base image with the previous commit. Build and tag the new image with the latest commit and push it on dockerhub.

I don’t know much about github webhooks but I think we can do something to place the previous commit’s sha1 as the tag for its base image. Is this the correct way?

I’m not following how that will happen. Wont a .travis.yml file automatically trigger a build when we push new commits to the repository? Why do we need an incoming hook in this case?

You have to be careful here… By the time travis starts to build the new image, the latest commit might not be the one we want. You have to change your Dockerfile to have a git reset --hard <commit sha1> some where.

Take time to read about it :slight_smile:

Here the commits will be pushed to your ruby repository and .travis.yml file will be present in ruby-bench-docker. Does .travis.yml still trigger automatically?

Travis will trigger a build for any repository that contains a .travis.yml file.

Travis will trigger a build for any repository that contains a .travis.yml file when there is a push in the repo. I don’t think we are having any push in ruby-bench-docker when there is a commit in ruby. So how can it trigger automatically?

Ok I think we need to take a step back here and reorganize the work you’re doing.

Our end goal here is to have a Docker image built for each commit of Ruby and the built should be triggered when we push to our fork of Ruby.

So here are some questions you need to answer and figure out the solution for:

  1. How can I be notified of when a commit has been made to our fork of Ruby?
  2. Once I know there is a new commit, how do I get the payload of the commit so that I have the relevant information I need to build a new Ruby image based on that commit.
  3. What service do we need in order to build the image? Some CI or can it just be a script which we can run to listen for changes. See how we process an incoming hook in order to run the benchmarks for each commit.
1 Like

I figured out that we can run travis builds through the api. Also, we already have a Github hook that triggers one of the remote server jobs. So what we can do is we run the script as shown here in the remote_server_jobs.rb to trigger the travis ci build in ruby-bench-docker.

We can replace the ‘previous commit’ in my .travis.yml with this command: curl -s -S "https://registry.hub.docker.com/v2/repositories/repo/image/tags/" | jq '."results"[]["name"]'| sed -n 1p |cut -c2-7 which fetches the tag of previous image from dockerhub and sed it to our base image. We can fetch the latest commit from your ruby fork and tag our new image.

So finally, whenever there is a commit in your fork of ruby, we will run .travis.yml file. This will fetch the tag of previous image from dockerhub, build our new image and tag it with the latest commit. We can then pull our new image and do the rest of the stuff.

I think this can answer your three questions.

1 Like

:slight_smile: Ok I like this direction we’re heading. Instead of remote_server_jobs, we should probably trigger the build in https://github.com/ruby-bench/ruby-bench-web/blob/d457f282f7453464b79a070ca7bbd5e2c8d5ff81/app/services/github_event_handler.rb.

Right now, you just need to glue all this pieces together and we should be getting our images built real soon :slight_smile:

Nice :smile:

So can we trigger our travis build exactly here? Because there is just one problem left now. Building our image will take sometime and I think we pull our final built image from here. So we need to ensure that the image is pulled only after it is completely built. Is this done here?

1 Like

yup run a background job to trigger the build. You’ll need to find some way to check and make sure the build is complete before we run our benchmarks using the image :slight_smile:

Summary of the complete workflow is as follows:

Goal: A docker image built for each commit of Ruby and the build should be triggered when we push to our fork of Ruby.

Approach: Firstly, we have our base Dockerfile which is to be manually built for a start. Tag this with the latest commit’s sha1.

Now our stage is set. As soon as there is a commit in ruby, we reach github_event_handler.rb through the github hook. I have modified this file to run script.sh and wait in the while loop till our .travis.yml completes its build. script.sh contains the api code to trigger the travis ci build. So here we first run our script to trigger the build. .travis.yml runs this Dockerfile. It first changes the base image to the previously built image on dockerhub, runs the runner script, builds our new image tagging it with latest commit’s sha1 and pushes it to the dockerhub. As we wait for this process to complete, on completion we can safely run our benchmarks.

Same process follows when there is next commit in ruby.

Can you submit a PR to integrate this into ruby-bench-web?

Now that the general idea is good, we want to get it working :slight_smile: