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:
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.
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.
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.
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.
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:
Remove the feature.
Remove the feature for merges.
Remove the feature for merges AND add a feature toggle for normal pushes.
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.