summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-03-22 03:08:17 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-03-22 03:08:17 +0000
commitb460d4a7c027452a221b6fa0e1215c307e2bf2b6 (patch)
treeb91b07ac65a2443b9105719184eb529287b5f154
parent6e3df404ce4365d20af0e06484528b29f92c31a3 (diff)
downloadgitlab-ce-b460d4a7c027452a221b6fa0e1215c307e2bf2b6.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue12
-rw-r--r--app/assets/javascripts/invite_members/constants.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue2
-rw-r--r--db/post_migrate/20230315161408_finalize_set_notifications_bigint_conversion_backfill.rb34
-rw-r--r--db/post_migrate/20230317195228_prepare_async_sent_notifications_index.rb27
-rw-r--r--db/schema_migrations/202303151614081
-rw-r--r--db/schema_migrations/202303171952281
-rw-r--r--doc/administration/gitaly/configure_gitaly.md51
-rw-r--r--doc/administration/gitaly/monitoring.md1
-rw-r--r--locale/gitlab.pot8
-rwxr-xr-xscripts/verify-tff-mapping5
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js59
-rw-r--r--tests.yml6
-rw-r--r--workhorse/go.mod2
-rw-r--r--workhorse/go.sum4
18 files changed, 150 insertions, 73 deletions
diff --git a/Gemfile b/Gemfile
index 8eeadda08fa..abe77b36741 100644
--- a/Gemfile
+++ b/Gemfile
@@ -372,7 +372,7 @@ gem 'prometheus-client-mmap', '~> 0.19', require: 'prometheus/client'
gem 'warning', '~> 1.3.0'
group :development do
- gem 'lefthook', '~> 1.3.5', require: false
+ gem 'lefthook', '~> 1.3.7', require: false
gem 'rubocop'
gem 'solargraph', '~> 0.47.2', require: false
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 89403a4f1bf..d740ef39aeb 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -326,7 +326,7 @@
{"name":"kramdown-parser-gfm","version":"1.1.0","platform":"ruby","checksum":"fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729"},
{"name":"kubeclient","version":"4.11.0","platform":"ruby","checksum":"4985fcd749fb8c364a668a8350a49821647f03aa52d9ee6cbc582beb8e883fcc"},
{"name":"launchy","version":"2.5.0","platform":"ruby","checksum":"954243c4255920982ce682f89a42e76372dba94770bf09c23a523e204bdebef5"},
-{"name":"lefthook","version":"1.3.5","platform":"ruby","checksum":"0e1e44763ff578c75a69fb44d2c24bad45b01ad9946925f110176e8c3dcd2443"},
+{"name":"lefthook","version":"1.3.7","platform":"ruby","checksum":"94bcec3a7bba79fa6f0d1aec9e9cf5b1a75ac507700edb5e7f5662cec710f651"},
{"name":"letter_opener","version":"1.7.0","platform":"ruby","checksum":"095bc0d58e006e5b43ea7d219e64ecf2de8d1f7d9dafc432040a845cf59b4725"},
{"name":"letter_opener_web","version":"2.0.0","platform":"ruby","checksum":"33860ad41e1785d75456500e8ca8bba8ed71ee6eaf08a98d06bbab67c5577b6f"},
{"name":"libyajl2","version":"1.2.0","platform":"ruby","checksum":"1117cd1e48db013b626e36269bbf1cef210538ca6d2e62d3fa3db9ded005b258"},
diff --git a/Gemfile.lock b/Gemfile.lock
index d7c1d970656..d1946ec0f70 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -876,7 +876,7 @@ GEM
rest-client (~> 2.0)
launchy (2.5.0)
addressable (~> 2.7)
- lefthook (1.3.5)
+ lefthook (1.3.7)
letter_opener (1.7.0)
launchy (~> 2.2)
letter_opener_web (2.0.0)
@@ -1780,7 +1780,7 @@ DEPENDENCIES
knapsack (~> 1.21.1)
kramdown (~> 2.3.1)
kubeclient (~> 4.11.0)
- lefthook (~> 1.3.5)
+ lefthook (~> 1.3.7)
letter_opener_web (~> 2.0.0)
license_finder (~> 7.0)
licensee (~> 9.15)
diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
index 812e39e6392..a2d3b47d8f0 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -13,7 +13,6 @@ import { partition, isString, uniqueId, isEmpty } from 'lodash';
import InviteModalBase from 'ee_else_ce/invite_members/components/invite_modal_base.vue';
import Api from '~/api';
import Tracking from '~/tracking';
-import ExperimentTracking from '~/experimentation/experiment_tracking';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import { getParameterValues } from '~/lib/utils/url_utility';
import { n__, sprintf } from '~/locale';
@@ -248,14 +247,10 @@ export default {
eventHub.$on('openModal', (options) => {
this.openModal(options);
- if (this.isOnLearnGitlab) {
- this.trackEvent(INVITE_MEMBERS_FOR_TASK.name, this.source);
- }
});
if (this.tasksToBeDoneEnabled) {
this.openModal({ source: 'in_product_marketing_email' });
- this.trackEvent(INVITE_MEMBERS_FOR_TASK.name, INVITE_MEMBERS_FOR_TASK.view);
}
},
methods: {
@@ -283,10 +278,6 @@ export default {
closeModal() {
this.$root.$emit(BV_HIDE_MODAL, this.modalId);
},
- trackEvent(experimentName, eventName) {
- const tracking = new ExperimentTracking(experimentName);
- tracking.event(eventName);
- },
showEmptyInvitesAlert() {
this.invalidFeedbackMessage = this.$options.labels.placeHolder;
this.shouldShowEmptyInvitesAlert = true;
@@ -347,8 +338,7 @@ export default {
trackinviteMembersForTask() {
const label = 'selected_tasks_to_be_done';
const property = this.selectedTasksToBeDone.join(',');
- const tracking = new ExperimentTracking(INVITE_MEMBERS_FOR_TASK.name, { label, property });
- tracking.event(INVITE_MEMBERS_FOR_TASK.submit);
+ this.track(INVITE_MEMBERS_FOR_TASK.submit, { label, property });
},
onCancel() {
this.track('click_cancel', { label: this.source });
diff --git a/app/assets/javascripts/invite_members/constants.js b/app/assets/javascripts/invite_members/constants.js
index 86badd16d6c..0dbbd00987b 100644
--- a/app/assets/javascripts/invite_members/constants.js
+++ b/app/assets/javascripts/invite_members/constants.js
@@ -5,8 +5,6 @@ export const VALID_TOKEN_BACKGROUND = 'gl-bg-green-100';
export const INVALID_TOKEN_BACKGROUND = 'gl-bg-red-100';
export const INVITE_MEMBERS_FOR_TASK = {
minimum_access_level: 30,
- name: 'invite_members_for_task',
- view: 'modal_opened_from_email',
submit: 'submit',
};
export const TOAST_MESSAGE_LOCALSTORAGE_KEY = 'members_invited_successfully';
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
index bcae1a12344..9bf815d5264 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
@@ -140,7 +140,7 @@ export default {
</gl-skeleton-loader>
</template>
<template v-if="!loading">
- <h4 class="gl-mr-3" data-testid="statusText">
+ <h4 class="gl-mr-3 gl-flex-grow-1" data-testid="statusText">
<gl-sprintf :message="statusText" data-testid="statusText">
<template #merge_author>
<mr-widget-author v-if="state.mergeUser" :author="state.mergeUser" />
diff --git a/db/post_migrate/20230315161408_finalize_set_notifications_bigint_conversion_backfill.rb b/db/post_migrate/20230315161408_finalize_set_notifications_bigint_conversion_backfill.rb
new file mode 100644
index 00000000000..d4a6d86d9cb
--- /dev/null
+++ b/db/post_migrate/20230315161408_finalize_set_notifications_bigint_conversion_backfill.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class FinalizeSetNotificationsBigintConversionBackfill < Gitlab::Database::Migration[2.1]
+ include Gitlab::Database::MigrationHelpers::ConvertToBigint
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = :sent_notifications
+
+ def up
+ return unless should_run?
+
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ )
+ end
+
+ def down
+ # No op
+ end
+
+ private
+
+ def should_run?
+ com_or_dev_or_test_but_not_jh?
+ end
+end
diff --git a/db/post_migrate/20230317195228_prepare_async_sent_notifications_index.rb b/db/post_migrate/20230317195228_prepare_async_sent_notifications_index.rb
new file mode 100644
index 00000000000..ea035b3ee58
--- /dev/null
+++ b/db/post_migrate/20230317195228_prepare_async_sent_notifications_index.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class PrepareAsyncSentNotificationsIndex < Gitlab::Database::Migration[2.1]
+ include Gitlab::Database::MigrationHelpers::ConvertToBigint
+
+ TABLE_NAME = :sent_notifications
+ COLUMN_NAME = :id_convert_to_bigint
+ INDEX_NAME = :index_sent_notifications_on_id_convert_to_bigint
+
+ def up
+ return unless should_run?
+
+ prepare_async_index TABLE_NAME, COLUMN_NAME, name: INDEX_NAME, unique: true
+ end
+
+ def down
+ return unless should_run?
+
+ unprepare_async_index TABLE_NAME, COLUMN_NAME, name: INDEX_NAME
+ end
+
+ private
+
+ def should_run?
+ com_or_dev_or_test_but_not_jh?
+ end
+end
diff --git a/db/schema_migrations/20230315161408 b/db/schema_migrations/20230315161408
new file mode 100644
index 00000000000..8f8e116de10
--- /dev/null
+++ b/db/schema_migrations/20230315161408
@@ -0,0 +1 @@
+edd3d506ad848f854fa9614df3b88619704c1cd834f5c2b7bb7bde20d76888bc \ No newline at end of file
diff --git a/db/schema_migrations/20230317195228 b/db/schema_migrations/20230317195228
new file mode 100644
index 00000000000..ba9f36ae31d
--- /dev/null
+++ b/db/schema_migrations/20230317195228
@@ -0,0 +1 @@
+cc3bc6913ae957318f1a41b00cf6b8c3b6b445b6a16c460e8744e94618416bf6 \ No newline at end of file
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index 543f5b3c119..2c7978c8d52 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -1560,3 +1560,54 @@ proposed in issue [19185](https://gitlab.com/gitlab-org/gitlab/-/issues/19185).
```
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+
+## Generate configuration using an external command
+
+> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4828) in GitLab 15.10.
+
+You can generate parts of the Gitaly configuration using an external command. You might do this:
+
+- To configure nodes without having to distribute the full configuration to each of them.
+- To configure using auto-discovery of the node's settings. For example, using DNS entries.
+- To configure secrets at startup of the node, so that don't need to be visible in plain text.
+
+To generate configuration using an external command, you must provide a script that dumps the
+desired configuration of the Gitaly node in JSON format to its standard output.
+
+For example, the following command configures the HTTP password used to connect to the
+GitLab internal API using an AWS secret:
+
+```ruby
+#!/usr/bin/env ruby
+require 'json'
+JSON.generate({"gitlab": {"http_settings": {"password": `aws get-secret-value --secret-id ...`}}})
+```
+
+You must then make the script path known to Gitaly.
+
+**For Omnibus GitLab**
+
+Edit `/etc/gitlab/gitlab.rb` and configure the `config_command`:
+
+```ruby
+gitaly['configuration'] = {
+ config_command: '/path/to/config_command',
+}
+```
+
+**For installations from source**
+
+Edit `/home/git/gitaly/config.toml` and configure `config_command`:
+
+```toml
+config_command = "/path/to/config_command"
+```
+
+After configuration, Gitaly executes the command on startup and parses its
+standard output as JSON. The resulting configuration is then merged back into
+the other Gitaly configuration.
+
+Gitaly fails to start up if either:
+
+- The configuration command fails.
+- The output produced by the command cannot be parsed as valid JSON.
diff --git a/doc/administration/gitaly/monitoring.md b/doc/administration/gitaly/monitoring.md
index d4f3d931b03..a854a0a3b48 100644
--- a/doc/administration/gitaly/monitoring.md
+++ b/doc/administration/gitaly/monitoring.md
@@ -156,6 +156,7 @@ The following metrics are available from the `/metrics` endpoint:
- `gitaly_praefect_replication_delay_bucket`, a histogram measuring how much time passes between
when the replication job is created and when it starts. Available in GitLab 12.10 and later.
- `gitaly_praefect_connections_total`, the total number of connections to Praefect. [Introduced](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/4220) in GitLab 14.7.
+- `gitaly_praefect_method_types`, a count of accessor and mutator RPCs per node.
To monitor [strong consistency](index.md#strong-consistency), you can use the following Prometheus metrics:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c5471e1e183..31e94d1c47c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -12743,9 +12743,6 @@ msgstr ""
msgid "CycleAnalytics|Create a custom value stream to view metrics about stages specific to your development process. Use your value stream to visualize your DevSecOps lifecycle, determine the velocity of your group, and identify inefficient processes."
msgstr ""
-msgid "CycleAnalytics|Create a custom value stream…"
-msgstr ""
-
msgid "CycleAnalytics|Custom value streams to measure your DevSecOps lifecycle"
msgstr ""
@@ -12758,12 +12755,15 @@ msgstr ""
msgid "CycleAnalytics|Display chart filters"
msgstr ""
-msgid "CycleAnalytics|If you have recently upgraded to GitLab Premium, it can take up to 30 minutes for data to collect and display."
+msgid "CycleAnalytics|If you have recently upgraded your GitLab license from a tier without this feature, it can take up to 30 minutes for data to collect and display."
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
+msgid "CycleAnalytics|New value stream…"
+msgstr ""
+
msgid "CycleAnalytics|Number of tasks"
msgstr ""
diff --git a/scripts/verify-tff-mapping b/scripts/verify-tff-mapping
index 872f8dae86e..2fbafed3987 100755
--- a/scripts/verify-tff-mapping
+++ b/scripts/verify-tff-mapping
@@ -196,6 +196,11 @@ tests = [
explanation: 'https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/287#note_1192008962',
source: 'ee/lib/ee/gitlab/usage_data_counters/known_events/common.yml',
expected: ['ee/spec/config/metrics/every_metric_definition_spec.rb']
+ },
+ {
+ explanation: 'https://gitlab.com/gitlab-org/quality/engineering-productivity/team/-/issues/146',
+ source: 'config/feature_categories.yml',
+ expected: ['spec/db/docs_spec.rb', 'ee/spec/lib/ee/gitlab/database/docs/docs_spec.rb']
}
]
diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js
index 39d5ddee723..c80a6b30fb2 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -6,7 +6,6 @@ import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
-import ExperimentTracking from '~/experimentation/experiment_tracking';
import InviteMembersModal from '~/invite_members/components/invite_members_modal.vue';
import InviteModalBase from '~/invite_members/components/invite_modal_base.vue';
import ModalConfetti from '~/invite_members/components/confetti.vue';
@@ -63,11 +62,12 @@ describe('InviteMembersModal', () => {
let mock;
let trackingSpy;
- const expectTracking = (
- action,
- label = undefined,
- category = INVITE_MEMBER_MODAL_TRACKING_CATEGORY,
- ) => expect(trackingSpy).toHaveBeenCalledWith(category, action, { label, category });
+ const expectTracking = (action, label = undefined, property = undefined) =>
+ expect(trackingSpy).toHaveBeenCalledWith(INVITE_MEMBER_MODAL_TRACKING_CATEGORY, action, {
+ label,
+ category: INVITE_MEMBER_MODAL_TRACKING_CATEGORY,
+ property,
+ });
const createComponent = (props = {}, stubs = {}) => {
wrapper = shallowMountExtended(InviteMembersModal, {
@@ -278,38 +278,18 @@ describe('InviteMembersModal', () => {
});
describe('tracking events', () => {
- it('tracks the view for invite_members_for_task', async () => {
- await setupComponentWithTasks();
-
- expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name);
- expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
- INVITE_MEMBERS_FOR_TASK.view,
- );
- });
-
it('tracks the submit for invite_members_for_task', async () => {
await setupComponentWithTasks();
- await triggerMembersTokenSelect([user1]);
- clickInviteButton();
+ await triggerMembersTokenSelect([user1]);
- expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name, {
- label: 'selected_tasks_to_be_done',
- property: 'ci,code',
- });
- expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
- INVITE_MEMBERS_FOR_TASK.submit,
- );
- });
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
- it('does not track the submit for invite_members_for_task when invites have not been entered', async () => {
- await setupComponentWithTasks();
clickInviteButton();
- expect(ExperimentTracking).not.toHaveBeenCalledWith(
- INVITE_MEMBERS_FOR_TASK.name,
- expect.any,
- );
+ expectTracking(INVITE_MEMBERS_FOR_TASK.submit, 'selected_tasks_to_be_done', 'ci,code');
+
+ unmockTracking();
});
});
});
@@ -955,22 +935,5 @@ describe('InviteMembersModal', () => {
});
});
});
-
- describe('tracking', () => {
- beforeEach(async () => {
- createComponent();
- await triggerMembersTokenSelect([user3]);
-
- wrapper.vm.$toast = { show: jest.fn() };
- jest.spyOn(Api, 'inviteGroupMembers').mockResolvedValue({});
- });
-
- it('tracks the view for learn_gitlab source', () => {
- eventHub.$emit('openModal', { source: LEARN_GITLAB });
-
- expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name);
- expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(LEARN_GITLAB);
- });
- });
});
});
diff --git a/tests.yml b/tests.yml
index 1135d475cc4..2bfb5a8c1a8 100644
--- a/tests.yml
+++ b/tests.yml
@@ -102,3 +102,9 @@ mapping:
test: ee/spec/config/metrics/every_metric_definition_spec.rb
- source: ee/lib/ee/gitlab/usage_data_counters/known_events/.*.yml
test: ee/spec/config/metrics/every_metric_definition_spec.rb
+
+ # See https://gitlab.com/gitlab-org/quality/engineering-productivity/team/-/issues/146
+ - source: config/feature_categories.yml
+ test: spec/db/docs_spec.rb
+ - source: config/feature_categories.yml
+ test: ee/spec/lib/ee/gitlab/database/docs/docs_spec.rb
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 4f0d1cabbc9..ce01c62568d 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -36,7 +36,7 @@ require (
golang.org/x/oauth2 v0.5.0
golang.org/x/tools v0.6.0
google.golang.org/grpc v1.53.0
- google.golang.org/protobuf v1.29.0
+ google.golang.org/protobuf v1.29.1
honnef.co/go/tools v0.3.3
)
diff --git a/workhorse/go.sum b/workhorse/go.sum
index e7cd75f0745..8fa264a60ff 100644
--- a/workhorse/go.sum
+++ b/workhorse/go.sum
@@ -2845,8 +2845,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0=
-google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM=
+google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc=
gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=