Commit 7f4049c3 authored by Felix Becker's avatar Felix Becker Committed by Paul Slaughter

Add Sourcegraph integration

- Initial draft
parent 997a786e
...@@ -33,6 +33,7 @@ import initBreadcrumbs from './breadcrumb'; ...@@ -33,6 +33,7 @@ import initBreadcrumbs from './breadcrumb';
import initUsagePingConsent from './usage_ping_consent'; import initUsagePingConsent from './usage_ping_consent';
import initPerformanceBar from './performance_bar'; import initPerformanceBar from './performance_bar';
import initSearchAutocomplete from './search_autocomplete'; import initSearchAutocomplete from './search_autocomplete';
import initSourcegraph from './sourcegraph';
import GlFieldErrors from './gl_field_errors'; import GlFieldErrors from './gl_field_errors';
import initUserPopovers from './user_popovers'; import initUserPopovers from './user_popovers';
import { initUserTracking } from './tracking'; import { initUserTracking } from './tracking';
...@@ -160,6 +161,10 @@ function deferredInitialisation() { ...@@ -160,6 +161,10 @@ function deferredInitialisation() {
}); });
loadAwardsHandler(); loadAwardsHandler();
if (gon.sourcegraph_enabled) {
initSourcegraph();
}
} }
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
......
/**
* Loads the Sourcegraph integration for support for Sourcegraph extensions and
* code intelligence.
*/
export default function initSourcegraph() {
const sourcegraphUrl = gon.sourcegraph_url;
const assetsUrl = new URL('/assets/webpack/sourcegraph/', window.location.href);
window.SOURCEGRAPH_ASSETS_URL = assetsUrl.href;
window.SOURCEGRAPH_URL = sourcegraphUrl;
window.SOURCEGRAPH_INTEGRATION = 'gitlab-integration';
// inject a <script> tag to fetch the main JS bundle from the Sourcegraph instance
const script = document.createElement('script');
script.type = 'application/javascript';
script.src = new URL('scripts/integration.bundle.js', assetsUrl).href;
script.defer = true;
document.head.appendChild(script);
}
...@@ -259,6 +259,8 @@ module ApplicationSettingsHelper ...@@ -259,6 +259,8 @@ module ApplicationSettingsHelper
:shared_runners_text, :shared_runners_text,
:sign_in_text, :sign_in_text,
:signup_enabled, :signup_enabled,
:sourcegraph_enabled,
:sourcegraph_url,
:terminal_max_session_time, :terminal_max_session_time,
:terms, :terms,
:throttle_authenticated_api_enabled, :throttle_authenticated_api_enabled,
......
...@@ -99,6 +99,10 @@ class ApplicationSetting < ApplicationRecord ...@@ -99,6 +99,10 @@ class ApplicationSetting < ApplicationRecord
presence: true, presence: true,
if: :plantuml_enabled if: :plantuml_enabled
validates :sourcegraph_url,
presence: true,
if: :sourcegraph_enabled
validates :snowplow_collector_hostname, validates :snowplow_collector_hostname,
presence: true, presence: true,
hostname: true, hostname: true,
......
...@@ -102,6 +102,8 @@ module ApplicationSettingImplementation ...@@ -102,6 +102,8 @@ module ApplicationSettingImplementation
shared_runners_text: nil, shared_runners_text: nil,
sign_in_text: nil, sign_in_text: nil,
signup_enabled: Settings.gitlab['signup_enabled'], signup_enabled: Settings.gitlab['signup_enabled'],
sourcegraph_enabled: false,
sourcegraph_url: nil,
terminal_max_session_time: 0, terminal_max_session_time: 0,
throttle_authenticated_api_enabled: false, throttle_authenticated_api_enabled: false,
throttle_authenticated_api_period_in_seconds: 3600, throttle_authenticated_api_period_in_seconds: 3600,
......
- expanded = integration_expanded?('sourcegraph_')
%section.settings.as-sourcegraph.no-animate#js-sourcegraph-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
= _('Sourcegraph')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Enable code intelligence powered by %{link}.').html_safe % { link: link_to('Sourcegraph', 'https://sourcegraph.com', target: '_blank') }
.settings-content
= form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-sourcegraph-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
%fieldset
.form-group
.form-check
= f.check_box :sourcegraph_enabled, class: 'form-check-input'
= f.label :sourcegraph_enabled, _('Enable Sourcegraph'), class: 'form-check-label'
.form-group
= f.label :sourcegraph_url, _('Sourcegraph URL'), class: 'label-bold'
= f.text_field :sourcegraph_url, class: 'form-control', placeholder: 'https://example.sourcegraph.com'
.form-text.text-muted
= _('Add %{link} code intelligence to your GitLab instance code views and pull requests.').html_safe % { link: link_to('Sourcegraph', 'https://sourcegraph.com/', target: '_blank') }
= f.submit _('Save changes'), class: 'btn btn-success'
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
= render_if_exists 'admin/application_settings/elasticsearch_form' = render_if_exists 'admin/application_settings/elasticsearch_form'
= render 'admin/application_settings/plantuml' = render 'admin/application_settings/plantuml'
= render 'admin/application_settings/sourcegraph'
= render_if_exists 'admin/application_settings/slack' = render_if_exists 'admin/application_settings/slack'
= render 'admin/application_settings/third_party_offers' = render 'admin/application_settings/third_party_offers'
= render 'admin/application_settings/snowplow' = render 'admin/application_settings/snowplow'
......
...@@ -299,6 +299,11 @@ module.exports = { ...@@ -299,6 +299,11 @@ module.exports = {
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'), from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'),
to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'), to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'),
}, },
{
from: path.join(ROOT_PATH, 'node_modules/@sourcegraph/code-host-integration/'),
to: path.join(ROOT_PATH, 'public/assets/webpack/sourcegraph/'),
ignore: ['package.json'],
},
{ {
from: path.join( from: path.join(
ROOT_PATH, ROOT_PATH,
......
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddSourcegraphConfigurationToApplicationSettings < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def up
add_column(:application_settings, :sourcegraph_enabled, :boolean, default: false, null: false)
add_column(:application_settings, :sourcegraph_url, :string, null: true, limit: 255)
end
def down
remove_column(:application_settings, :sourcegraph_enabled)
remove_column(:application_settings, :sourcegraph_url)
end
end
...@@ -352,6 +352,8 @@ ActiveRecord::Schema.define(version: 2019_11_12_232338) do ...@@ -352,6 +352,8 @@ ActiveRecord::Schema.define(version: 2019_11_12_232338) do
t.string "snowplow_app_id" t.string "snowplow_app_id"
t.datetime_with_timezone "productivity_analytics_start_date" t.datetime_with_timezone "productivity_analytics_start_date"
t.string "default_ci_config_path", limit: 255 t.string "default_ci_config_path", limit: 255
t.boolean "sourcegraph_enabled", default: false, null: false
t.string "sourcegraph_url", limit: 255
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id" t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id" t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id" t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"
......
...@@ -324,6 +324,8 @@ are listed in the descriptions of the relevant settings. ...@@ -324,6 +324,8 @@ are listed in the descriptions of the relevant settings.
| `snowplow_enabled` | boolean | no | Enable snowplow tracking. | | `snowplow_enabled` | boolean | no | Enable snowplow tracking. |
| `snowplow_app_id` | string | no | The Snowplow site name / application id. (e.g. `gitlab`) | | `snowplow_app_id` | string | no | The Snowplow site name / application id. (e.g. `gitlab`) |
| `snowplow_iglu_registry_url` | string | no | The Snowplow base Iglu Schema Registry URL to use for custom context and self describing events'| | `snowplow_iglu_registry_url` | string | no | The Snowplow base Iglu Schema Registry URL to use for custom context and self describing events'|
| `sourcegraph_enabled` | boolean | no | Enables Sourcegraph integration. Default is `false`. **If enabled, requires** `sourcegraph_url`. |
| `sourcegraph_url` | string | required by: `sourcegraph_enabled` | The Sourcegraph instance URL for integration. |
| `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. | | `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. |
| `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. | | `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. |
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (e.g. from crawlers or abusive bots). | | `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (e.g. from crawlers or abusive bots). |
......
...@@ -54,6 +54,7 @@ GitLab can be integrated with the following enhancements: ...@@ -54,6 +54,7 @@ GitLab can be integrated with the following enhancements:
- Add GitLab actions to [Gmail actions buttons](gmail_action_buttons_for_gitlab.md). - Add GitLab actions to [Gmail actions buttons](gmail_action_buttons_for_gitlab.md).
- Configure [PlantUML](../administration/integration/plantuml.md) to use diagrams in AsciiDoc documents. - Configure [PlantUML](../administration/integration/plantuml.md) to use diagrams in AsciiDoc documents.
- Attach merge requests to [Trello](trello_power_up.md) cards. - Attach merge requests to [Trello](trello_power_up.md) cards.
- Enable integrated code intelligence powered by [Sourcegraph](sourcegraph.md).
## Project services ## Project services
......
---
type: reference, how-to
---
# Sourcegraph integration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/16556) in GitLab X.X.
[Sourcegraph](https://sourcegraph.com) provides complete code intelligence functionality
(historically provided by the Sourcegraph browser extension) including hover tooltips and go-to-definition
working by default for all users.
## Setup **(CORE ONLY)**
> These steps are required for self-managed instances.
> Once enabled in your instance, it will become available to all projects (public, internal, and private).
> Sourcegraph integration is already enabled on GitLab.com and ready to use but restricted to only **public** projects.
Before you can enable Sourcegraph code intelligence in GitLab you need to have a
Sourcegraph instance running and configured with your GitLab instance as an external
service.
### Set up your Sourcegraph instance
If you are new to Sourcegraph, head over to the [Sourcegraph installation documentation](https://docs.sourcegraph.com/admin) and get your instance up and running.
### Configure your Sourcegraph instance with GitLab
1. Navigate to the site admin area in Sourcegraph.
1. [Configure your GitLab external service](https://docs.sourcegraph.com/admin/external_service/gitlab).
You can skip this step if you already have your GitLab repositories searchable in Sourcegraph.
1. Validate that you can search your repositories from GitLab in your Sourcegraph instance by running a test query.
1. Add your GitLab instance URL to the [`corsOrigin` setting](https://docs.sourcegraph.com/admin/config/site_config#corsOrigin) in your site configuration (e.g. `https://sourcegraph.example.com/site-admin/configuration`).
### Configure your GitLab instance with Sourcegraph
1. In GitLab, go to **Admin Area > Settings > Integrations**.
1. Expand the **Sourcegraph** configuration section.
1. Check the **Enable Sourcegraph** checkbox.
1. Set the Sourcegraph URL to your Sourcegraph instance, e.g., `https://sourcegraph.example.com`.
You should now see code intelligence on your files, without needing the browser
extension installed!
...@@ -136,6 +136,10 @@ module API ...@@ -136,6 +136,10 @@ module API
optional :sign_in_text, type: String, desc: 'The sign in text of the GitLab application' optional :sign_in_text, type: String, desc: 'The sign in text of the GitLab application'
optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5 optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5
optional :signup_enabled, type: Boolean, desc: 'Flag indicating if sign up is enabled' optional :signup_enabled, type: Boolean, desc: 'Flag indicating if sign up is enabled'
optional :sourcegraph_enabled, type: Boolean, desc: 'Enable Sourcegraph'
given sourcegraph_enabled: ->(val) { val } do
requires :sourcegraph_url, type: String, desc: 'The configured Sourcegraph instance URL'
end
optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.' optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.'
optional :usage_ping_enabled, type: Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.' optional :usage_ping_enabled, type: Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.'
optional :instance_statistics_visibility_private, type: Boolean, desc: 'When set to `true` Instance statistics will only be available to admins' optional :instance_statistics_visibility_private, type: Boolean, desc: 'When set to `true` Instance statistics will only be available to admins'
......
...@@ -32,6 +32,9 @@ module Gitlab ...@@ -32,6 +32,9 @@ module Gitlab
gon.first_day_of_week = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week gon.first_day_of_week = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week
gon.ee = Gitlab.ee? gon.ee = Gitlab.ee?
gon.sourcegraph_enabled = Gitlab::CurrentSettings.sourcegraph_enabled
gon.sourcegraph_url = Gitlab::CurrentSettings.sourcegraph_url
if current_user if current_user
gon.current_user_id = current_user.id gon.current_user_id = current_user.id
gon.current_username = current_user.username gon.current_username = current_user.username
......
...@@ -887,6 +887,9 @@ msgid_plural "Add %d issues" ...@@ -887,6 +887,9 @@ msgid_plural "Add %d issues"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Add %{link} code intelligence to your GitLab instance code views and pull requests."
msgstr ""
msgid "Add CHANGELOG" msgid "Add CHANGELOG"
msgstr "" msgstr ""
...@@ -6235,6 +6238,9 @@ msgstr "" ...@@ -6235,6 +6238,9 @@ msgstr ""
msgid "Enable SAML authentication for this group" msgid "Enable SAML authentication for this group"
msgstr "" msgstr ""
msgid "Enable Sourcegraph"
msgstr ""
msgid "Enable access to Grafana" msgid "Enable access to Grafana"
msgstr "" msgstr ""
...@@ -6253,6 +6259,9 @@ msgstr "" ...@@ -6253,6 +6259,9 @@ msgstr ""
msgid "Enable classification control using an external service" msgid "Enable classification control using an external service"
msgstr "" msgstr ""
msgid "Enable code intelligence powered by %{link}."
msgstr ""
msgid "Enable error tracking" msgid "Enable error tracking"
msgstr "" msgstr ""
...@@ -16163,6 +16172,12 @@ msgstr "" ...@@ -16163,6 +16172,12 @@ msgstr ""
msgid "Source project cannot be found." msgid "Source project cannot be found."
msgstr "" msgstr ""
msgid "Sourcegraph"
msgstr ""
msgid "Sourcegraph URL"
msgstr ""
msgid "Spam Logs" msgid "Spam Logs"
msgstr "" msgstr ""
......
...@@ -19,6 +19,7 @@ describe API::Settings, 'Settings' do ...@@ -19,6 +19,7 @@ describe API::Settings, 'Settings' do
expect(json_response['plantuml_enabled']).to be_falsey expect(json_response['plantuml_enabled']).to be_falsey
expect(json_response['plantuml_url']).to be_nil expect(json_response['plantuml_url']).to be_nil
expect(json_response['default_ci_config_path']).to be_nil expect(json_response['default_ci_config_path']).to be_nil
expect(json_response['sourcegraph_url']).to be_nil
expect(json_response['default_project_visibility']).to be_a String expect(json_response['default_project_visibility']).to be_a String
expect(json_response['default_snippet_visibility']).to be_a String expect(json_response['default_snippet_visibility']).to be_a String
expect(json_response['default_group_visibility']).to be_a String expect(json_response['default_group_visibility']).to be_a String
...@@ -57,6 +58,8 @@ describe API::Settings, 'Settings' do ...@@ -57,6 +58,8 @@ describe API::Settings, 'Settings' do
repository_storages: ['custom'], repository_storages: ['custom'],
plantuml_enabled: true, plantuml_enabled: true,
plantuml_url: 'http://plantuml.example.com', plantuml_url: 'http://plantuml.example.com',
sourcegraph_enabled: true,
sourcegraph_url: 'https://sourcegraph.com',
default_snippet_visibility: 'internal', default_snippet_visibility: 'internal',
restricted_visibility_levels: ['public'], restricted_visibility_levels: ['public'],
default_artifacts_expire_in: '2 days', default_artifacts_expire_in: '2 days',
...@@ -89,6 +92,8 @@ describe API::Settings, 'Settings' do ...@@ -89,6 +92,8 @@ describe API::Settings, 'Settings' do
expect(json_response['repository_storages']).to eq(['custom']) expect(json_response['repository_storages']).to eq(['custom'])
expect(json_response['plantuml_enabled']).to be_truthy expect(json_response['plantuml_enabled']).to be_truthy
expect(json_response['plantuml_url']).to eq('http://plantuml.example.com') expect(json_response['plantuml_url']).to eq('http://plantuml.example.com')
expect(json_response['sourcegraph_enabled']).to be_truthy
expect(json_response['sourcegraph_url']).to eq('https://sourcegraph.com')
expect(json_response['default_snippet_visibility']).to eq('internal') expect(json_response['default_snippet_visibility']).to eq('internal')
expect(json_response['restricted_visibility_levels']).to eq(['public']) expect(json_response['restricted_visibility_levels']).to eq(['public'])
expect(json_response['default_artifacts_expire_in']).to eq('2 days') expect(json_response['default_artifacts_expire_in']).to eq('2 days')
...@@ -355,5 +360,14 @@ describe API::Settings, 'Settings' do ...@@ -355,5 +360,14 @@ describe API::Settings, 'Settings' do
expect(json_response['domain_blacklist']).to eq(['domain3.com', '*.domain4.com']) expect(json_response['domain_blacklist']).to eq(['domain3.com', '*.domain4.com'])
end end
end end
context "missing sourcegraph_url value when sourcegraph_enabled is true" do
it "returns a blank parameter error message" do
put api("/application/settings", admin), params: { sourcegraph_enabled: true }
expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('sourcegraph_url is missing')
end
end
end end
end end
...@@ -970,6 +970,11 @@ ...@@ -970,6 +970,11 @@
"@sentry/types" "5.7.1" "@sentry/types" "5.7.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sourcegraph/code-host-integration@^0.0.9":
version "0.0.9"
resolved "https://registry.npmjs.org/@sourcegraph/code-host-integration/-/code-host-integration-0.0.9.tgz#0e14dd8986b0219d4f3bb99b66afbb4956b5be36"
integrity sha512-APBHmHKaDNjps5ERuYWQKmUbk1f3TjPP6+8a99g56xwyxvpa0HhitAevfdXxQyp3jGJCdwaIt6OBd6kkkZbOsw==
"@types/anymatch@*": "@types/anymatch@*":
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.0.tgz#d1d55958d1fccc5527d4aba29fc9c4b942f563ff" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.0.tgz#d1d55958d1fccc5527d4aba29fc9c4b942f563ff"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment