diff options
25 files changed, 299 insertions, 149 deletions
diff --git a/.gitlab/merge_request_templates/Database Changes.md b/.gitlab/merge_request_templates/Database Changes.md index 68bc0fd1c7f..2bb1f374e98 100644 --- a/.gitlab/merge_request_templates/Database Changes.md +++ b/.gitlab/merge_request_templates/Database Changes.md @@ -45,4 +45,4 @@ When removing columns, tables, indexes or other structures: - [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) - [ ] Internationalization required/considered - [ ] If paid feature, have we considered GitLab.com plan and how it works for groups and is there a design for promoting it to users who aren't on the correct plan -- [ ] End-to-end tests pass (`package-qa` manual pipeline job) +- [ ] End-to-end tests pass (`package-and-qa` manual pipeline job) diff --git a/Gemfile.lock b/Gemfile.lock index 23b6c2423e6..bbe3c9e49b8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -206,7 +206,7 @@ GEM railties (>= 3.0.0) faraday (0.12.2) multipart-post (>= 1.2, < 3) - faraday_middleware (0.11.0.1) + faraday_middleware (0.12.2) faraday (>= 0.7.4, < 1.0) faraday_middleware-multi_json (0.0.6) faraday_middleware diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 4f41f2ea57a..1d1c8ebc179 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -1,3 +1,4 @@ +<script> import successSvg from 'icons/_icon_status_success.svg'; import warningSvg from 'icons/_icon_status_warning.svg'; import simplePoll from '~/lib/utils/simple_poll'; @@ -7,7 +8,10 @@ import statusIcon from '../mr_widget_status_icon.vue'; import eventHub from '../../event_hub'; export default { - name: 'MRWidgetReadyToMerge', + name: 'ReadyToMerge', + components: { + statusIcon, + }, props: { mr: { type: Object, required: true }, service: { type: Object, required: true }, @@ -26,9 +30,6 @@ export default { warningSvg, }; }, - components: { - statusIcon, - }, computed: { shouldShowMergeWhenPipelineSucceedsText() { return this.mr.isPipelineActive; @@ -217,136 +218,146 @@ export default { }); }, }, - template: ` - <div class="mr-widget-body media"> - <status-icon :status="iconClass" /> - <div class="media-body"> - <div class="mr-widget-body-controls media space-children"> - <span class="btn-group append-bottom-5"> - <button - @click="handleMergeButtonClick()" - :disabled="isMergeButtonDisabled" - :class="mergeButtonClass" - type="button" - class="qa-merge-button"> - <i - v-if="isMakingRequest" - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - {{mergeButtonText}} - </button> +}; +</script> + +<template> + <div class="mr-widget-body media"> + <status-icon :status="iconClass" /> + <div class="media-body"> + <div class="mr-widget-body-controls media space-children"> + <span class="btn-group append-bottom-5"> + <button + @click="handleMergeButtonClick()" + :disabled="isMergeButtonDisabled" + :class="mergeButtonClass" + type="button" + class="qa-merge-button"> + <i + v-if="isMakingRequest" + class="fa fa-spinner fa-spin" + aria-hidden="true" + ></i> + {{ mergeButtonText }} + </button> + <button + v-if="shouldShowMergeOptionsDropdown" + :disabled="isMergeButtonDisabled" + type="button" + class="btn btn-sm btn-info dropdown-toggle js-merge-moment" + data-toggle="dropdown" + aria-label="Select merge moment"> + <i + class="fa fa-chevron-down" + aria-hidden="true" + ></i> + </button> + <ul + v-if="shouldShowMergeOptionsDropdown" + class="dropdown-menu dropdown-menu-right" + role="menu"> + <li> + <a + @click.prevent="handleMergeButtonClick(true)" + class="merge_when_pipeline_succeeds" + href="#"> + <span class="media"> + <span + v-html="successSvg" + class="merge-opt-icon" + aria-hidden="true"></span> + <span class="media-body merge-opt-title">Merge when pipeline succeeds</span> + </span> + </a> + </li> + <li> + <a + @click.prevent="handleMergeButtonClick(false, true)" + class="accept-merge-request" + href="#"> + <span class="media"> + <span + v-html="warningSvg" + class="merge-opt-icon" + aria-hidden="true"></span> + <span class="media-body merge-opt-title">Merge immediately</span> + </span> + </a> + </li> + </ul> + </span> + <div class="media-body-wrap space-children"> + <template v-if="shouldShowMergeControls()"> + <label v-if="mr.canRemoveSourceBranch"> + <input + id="remove-source-branch-input" + v-model="removeSourceBranch" + class="js-remove-source-branch-checkbox" + :disabled="isRemoveSourceBranchButtonDisabled" + type="checkbox"/> Remove source branch + </label> + + <!-- Placeholder for EE extension of this component --> + <squash-before-merge + v-if="shouldShowSquashBeforeMerge" + :mr="mr" + :is-merge-button-disabled="isMergeButtonDisabled" /> + + <span + v-if="mr.ffOnlyEnabled" + class="js-fast-forward-message"> + Fast-forward merge without a merge commit + </span> <button - v-if="shouldShowMergeOptionsDropdown" + v-else + @click="toggleCommitMessageEditor" :disabled="isMergeButtonDisabled" - type="button" - class="btn btn-sm btn-info dropdown-toggle js-merge-moment" - data-toggle="dropdown" - aria-label="Select merge moment"> - <i - class="fa fa-chevron-down" - aria-hidden="true" /> + class="js-modify-commit-message-button btn btn-default btn-sm" + type="button"> + Modify commit message </button> - <ul - v-if="shouldShowMergeOptionsDropdown" - class="dropdown-menu dropdown-menu-right" - role="menu"> - <li> - <a - @click.prevent="handleMergeButtonClick(true)" - class="merge_when_pipeline_succeeds" - href="#"> - <span class="media"> - <span - v-html="successSvg" - class="merge-opt-icon" - aria-hidden="true"></span> - <span class="media-body merge-opt-title">Merge when pipeline succeeds</span> - </span> - </a> - </li> - <li> - <a - @click.prevent="handleMergeButtonClick(false, true)" - class="accept-merge-request" - href="#"> - <span class="media"> - <span - v-html="warningSvg" - class="merge-opt-icon" - aria-hidden="true"></span> - <span class="media-body merge-opt-title">Merge immediately</span> - </span> - </a> - </li> - </ul> - </span> - <div class="media-body-wrap space-children"> - <template v-if="shouldShowMergeControls()"> - <label v-if="mr.canRemoveSourceBranch"> - <input - id="remove-source-branch-input" - v-model="removeSourceBranch" - class="js-remove-source-branch-checkbox" - :disabled="isRemoveSourceBranchButtonDisabled" - type="checkbox"/> Remove source branch - </label> - - <!-- Placeholder for EE extension of this component --> - <squash-before-merge - v-if="shouldShowSquashBeforeMerge" - :mr="mr" - :is-merge-button-disabled="isMergeButtonDisabled" /> - - <span - v-if="mr.ffOnlyEnabled" - class="js-fast-forward-message"> - Fast-forward merge without a merge commit - </span> - <button - v-else - @click="toggleCommitMessageEditor" - :disabled="isMergeButtonDisabled" - class="js-modify-commit-message-button btn btn-default btn-sm" - type="button"> - Modify commit message - </button> - </template> - <template v-else> - <span class="bold js-resolve-mr-widget-items-message"> - You can only merge once the items above are resolved - </span> - </template> - </div> + </template> + <template v-else> + <span class="bold js-resolve-mr-widget-items-message"> + You can only merge once the items above are resolved + </span> + </template> </div> - <div - v-if="showCommitMessageEditor" - class="prepend-top-default commit-message-editor"> - <div class="form-group clearfix"> - <label - class="col-form-label" - for="commit-message"> - Commit message - </label> - <div class="col-sm-10"> - <div class="commit-message-container"> - <div class="max-width-marker"></div> - <textarea - v-model="commitMessage" - class="form-control js-commit-message" - required="required" - rows="14" - name="Commit message"></textarea> - </div> - <p class="hint">Try to keep the first line under 52 characters and the others under 72</p> - <div class="hint"> - <a - @click.prevent="updateCommitMessage" - href="#">{{commitMessageLinkTitle}}</a> - </div> + </div> + <div + v-if="showCommitMessageEditor" + class="prepend-top-default commit-message-editor"> + <div class="form-group clearfix"> + <label + class="col-form-label" + for="commit-message"> + Commit message + </label> + <div class="col-sm-10"> + <div class="commit-message-container"> + <div class="max-width-marker"></div> + <textarea + id="commit-message" + v-model="commitMessage" + class="form-control js-commit-message" + required="required" + rows="14" + name="Commit message"></textarea> + </div> + <p class="hint"> + Try to keep the first line under 52 characters and the others under 72 + </p> + <div class="hint"> + <a + @click.prevent="updateCommitMessage" + href="#" + > + {{ commitMessageLinkTitle }} + </a> </div> </div> </div> </div> </div> - `, -}; + </div> +</template> diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js index ed15fc6ab0f..86d52f89d38 100644 --- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js +++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js @@ -27,7 +27,7 @@ export { default as ConflictsState } from './components/states/mr_widget_conflic export { default as NothingToMergeState } from './components/states/nothing_to_merge.vue'; export { default as MissingBranchState } from './components/states/mr_widget_missing_branch.vue'; export { default as NotAllowedState } from './components/states/mr_widget_not_allowed.vue'; -export { default as ReadyToMergeState } from './components/states/mr_widget_ready_to_merge'; +export { default as ReadyToMergeState } from './components/states/ready_to_merge.vue'; export { default as ShaMismatchState } from './components/states/sha_mismatch.vue'; export { default as UnresolvedDiscussionsState } from './components/states/unresolved_discussions.vue'; export { default as PipelineBlockedState } from './components/states/mr_widget_pipeline_blocked.vue'; diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb index cbec735c2dd..96a43006642 100644 --- a/app/models/internal_id.rb +++ b/app/models/internal_id.rb @@ -23,9 +23,12 @@ class InternalId < ActiveRecord::Base # # The operation locks the record and gathers a `ROW SHARE` lock (in PostgreSQL). # As such, the increment is atomic and safe to be called concurrently. - def increment_and_save! + # + # If a `maximum_iid` is passed in, this overrides the incremented value if it's + # greater than that. This can be used to correct the increment value if necessary. + def increment_and_save!(maximum_iid) lock! - self.last_value = (last_value || 0) + 1 + self.last_value = [(last_value || 0) + 1, (maximum_iid || 0) + 1].max save! last_value end @@ -89,7 +92,16 @@ class InternalId < ActiveRecord::Base # and increment its last value # # Note this will acquire a ROW SHARE lock on the InternalId record - (lookup || create_record).increment_and_save! + + # Note we always calculate the maximum iid present here and + # pass it in to correct the InternalId entry if it's last_value is off. + # + # This can happen in a transition phase where both `AtomicInternalId` and + # `NonatomicInternalId` code runs (e.g. during a deploy). + # + # This is subject to be cleaned up with the 10.8 release: + # https://gitlab.com/gitlab-org/gitlab-ce/issues/45389. + (lookup || create_record).increment_and_save!(maximum_iid) end end @@ -115,11 +127,15 @@ class InternalId < ActiveRecord::Base InternalId.create!( **scope, usage: usage_value, - last_value: init.call(subject) || 0 + last_value: maximum_iid ) end rescue ActiveRecord::RecordNotUnique lookup end + + def maximum_iid + @maximum_iid ||= init.call(subject) || 0 + end end end diff --git a/changelogs/unreleased/45397-update-faraday_middleware-to-0-12-2.yml b/changelogs/unreleased/45397-update-faraday_middleware-to-0-12-2.yml new file mode 100644 index 00000000000..3370ec3feba --- /dev/null +++ b/changelogs/unreleased/45397-update-faraday_middleware-to-0-12-2.yml @@ -0,0 +1,5 @@ +--- +title: Update faraday_middlewar to 0.12.2 +merge_request: 18397 +author: Takuya Noguchi +type: security diff --git a/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml b/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml new file mode 100644 index 00000000000..90192fae030 --- /dev/null +++ b/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml @@ -0,0 +1,5 @@ +--- +title: Move ReadyToMerge vue component +merge_request: 17545 +author: George Tsiolis +type: performance diff --git a/doc/administration/plugins.md b/doc/administration/plugins.md index 3ae41638ac3..4302667caf5 100644 --- a/doc/administration/plugins.md +++ b/doc/administration/plugins.md @@ -33,6 +33,10 @@ Follow the steps below to set up a custom hook: For an installation from source the path is usually `/home/git/gitlab/plugins/`. For Omnibus installs the path is usually `/opt/gitlab/embedded/service/gitlab-rails/plugins`. + + For [highly available] configurations, your hook file should exist on each + application server. + 1. Inside the `plugins` directory, create a file with a name of your choice, without spaces or special characters. 1. Make the hook file executable and make sure it's owned by the git user. @@ -78,3 +82,4 @@ Validating plugins from /plugins directory [system hooks]: ../system_hooks/system_hooks.md [webhooks]: ../user/project/integrations/webhooks.md +[highly available]: ./high_availability/README.md
\ No newline at end of file diff --git a/doc/ci/examples/container_scanning.md b/doc/ci/examples/container_scanning.md index c58efc7392a..dc34f4acd75 100644 --- a/doc/ci/examples/container_scanning.md +++ b/doc/ci/examples/container_scanning.md @@ -30,6 +30,7 @@ sast:container: - mv clair-scanner_linux_amd64 clair-scanner - chmod +x clair-scanner - touch clair-whitelist.yml + - while( ! wget -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; done - ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true artifacts: paths: [gl-sast-container-report.json] diff --git a/doc/install/kubernetes/gitlab_runner_chart.md b/doc/install/kubernetes/gitlab_runner_chart.md index 3feef8cbd19..a03c49cbd89 100644 --- a/doc/install/kubernetes/gitlab_runner_chart.md +++ b/doc/install/kubernetes/gitlab_runner_chart.md @@ -72,6 +72,18 @@ concurrent: 10 ## checkInterval: 30 +## For RBAC support: +rbac: + create: false + + ## Run the gitlab-bastion container with the ability to deploy/manage containers of jobs + ## cluster-wide or only within namespace + clusterWideAccess: false + + ## Use the following Kubernetes Service Account name if RBAC is disabled in this Helm chart (see rbac.create) + ## + # serviceAccountName: default + ## Configuration for the Pods that that the runner launches for each new job ## runners: @@ -116,6 +128,12 @@ runners: ``` +### Enabling RBAC support + +If your cluster has RBAC enabled, you can choose to either have the chart create its own sevice account or provide one. + +To have the chart create the service account for you, set `rbac.create` to true. + ### Controlling maximum Runner concurrency A single GitLab Runner deployed on Kubernetes is able to execute multiple jobs in parallel by automatically starting additional Runner pods. The [`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section) controls the maximum number of pods allowed at a single time, and defaults to `10`. diff --git a/doc/user/permissions.md b/doc/user/permissions.md index a520279c29e..a9ba2a51242 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -15,6 +15,10 @@ GitLab [administrators](../README.md#administrator-documentation) receive all pe To add or import a user, you can follow the [project members documentation](../user/project/members/index.md). +## Principles behind permissions + +See our [product handbook on permissions](https://about.gitlab.com/handbook/product#permissions-in-gitlab) + ## Project members permissions The following table depicts the various user permission levels in a project. diff --git a/doc/user/project/index.md b/doc/user/project/index.md index 5ce4ebfa811..a3d53fde399 100644 --- a/doc/user/project/index.md +++ b/doc/user/project/index.md @@ -45,6 +45,7 @@ and time spent on templates for issue and merge request description fields for your project - [Slash commands (quick actions)](quick_actions.md): Textual shortcuts for common actions on issues or merge requests +- [Web IDE](web_ide/index.md) **GitLab CI/CD:** diff --git a/doc/user/project/web_ide/img/commit_changes.png b/doc/user/project/web_ide/img/commit_changes.png Binary files differnew file mode 100644 index 00000000000..b6fcbf699aa --- /dev/null +++ b/doc/user/project/web_ide/img/commit_changes.png diff --git a/doc/user/project/web_ide/img/enable_web_ide.png b/doc/user/project/web_ide/img/enable_web_ide.png Binary files differnew file mode 100644 index 00000000000..196baa82ad2 --- /dev/null +++ b/doc/user/project/web_ide/img/enable_web_ide.png diff --git a/doc/user/project/web_ide/img/open_web_ide.png b/doc/user/project/web_ide/img/open_web_ide.png Binary files differnew file mode 100644 index 00000000000..d1192daf506 --- /dev/null +++ b/doc/user/project/web_ide/img/open_web_ide.png diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md new file mode 100644 index 00000000000..4b0d2c65642 --- /dev/null +++ b/doc/user/project/web_ide/index.md @@ -0,0 +1,34 @@ +# Web IDE + +> Introduced in [GitLab Ultimate][ee] 10.4. +> Brought to [GitLab CE][ce] in 10.7. + +The Web IDE makes it faster and easier to contribute changes to your projects +by providing an advanced editor with commit staging. + +## Open the Web IDE + +The Web IDE can be opened when viewing a file, from the repository file list, +and from merge requests. + +![Open Web IDE](img/open_web_ide.png) + +## Commit changes + +Changed files are shown on the right in the commit panel. All changes are +automatically staged. To commit your changes, add a commit message and click +the 'Commit Button'. + +![Commit changes](img/commit_changes.png) + +## Comparing changes + +Before you commit your changes, you can compare them with the previous commit +by switching to the review mode or selecting the file from the staged files +list. + +An additional review mode is available when you open a merge request, which +shows you a preview of the merge request diff if you commit your changes. + +[ee]: https://about.gitlab.com/products/ +[ce]: https://about.gitlab.com/products/ diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 2f2506f08fb..166861e6c4a 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -2,7 +2,7 @@ module QA module Page module MergeRequest class Show < Page::Base - view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js' do + view 'app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue' do element :merge_button element :fast_forward_message, 'Fast-forward merge without a merge commit' end diff --git a/spec/javascripts/helpers/vue_component_helper.js b/spec/javascripts/helpers/vue_component_helper.js index 257c9f5526a..e0fe18e5560 100644 --- a/spec/javascripts/helpers/vue_component_helper.js +++ b/spec/javascripts/helpers/vue_component_helper.js @@ -1,3 +1,18 @@ -export default function removeBreakLine (data) { - return data.replace(/\r?\n|\r/g, ' '); -} +/** + * Replaces line break with an empty space + * @param {*} data + */ +export const removeBreakLine = data => data.replace(/\r?\n|\r/g, ' '); + +/** + * Removes line breaks, spaces and trims the given text + * @param {String} str + * @returns {String} + */ +export const trimText = str => + str + .replace(/\r?\n|\r/g, '') + .replace(/\s\s+/g, ' ') + .trim(); + +export const removeWhitespace = str => str.replace(/\s\s+/g, ' '); diff --git a/spec/javascripts/ide/components/commit_sidebar/list_collapsed_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_collapsed_spec.js index 5b402886b55..32dbc3bf72e 100644 --- a/spec/javascripts/ide/components/commit_sidebar/list_collapsed_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/list_collapsed_spec.js @@ -3,6 +3,7 @@ import store from '~/ide/stores'; import listCollapsed from '~/ide/components/commit_sidebar/list_collapsed.vue'; import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { file } from '../../helpers'; +import { removeWhitespace } from '../../../helpers/vue_component_helper'; describe('Multi-file editor commit sidebar list collapsed', () => { let vm; @@ -23,6 +24,6 @@ describe('Multi-file editor commit sidebar list collapsed', () => { }); it('renders added & modified files count', () => { - expect(vm.$el.textContent.replace(/\s+/g, ' ').trim()).toBe('1 1'); + expect(removeWhitespace(vm.$el.textContent).trim()).toBe('1 1'); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index fcbd8169bc7..3d05dbfa305 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import conflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import removeBreakLine from 'spec/helpers/vue_component_helper'; +import { removeBreakLine } from 'spec/helpers/vue_component_helper'; describe('MRWidgetConflicts', () => { let Component; diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js index 894dbe3382f..ab096a56918 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import pipelineBlockedComponent from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import removeBreakLine from 'spec/helpers/vue_component_helper'; +import { removeBreakLine } from 'spec/helpers/vue_component_helper'; describe('MRWidgetPipelineBlocked', () => { let vm; diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 58f683fb3e6..300b7882d03 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -1,12 +1,12 @@ import Vue from 'vue'; -import readyToMergeComponent from '~/vue_merge_request_widget/components/states/mr_widget_ready_to_merge'; +import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue'; import eventHub from '~/vue_merge_request_widget/event_hub'; import * as simplePoll from '~/lib/utils/simple_poll'; const commitMessage = 'This is the commit message'; const commitMessageWithDescription = 'This is the commit message description'; const createComponent = (customConfig = {}) => { - const Component = Vue.extend(readyToMergeComponent); + const Component = Vue.extend(ReadyToMerge); const mr = { isPipelineActive: false, pipeline: null, @@ -36,7 +36,7 @@ const createComponent = (customConfig = {}) => { }); }; -describe('MRWidgetReadyToMerge', () => { +describe('ReadyToMerge', () => { let vm; beforeEach(() => { @@ -49,7 +49,7 @@ describe('MRWidgetReadyToMerge', () => { describe('props', () => { it('should have props', () => { - const { mr, service } = readyToMergeComponent.props; + const { mr, service } = ReadyToMerge.props; expect(mr.type instanceof Object).toBeTruthy(); expect(mr.required).toBeTruthy(); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js index b02af94d03a..abf642c166a 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import ShaMismatch from '~/vue_merge_request_widget/components/states/sha_mismatch.vue'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import removeBreakLine from 'spec/helpers/vue_component_helper'; +import { removeBreakLine } from 'spec/helpers/vue_component_helper'; describe('ShaMismatch', () => { let vm; diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb index 581fd0293cc..8ef91e8fab5 100644 --- a/spec/models/internal_id_spec.rb +++ b/spec/models/internal_id_spec.rb @@ -5,7 +5,7 @@ describe InternalId do let(:usage) { :issues } let(:issue) { build(:issue, project: project) } let(:scope) { { project: project } } - let(:init) { ->(s) { s.project.issues.size } } + let(:init) { ->(s) { s.project.issues.maximum(:iid) } } context 'validations' do it { is_expected.to validate_presence_of(:usage) } @@ -39,6 +39,29 @@ describe InternalId do end end + context 'with an InternalId record present and existing issues with a higher internal id' do + # This can happen if the old NonatomicInternalId is still in use + before do + issues = Array.new(rand(1..10)).map { create(:issue, project: project) } + + issue = issues.last + issue.iid = issues.map { |i| i.iid }.max + 1 + issue.save + end + + let(:maximum_iid) { project.issues.map { |i| i.iid }.max } + + it 'updates last_value to the maximum internal id present' do + subject + + expect(described_class.find_by(project: project, usage: described_class.usages[usage.to_s]).last_value).to eq(maximum_iid + 1) + end + + it 'returns next internal id correctly' do + expect(subject).to eq(maximum_iid + 1) + end + end + context 'with concurrent inserts on table' do it 'looks up the record if it was created concurrently' do args = { **scope, usage: described_class.usages[usage.to_s] } @@ -81,7 +104,8 @@ describe InternalId do describe '#increment_and_save!' do let(:id) { create(:internal_id) } - subject { id.increment_and_save! } + let(:maximum_iid) { nil } + subject { id.increment_and_save!(maximum_iid) } it 'returns incremented iid' do value = id.last_value @@ -102,5 +126,14 @@ describe InternalId do expect(subject).to eq(1) end end + + context 'with maximum_iid given' do + let(:id) { create(:internal_id, last_value: 1) } + let(:maximum_iid) { id.last_value + 10 } + + it 'returns maximum_iid instead' do + expect(subject).to eq(12) + end + end end end diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml index 4810035a9e3..4f4ed80d101 100644 --- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml @@ -315,6 +315,7 @@ production: mv clair-scanner_linux_amd64 clair-scanner chmod +x clair-scanner touch clair-whitelist.yml + while( ! wget -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; done ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true } |