Skip to content

Web edit and HTTPS push work if multiple Rubies installed [failure unrelated]

Created by: cirosantilli

Fixes:

Before this:

  • web edit
  • HTTPS push

would fail because if you had multiple Rubies (e.g. RVM + /usr/bin/ruby) because git hooks automatically prepend things to the PATH (see https://github.com/gitlabhq/gitlabhq/issues/8045#issuecomment-59495603) which can lead the wrong Ruby version to be called in which dependencies are not installed (typically stuff is installed in RVM but not in the system Ruby which the hooks end up calling).

Only one line here is required for the fix is:

ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH']

plus the update of GitLab shell https://github.com/gitlabhq/gitlab-shell/pull/186

All other lines are to be able to test that the fix works: this is done through the forked_merge_requests commented out test that depends on this change (got commented out at https://github.com/gitlabhq/gitlabhq/commit/71fce0b2). This shows that the feature works because:

  • it is the first test that clones and modifies the clone. Other tests simply copied a test repo without the hooks, but the clone automatically installs the hooks.
  • Semaphore itself uses rbenv and has a system ruby installed.

For that test to pass, it is also necessary to setup the mock server on port 3001 under test_env.rb as explained bellow.

Includes:

  • https://github.com/gitlabhq/gitlabhq/pull/8128 which is necessary for the tests to pass on the remote because we need to get the new shell
  • log_level: Rails.env.test? ? 'DEBUG' : 'INFO', is not strictly necessary but it helped a lot while debugging this (many many hours...)

Dependencies:

GitLab mock internal API server

It is not possible to run the test server on a port: http://stackoverflow.com/questions/6807268/rails-port-of-testing-environment

But GitLab Shell needs to make an API call to /internal/allowed after the push hooks to check if the push is OK, but there is no such port.

On the current testing environment, things work because of a workaround: spec/factories/projects.rb does an explicit repository copy without setting up the hooks.

But now this is not possible anymore, because we need to both clone and modifying the clone on a single test!

I have considered tons of alternatives, and the best I found was: start a mock server on port 3001 which always returns true to gitlab shell.

This is a good option because:

  • it is very little to mock, only a single place with constant simple response. Mocking into GitLab would be much harder.
  • it is the mock point which tests the most of the system since the limit is not being able to serve gitlab at the port
  • does not cause any behavior change since controllers currently deal with all web UI permission questions, and direct HTTP pushes are not tested.

Downsides:

  • it takes up a port
  • it will cause current developer's test environment to break until they update config/gitlab.yml and set test -> gitlab -> port to something accessible. The current value 80 will fail because requires root, so I proposed 3001 on the gitlab.yml.example.

However:

  • I have added a clear error message that should allow any dev to quickly find what is going wrong
  • if someday someone is able to run gitlab tests on a fixed port (the perfect solution), they will need an accessible port anyways. So let's do it now and be done with it.

Merge request reports