[ci skip] in merge commit builds previous commit

The problem I have is that when a merge commit contains [ci skip] then the merge commit is not built as is expected, but instead the previous commit is built which is unexpected.
When [ci-skip] is used, I assume no travis build is triggered at all.

You can see this better with an image here:
Image of the issue in github
In the image the merge commit is not built by travis, but the last merged commit is built by travis. The build has failed and is marked with a red X in github. Build failing is unrelated to this issue.

The merge commit was created with with
git merge -m "merge commit message [skip ci]" somebranch
and the result was pushed to github. After that travis will build the commit before the merge commit, which is unexpected.

Here is a concrete example:
This travis job made a merge and push: https://travis-ci.com/Rochet2/TrinityCore3.3.5/jobs/157766489
and it triggered the following build even though I expected it not to create travis builds: https://travis-ci.org/Rochet2/TrinityCore/builds/453672556

Where are the builds corresponding to these commits you show in the screen grab? Neither https://github.com/Rochet2/TrinityCore3.3.5/commits/master nor https://github.com/Rochet2/TrinityCore3.3.5/commits/pch shows any commit other than your nondescript Update .travis.yml commits.

@BanzaiMan they are in https://github.com/Rochet2/TrinityCore/commits/gomove

That’s a different repository.

Please describe the sequence of events, preferably with time stamps, what you did to which repository, what you observed happen, and what you expected to happen? Also, if you can, perform the same actions again so that the events are more recent than 21 days old.


There are two repositories, official repository and my fork.
The official repository is https://github.com/TrinityCore/TrinityCore/tree/3.3.5 and my fork is https://github.com/Rochet2/TrinityCore/commits/gomove

When I merge the official repository to my fork with

git remote add Trinity https://github.com/TrinityCore/TrinityCore.git
git fetch Trinity 3.3.5
git merge -m "Merge TrinityCore 3.3.5 to gomove [skip ci]" Trinity/3.3.5
git push

Then Travis will not build the skipped commit, but builds the previous commit which was merged from official repository to my fork in this action.

A merge and push is made at 7.1.2019 23:32 UTC+2
after which at 7.1.2019 23:35 UTC+2 travis starts to build the previous commit https://travis-ci.org/Rochet2/TrinityCore/builds/476565851?utm_source=github_status&utm_medium=notification

The merge commit is https://github.com/Rochet2/TrinityCore/commit/46179e95b2b2bf669e4ee82a72a3fe8725aa9416
and the commit travis builds is https://github.com/Rochet2/TrinityCore/commit/d12f0841f198045e80a6bca52c03507df8db5b6d

The repository the commits are in is: https://github.com/Rochet2/TrinityCore/commits/gomove
Here is a screencapture: https://i.imgur.com/xDAdW4W.png

Thanks for the additional information. This does appear to be a bug.

Sorry about the long delay.

For reference, here’s a more concrete steps to reproduce the issue:

git checkout -b other-branch
git commit --allow-empty -m "Empty commit"
git checkout -
git merge --no-ff -m "Merge other-branch [skip ci]" other-branch
git push origin default

GitHub recognizes that there are two commits when we push to it, but we somehow end up building Empty commit.

Actually, this doesn’t need to be a merge commit at all. Simply push multiple commits at once; if the last one or more commits have the magic command [skip ci], we look for a commit without it.

I feel that there was a reason for this behavior, but I have not come up with a good one yet.

For merge commits the behaviour is particular surprising, though, since the commit that gets actually built feels rather random.

Additionally, the created build contains a “Compare link” that shows a diff for a range that is not actually tested by the build. The range ends with the commit that contains the [ci skip] command, which is not actually built.

This behavior comes from

I tend to think not skipping such a push event is the wrong behavior.

In my opinion the current behavior makes no sense for merges for the reasons smarnach said.
Also I would not expect any parent commits to build when skipping the HEAD commit of the work I am pushing.
It seems that many other CI services also skip all commits if the HEAD is skipped in a push according to their documentations.

The travis documentation currently says

If you don’t want to run a build for a particular commit for any reason, you may instruct Travis CI to skip building this commit via a command in the commit message.
Note that in case multiple commits are pushed together, the skip command is effective only if present in the commit message of the HEAD commit.

which would imply that skipping occurs for all of the commits pushed, not just for the HEAD one. Normally only latest pushed commit is built and there is no mention of building parent commits, so I think the current behavior is undocumented.

One f these could be a solution in my opinion:

  1. Remove the feature.
  2. Remove the feature for merges.
  3. Remove the feature for merges AND add a feature toggle for normal pushes.
  4. Remove the feature and implement building of every commit. Together with auto cancellation feature it can replicate the old behavior as it would build all and skip everything except latest build for a branch. There would still probably be some problems to solve with merges though…

In my opinion, respecting the command is the only logically consistent option.

There is no way to know that the PushEvent is the result of a merge; the event payload simply does not give us clues. (It is possible to make additional API queries to GitHub, but they can add up quite quickly.)

Building every commit is wasteful, and I would argue that it is also counterintuitive.

I’ll talk about this with others, and update this topic.


We’ve pushed the fix.

1 Like