diff options
338 files changed, 1117 insertions, 1156 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index af5f5809c41..905c588d338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,220 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.3.0 (2017-06-22) + +- Refactored gitlab:app:check into SystemCheck liberary and improve some checks. !9173 +- Add an ability to cancel attaching file and redesign attaching files UI. !9431 (blackst0ne) +- Add Aliyun OSS as the backup storage provider. !9721 (Yuanfei Zhu) +- Add suport for find_local_branches GRPC from Gitaly. !10059 +- Allow manual bypass of auto_sign_in_with_provider with a new param. !10187 (Maxime Besson) +- Redirect to user's keys index instead of user's index after a key is deleted in the admin. !10227 (Cyril Jouve) +- Changed Blame to Annotate in the UI to promote blameless culture. !10378 (Ilya Vassilevsky) +- Implement ability to update deploy keys. !10383 (Alexander Randa) +- Allow numeric values in gitlab-ci.yml. !10607 (blackst0ne) +- Add a feature test for Unicode trace. !10736 (dosuken123) +- Notes: Warning message should go away once resolved. !10823 (Jacopo Beschi @jacopo-beschi) +- Project authorizations are calculated much faster when using PostgreSQL, and nested groups support for MySQL has been removed +. !10885 +- Fix long urls in the title of commit. !10938 (Alexander Randa) +- Update gem sidekiq-cron from 0.4.4 to 0.6.0 and rufus-scheduler from 3.1.10 to 3.4.0. !10976 (dosuken123) +- Use relative paths for group/project/user avatars. !11001 (blackst0ne) +- Enable cancelling non-HEAD pending pipelines by default for all projects. !11023 +- Implement web hook logging. !11027 (Alexander Randa) +- Add indices for auto_canceled_by_id for ci_pipelines and ci_builds on PostgreSQL. !11034 +- Add post-deploy migration to clean up projects in `pending_delete` state. !11044 +- Limit User's trackable attributes, like `current_sign_in_at`, to update at most once/hour. !11053 +- Disallow multiple selections for Milestone dropdown. !11084 +- Link to commit author user page from pipelines. !11100 +- Fix the last coverage in trace log should be extracted. !11128 (dosuken123) +- Remove redirect for old issue url containing id instead of iid. !11135 (blackst0ne) +- Backported new SystemHook event: `repository_update`. !11140 +- Keep input data after creating a tag that already exists. !11155 +- Fix support for external CI services. !11176 +- Translate backend for Project & Repository pages. !11183 +- Fix LaTeX formatting for AsciiDoc wiki. !11212 +- Add foreign key for pipeline schedule owner. !11233 +- Print Go version in rake gitlab:env:info. !11241 +- Include the blob content when printing a blob page. !11247 +- Sync email address from specified omniauth provider. !11268 (Robin Bobbitt) +- Disable reference prefixes in notes for Snippets. !11278 +- Rename build_events to job_events. !11287 +- Add API support for pipeline schedule. !11307 (dosuken123) +- Use route.cache_key for project list cache key. !11325 +- Make environment table realtime. !11333 +- Cache npm modules between pipelines with yarn to speed up setup-test-env. !11343 +- Allow GitLab instance to start when InfluxDB hostname cannot be resolved. !11356 +- Add ConvDev Index page to admin area. !11377 +- Fix Git-over-HTTP error statuses and improve error messages. !11398 +- Renamed users 'Audit Log'' to 'Authentication Log'. !11400 +- Style people in issuable search bar. !11402 +- Change /builds in the URL to /-/jobs. Backward URLs were also added. !11407 +- Update password field label while editing service settings. !11431 +- Add an optional performance bar to view performance metrics for the current page. !11439 +- Update task_list to version 2.0.0. !11525 (Jared Deckard <jared.deckard@gmail.com>) +- Avoid resource intensive login checks if password is not provided. !11537 (Horatiu Eugen Vlad) +- Allow numeric pages domain. !11550 +- Exclude manual actions when checking if pipeline can be canceled. !11562 +- Add server uptime to System Info page in admin dashboard. !11590 (Justin Boltz) +- Simplify testing and saving service integrations. !11599 +- Fixed handling of the `can_push` attribute in the v3 deploy_keys api. !11607 (Richard Clamp) +- Improve user experience around slash commands in instant comments. !11612 +- Show current user immediately in issuable filters. !11630 +- Add extra context-sensitive functionality for the top right menu button. !11632 +- Reorder Issue action buttons in order of usability. !11642 +- Expose atom links with an RSS token instead of using the private token. !11647 (Alexis Reigel) +- Respect merge, instead of push, permissions for protected actions. !11648 +- Job details page update real time. !11651 +- Improve performance of ProjectFinder used in /projects API endpoint. !11666 +- Remove redundant data-turbolink attributes from links. !11672 (blackst0ne) +- Minimum postgresql version is now 9.2. !11677 +- Add protected variables which would only be passed to protected branches or protected tags. !11688 +- Introduce optimistic locking support via optional parameter last_commit_sha on File Update API. !11694 (electroma) +- Add $CI_ENVIRONMENT_URL to predefined variables for pipelines. !11695 +- Simplify project repository settings page. !11698 +- Fix pipeline_schedules pages throwing error 500. !11706 (dosuken123) +- Add performance deltas between app deployments on Merge Request widget. !11730 +- Add feature toggles and API endpoints for admins. !11747 +- Replace 'starred_projects.feature' spinach test with an rspec analog. !11752 (blackst0ne) +- Introduce an Events API. !11755 +- Display Shared Runner status in Admin Dashboard. !11783 (Ivan Chernov) +- Persist pipeline stages in the database. !11790 +- Revert the feature that would include the current user's username in the HTTP clone URL. !11792 +- Enable Gitaly by default in installations from source. !11796 +- Use zopfli compression for frontend assets. !11798 +- Add tag_list param to project api. !11799 (Ivan Chernov) +- Add changelog for improved Registry description. !11816 +- Automatically adjust project settings to match changes in project visibility. !11831 +- Add slugify project path to CI enviroment variables. !11838 (Ivan Chernov) +- Add all pipeline sources as special keywords to 'only' and 'except'. !11844 (Filip Krakowski) +- Allow pulling of container images using personal access tokens. !11845 +- Expose import_status in Projects API. !11851 (Robin Bobbitt) +- Allow admins to delete users from the admin users page. !11852 +- Allow users to be hard-deleted from the API. !11853 +- Fix hard-deleting users when they have authored issues. !11855 +- Fix missing optional path parameter in "Create project for user" API. !11868 +- Allow users to be hard-deleted from the admin panel. !11874 +- Add a Rake task to aid in rotating otp_key_base. !11881 +- Fix submodule link to then project under subgroup. !11906 +- Fix binary encoding error on MR diffs. !11929 +- Limit non-administrators to adding 100 members at a time to groups and projects. !11940 +- add bulgarian translation of cycle analytics page to I18N. !11958 (Lyubomir Vasilev) +- Make backup task to continue on corrupt repositories. !11962 +- Fix incorrect ETag cache key when relative instance URL is used. !11964 +- Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm) +- Fix edit button for deploy keys available from other projects. !12301 (Alexander Randa) +- Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL. !12344 +- Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab-ee/issues/2677. !12347 +- Standardize timeline note margins across different viewport sizes. !12364 +- Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>) +- Upgrade dependency to Go 1.8.3. !31943 +- Add prometheus metrics on pipeline creation. +- Fix etag route not being a match for environments. +- Sort folder for environments. +- Support descriptions for snippets. +- Hide clone panel and file list when user is only a guest. (James Clark) +- Don’t create comment on JIRA if it already exists for the entity. +- Update Dashboard Groups UI with better support for subgroups. +- Confirm Project forking behaviour via the API. +- Add prometheus based metrics collection to gitlab webapp. +- Fix: Wiki is not searchable with Guest permissions. +- Center all empty states. +- Remove 'New issue' button when issues search returns no results. +- Add API URL to JIRA settings. +- animate adding issue to boards. +- Update session cookie key name to be unique to instance in development. +- Single click on filter to open filtered search dropdown. +- Makes header information of pipeline show page realtine. +- Creates a mediator for pipeline details vue in order to mount several vue apps with the same data. +- Scope issue/merge request recent searches to project. +- Increase individual diff collapse limit to 100 KB, and render limit to 200 KB. +- Fix Pipelines table empty state - only render empty state if we receive 0 pipelines. +- Make New environment empty state btn lowercase. +- Removes duplicate environment variable in documentation. +- Change links in issuable meta to black. +- Fix border-bottom for project activity tab. +- Adds new icon for CI skipped status. +- Create equal padding for emoji. +- Use briefcase icon for company in profile page. +- Remove overflow from comment form for confidential issues and vertically aligns confidential issue icon. +- Keep trailing newline when resolving conflicts by picking sides. +- Fix /unsubscribe slash command creating extra todos when you were already mentioned in an issue. +- Fix math rendering on blob pages. +- Allow group reporters to manage group labels. +- Use pre-wrap for commit messages to keep lists indented. +- Count badges depend on translucent color to better adjust to different background colors and permission badges now feature a pill shaped design similar to labels. +- Allow reporters to promote project labels to group labels. +- Enabled keyboard shortcuts on artifacts pages. +- Perform filtered search when state tab is changed. +- Remove duplication for sharing projects with groups in project settings. +- Change order of commits ahead and behind on divergence graph for branch list view. +- Creates CI Header component for Pipelines and Jobs details pages. +- Invalidate cache for issue and MR counters more granularly. +- disable blocked manual actions. +- Load tree readme asynchronously. +- Display extra info about files on .gitlab-ci.yml, .gitlab/route-map.yml and LICENSE blob pages. +- Fix replying to a commit discussion displayed in the context of an MR. +- Consistently use monospace font for commit SHAs and branch and tag names. +- Consistently display last push event widget. +- Don't copy empty elements that were not selected on purpose as GFM. +- Copy as GFM even when parts of other elements are selected. +- Autolink package names in Gemfile. +- Resolve N+1 query issue with discussions. +- Don't match email addresses or foo@bar as user references. +- Fix title of discussion jump button at top of page. +- Don't return nil for missing objects from parser cache. +- Make .gitmodules parsing more resilient to syntax errors. +- Add username parameter to gravatar URL. +- Autolink package names in more dependency files. +- Return nil when looking up config for unknown LDAP provider. +- Add system note with link to diff comparison when MR discussion becomes outdated. +- Don't wrap pasted code when it's already inside code tags. +- Revert 'New file from interface on existing branch'. +- Show last commit for current tree on tree page. +- Add documentation about adding foreign keys. +- add username field to push webhook. (David Turner) +- Rename CI/CD Pipelines to Pipelines in the project settings. +- Make environment tables responsive. +- Expand/collapse backlog & closed lists in issue boards. +- Fix GitHub importer performance on branch existence check. +- Fix counter cache for acts as taggable. +- Github - Fix token interpolation when cloning wiki repository. +- Fix token interpolation when setting the Github remote. +- Fix N+1 queries for non-members in comment threads. +- Fix terminals support for Kubernetes Service. +- Fix: A diff comment on a change at last line of a file shows as two comments in discussion. +- Instrument MergeRequestDiff#load_commits. +- Introduce source to Pipeline entity. +- Fixed create new label form in issue form not working for sub-group projects. +- Fixed style on unsubscribe page. (Gustav Ernberg) +- Enables inline editing for an issues title & description. +- Ask for an example project for bug reports. +- Add summary lines for collapsed details in the bug report template. +- Prevent commits from upstream repositories to be re-processed by forks. +- Avoid repeated queries for pipeline builds on merge requests. +- Preloads head pipeline for merge request collection. +- Handle head pipeline when creating merge requests. +- Migrate artifacts to a new path. +- Rescue OpenSSL::SSL::SSLError in JiraService & IssueTrackerService. +- Repository browser: handle in-repository submodule urls. (David Turner) +- Prevent project transfers if a new group is not selected. +- Allow 'no one' as an option for allowed to merge on a procted branch. +- Reduce time spent waiting for certain Sidekiq jobs to complete. +- Refactor ProjectsFinder#init_collection to produce more efficient queries for retrieving projects. +- Remove unused code and uses underscore. +- Restricts search projects dropdown to group projects when group is selected. +- Properly handle container registry redirects to fix metadata stored on a S3 backend. +- Fix LFS timeouts when trying to save large files. +- Set artifact working directory to be in the destination store to prevent unnecessary I/O. +- Strip trailing whitespaces in submodule URLs. +- Make sure reCAPTCHA configuration is loaded when spam checks are initiated. +- Fix up arrow not editing last discussion comment. +- Added application readiness endpoints to the monitoring health check admin view. +- Use wait_for_requests for both ajax and Vue requests. +- Cleanup ci_variables schema and table. +- Remove foreigh key on ci_trigger_schedules only if it exists. +- Allow translation of Pipeline Schedules. + ## 9.2.7 (2017-06-21) - Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm) diff --git a/Gemfile.lock b/Gemfile.lock index 4715363c5b8..7c9dd051211 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -352,7 +352,7 @@ GEM grape-entity (0.6.0) activesupport multi_json (>= 1.3.2) - grpc (1.2.5) + grpc (1.4.0) google-protobuf (~> 3.1) googleauth (~> 0.5.1) haml (4.0.7) diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue index a2448520a5f..e7495677e7c 100644 --- a/app/assets/javascripts/environments/components/environment_actions.vue +++ b/app/assets/javascripts/environments/components/environment_actions.vue @@ -2,6 +2,7 @@ import playIconSvg from 'icons/_icon_play.svg'; import eventHub from '../event_hub'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -12,6 +13,10 @@ export default { }, }, + directives: { + tooltip, + }, + components: { loadingIcon, }, @@ -33,8 +38,6 @@ export default { onClickAction(endpoint) { this.isLoading = true; - $(this.$refs.tooltip).tooltip('destroy'); - eventHub.$emit('postAction', endpoint); }, @@ -53,11 +56,11 @@ export default { class="btn-group" role="group"> <button + v-tooltip type="button" - class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container has-tooltip" + class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container" data-container="body" data-toggle="dropdown" - ref="tooltip" :title="title" :aria-label="title" :disabled="isLoading"> diff --git a/app/assets/javascripts/environments/components/environment_external_url.vue b/app/assets/javascripts/environments/components/environment_external_url.vue index eaeec2bc53c..6b749814ea4 100644 --- a/app/assets/javascripts/environments/components/environment_external_url.vue +++ b/app/assets/javascripts/environments/components/environment_external_url.vue @@ -1,4 +1,6 @@ <script> +import tooltip from '../../vue_shared/directives/tooltip'; + /** * Renders the external url link in environments table. */ @@ -10,6 +12,10 @@ export default { }, }, + directives: { + tooltip, + }, + computed: { title() { return 'Open'; @@ -19,7 +25,8 @@ export default { </script> <template> <a - class="btn external-url has-tooltip" + v-tooltip + class="btn external-url" data-container="body" target="_blank" rel="noopener noreferrer nofollow" diff --git a/app/assets/javascripts/environments/components/environment_monitoring.vue b/app/assets/javascripts/environments/components/environment_monitoring.vue index 07cf92281a0..1655561cdd3 100644 --- a/app/assets/javascripts/environments/components/environment_monitoring.vue +++ b/app/assets/javascripts/environments/components/environment_monitoring.vue @@ -2,6 +2,8 @@ /** * Renders the Monitoring (Metrics) link in environments table. */ +import tooltip from '../../vue_shared/directives/tooltip'; + export default { props: { monitoringUrl: { @@ -10,6 +12,10 @@ export default { }, }, + directives: { + tooltip, + }, + computed: { title() { return 'Monitoring'; @@ -19,7 +25,8 @@ export default { </script> <template> <a - class="btn monitoring-url has-tooltip hidden-xs hidden-sm" + v-tooltip + class="btn monitoring-url hidden-xs hidden-sm" data-container="body" rel="noopener noreferrer nofollow" :href="monitoringUrl" diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue index 091c543860b..85f11d2071b 100644 --- a/app/assets/javascripts/environments/components/environment_stop.vue +++ b/app/assets/javascripts/environments/components/environment_stop.vue @@ -5,6 +5,7 @@ */ import eventHub from '../event_hub'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -14,6 +15,10 @@ export default { }, }, + directives: { + tooltip, + }, + data() { return { isLoading: false, @@ -46,8 +51,9 @@ export default { </script> <template> <button + v-tooltip type="button" - class="btn stop-env-link has-tooltip hidden-xs hidden-sm" + class="btn stop-env-link hidden-xs hidden-sm" data-container="body" @click="onClick" :disabled="isLoading" diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.vue b/app/assets/javascripts/environments/components/environment_terminal_button.vue index 1ca65a79951..2037bf618e3 100644 --- a/app/assets/javascripts/environments/components/environment_terminal_button.vue +++ b/app/assets/javascripts/environments/components/environment_terminal_button.vue @@ -4,6 +4,7 @@ * Used in environments table. */ import terminalIconSvg from 'icons/_icon_terminal.svg'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -14,6 +15,10 @@ export default { }, }, + directives: { + tooltip, + }, + data() { return { terminalIconSvg, @@ -29,7 +34,8 @@ export default { </script> <template> <a - class="btn terminal-button has-tooltip hidden-xs hidden-sm" + v-tooltip + class="btn terminal-button hidden-xs hidden-sm" data-container="body" :title="title" :aria-label="title" diff --git a/app/assets/javascripts/issue_show/components/fields/description.vue b/app/assets/javascripts/issue_show/components/fields/description.vue index 54650d2f184..27b1b814f9a 100644 --- a/app/assets/javascripts/issue_show/components/fields/description.vue +++ b/app/assets/javascripts/issue_show/components/fields/description.vue @@ -47,7 +47,8 @@ ref="textarea" slot="textarea" placeholder="Write a comment or drag your files here..." - @keydown.meta.enter="updateIssuable"> + @keydown.meta.enter="updateIssuable" + @keydown.ctrl.enter="updateIssuable"> </textarea> </markdown-field> </div> diff --git a/app/assets/javascripts/issue_show/components/fields/project_move.vue b/app/assets/javascripts/issue_show/components/fields/project_move.vue index f811fb0de24..7bf2be8b28a 100644 --- a/app/assets/javascripts/issue_show/components/fields/project_move.vue +++ b/app/assets/javascripts/issue_show/components/fields/project_move.vue @@ -1,10 +1,10 @@ <script> - import tooltipMixin from '../../../vue_shared/mixins/tooltip'; + import tooltip from '../../../vue_shared/directives/tooltip'; export default { - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, props: { formState: { type: Object, @@ -71,9 +71,9 @@ data-placeholder="Move to a different project" /> </div> <span + v-tooltip data-placement="auto top" - title="Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location." - ref="tooltip"> + title="Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location."> <i class="fa fa-question-circle" aria-hidden="true"> diff --git a/app/assets/javascripts/issue_show/components/fields/title.vue b/app/assets/javascripts/issue_show/components/fields/title.vue index 6556bf117e2..83af8e1e245 100644 --- a/app/assets/javascripts/issue_show/components/fields/title.vue +++ b/app/assets/javascripts/issue_show/components/fields/title.vue @@ -26,6 +26,7 @@ placeholder="Issue title" aria-label="Issue title" v-model="formState.title" - @keydown.meta.enter="updateIssuable" /> + @keydown.meta.enter="updateIssuable" + @keydown.ctrl.enter="updateIssuable" /> </fieldset> </template> diff --git a/app/assets/javascripts/pipelines/components/async_button.vue b/app/assets/javascripts/pipelines/components/async_button.vue index abcd0c4ecea..16cc0761fc1 100644 --- a/app/assets/javascripts/pipelines/components/async_button.vue +++ b/app/assets/javascripts/pipelines/components/async_button.vue @@ -3,7 +3,7 @@ import eventHub from '../event_hub'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; -import tooltipMixin from '../../vue_shared/mixins/tooltip'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -28,12 +28,12 @@ export default { required: false, }, }, + directives: { + tooltip, + }, components: { loadingIcon, }, - mixins: [ - tooltipMixin, - ], data() { return { isLoading: false, @@ -58,7 +58,6 @@ export default { makeRequest() { this.isLoading = true; - $(this.$refs.tooltip).tooltip('destroy'); eventHub.$emit('postAction', this.endpoint); }, }, @@ -67,6 +66,7 @@ export default { <template> <button + v-tooltip type="button" @click="onClick" :class="buttonClass" @@ -74,7 +74,6 @@ export default { :aria-label="title" data-container="body" data-placement="top" - ref="tooltip" :disabled="isLoading"> <i :class="iconClass" diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue index 1f9e3d39779..54227425d2a 100644 --- a/app/assets/javascripts/pipelines/components/graph/action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue @@ -1,6 +1,6 @@ <script> import getActionIcon from '../../../vue_shared/ci_action_icons'; - import tooltipMixin from '../../../vue_shared/mixins/tooltip'; + import tooltip from '../../../vue_shared/directives/tooltip'; /** * Renders either a cancel, retry or play icon pointing to the given path. @@ -29,9 +29,9 @@ }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, computed: { actionIconSvg() { @@ -46,12 +46,11 @@ </script> <template> <a + v-tooltip :data-method="actionMethod" :title="tooltipText" :href="link" - ref="tooltip" class="ci-action-icon-container" - data-toggle="tooltip" data-container="body"> <i diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue index 19cafff4e1c..18fe1847eef 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue @@ -1,6 +1,6 @@ <script> import getActionIcon from '../../../vue_shared/ci_action_icons'; - import tooltipMixin from '../../../vue_shared/mixins/tooltip'; + import tooltip from '../../../vue_shared/directives/tooltip'; /** * Renders either a cancel, retry or play icon pointing to the given path. @@ -29,9 +29,9 @@ }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, computed: { actionIconSvg() { @@ -42,13 +42,12 @@ </script> <template> <a + v-tooltip :data-method="actionMethod" :title="tooltipText" :href="link" - ref="tooltip" rel="nofollow" class="ci-action-icon-wrapper js-ci-status-icon" - data-toggle="tooltip" data-container="body" v-html="actionIconSvg" aria-label="Job's action"> diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue index d597af8dfb5..2944689a5a7 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -1,7 +1,7 @@ <script> import jobNameComponent from './job_name_component.vue'; import jobComponent from './job_component.vue'; - import tooltipMixin from '../../../vue_shared/mixins/tooltip'; + import tooltip from '../../../vue_shared/directives/tooltip'; /** * Renders the dropdown for the pipeline graph. @@ -34,9 +34,9 @@ }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, components: { jobComponent, @@ -53,12 +53,12 @@ <template> <div> <button + v-tooltip type="button" data-toggle="dropdown" data-container="body" class="dropdown-menu-toggle build-content" - :title="tooltipText" - ref="tooltip"> + :title="tooltipText"> <job-name-component :name="job.name" diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index b39c936101e..1f5ed3f1074 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -2,7 +2,7 @@ import actionComponent from './action_component.vue'; import dropdownActionComponent from './dropdown_action_component.vue'; import jobNameComponent from './job_name_component.vue'; - import tooltipMixin from '../../../vue_shared/mixins/tooltip'; + import tooltip from '../../../vue_shared/directives/tooltip'; /** * Renders the badge for the pipeline graph and the job's dropdown. @@ -54,9 +54,9 @@ jobNameComponent, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, computed: { tooltipText() { @@ -77,12 +77,11 @@ <template> <div> <a + v-tooltip v-if="job.status.details_path" :href="job.status.details_path" :title="tooltipText" :class="cssClassJobName" - ref="tooltip" - data-toggle="tooltip" data-container="body"> <job-name-component @@ -93,10 +92,9 @@ <div v-else + v-tooltip :title="tooltipText" :class="cssClassJobName" - ref="tooltip" - data-toggle="tooltip" data-container="body"> <job-name-component diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 8333ec0fbc3..2ca5ac2912f 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -1,6 +1,6 @@ <script> import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; -import tooltipMixin from '../../vue_shared/mixins/tooltip'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -12,9 +12,9 @@ export default { components: { userAvatarLink, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, computed: { user() { return this.pipeline.user; @@ -45,16 +45,16 @@ export default { <div class="label-container"> <span v-if="pipeline.flags.latest" + v-tooltip class="js-pipeline-url-latest label label-success" - title="Latest pipeline for this branch" - ref="tooltip"> + title="Latest pipeline for this branch"> latest </span> <span v-if="pipeline.flags.yaml_errors" + v-tooltip class="js-pipeline-url-yaml label label-danger" - :title="pipeline.yaml_errors" - ref="tooltip"> + :title="pipeline.yaml_errors"> yaml invalid </span> <span diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue index a6fc4f04237..01dfe51cc17 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue @@ -4,6 +4,7 @@ import playIconSvg from 'icons/_icon_play.svg'; import eventHub from '../event_hub'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; + import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -12,6 +13,9 @@ required: true, }, }, + directives: { + tooltip, + }, components: { loadingIcon, }, @@ -25,8 +29,6 @@ onClickAction(endpoint) { this.isLoading = true; - $(this.$refs.tooltip).tooltip('destroy'); - eventHub.$emit('postAction', endpoint); }, @@ -43,13 +45,13 @@ <template> <div class="btn-group"> <button + v-tooltip type="button" - class="dropdown-new btn btn-default has-tooltip js-pipeline-dropdown-manual-actions" + class="dropdown-new btn btn-default js-pipeline-dropdown-manual-actions" title="Manual job" data-toggle="dropdown" data-placement="top" aria-label="Manual job" - ref="tooltip" :disabled="isLoading"> <span v-html="playIconSvg"></span> <i diff --git a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue index b4520481cdc..b19bd509a00 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue @@ -1,5 +1,5 @@ <script> - import tooltipMixin from '../../vue_shared/mixins/tooltip'; + import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -8,9 +8,9 @@ required: true, }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, }; </script> <template> @@ -18,12 +18,12 @@ class="btn-group" role="group"> <button + v-tooltip class="dropdown-toggle btn btn-default build-artifacts js-pipeline-dropdown-download" title="Artifacts" data-placement="top" data-toggle="dropdown" - aria-label="Artifacts" - ref="tooltip"> + aria-label="Artifacts"> <i class="fa fa-download" aria-hidden="true"> diff --git a/app/assets/javascripts/pipelines/components/stage.vue b/app/assets/javascripts/pipelines/components/stage.vue index c05c76c9a64..e98f35bb58c 100644 --- a/app/assets/javascripts/pipelines/components/stage.vue +++ b/app/assets/javascripts/pipelines/components/stage.vue @@ -16,7 +16,7 @@ /* global Flash */ import { borderlessStatusIconEntityMap } from '../../vue_shared/ci_status_icons'; import loadingIcon from '../../vue_shared/components/loading_icon.vue'; -import tooltipMixin from '../../vue_shared/mixins/tooltip'; +import tooltip from '../../vue_shared/directives/tooltip'; export default { props: { @@ -32,9 +32,9 @@ export default { }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, data() { return { @@ -132,7 +132,7 @@ export default { <template> <div class="dropdown"> <button - ref="tooltip" + v-tooltip :class="triggerButtonClass" @click="onClickStage" class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button" diff --git a/app/assets/javascripts/pipelines/components/time_ago.vue b/app/assets/javascripts/pipelines/components/time_ago.vue index be3f32afa09..037684b4e72 100644 --- a/app/assets/javascripts/pipelines/components/time_ago.vue +++ b/app/assets/javascripts/pipelines/components/time_ago.vue @@ -1,7 +1,7 @@ <script> import iconTimerSvg from 'icons/_icon_timer.svg'; import '../../lib/utils/datetime_utility'; - import tooltipMixin from '../../vue_shared/mixins/tooltip'; + import tooltip from '../../vue_shared/directives/tooltip'; import timeagoMixin from '../../vue_shared/mixins/timeago'; export default { @@ -16,9 +16,11 @@ }, }, mixins: [ - tooltipMixin, timeagoMixin, ], + directives: { + tooltip, + }, data() { return { iconTimerSvg, @@ -81,7 +83,7 @@ </i> <time - ref="tooltip" + v-tooltip data-placement="top" data-container="body" :title="tooltipTitle(finishedTime)"> diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue index 1d4d90f75b6..bdc059f4a03 100644 --- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue +++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue @@ -2,7 +2,7 @@ import ciIconBadge from './ci_badge_link.vue'; import loadingIcon from './loading_icon.vue'; import timeagoTooltip from './time_ago_tooltip.vue'; -import tooltipMixin from '../mixins/tooltip'; +import tooltip from '../directives/tooltip'; import userAvatarImage from './user_avatar/user_avatar_image.vue'; /** @@ -47,9 +47,9 @@ export default { }, }, - mixins: [ - tooltipMixin, - ], + directives: { + tooltip, + }, components: { ciIconBadge, @@ -90,10 +90,10 @@ export default { <template v-if="user"> <a + v-tooltip :href="user.path" :title="user.email" - class="js-user-link commit-committer-link" - ref="tooltip"> + class="js-user-link commit-committer-link"> <user-avatar-image :img-src="user.avatar_url" diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 1a11f493b7f..5bf2a90cc3b 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -1,17 +1,17 @@ <script> - import tooltipMixin from '../../mixins/tooltip'; + import tooltip from '../../directives/tooltip'; import toolbarButton from './toolbar_button.vue'; export default { - mixins: [ - tooltipMixin, - ], props: { previewMarkdown: { type: Boolean, required: true, }, }, + directives: { + tooltip, + }, components: { toolbarButton, }, @@ -94,13 +94,13 @@ </div> <div class="toolbar-group"> <button + v-tooltip aria-label="Go full screen" class="toolbar-btn js-zen-enter" data-container="body" tabindex="-1" title="Go full screen" - type="button" - ref="tooltip"> + type="button"> <i aria-hidden="true" class="fa fa-arrows-alt fa-fw"> diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue index 096be507625..f7da7ebfcfe 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue @@ -1,10 +1,7 @@ <script> - import tooltipMixin from '../../mixins/tooltip'; + import tooltip from '../../directives/tooltip'; export default { - mixins: [ - tooltipMixin, - ], props: { buttonTitle: { type: String, @@ -29,6 +26,9 @@ default: false, }, }, + directives: { + tooltip, + }, computed: { iconClass() { return `fa-${this.icon}`; @@ -39,10 +39,10 @@ <template> <button + v-tooltip type="button" class="toolbar-btn js-md hidden-xs" tabindex="-1" - ref="tooltip" data-container="body" :data-md-tag="tag" :data-md-block="tagBlock" diff --git a/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue b/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue index 1c6ef071a6d..3ff7f6e2c4e 100644 --- a/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue +++ b/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue @@ -1,5 +1,5 @@ <script> -import tooltipMixin from '../mixins/tooltip'; +import tooltip from '../directives/tooltip'; import timeagoMixin from '../mixins/timeago'; import '../../lib/utils/datetime_utility'; @@ -28,19 +28,21 @@ export default { }, mixins: [ - tooltipMixin, timeagoMixin, ], + + directives: { + tooltip, + }, }; </script> <template> <time + v-tooltip :class="cssClass" - class="js-vue-timeago" :title="tooltipTitle(time)" :data-placement="tooltipPlacement" - data-container="body" - ref="tooltip"> + data-container="body"> {{timeFormated(time)}} </time> </template> diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue index cd6f8c7aee4..dd9a2ebb184 100644 --- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue +++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue @@ -16,11 +16,10 @@ */ import defaultAvatarUrl from 'images/no_avatar.png'; -import TooltipMixin from '../../mixins/tooltip'; +import tooltip from '../../directives/tooltip'; export default { name: 'UserAvatarImage', - mixins: [TooltipMixin], props: { imgSrc: { type: String, @@ -53,6 +52,9 @@ export default { default: 'top', }, }, + directives: { + tooltip, + }, computed: { tooltipContainer() { return this.tooltipText ? 'body' : null; @@ -72,6 +74,7 @@ export default { <template> <img + v-tooltip class="avatar" :class="[avatarSizeClass, cssClasses]" :src="imageSource" @@ -81,6 +84,5 @@ export default { :data-container="tooltipContainer" :data-placement="tooltipPlacement" :title="tooltipText" - ref="tooltip" /> </template> diff --git a/app/assets/javascripts/vue_shared/directives/tooltip.js b/app/assets/javascripts/vue_shared/directives/tooltip.js new file mode 100644 index 00000000000..dc896cf5c7d --- /dev/null +++ b/app/assets/javascripts/vue_shared/directives/tooltip.js @@ -0,0 +1,13 @@ +export default { + bind(el) { + $(el).tooltip(); + }, + + componentUpdated(el) { + $(el).tooltip('fixTitle'); + }, + + unbind(el) { + $(el).tooltip('destroy'); + }, +}; diff --git a/app/assets/javascripts/vue_shared/mixins/tooltip.js b/app/assets/javascripts/vue_shared/mixins/tooltip.js deleted file mode 100644 index 995c0c98505..00000000000 --- a/app/assets/javascripts/vue_shared/mixins/tooltip.js +++ /dev/null @@ -1,13 +0,0 @@ -export default { - mounted() { - $(this.$refs.tooltip).tooltip(); - }, - - updated() { - $(this.$refs.tooltip).tooltip('fixTitle'); - }, - - beforeDestroy() { - $(this.$refs.tooltip).tooltip('destroy'); - }, -}; diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 31220ab438e..245117b2559 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -129,7 +129,7 @@ } /** - * Annotate file + * Blame file */ &.blame { table { diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b09eef17c23..fa1bc72560e 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -54,7 +54,7 @@ class Admin::UsersController < Admin::ApplicationController end def block - if user.block + if update_user { |user| user.block } redirect_back_or_admin_user(notice: "Successfully blocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not blocked") @@ -64,7 +64,7 @@ class Admin::UsersController < Admin::ApplicationController def unblock if user.ldap_blocked? redirect_back_or_admin_user(alert: "This user cannot be unlocked manually from GitLab") - elsif user.activate + elsif update_user { |user| user.activate } redirect_back_or_admin_user(notice: "Successfully unblocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not unblocked") @@ -72,7 +72,7 @@ class Admin::UsersController < Admin::ApplicationController end def unlock - if user.unlock_access! + if update_user { |user| user.unlock_access! } redirect_back_or_admin_user(alert: "Successfully unlocked") else redirect_back_or_admin_user(alert: "Error occurred. User was not unlocked") @@ -80,7 +80,7 @@ class Admin::UsersController < Admin::ApplicationController end def confirm - if user.confirm + if update_user { |user| user.confirm } redirect_back_or_admin_user(notice: "Successfully confirmed") else redirect_back_or_admin_user(alert: "Error occurred. User was not confirmed") @@ -88,7 +88,8 @@ class Admin::UsersController < Admin::ApplicationController end def disable_two_factor - user.disable_two_factor! + update_user { |user| user.disable_two_factor! } + redirect_to admin_user_path(user), notice: 'Two-factor Authentication has been disabled for this user' end @@ -124,15 +125,18 @@ class Admin::UsersController < Admin::ApplicationController end respond_to do |format| - user.skip_reconfirmation! - if user.update_attributes(user_params_with_pass) + result = Users::UpdateService.new(user, user_params_with_pass).execute do |user| + user.skip_reconfirmation! + end + + if result[:status] == :success format.html { redirect_to [:admin, user], notice: 'User was successfully updated.' } format.json { head :ok } else # restore username to keep form action url. user.username = params[:id] format.html { render "edit" } - format.json { render json: user.errors, status: :unprocessable_entity } + format.json { render json: [result[:message]], status: result[:status] } end end end @@ -148,13 +152,16 @@ class Admin::UsersController < Admin::ApplicationController def remove_email email = user.emails.find(params[:email_id]) - email.destroy - - user.update_secondary_emails! + success = Emails::DestroyService.new(user, email: email.email).execute respond_to do |format| - format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") } - format.js { head :ok } + if success + format.html { redirect_back_or_admin_user(notice: 'Successfully removed email.') } + format.json { head :ok } + else + format.html { redirect_back_or_admin_user(alert: 'There was an error removing the e-mail.') } + format.json { render json: 'There was an error removing the e-mail.', status: 400 } + end end end @@ -202,4 +209,10 @@ class Admin::UsersController < Admin::ApplicationController :website_url ] end + + def update_user(&block) + result = Users::UpdateService.new(user).execute(&block) + + result[:status] == :success + end end diff --git a/app/controllers/profiles/avatars_controller.rb b/app/controllers/profiles/avatars_controller.rb index 933e0f3bceb..408650aac54 100644 --- a/app/controllers/profiles/avatars_controller.rb +++ b/app/controllers/profiles/avatars_controller.rb @@ -1,9 +1,8 @@ class Profiles::AvatarsController < Profiles::ApplicationController def destroy @user = current_user - @user.remove_avatar! - @user.save + Users::UpdateService.new(@user).execute { |user| user.remove_avatar! } redirect_to profile_path, status: 302 end diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb index 5655fb2ba0e..17b66df43e7 100644 --- a/app/controllers/profiles/emails_controller.rb +++ b/app/controllers/profiles/emails_controller.rb @@ -5,9 +5,9 @@ class Profiles::EmailsController < Profiles::ApplicationController end def create - @email = current_user.emails.new(email_params) + @email = Emails::CreateService.new(current_user, email_params).execute - if @email.save + if @email.errors.blank? NotificationService.new.new_email(@email) else flash[:alert] = @email.errors.full_messages.first @@ -18,9 +18,8 @@ class Profiles::EmailsController < Profiles::ApplicationController def destroy @email = current_user.emails.find(params[:id]) - @email.destroy - current_user.update_secondary_emails! + Emails::DestroyService.new(current_user, email: @email.email).execute respond_to do |format| format.html { redirect_to profile_emails_url, status: 302 } diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index a271e2dfc4b..960b7512602 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -7,7 +7,9 @@ class Profiles::NotificationsController < Profiles::ApplicationController end def update - if current_user.update_attributes(user_params) + result = Users::UpdateService.new(current_user, user_params).execute + + if result[:status] == :success flash[:notice] = "Notification settings saved" else flash[:alert] = "Failed to save new settings" diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb index 6217ec5ecef..10145bae0d3 100644 --- a/app/controllers/profiles/passwords_controller.rb +++ b/app/controllers/profiles/passwords_controller.rb @@ -15,17 +15,17 @@ class Profiles::PasswordsController < Profiles::ApplicationController return end - new_password = user_params[:password] - new_password_confirmation = user_params[:password_confirmation] - - result = @user.update_attributes( - password: new_password, - password_confirmation: new_password_confirmation, + password_attributes = { + password: user_params[:password], + password_confirmation: user_params[:password_confirmation], password_automatically_set: false - ) + } + + result = Users::UpdateService.new(@user, password_attributes).execute + + if result[:status] == :success + Users::UpdateService.new(@user, password_expires_at: nil).execute - if result - @user.update_attributes(password_expires_at: nil) redirect_to root_path, notice: 'Password successfully changed' else render :new @@ -46,7 +46,9 @@ class Profiles::PasswordsController < Profiles::ApplicationController return end - if @user.update_attributes(password_attributes) + result = Users::UpdateService.new(@user, password_attributes).execute + + if result[:status] == :success flash[:notice] = "Password was successfully updated. Please login with it" redirect_to new_user_session_path else diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index 5414142e2df..1e557c47638 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -6,7 +6,9 @@ class Profiles::PreferencesController < Profiles::ApplicationController def update begin - if @user.update_attributes(preferences_params) + result = Users::UpdateService.new(user, preferences_params).execute + + if result[:status] == :success flash[:notice] = 'Preferences saved.' else flash[:alert] = 'Failed to save preferences.' diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 313cdcd1c15..1a4f77639e7 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -10,7 +10,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController current_user.otp_grace_period_started_at = Time.current end - current_user.save! if current_user.changed? + Users::UpdateService.new(current_user).execute! if two_factor_authentication_required? && !current_user.two_factor_enabled? two_factor_authentication_reason( @@ -41,9 +41,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController def create if current_user.validate_and_consume_otp!(params[:pin_code]) - current_user.otp_required_for_login = true - @codes = current_user.generate_otp_backup_codes! - current_user.save! + Users::UpdateService.new(current_user, otp_required_for_login: true).execute! do |user| + @codes = user.generate_otp_backup_codes! + end render 'create' else @@ -70,8 +70,9 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController end def codes - @codes = current_user.generate_otp_backup_codes! - current_user.save! + Users::UpdateService.new(current_user).execute! do |user| + @codes = user.generate_otp_backup_codes! + end end def destroy diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index f98a9e24de1..076076fd1b3 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -12,39 +12,47 @@ class ProfilesController < Profiles::ApplicationController user_params.except!(:email) if @user.external_email? respond_to do |format| - if @user.update_attributes(user_params) + result = Users::UpdateService.new(@user, user_params).execute + + if result[:status] == :success message = "Profile was successfully updated" + format.html { redirect_back_or_default(default: { action: 'show' }, options: { notice: message }) } format.json { render json: { message: message } } else - message = @user.errors.full_messages.uniq.join('. ') - format.html { redirect_back_or_default(default: { action: 'show' }, options: { alert: "Failed to update profile. #{message}" }) } - format.json { render json: { message: message }, status: :unprocessable_entity } + format.html { redirect_back_or_default(default: { action: 'show' }, options: { alert: result[:message] }) } + format.json { render json: result } end end end def reset_private_token - if current_user.reset_authentication_token! - flash[:notice] = "Private token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_authentication_token! end + flash[:notice] = "Private token was successfully reset" + redirect_to profile_account_path end def reset_incoming_email_token - if current_user.reset_incoming_email_token! - flash[:notice] = "Incoming email token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_incoming_email_token! end + flash[:notice] = "Incoming email token was successfully reset" + redirect_to profile_account_path end def reset_rss_token - if current_user.reset_rss_token! - flash[:notice] = "RSS token was successfully reset" + Users::UpdateService.new(@user).execute! do |user| + user.reset_rss_token! end + flash[:notice] = "RSS token was successfully reset" + redirect_to profile_account_path end @@ -55,12 +63,13 @@ class ProfilesController < Profiles::ApplicationController end def update_username - if @user.update_attributes(username: user_params[:username]) - options = { notice: "Username successfully changed" } - else - message = @user.errors.full_messages.uniq.join('. ') - options = { alert: "Username change failed - #{message}" } - end + result = Users::UpdateService.new(@user, username: user_params[:username]).execute + + options = if result[:status] == :success + { notice: "Username successfully changed" } + else + { alert: "Username change failed - #{result[:message]}" } + end redirect_back_or_default(default: { action: 'show' }, options: options) end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 8effb792689..303e91a8dc0 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -135,7 +135,12 @@ class Projects::PipelinesController < Projects::ApplicationController @charts[:week] = Ci::Charts::WeekChart.new(project) @charts[:month] = Ci::Charts::MonthChart.new(project) @charts[:year] = Ci::Charts::YearChart.new(project) - @charts[:build_times] = Ci::Charts::BuildTime.new(project) + @charts[:pipeline_times] = Ci::Charts::PipelineTime.new(project) + + @counts = {} + @counts[:total] = @project.pipelines.count(:all) + @counts[:success] = @project.pipelines.success.count(:all) + @counts[:failed] = @project.pipelines.failed.count(:all) end private diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 0d8186dce02..f39441a281e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -60,10 +60,11 @@ class SessionsController < Devise::SessionsController return unless user && user.require_password? - token = user.generate_reset_token - user.save + Users::UpdateService.new(user).execute do |user| + @token = user.generate_reset_token + end - redirect_to edit_user_password_path(reset_password_token: token), + redirect_to edit_user_password_path(reset_password_token: @token), notice: "Please create a password for your new account." end diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index b4c074bc69c..3da5508aefd 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -41,7 +41,7 @@ class IssuesFinder < IssuableFinder def self.not_restricted_by_confidentiality(user) return Issue.where('issues.confidential IS NOT TRUE') if user.blank? - return Issue.all if user.admin? + return Issue.all if user.full_private_access? Issue.where(' issues.confidential IS NOT TRUE diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb index c2ab80f2e0d..2e9b72e9613 100644 --- a/app/helpers/graph_helper.rb +++ b/app/helpers/graph_helper.rb @@ -17,13 +17,10 @@ module GraphHelper ids.zip(parent_spaces) end - def success_ratio(success_builds, failed_builds) - failed_builds = failed_builds.count(:all) - success_builds = success_builds.count(:all) + def success_ratio(counts) + return 100 if counts[:failed].zero? - return 100 if failed_builds.zero? - - ratio = (success_builds.to_f / (success_builds + failed_builds)) * 100 + ratio = (counts[:success].to_f / (counts[:success] + counts[:failed])) * 100 ratio.to_i end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index c003b01e226..eb45241615f 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -15,7 +15,7 @@ module GroupsHelper @has_group_title = true full_title = '' - group.ancestors.each do |parent| + group.ancestors.reverse.each do |parent| full_title += link_to(simple_sanitize(parent.name), group_path(parent), class: 'group-path hidable') full_title += '<span class="hidable"> / </span>'.html_safe end diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index 3c9c6584e02..32af5566135 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -11,18 +11,21 @@ module HasStatus class_methods do def status_sql - scope = respond_to?(:exclude_ignored) ? exclude_ignored : all - - builds = scope.select('count(*)').to_sql - created = scope.created.select('count(*)').to_sql - success = scope.success.select('count(*)').to_sql - manual = scope.manual.select('count(*)').to_sql - pending = scope.pending.select('count(*)').to_sql - running = scope.running.select('count(*)').to_sql - skipped = scope.skipped.select('count(*)').to_sql - canceled = scope.canceled.select('count(*)').to_sql + scope_relevant = respond_to?(:exclude_ignored) ? exclude_ignored : all + scope_warnings = respond_to?(:failed_but_allowed) ? failed_but_allowed : none + + builds = scope_relevant.select('count(*)').to_sql + created = scope_relevant.created.select('count(*)').to_sql + success = scope_relevant.success.select('count(*)').to_sql + manual = scope_relevant.manual.select('count(*)').to_sql + pending = scope_relevant.pending.select('count(*)').to_sql + running = scope_relevant.running.select('count(*)').to_sql + skipped = scope_relevant.skipped.select('count(*)').to_sql + canceled = scope_relevant.canceled.select('count(*)').to_sql + warnings = scope_warnings.select('count(*) > 0').to_sql.presence || 'false' "(CASE + WHEN (#{builds})=(#{skipped}) AND (#{warnings}) THEN 'success' WHEN (#{builds})=(#{skipped}) THEN 'skipped' WHEN (#{builds})=(#{success}) THEN 'success' WHEN (#{builds})=(#{created}) THEN 'created' diff --git a/app/models/project.rb b/app/models/project.rb index 2c2685875f8..6e593d3c86b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -350,7 +350,10 @@ class Project < ActiveRecord::Base project.run_after_commit { add_import_job } end - after_transition started: :finished, do: :reset_cache_and_import_attrs + after_transition started: :finished do |project, _| + project.reset_cache_and_import_attrs + project.perform_housekeeping + end end class << self @@ -510,6 +513,18 @@ class Project < ActiveRecord::Base remove_import_data end + def perform_housekeeping + return unless repo_exists? + + run_after_commit do + begin + Projects::HousekeepingService.new(self).execute + rescue Projects::HousekeepingService::LeaseTaken => e + Rails.logger.info("Could not perform housekeeping for project #{self.path_with_namespace} (#{self.id}): #{e}") + end + end + end + def remove_import_data import_data&.destroy end diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index dde2a11440d..48edd0738ee 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -90,7 +90,7 @@ class ProjectFeature < ActiveRecord::Base when DISABLED false when PRIVATE - user && (project.team.member?(user) || user.admin?) + user && (project.team.member?(user) || user.full_private_access?) when ENABLED true else diff --git a/app/models/user.rb b/app/models/user.rb index 954a30155f7..650b64e7551 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -53,7 +53,7 @@ class User < ActiveRecord::Base lease = Gitlab::ExclusiveLease.new("user_update_tracked_fields:#{id}", timeout: 1.hour.to_i) return unless lease.try_obtain - save(validate: false) + Users::UpdateService.new(self).execute(validate: false) end attr_accessor :force_random_password @@ -494,10 +494,8 @@ class User < ActiveRecord::Base def update_emails_with_primary_email primary_email_record = emails.find_by(email: email) if primary_email_record - primary_email_record.destroy - emails.create(email: email_was) - - update_secondary_emails! + Emails::DestroyService.new(self, email: email).execute + Emails::CreateService.new(self, email: email_was).execute end end @@ -965,7 +963,7 @@ class User < ActiveRecord::Base if attempts_exceeded? lock_access! unless access_locked? else - save(validate: false) + Users::UpdateService.new(self).execute(validate: false) end end @@ -984,6 +982,12 @@ class User < ActiveRecord::Base self.admin = (new_level == 'admin') end + # Does the user have access to all private groups & projects? + # Overridden in EE to also check auditor? + def full_private_access? + admin? + end + def update_two_factor_requirement periods = expanded_groups_requiring_two_factor_authentication.pluck(:two_factor_grace_period) @@ -1123,7 +1127,8 @@ class User < ActiveRecord::Base email: email, &creation_block ) - user.save(validate: false) + + Users::UpdateService.new(user).execute(validate: false) user ensure Gitlab::ExclusiveLease.cancel(lease_key, uuid) diff --git a/app/services/emails/base_service.rb b/app/services/emails/base_service.rb new file mode 100644 index 00000000000..ace49889097 --- /dev/null +++ b/app/services/emails/base_service.rb @@ -0,0 +1,8 @@ +module Emails + class BaseService + def initialize(user, opts) + @user = user + @email = opts[:email] + end + end +end diff --git a/app/services/emails/create_service.rb b/app/services/emails/create_service.rb new file mode 100644 index 00000000000..b6491ee9804 --- /dev/null +++ b/app/services/emails/create_service.rb @@ -0,0 +1,7 @@ +module Emails + class CreateService < ::Emails::BaseService + def execute + @user.emails.create(email: @email) + end + end +end diff --git a/app/services/emails/destroy_service.rb b/app/services/emails/destroy_service.rb new file mode 100644 index 00000000000..d586b9dfe0c --- /dev/null +++ b/app/services/emails/destroy_service.rb @@ -0,0 +1,17 @@ +module Emails + class DestroyService < ::Emails::BaseService + def execute + Email.find_by_email!(@email).destroy && update_secondary_emails! + end + + private + + def update_secondary_emails! + result = ::Users::UpdateService.new(@user).execute do |user| + user.update_secondary_emails! + end + + result[:status] == 'success' + end + end +end diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index 363135ef09b..ff234a3440f 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -1,5 +1,4 @@ module Users - # Service for building a new user. class BuildService < BaseService def initialize(current_user, params = {}) @current_user = current_user diff --git a/app/services/users/create_service.rb b/app/services/users/create_service.rb index e22f7225ae2..74abc017cea 100644 --- a/app/services/users/create_service.rb +++ b/app/services/users/create_service.rb @@ -1,5 +1,4 @@ module Users - # Service for creating a new user. class CreateService < BaseService def initialize(current_user, params = {}) @current_user = current_user diff --git a/app/services/users/update_service.rb b/app/services/users/update_service.rb new file mode 100644 index 00000000000..dfbd6016c3f --- /dev/null +++ b/app/services/users/update_service.rb @@ -0,0 +1,34 @@ +module Users + class UpdateService < BaseService + def initialize(user, params = {}) + @user = user + @params = params.dup + end + + def execute(validate: true, &block) + yield(@user) if block_given? + + assign_attributes(&block) + + if @user.save(validate: validate) + success + else + error(@user.errors.full_messages.uniq.join('. ')) + end + end + + def execute!(*args, &block) + result = execute(*args, &block) + + raise ActiveRecord::RecordInvalid.new(@user) unless result[:status] == :success + + true + end + + private + + def assign_attributes(&block) + @user.assign_attributes(params) if params.any? + end + end +end diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml index 41f54f6bf42..181c7bee702 100644 --- a/app/views/groups/_home_panel.html.haml +++ b/app/views/groups/_home_panel.html.haml @@ -3,7 +3,7 @@ .avatar-container.s70.group-avatar = image_tag group_icon(@group), class: "avatar s70 avatar-tile" %h1.group-title - @#{@group.path} + = @group.name %span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) } = visibility_level_icon(@group.visibility_level, fw: false) diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index c7302414386..969c423b032 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -4,7 +4,7 @@ = icon('caret-down') .dropdown-menu-nav.dropdown-menu-align-right %ul - - if @group + - if @group&.persisted? - create_group_project = can?(current_user, :create_projects, @group) - create_group_subgroup = can?(current_user, :create_subgroup, @group) - if create_group_project || create_group_subgroup @@ -18,7 +18,7 @@ %li.divider %li.dropdown-bold-header GitLab - - if @project && @project.persisted? + - if @project&.persisted? - create_project_issue = can?(current_user, :create_issue, @project) - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) - create_project_snippet = can?(current_user, :create_project_snippet, @project) diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 087ae778b0f..819c98946ab 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -48,7 +48,7 @@ = f.text_field :id, readonly: true, label: 'User ID', wrapper: { class: 'col-md-3' } - if @user.external_email? - = f.text_field :email, required: true, readonly: true, help: 'Your email address was automatically set based on your #{email_provider_label} account.' + = f.text_field :email, required: true, readonly: true, help: "Your email address was automatically set based on your #{email_provider_label} account." - else = f.text_field :email, required: true, value: (@user.email unless @user.temp_oauth_email?), help: user_email_help_text(@user) diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index ce937ee1842..3627f72f5e1 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -1,6 +1,6 @@ - @no_container = true - project_duration = age_map_duration(@blame_groups, @project) -- page_title "Annotate", @blob.path, @ref +- page_title "Blame", @blob.path, @ref = render "projects/commits/head" %div{ class: container_class } diff --git a/app/views/projects/blob/_breadcrumb.html.haml b/app/views/projects/blob/_breadcrumb.html.haml index 5840e9863f4..2c944b516a4 100644 --- a/app/views/projects/blob/_breadcrumb.html.haml +++ b/app/views/projects/blob/_breadcrumb.html.haml @@ -27,7 +27,7 @@ = link_to 'Normal view', namespace_project_blob_path(@project.namespace, @project, @id), class: 'btn' - else - = link_to 'Annotate', namespace_project_blame_path(@project.namespace, @project, @id), + = link_to 'Blame', namespace_project_blame_path(@project.namespace, @project, @id), class: 'btn js-blob-blame-link' unless blob.empty? = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index 4a5043aac3c..8ffddfe6154 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -15,7 +15,7 @@ .col-md-6 = render 'projects/pipelines/charts/overall' .col-md-6 - = render 'projects/pipelines/charts/build_times' + = render 'projects/pipelines/charts/pipeline_times' %hr - = render 'projects/pipelines/charts/builds' + = render 'projects/pipelines/charts/pipelines' diff --git a/app/views/projects/pipelines/charts/_overall.haml b/app/views/projects/pipelines/charts/_overall.haml index 0b7e3d22dd7..93083397d5b 100644 --- a/app/views/projects/pipelines/charts/_overall.haml +++ b/app/views/projects/pipelines/charts/_overall.haml @@ -2,18 +2,14 @@ %ul %li Total: - %strong= pluralize @project.builds.count(:all), 'job' + %strong= pluralize @counts[:total], 'pipeline' %li Successful: - %strong= pluralize @project.builds.success.count(:all), 'job' + %strong= pluralize @counts[:success], 'pipeline' %li Failed: - %strong= pluralize @project.builds.failed.count(:all), 'job' + %strong= pluralize @counts[:failed], 'pipeline' %li Success ratio: %strong - #{success_ratio(@project.builds.success, @project.builds.failed)}% - %li - Commits covered: - %strong - = @project.pipelines.count(:all) + #{success_ratio(@counts)}% diff --git a/app/views/projects/pipelines/charts/_build_times.haml b/app/views/projects/pipelines/charts/_pipeline_times.haml index bb0975a9535..aee7c5492aa 100644 --- a/app/views/projects/pipelines/charts/_build_times.haml +++ b/app/views/projects/pipelines/charts/_pipeline_times.haml @@ -6,7 +6,7 @@ :javascript var data = { - labels : #{@charts[:build_times].labels.to_json}, + labels : #{@charts[:pipeline_times].labels.to_json}, datasets : [ { fillColor : "rgba(220,220,220,0.5)", @@ -14,7 +14,7 @@ barStrokeWidth: 1, barValueSpacing: 1, barDatasetSpacing: 1, - data : #{@charts[:build_times].build_times.to_json} + data : #{@charts[:pipeline_times].pipeline_times.to_json} } ] } diff --git a/app/views/projects/pipelines/charts/_builds.haml b/app/views/projects/pipelines/charts/_pipelines.haml index b6f453b9736..b6f453b9736 100644 --- a/app/views/projects/pipelines/charts/_builds.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index 22547a30cdf..a7c67ac9980 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -16,7 +16,7 @@ %strong #{project.name_with_namespace} · - if issuable.is_a?(Issue) = confidential_icon(issuable) - = link_to_gfm issuable.title, issuable_url_args, title: issuable.title + = link_to issuable.title, issuable_url_args, title: issuable.title .issuable-detail = link_to [project.namespace.becomes(Namespace), project, issuable] do %span.issuable-number= issuable.to_reference diff --git a/changelogs/unreleased/10378-promote-blameless-culture.yml b/changelogs/unreleased/10378-promote-blameless-culture.yml deleted file mode 100644 index 8cf64dfd793..00000000000 --- a/changelogs/unreleased/10378-promote-blameless-culture.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Changed Blame to Annotate in the UI to promote blameless culture -merge_request: 10378 -author: Ilya Vassilevsky diff --git a/changelogs/unreleased/12614-fix-long-message-from-mr.yml b/changelogs/unreleased/12614-fix-long-message-from-mr.yml deleted file mode 100644 index 30408ea4216..00000000000 --- a/changelogs/unreleased/12614-fix-long-message-from-mr.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Implement web hook logging -merge_request: 11027 -author: Alexander Randa diff --git a/changelogs/unreleased/12614-fix-long-message.yml b/changelogs/unreleased/12614-fix-long-message.yml deleted file mode 100644 index 94f8127c3c1..00000000000 --- a/changelogs/unreleased/12614-fix-long-message.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix long urls in the title of commit -merge_request: 10938 -author: Alexander Randa diff --git a/changelogs/unreleased/12910-snippets-description.yml b/changelogs/unreleased/12910-snippets-description.yml deleted file mode 100644 index ac3d754fee1..00000000000 --- a/changelogs/unreleased/12910-snippets-description.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Support descriptions for snippets -merge_request: -author: diff --git a/changelogs/unreleased/14707-allow-activity-feed-to-be-accessible-through-api.yml b/changelogs/unreleased/14707-allow-activity-feed-to-be-accessible-through-api.yml deleted file mode 100644 index 9c17c3b949c..00000000000 --- a/changelogs/unreleased/14707-allow-activity-feed-to-be-accessible-through-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Introduce an Events API -merge_request: 11755 -author: diff --git a/changelogs/unreleased/17489-hide-code-from-guests.yml b/changelogs/unreleased/17489-hide-code-from-guests.yml deleted file mode 100644 index eb6daffedfe..00000000000 --- a/changelogs/unreleased/17489-hide-code-from-guests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Hide clone panel and file list when user is only a guest -merge_request: -author: James Clark diff --git a/changelogs/unreleased/18927-reorder-issue-action-buttons.yml b/changelogs/unreleased/18927-reorder-issue-action-buttons.yml deleted file mode 100644 index 793d6582940..00000000000 --- a/changelogs/unreleased/18927-reorder-issue-action-buttons.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Reorder Issue action buttons in order of usability -merge_request: 11642 -author: diff --git a/changelogs/unreleased/19107-404-when-creating-new-milestone-or-issue-for-project-that-has-issues-disabled.yml b/changelogs/unreleased/19107-404-when-creating-new-milestone-or-issue-for-project-that-has-issues-disabled.yml deleted file mode 100644 index bec9aa34761..00000000000 --- a/changelogs/unreleased/19107-404-when-creating-new-milestone-or-issue-for-project-that-has-issues-disabled.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'New issue'/'New merge request' dropdowns should show only projects with issues/merge requests feature enabled -merge_request: 19107 -author: blackst0ne diff --git a/changelogs/unreleased/20517-delete-projects-issuescontroller-redirect_old.yml b/changelogs/unreleased/20517-delete-projects-issuescontroller-redirect_old.yml deleted file mode 100644 index 1f3ab3a2c10..00000000000 --- a/changelogs/unreleased/20517-delete-projects-issuescontroller-redirect_old.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove redirect for old issue url containing id instead of iid -merge_request: 11135 -author: blackst0ne diff --git a/changelogs/unreleased/23036-replace-all-spinach-tests-with-rspec-feature-tests.yml b/changelogs/unreleased/23036-replace-all-spinach-tests-with-rspec-feature-tests.yml deleted file mode 100644 index b350b27d863..00000000000 --- a/changelogs/unreleased/23036-replace-all-spinach-tests-with-rspec-feature-tests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace 'starred_projects.feature' spinach test with an rspec analog -merge_request: 11752 -author: blackst0ne diff --git a/changelogs/unreleased/23603-add-extra-functionality-for-the-top-right-button.yml b/changelogs/unreleased/23603-add-extra-functionality-for-the-top-right-button.yml deleted file mode 100644 index 77f8e31e16e..00000000000 --- a/changelogs/unreleased/23603-add-extra-functionality-for-the-top-right-button.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add extra context-sensitive functionality for the top right menu button -merge_request: 11632 -author: diff --git a/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml b/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml deleted file mode 100644 index dbd8a538d51..00000000000 --- a/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Automatically adjust project settings to match changes in project visibility -merge_request: 11831 -author: diff --git a/changelogs/unreleased/24196-protected-variables.yml b/changelogs/unreleased/24196-protected-variables.yml deleted file mode 100644 index 71567a9d794..00000000000 --- a/changelogs/unreleased/24196-protected-variables.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add protected variables which would only be passed to protected branches or - protected tags -merge_request: 11688 -author: diff --git a/changelogs/unreleased/24373-warning-message-go-away.yml b/changelogs/unreleased/24373-warning-message-go-away.yml deleted file mode 100644 index c0f2fd260ba..00000000000 --- a/changelogs/unreleased/24373-warning-message-go-away.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Notes: Warning message should go away once resolved' -merge_request: 10823 -author: Jacopo Beschi @jacopo-beschi diff --git a/changelogs/unreleased/25373-jira-links.yml b/changelogs/unreleased/25373-jira-links.yml deleted file mode 100644 index 09589d4b992..00000000000 --- a/changelogs/unreleased/25373-jira-links.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don’t create comment on JIRA if it already exists for the entity -merge_request: -author: diff --git a/changelogs/unreleased/25426-group-dashboard-ui.yml b/changelogs/unreleased/25426-group-dashboard-ui.yml deleted file mode 100644 index cc2bf62d07b..00000000000 --- a/changelogs/unreleased/25426-group-dashboard-ui.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update Dashboard Groups UI with better support for subgroups -merge_request: -author: diff --git a/changelogs/unreleased/25680-CI_ENVIRONMENT_URL.yml b/changelogs/unreleased/25680-CI_ENVIRONMENT_URL.yml deleted file mode 100644 index af9fe3b5041..00000000000 --- a/changelogs/unreleased/25680-CI_ENVIRONMENT_URL.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add $CI_ENVIRONMENT_URL to predefined variables for pipelines -merge_request: 11695 -author: diff --git a/changelogs/unreleased/26325-system-hooks.yml b/changelogs/unreleased/26325-system-hooks.yml deleted file mode 100644 index 62b8adaeccd..00000000000 --- a/changelogs/unreleased/26325-system-hooks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Backported new SystemHook event: `repository_update`' -merge_request: 11140 -author: diff --git a/changelogs/unreleased/27148-limit-bulk-create-memberships.yml b/changelogs/unreleased/27148-limit-bulk-create-memberships.yml deleted file mode 100644 index ac4aba2f4e0..00000000000 --- a/changelogs/unreleased/27148-limit-bulk-create-memberships.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Limit non-administrators to adding 100 members at a time to groups and projects -merge_request: 11940 -author: diff --git a/changelogs/unreleased/27439-memory-usage-info.yml b/changelogs/unreleased/27439-memory-usage-info.yml deleted file mode 100644 index dd212853f57..00000000000 --- a/changelogs/unreleased/27439-memory-usage-info.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add performance deltas between app deployments on Merge Request widget -merge_request: 11730 -author: diff --git a/changelogs/unreleased/27614-improve-instant-comments-exp.yml b/changelogs/unreleased/27614-improve-instant-comments-exp.yml deleted file mode 100644 index 4db676801f1..00000000000 --- a/changelogs/unreleased/27614-improve-instant-comments-exp.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve user experience around slash commands in instant comments -merge_request: 11612 -author: diff --git a/changelogs/unreleased/28080-system-checks.yml b/changelogs/unreleased/28080-system-checks.yml deleted file mode 100644 index 7d83014279a..00000000000 --- a/changelogs/unreleased/28080-system-checks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Refactored gitlab:app:check into SystemCheck liberary and improve some checks -merge_request: 9173 -author: diff --git a/changelogs/unreleased/28607-forking-and-configuring-project-via-api-works-very-unreliable.yml b/changelogs/unreleased/28607-forking-and-configuring-project-via-api-works-very-unreliable.yml deleted file mode 100644 index 9cf8d745f92..00000000000 --- a/changelogs/unreleased/28607-forking-and-configuring-project-via-api-works-very-unreliable.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Confirm Project forking behaviour via the API -merge_request: -author: diff --git a/changelogs/unreleased/28694-hard-delete-user-from-admin-panel.yml b/changelogs/unreleased/28694-hard-delete-user-from-admin-panel.yml deleted file mode 100644 index 2308a528580..00000000000 --- a/changelogs/unreleased/28694-hard-delete-user-from-admin-panel.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow users to be hard-deleted from the admin panel -merge_request: 11874 -author: diff --git a/changelogs/unreleased/28694-hard-delete-user-from-api.yml b/changelogs/unreleased/28694-hard-delete-user-from-api.yml deleted file mode 100644 index ad46540495c..00000000000 --- a/changelogs/unreleased/28694-hard-delete-user-from-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow users to be hard-deleted from the API -merge_request: 11853 -author: diff --git a/changelogs/unreleased/29010-perf-bar.yml b/changelogs/unreleased/29010-perf-bar.yml deleted file mode 100644 index f4167e5562f..00000000000 --- a/changelogs/unreleased/29010-perf-bar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add an optional performance bar to view performance metrics for the current page -merge_request: 11439 -author: diff --git a/changelogs/unreleased/29118-add-prometheus-instrumenting-to-gitlab-webapp.yml b/changelogs/unreleased/29118-add-prometheus-instrumenting-to-gitlab-webapp.yml deleted file mode 100644 index 99c55f128e3..00000000000 --- a/changelogs/unreleased/29118-add-prometheus-instrumenting-to-gitlab-webapp.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add prometheus based metrics collection to gitlab webapp -merge_request: -author: diff --git a/changelogs/unreleased/29690-rotate-otp-key-base.yml b/changelogs/unreleased/29690-rotate-otp-key-base.yml deleted file mode 100644 index 94d73a24758..00000000000 --- a/changelogs/unreleased/29690-rotate-otp-key-base.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add a Rake task to aid in rotating otp_key_base -merge_request: 11881 -author: diff --git a/changelogs/unreleased/29852-latex-formatting.yml b/changelogs/unreleased/29852-latex-formatting.yml deleted file mode 100644 index e96cda1d6b3..00000000000 --- a/changelogs/unreleased/29852-latex-formatting.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix LaTeX formatting for AsciiDoc wiki -merge_request: 11212 -author: diff --git a/changelogs/unreleased/30378-simplified-repository-settings-page.yml b/changelogs/unreleased/30378-simplified-repository-settings-page.yml deleted file mode 100644 index e8b87c8bb33..00000000000 --- a/changelogs/unreleased/30378-simplified-repository-settings-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Simplify project repository settings page -merge_request: 11698 -author: diff --git a/changelogs/unreleased/30410-revert-9347-and-10079.yml b/changelogs/unreleased/30410-revert-9347-and-10079.yml deleted file mode 100644 index 0149209caf2..00000000000 --- a/changelogs/unreleased/30410-revert-9347-and-10079.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Revert the feature that would include the current user's username in the HTTP - clone URL -merge_request: 11792 -author: diff --git a/changelogs/unreleased/30469-convdev-index.yml b/changelogs/unreleased/30469-convdev-index.yml deleted file mode 100644 index 0bdd9c4a699..00000000000 --- a/changelogs/unreleased/30469-convdev-index.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add ConvDev Index page to admin area -merge_request: 11377 -author: diff --git a/changelogs/unreleased/30651-improve-container-registry-description.yml b/changelogs/unreleased/30651-improve-container-registry-description.yml deleted file mode 100644 index 0157c9885bc..00000000000 --- a/changelogs/unreleased/30651-improve-container-registry-description.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add changelog for improved Registry description -merge_request: 11816 -author: diff --git a/changelogs/unreleased/30827-changes-to-audit-log.yml b/changelogs/unreleased/30827-changes-to-audit-log.yml deleted file mode 100644 index 32db3bf8e95..00000000000 --- a/changelogs/unreleased/30827-changes-to-audit-log.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Renamed users 'Audit Log'' to 'Authentication Log' -merge_request: 11400 -author: diff --git a/changelogs/unreleased/30892-add-api-support-for-pipeline-schedule.yml b/changelogs/unreleased/30892-add-api-support-for-pipeline-schedule.yml deleted file mode 100644 index 26ce84697d0..00000000000 --- a/changelogs/unreleased/30892-add-api-support-for-pipeline-schedule.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add API support for pipeline schedule -merge_request: 11307 -author: dosuken123 diff --git a/changelogs/unreleased/30917-wiki-is-not-searchable-with-guest-permissions.yml b/changelogs/unreleased/30917-wiki-is-not-searchable-with-guest-permissions.yml deleted file mode 100644 index c9bd2dc465e..00000000000 --- a/changelogs/unreleased/30917-wiki-is-not-searchable-with-guest-permissions.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Fix: Wiki is not searchable with Guest permissions' -merge_request: -author: diff --git a/changelogs/unreleased/30949-empty-states.yml b/changelogs/unreleased/30949-empty-states.yml deleted file mode 100644 index bef87a954b7..00000000000 --- a/changelogs/unreleased/30949-empty-states.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Center all empty states -merge_request: -author: diff --git a/changelogs/unreleased/31061-26135-ci-project-slug-enviroment-variables.yml b/changelogs/unreleased/31061-26135-ci-project-slug-enviroment-variables.yml deleted file mode 100644 index e71910dbd67..00000000000 --- a/changelogs/unreleased/31061-26135-ci-project-slug-enviroment-variables.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add slugify project path to CI enviroment variables -merge_request: 11838 -author: Ivan Chernov diff --git a/changelogs/unreleased/31384-new-issue-button-on-no-results-page-after-search-doesn-t-go-to-correct-form.yml b/changelogs/unreleased/31384-new-issue-button-on-no-results-page-after-search-doesn-t-go-to-correct-form.yml deleted file mode 100644 index 8d586616e07..00000000000 --- a/changelogs/unreleased/31384-new-issue-button-on-no-results-page-after-search-doesn-t-go-to-correct-form.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove 'New issue' button when issues search returns no results. -merge_request: !11263 -author: diff --git a/changelogs/unreleased/31448-jira-urls.yml b/changelogs/unreleased/31448-jira-urls.yml deleted file mode 100644 index d0e39f61b55..00000000000 --- a/changelogs/unreleased/31448-jira-urls.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add API URL to JIRA settings -merge_request: -author: diff --git a/changelogs/unreleased/31474-issue-boards-sidebar-milestone-dropdown-should-not-be-multi-select.yml b/changelogs/unreleased/31474-issue-boards-sidebar-milestone-dropdown-should-not-be-multi-select.yml deleted file mode 100644 index 88e79e3b6ea..00000000000 --- a/changelogs/unreleased/31474-issue-boards-sidebar-milestone-dropdown-should-not-be-multi-select.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disallow multiple selections for Milestone dropdown -merge_request: 11084 -author: diff --git a/changelogs/unreleased/31483-ordered-task-list.yml b/changelogs/unreleased/31483-ordered-task-list.yml deleted file mode 100644 index c43915b3268..00000000000 --- a/changelogs/unreleased/31483-ordered-task-list.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Ordered Task List Items -merge_request: 31483 -author: Jared Deckard <jared.deckard@gmail.com> diff --git a/changelogs/unreleased/31510-mask-password-field-edit.yml b/changelogs/unreleased/31510-mask-password-field-edit.yml deleted file mode 100644 index 0ef37be328d..00000000000 --- a/changelogs/unreleased/31510-mask-password-field-edit.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update password field label while editing service settings -merge_request: 11431 -author: diff --git a/changelogs/unreleased/31511-jira-settings.yml b/changelogs/unreleased/31511-jira-settings.yml deleted file mode 100644 index 4f9ddb13ef6..00000000000 --- a/changelogs/unreleased/31511-jira-settings.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Simplify testing and saving service integrations -merge_request: 11599 -author: diff --git a/changelogs/unreleased/31554-update-rufus-scheduler-and-sidekiq.yml b/changelogs/unreleased/31554-update-rufus-scheduler-and-sidekiq.yml deleted file mode 100644 index 0a36b52d561..00000000000 --- a/changelogs/unreleased/31554-update-rufus-scheduler-and-sidekiq.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update gem sidekiq-cron from 0.4.4 to 0.6.0 and rufus-scheduler from 3.1.10 - to 3.4.0 -merge_request: 10976 -author: dosuken123 diff --git a/changelogs/unreleased/31602-display-whether-shared-runner-is-enabled-in-the-admin-dashboard.yml b/changelogs/unreleased/31602-display-whether-shared-runner-is-enabled-in-the-admin-dashboard.yml deleted file mode 100644 index 00957f7e4f7..00000000000 --- a/changelogs/unreleased/31602-display-whether-shared-runner-is-enabled-in-the-admin-dashboard.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Display Shared Runner status in Admin Dashboard -merge_request: 11783 -author: Ivan Chernov diff --git a/changelogs/unreleased/31616-add-uptime-of-gitlab-instance-in-admin-area.yml b/changelogs/unreleased/31616-add-uptime-of-gitlab-instance-in-admin-area.yml deleted file mode 100644 index 6dc48d6b2d8..00000000000 --- a/changelogs/unreleased/31616-add-uptime-of-gitlab-instance-in-admin-area.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add server uptime to System Info page in admin dashboard -merge_request: 11590 -author: Justin Boltz diff --git a/changelogs/unreleased/31625-tag-editor-loses-all-inputs-when-you-try-to-add-a-tag-that-already-exists.yml b/changelogs/unreleased/31625-tag-editor-loses-all-inputs-when-you-try-to-add-a-tag-that-already-exists.yml deleted file mode 100644 index aae760b0ef5..00000000000 --- a/changelogs/unreleased/31625-tag-editor-loses-all-inputs-when-you-try-to-add-a-tag-that-already-exists.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Keep input data after creating a tag that already exists -merge_request: 11155 -author: diff --git a/changelogs/unreleased/31633-animate-issue.yml b/changelogs/unreleased/31633-animate-issue.yml deleted file mode 100644 index 6df4135b09c..00000000000 --- a/changelogs/unreleased/31633-animate-issue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: animate adding issue to boards -merge_request: -author: diff --git a/changelogs/unreleased/31644-make-cookie-sessions-unique.yml b/changelogs/unreleased/31644-make-cookie-sessions-unique.yml deleted file mode 100644 index e9a6a32cf70..00000000000 --- a/changelogs/unreleased/31644-make-cookie-sessions-unique.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update session cookie key name to be unique to instance in development -merge_request: -author: diff --git a/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml b/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml deleted file mode 100644 index 48b8a8507ec..00000000000 --- a/changelogs/unreleased/31757-single-click-on-filter-in-search-bar-to-activate-dropdown.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Single click on filter to open filtered search dropdown -merge_request: -author: diff --git a/changelogs/unreleased/31781-print-rendered-files-not-possible.yml b/changelogs/unreleased/31781-print-rendered-files-not-possible.yml deleted file mode 100644 index 14915823ff7..00000000000 --- a/changelogs/unreleased/31781-print-rendered-files-not-possible.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Include the blob content when printing a blob page -merge_request: 11247 -author: diff --git a/changelogs/unreleased/31840-add-a-rubocop-that-forbids-redirect_to-inside-a-controller-destroy-action-without-an-explicit-status.yml b/changelogs/unreleased/31840-add-a-rubocop-that-forbids-redirect_to-inside-a-controller-destroy-action-without-an-explicit-status.yml deleted file mode 100644 index 52bfe771e2b..00000000000 --- a/changelogs/unreleased/31840-add-a-rubocop-that-forbids-redirect_to-inside-a-controller-destroy-action-without-an-explicit-status.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add a rubocop rule to check if a method 'redirect_to' is used without explicitly set 'status' in 'destroy' actions of controllers -merge_request: 11749 -author: @blackst0ne diff --git a/changelogs/unreleased/31849-pipeline-real-time-header.yml b/changelogs/unreleased/31849-pipeline-real-time-header.yml deleted file mode 100644 index 2bb7af897ff..00000000000 --- a/changelogs/unreleased/31849-pipeline-real-time-header.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Makes header information of pipeline show page realtine -merge_request: -author: diff --git a/changelogs/unreleased/31849-pipeline-show-view-realtime.yml b/changelogs/unreleased/31849-pipeline-show-view-realtime.yml deleted file mode 100644 index 838a769a26e..00000000000 --- a/changelogs/unreleased/31849-pipeline-show-view-realtime.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates a mediator for pipeline details vue in order to mount several vue apps - with the same data -merge_request: -author: diff --git a/changelogs/unreleased/31902-namespace-recent-searches-to-project.yml b/changelogs/unreleased/31902-namespace-recent-searches-to-project.yml deleted file mode 100644 index e00eb6d8f72..00000000000 --- a/changelogs/unreleased/31902-namespace-recent-searches-to-project.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Scope issue/merge request recent searches to project -merge_request: -author: diff --git a/changelogs/unreleased/3191-deploy-keys-update.yml b/changelogs/unreleased/3191-deploy-keys-update.yml deleted file mode 100644 index 4100163e94f..00000000000 --- a/changelogs/unreleased/3191-deploy-keys-update.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Implement ability to update deploy keys -merge_request: 10383 -author: Alexander Randa diff --git a/changelogs/unreleased/31943-document-go-183.yml b/changelogs/unreleased/31943-document-go-183.yml deleted file mode 100644 index 201cd48f1ab..00000000000 --- a/changelogs/unreleased/31943-document-go-183.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Upgrade dependency to Go 1.8.3 -merge_request: 31943 diff --git a/changelogs/unreleased/31983-increase-merge-request-diff-file-size-limit-for-default-toggle-opening.yml b/changelogs/unreleased/31983-increase-merge-request-diff-file-size-limit-for-default-toggle-opening.yml deleted file mode 100644 index f61aa0a6b6e..00000000000 --- a/changelogs/unreleased/31983-increase-merge-request-diff-file-size-limit-for-default-toggle-opening.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Increase individual diff collapse limit to 100 KB, and render limit to 200 KB -merge_request: -author: diff --git a/changelogs/unreleased/31998-pipelines-empty-state.yml b/changelogs/unreleased/31998-pipelines-empty-state.yml deleted file mode 100644 index 78ae222255e..00000000000 --- a/changelogs/unreleased/31998-pipelines-empty-state.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Pipelines table empty state - only render empty state if we receive 0 pipelines -merge_request: -author: diff --git a/changelogs/unreleased/32086-atwho-is-still-enabled-for-personal-snippet-comments-form.yml b/changelogs/unreleased/32086-atwho-is-still-enabled-for-personal-snippet-comments-form.yml deleted file mode 100644 index 0fd248e0400..00000000000 --- a/changelogs/unreleased/32086-atwho-is-still-enabled-for-personal-snippet-comments-form.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disable reference prefixes in notes for Snippets -merge_request: 11278 -author: diff --git a/changelogs/unreleased/32118-new-environment-btn-copy.yml b/changelogs/unreleased/32118-new-environment-btn-copy.yml deleted file mode 100644 index 16a51c3db6a..00000000000 --- a/changelogs/unreleased/32118-new-environment-btn-copy.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make New environment empty state btn lowercase -merge_request: -author: diff --git a/changelogs/unreleased/32219-speed-up-yarn-install-in-ci-by-utilizing-inter-pipeline-cache.yml b/changelogs/unreleased/32219-speed-up-yarn-install-in-ci-by-utilizing-inter-pipeline-cache.yml deleted file mode 100644 index 7fb3cb3a30b..00000000000 --- a/changelogs/unreleased/32219-speed-up-yarn-install-in-ci-by-utilizing-inter-pipeline-cache.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Cache npm modules between pipelines with yarn to speed up setup-test-env -merge_request: 11343 -author: diff --git a/changelogs/unreleased/32395-duplicate-string-in-https-docs-gitlab-com-ce-administration-environment_variables-html.yml b/changelogs/unreleased/32395-duplicate-string-in-https-docs-gitlab-com-ce-administration-environment_variables-html.yml deleted file mode 100644 index d2be3d6cc4b..00000000000 --- a/changelogs/unreleased/32395-duplicate-string-in-https-docs-gitlab-com-ce-administration-environment_variables-html.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Removes duplicate environment variable in documentation -merge_request: -author: diff --git a/changelogs/unreleased/32418-make-link-to-self-less-obvious.yml b/changelogs/unreleased/32418-make-link-to-self-less-obvious.yml deleted file mode 100644 index aabe87dac0f..00000000000 --- a/changelogs/unreleased/32418-make-link-to-self-less-obvious.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Change links in issuable meta to black -merge_request: -author: diff --git a/changelogs/unreleased/32570-project-activity-tab-border.yml b/changelogs/unreleased/32570-project-activity-tab-border.yml deleted file mode 100644 index 100a3e6a74d..00000000000 --- a/changelogs/unreleased/32570-project-activity-tab-border.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix border-bottom for project activity tab -merge_request: -author: diff --git a/changelogs/unreleased/32598-avoid-resource-intensive-login-checks-if-password-is-not-provided-for-git-http.yml b/changelogs/unreleased/32598-avoid-resource-intensive-login-checks-if-password-is-not-provided-for-git-http.yml deleted file mode 100644 index 6da7491bbda..00000000000 --- a/changelogs/unreleased/32598-avoid-resource-intensive-login-checks-if-password-is-not-provided-for-git-http.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Avoid resource intensive login checks if password is not provided. -merge_request: 11537 -author: Horatiu Eugen Vlad diff --git a/changelogs/unreleased/32642_last_commit_id_in_file_api.yml b/changelogs/unreleased/32642_last_commit_id_in_file_api.yml deleted file mode 100644 index 80435352e10..00000000000 --- a/changelogs/unreleased/32642_last_commit_id_in_file_api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Introduce optimistic locking support via optional parameter last_commit_sha on File Update API' -merge_request: 11694 -author: electroma diff --git a/changelogs/unreleased/32682-skipped-ci-icon.yml b/changelogs/unreleased/32682-skipped-ci-icon.yml deleted file mode 100644 index ad498b51900..00000000000 --- a/changelogs/unreleased/32682-skipped-ci-icon.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Adds new icon for CI skipped status -merge_request: -author: diff --git a/changelogs/unreleased/32720-emoji-spacing.yml b/changelogs/unreleased/32720-emoji-spacing.yml deleted file mode 100644 index da3df0f9093..00000000000 --- a/changelogs/unreleased/32720-emoji-spacing.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Create equal padding for emoji -merge_request: -author: diff --git a/changelogs/unreleased/32799-remove-no_turbolink-attribute-from-haml.yml b/changelogs/unreleased/32799-remove-no_turbolink-attribute-from-haml.yml deleted file mode 100644 index 9c1c1fe77f2..00000000000 --- a/changelogs/unreleased/32799-remove-no_turbolink-attribute-from-haml.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove redundant data-turbolink attributes from links -merge_request: 11672 -author: blackst0ne diff --git a/changelogs/unreleased/32807-company-icon.yml b/changelogs/unreleased/32807-company-icon.yml deleted file mode 100644 index 718108d3733..00000000000 --- a/changelogs/unreleased/32807-company-icon.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use briefcase icon for company in profile page -merge_request: -author: diff --git a/changelogs/unreleased/32832-confidential-issue-overflow.yml b/changelogs/unreleased/32832-confidential-issue-overflow.yml deleted file mode 100644 index 7d3d3bfed2e..00000000000 --- a/changelogs/unreleased/32832-confidential-issue-overflow.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove overflow from comment form for confidential issues and vertically aligns - confidential issue icon -merge_request: -author: diff --git a/changelogs/unreleased/32851-postgres-min-version.yml b/changelogs/unreleased/32851-postgres-min-version.yml deleted file mode 100644 index 139307d65c6..00000000000 --- a/changelogs/unreleased/32851-postgres-min-version.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Minimum postgresql version is now 9.2 -merge_request: 11677 -author: diff --git a/changelogs/unreleased/32955-special-keywords.yml b/changelogs/unreleased/32955-special-keywords.yml deleted file mode 100644 index 0f9939ced8c..00000000000 --- a/changelogs/unreleased/32955-special-keywords.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add all pipeline sources as special keywords to 'only' and 'except' -merge_request: 11844 -author: Filip Krakowski diff --git a/changelogs/unreleased/32983-merge-conflict-resolution-removed-the-newline-in-the-end-of-file.yml b/changelogs/unreleased/32983-merge-conflict-resolution-removed-the-newline-in-the-end-of-file.yml deleted file mode 100644 index eca42176501..00000000000 --- a/changelogs/unreleased/32983-merge-conflict-resolution-removed-the-newline-in-the-end-of-file.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Keep trailing newline when resolving conflicts by picking sides -merge_request: -author: diff --git a/changelogs/unreleased/32992-consider-using-zopfli-over-standard-gzip-compression-for-webpack-assets.yml b/changelogs/unreleased/32992-consider-using-zopfli-over-standard-gzip-compression-for-webpack-assets.yml deleted file mode 100644 index 93037d6181e..00000000000 --- a/changelogs/unreleased/32992-consider-using-zopfli-over-standard-gzip-compression-for-webpack-assets.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use zopfli compression for frontend assets -merge_request: 11798 -author: diff --git a/changelogs/unreleased/33000-tag-list-in-project-create-api.yml b/changelogs/unreleased/33000-tag-list-in-project-create-api.yml deleted file mode 100644 index b0d0d3cbeba..00000000000 --- a/changelogs/unreleased/33000-tag-list-in-project-create-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add tag_list param to project api -merge_request: 11799 -author: Ivan Chernov diff --git a/changelogs/unreleased/33032-invalid-you-directly-addressed-yourself-todo-when-using-unsubscribe.yml b/changelogs/unreleased/33032-invalid-you-directly-addressed-yourself-todo-when-using-unsubscribe.yml deleted file mode 100644 index 1eaa0d0124e..00000000000 --- a/changelogs/unreleased/33032-invalid-you-directly-addressed-yourself-todo-when-using-unsubscribe.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix /unsubscribe slash command creating extra todos when you were already mentioned - in an issue -merge_request: -author: diff --git a/changelogs/unreleased/33154-permissions-for-project-labels-and-group-labels.yml b/changelogs/unreleased/33154-permissions-for-project-labels-and-group-labels.yml deleted file mode 100644 index 3b98525167d..00000000000 --- a/changelogs/unreleased/33154-permissions-for-project-labels-and-group-labels.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow group reporters to manage group labels -merge_request: -author: diff --git a/changelogs/unreleased/33207-show-delete-option-in-admin-users-page.yml b/changelogs/unreleased/33207-show-delete-option-in-admin-users-page.yml deleted file mode 100644 index 5eb4e15e311..00000000000 --- a/changelogs/unreleased/33207-show-delete-option-in-admin-users-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow admins to delete users from the admin users page -merge_request: 11852 -author: diff --git a/changelogs/unreleased/33215-fix-hard-delete-of-users.yml b/changelogs/unreleased/33215-fix-hard-delete-of-users.yml deleted file mode 100644 index 29699ff745a..00000000000 --- a/changelogs/unreleased/33215-fix-hard-delete-of-users.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix hard-deleting users when they have authored issues -merge_request: 11855 -author: diff --git a/changelogs/unreleased/33242-create-project-for-user-api-ignores-path-parameter.yml b/changelogs/unreleased/33242-create-project-for-user-api-ignores-path-parameter.yml deleted file mode 100644 index c33278998ee..00000000000 --- a/changelogs/unreleased/33242-create-project-for-user-api-ignores-path-parameter.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix missing optional path parameter in "Create project for user" API -merge_request: 11868 -author: diff --git a/changelogs/unreleased/33245-chinese_translation_of_cycle_analytics_page.yml b/changelogs/unreleased/33245-chinese_translation_of_cycle_analytics_page.yml deleted file mode 100644 index 07dd0872d3b..00000000000 --- a/changelogs/unreleased/33245-chinese_translation_of_cycle_analytics_page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add Chinese translation of Cycle Analytics Page to I18N -merge_request: 11644 -author:Huang Tao diff --git a/changelogs/unreleased/33308-use-pre-wrap-for-commit-messages.yml b/changelogs/unreleased/33308-use-pre-wrap-for-commit-messages.yml deleted file mode 100644 index 43e8f242947..00000000000 --- a/changelogs/unreleased/33308-use-pre-wrap-for-commit-messages.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use pre-wrap for commit messages to keep lists indented -merge_request: -author: diff --git a/changelogs/unreleased/33334-portuguese_brazil_translation_of_cycle_analytics_page.yml b/changelogs/unreleased/33334-portuguese_brazil_translation_of_cycle_analytics_page.yml deleted file mode 100644 index a0e0458da16..00000000000 --- a/changelogs/unreleased/33334-portuguese_brazil_translation_of_cycle_analytics_page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add Portuguese Brazil of Cycle Analytics Page to I18N -merge_request: 11920 -author:Huang Tao diff --git a/changelogs/unreleased/33383-bulgarian_translation_of_cycle_analytics_page.yml b/changelogs/unreleased/33383-bulgarian_translation_of_cycle_analytics_page.yml deleted file mode 100644 index 71bd5505be7..00000000000 --- a/changelogs/unreleased/33383-bulgarian_translation_of_cycle_analytics_page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: add bulgarian translation of cycle analytics page to I18N -merge_request: 11958 -author: Lyubomir Vasilev diff --git a/changelogs/unreleased/33878_fix_edit_deploy_key.yml b/changelogs/unreleased/33878_fix_edit_deploy_key.yml deleted file mode 100644 index bc47d522240..00000000000 --- a/changelogs/unreleased/33878_fix_edit_deploy_key.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix edit button for deploy keys available from other projects -merge_request: 12301 -author: Alexander Randa diff --git a/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml b/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml deleted file mode 100644 index f3b92878f6d..00000000000 --- a/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Standardize timeline note margins across different viewport sizes -merge_request: 12364 -author: diff --git a/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml b/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml deleted file mode 100644 index 7f4d6e3bc67..00000000000 --- a/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL -merge_request: 12344 -author: diff --git a/changelogs/unreleased/34289-drop-gfm-on-milestone-issuable-title.yml b/changelogs/unreleased/34289-drop-gfm-on-milestone-issuable-title.yml new file mode 100644 index 00000000000..42e906d24c6 --- /dev/null +++ b/changelogs/unreleased/34289-drop-gfm-on-milestone-issuable-title.yml @@ -0,0 +1,4 @@ +--- +title: Drop GFM support for issuable title on milestone for consistency and performance +merge_request: +author: Takuya Noguchi diff --git a/changelogs/unreleased/UI-improvements-for-count-badges-and-permission-badges.yml b/changelogs/unreleased/UI-improvements-for-count-badges-and-permission-badges.yml deleted file mode 100644 index 374f643faa7..00000000000 --- a/changelogs/unreleased/UI-improvements-for-count-badges-and-permission-badges.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Count badges depend on translucent color to better adjust to different background - colors and permission badges now feature a pill shaped design similar to labels -merge_request: -author: diff --git a/changelogs/unreleased/adam-influxdb-hostname.yml b/changelogs/unreleased/adam-influxdb-hostname.yml deleted file mode 100644 index ab201ae7894..00000000000 --- a/changelogs/unreleased/adam-influxdb-hostname.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow GitLab instance to start when InfluxDB hostname cannot be resolved -merge_request: 11356 -author: diff --git a/changelogs/unreleased/add-index-for-auto_canceled_by_id-mysql.yml b/changelogs/unreleased/add-index-for-auto_canceled_by_id-mysql.yml deleted file mode 100644 index eac78e9ee1f..00000000000 --- a/changelogs/unreleased/add-index-for-auto_canceled_by_id-mysql.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add indices for auto_canceled_by_id for ci_pipelines and ci_builds on PostgreSQL -merge_request: 11034 -author: diff --git a/changelogs/unreleased/add-unicode-trace-feature-test.yml b/changelogs/unreleased/add-unicode-trace-feature-test.yml deleted file mode 100644 index 90c6a9afefc..00000000000 --- a/changelogs/unreleased/add-unicode-trace-feature-test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add a feature test for Unicode trace -merge_request: 10736 -author: dosuken123 diff --git a/changelogs/unreleased/add_ability_to_cancel_attaching_file_and_redesign_attaching_files_ui.yml b/changelogs/unreleased/add_ability_to_cancel_attaching_file_and_redesign_attaching_files_ui.yml deleted file mode 100644 index fcf4efa2846..00000000000 --- a/changelogs/unreleased/add_ability_to_cancel_attaching_file_and_redesign_attaching_files_ui.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add an ability to cancel attaching file and redesign attaching files UI -merge_request: 9431 -author: blackst0ne diff --git a/changelogs/unreleased/aliyun-backup-provider.yml b/changelogs/unreleased/aliyun-backup-provider.yml deleted file mode 100644 index e7505e44a59..00000000000 --- a/changelogs/unreleased/aliyun-backup-provider.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add Aliyun OSS as the backup storage provider -merge_request: 9721 -author: Yuanfei Zhu diff --git a/changelogs/unreleased/allow-reporters-to-promote-group-labels.yml b/changelogs/unreleased/allow-reporters-to-promote-group-labels.yml deleted file mode 100644 index 2364ce6d068..00000000000 --- a/changelogs/unreleased/allow-reporters-to-promote-group-labels.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow reporters to promote project labels to group labels -merge_request: -author: diff --git a/changelogs/unreleased/allow_numeric_pages_domain.yml b/changelogs/unreleased/allow_numeric_pages_domain.yml deleted file mode 100644 index 10d9f26f88d..00000000000 --- a/changelogs/unreleased/allow_numeric_pages_domain.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow numeric pages domain -merge_request: 11550 -author: diff --git a/changelogs/unreleased/allow_numeric_values_in_gitlab_ci_yml.yml b/changelogs/unreleased/allow_numeric_values_in_gitlab_ci_yml.yml deleted file mode 100644 index 8c7fa53a18b..00000000000 --- a/changelogs/unreleased/allow_numeric_values_in_gitlab_ci_yml.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow numeric values in gitlab-ci.yml -merge_request: 10607 -author: blackst0ne diff --git a/changelogs/unreleased/artifacts-keyboard-shortcuts.yml b/changelogs/unreleased/artifacts-keyboard-shortcuts.yml deleted file mode 100644 index 69569504c4f..00000000000 --- a/changelogs/unreleased/artifacts-keyboard-shortcuts.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enabled keyboard shortcuts on artifacts pages -merge_request: -author: diff --git a/changelogs/unreleased/auto-search-when-state-changed.yml b/changelogs/unreleased/auto-search-when-state-changed.yml deleted file mode 100644 index 2723beb8600..00000000000 --- a/changelogs/unreleased/auto-search-when-state-changed.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Perform filtered search when state tab is changed -merge_request: -author: diff --git a/changelogs/unreleased/bugfix-v3-deploy_keys-can_push.yml b/changelogs/unreleased/bugfix-v3-deploy_keys-can_push.yml deleted file mode 100644 index 0306663ac8d..00000000000 --- a/changelogs/unreleased/bugfix-v3-deploy_keys-can_push.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Fixed handling of the `can_push` attribute in the v3 deploy_keys api" -merge_request: 11607 -author: Richard Clamp diff --git a/changelogs/unreleased/bvl-rename-build-events-to-job-events.yml b/changelogs/unreleased/bvl-rename-build-events-to-job-events.yml deleted file mode 100644 index 2ce01a71361..00000000000 --- a/changelogs/unreleased/bvl-rename-build-events-to-job-events.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rename build_events to job_events -merge_request: 11287 -author: diff --git a/changelogs/unreleased/bvl-translate-project-pages.yml b/changelogs/unreleased/bvl-translate-project-pages.yml deleted file mode 100644 index fb90aba08b4..00000000000 --- a/changelogs/unreleased/bvl-translate-project-pages.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Translate backend for Project & Repository pages -merge_request: 11183 -author: diff --git a/changelogs/unreleased/ce-31853-projects-shared-groups.yml b/changelogs/unreleased/ce-31853-projects-shared-groups.yml deleted file mode 100644 index ffa3aed682d..00000000000 --- a/changelogs/unreleased/ce-31853-projects-shared-groups.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove duplication for sharing projects with groups in project settings -merge_request: -author: diff --git a/changelogs/unreleased/ce-32623-browser-tooltip-commits-branch-list.yml b/changelogs/unreleased/ce-32623-browser-tooltip-commits-branch-list.yml deleted file mode 100644 index 93edafed699..00000000000 --- a/changelogs/unreleased/ce-32623-browser-tooltip-commits-branch-list.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Change order of commits ahead and behind on divergence graph for branch list - view -merge_request: -author: diff --git a/changelogs/unreleased/ci-build-pipeline-header-vue.yml b/changelogs/unreleased/ci-build-pipeline-header-vue.yml deleted file mode 100644 index 2bbff2fdd16..00000000000 --- a/changelogs/unreleased/ci-build-pipeline-header-vue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Creates CI Header component for Pipelines and Jobs details pages -merge_request: -author: diff --git a/changelogs/unreleased/disable-blocked-manual-actions.yml b/changelogs/unreleased/disable-blocked-manual-actions.yml deleted file mode 100644 index a640f61a7dd..00000000000 --- a/changelogs/unreleased/disable-blocked-manual-actions.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: disable blocked manual actions -merge_request: -author: diff --git a/changelogs/unreleased/disable-environment-list-refresh.yml b/changelogs/unreleased/disable-environment-list-refresh.yml deleted file mode 100644 index 62fd71496a0..00000000000 --- a/changelogs/unreleased/disable-environment-list-refresh.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab-ee/issues/2677 -merge_request: 12347 -author: diff --git a/changelogs/unreleased/dm-async-tree-readme.yml b/changelogs/unreleased/dm-async-tree-readme.yml deleted file mode 100644 index fb1cfeb210a..00000000000 --- a/changelogs/unreleased/dm-async-tree-readme.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Load tree readme asynchronously -merge_request: -author: diff --git a/changelogs/unreleased/dm-auxiliary-viewers.yml b/changelogs/unreleased/dm-auxiliary-viewers.yml deleted file mode 100644 index ba73a499115..00000000000 --- a/changelogs/unreleased/dm-auxiliary-viewers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Display extra info about files on .gitlab-ci.yml, .gitlab/route-map.yml and - LICENSE blob pages -merge_request: -author: diff --git a/changelogs/unreleased/dm-comment-on-mr-commit-discussion.yml b/changelogs/unreleased/dm-comment-on-mr-commit-discussion.yml deleted file mode 100644 index 50db66c89ba..00000000000 --- a/changelogs/unreleased/dm-comment-on-mr-commit-discussion.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix replying to a commit discussion displayed in the context of an MR -merge_request: -author: diff --git a/changelogs/unreleased/dm-consistent-commit-sha-style.yml b/changelogs/unreleased/dm-consistent-commit-sha-style.yml deleted file mode 100644 index b6dace34d9b..00000000000 --- a/changelogs/unreleased/dm-consistent-commit-sha-style.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Consistently use monospace font for commit SHAs and branch and tag names -merge_request: -author: diff --git a/changelogs/unreleased/dm-consistent-last-push-event.yml b/changelogs/unreleased/dm-consistent-last-push-event.yml deleted file mode 100644 index acc17cb4523..00000000000 --- a/changelogs/unreleased/dm-consistent-last-push-event.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Consistently display last push event widget -merge_request: -author: diff --git a/changelogs/unreleased/dm-copy-as-gfm-without-empty-elements.yml b/changelogs/unreleased/dm-copy-as-gfm-without-empty-elements.yml deleted file mode 100644 index 45a61320ff2..00000000000 --- a/changelogs/unreleased/dm-copy-as-gfm-without-empty-elements.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't copy empty elements that were not selected on purpose as GFM -merge_request: -author: diff --git a/changelogs/unreleased/dm-copy-gfm-when-parts-of-other-elements-are-selected.yml b/changelogs/unreleased/dm-copy-gfm-when-parts-of-other-elements-are-selected.yml deleted file mode 100644 index ae916c30ff8..00000000000 --- a/changelogs/unreleased/dm-copy-gfm-when-parts-of-other-elements-are-selected.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Copy as GFM even when parts of other elements are selected -merge_request: -author: diff --git a/changelogs/unreleased/dm-dependency-linker-gemfile.yml b/changelogs/unreleased/dm-dependency-linker-gemfile.yml deleted file mode 100644 index 2d4167a1be5..00000000000 --- a/changelogs/unreleased/dm-dependency-linker-gemfile.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Autolink package names in Gemfile -merge_request: -author: diff --git a/changelogs/unreleased/dm-discussions-n-plus-1.yml b/changelogs/unreleased/dm-discussions-n-plus-1.yml deleted file mode 100644 index b97e4344248..00000000000 --- a/changelogs/unreleased/dm-discussions-n-plus-1.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Resolve N+1 query issue with discussions -merge_request: -author: diff --git a/changelogs/unreleased/dm-emails-are-not-user-references.yml b/changelogs/unreleased/dm-emails-are-not-user-references.yml deleted file mode 100644 index fe55a75a88f..00000000000 --- a/changelogs/unreleased/dm-emails-are-not-user-references.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't match email addresses or foo@bar as user references -merge_request: -author: diff --git a/changelogs/unreleased/dm-fix-jump-button.yml b/changelogs/unreleased/dm-fix-jump-button.yml deleted file mode 100644 index 4cde354fa28..00000000000 --- a/changelogs/unreleased/dm-fix-jump-button.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix title of discussion jump button at top of page -merge_request: -author: diff --git a/changelogs/unreleased/dm-fix-parser-cache.yml b/changelogs/unreleased/dm-fix-parser-cache.yml deleted file mode 100644 index 31c163b7272..00000000000 --- a/changelogs/unreleased/dm-fix-parser-cache.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't return nil for missing objects from parser cache -merge_request: -author: diff --git a/changelogs/unreleased/dm-gitmodules-parsing.yml b/changelogs/unreleased/dm-gitmodules-parsing.yml deleted file mode 100644 index a7d755d6c4d..00000000000 --- a/changelogs/unreleased/dm-gitmodules-parsing.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make .gitmodules parsing more resilient to syntax errors -merge_request: -author: diff --git a/changelogs/unreleased/dm-gravatar-username.yml b/changelogs/unreleased/dm-gravatar-username.yml deleted file mode 100644 index d50455061ec..00000000000 --- a/changelogs/unreleased/dm-gravatar-username.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add username parameter to gravatar URL -merge_request: -author: diff --git a/changelogs/unreleased/dm-group-page-name.yml b/changelogs/unreleased/dm-group-page-name.yml new file mode 100644 index 00000000000..233879364e3 --- /dev/null +++ b/changelogs/unreleased/dm-group-page-name.yml @@ -0,0 +1,4 @@ +--- +title: Show group name instead of path on group page +merge_request: +author: diff --git a/changelogs/unreleased/dm-more-dependency-linkers.yml b/changelogs/unreleased/dm-more-dependency-linkers.yml deleted file mode 100644 index 12d45e71e85..00000000000 --- a/changelogs/unreleased/dm-more-dependency-linkers.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Autolink package names in more dependency files -merge_request: -author: diff --git a/changelogs/unreleased/dm-oauth-config-for.yml b/changelogs/unreleased/dm-oauth-config-for.yml deleted file mode 100644 index 8fbbd45bb57..00000000000 --- a/changelogs/unreleased/dm-oauth-config-for.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Return nil when looking up config for unknown LDAP provider -merge_request: -author: diff --git a/changelogs/unreleased/dm-outdated-system-note.yml b/changelogs/unreleased/dm-outdated-system-note.yml deleted file mode 100644 index a1038a1051b..00000000000 --- a/changelogs/unreleased/dm-outdated-system-note.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add system note with link to diff comparison when MR discussion becomes outdated -merge_request: -author: diff --git a/changelogs/unreleased/dm-paste-code-inside-gfm-code.yml b/changelogs/unreleased/dm-paste-code-inside-gfm-code.yml deleted file mode 100644 index d078ca449a5..00000000000 --- a/changelogs/unreleased/dm-paste-code-inside-gfm-code.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't wrap pasted code when it's already inside code tags -merge_request: -author: diff --git a/changelogs/unreleased/dm-requirements-txt-tilde.yml b/changelogs/unreleased/dm-requirements-txt-tilde.yml new file mode 100644 index 00000000000..ddb5325ddd5 --- /dev/null +++ b/changelogs/unreleased/dm-requirements-txt-tilde.yml @@ -0,0 +1,5 @@ +--- +title: Don't match tilde and exclamation mark as part of requirements.txt package + name +merge_request: +author: diff --git a/changelogs/unreleased/dm-revert-mr-8427.yml b/changelogs/unreleased/dm-revert-mr-8427.yml deleted file mode 100644 index a91cff2e9cd..00000000000 --- a/changelogs/unreleased/dm-revert-mr-8427.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Revert 'New file from interface on existing branch' -merge_request: -author: diff --git a/changelogs/unreleased/dm-tree-last-commit.yml b/changelogs/unreleased/dm-tree-last-commit.yml deleted file mode 100644 index 50619fd6ef2..00000000000 --- a/changelogs/unreleased/dm-tree-last-commit.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show last commit for current tree on tree page -merge_request: -author: diff --git a/changelogs/unreleased/document-foreign-keys.yml b/changelogs/unreleased/document-foreign-keys.yml deleted file mode 100644 index faa467e8185..00000000000 --- a/changelogs/unreleased/document-foreign-keys.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add documentation about adding foreign keys -merge_request: -author: diff --git a/changelogs/unreleased/dturner-username.yml b/changelogs/unreleased/dturner-username.yml deleted file mode 100644 index 09ba822ee65..00000000000 --- a/changelogs/unreleased/dturner-username.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: add username field to push webhook -merge_request: -author: David Turner diff --git a/changelogs/unreleased/dz-fix-submodule-subgroup.yml b/changelogs/unreleased/dz-fix-submodule-subgroup.yml deleted file mode 100644 index 20c7c9ce657..00000000000 --- a/changelogs/unreleased/dz-fix-submodule-subgroup.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix submodule link to then project under subgroup -merge_request: 11906 -author: diff --git a/changelogs/unreleased/dz-project-list-cache-key.yml b/changelogs/unreleased/dz-project-list-cache-key.yml deleted file mode 100644 index 9e4826e686a..00000000000 --- a/changelogs/unreleased/dz-project-list-cache-key.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use route.cache_key for project list cache key -merge_request: 11325 -author: diff --git a/changelogs/unreleased/dz-rename-pipelines-settings-tab.yml b/changelogs/unreleased/dz-rename-pipelines-settings-tab.yml deleted file mode 100644 index 6a1232523bb..00000000000 --- a/changelogs/unreleased/dz-rename-pipelines-settings-tab.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rename CI/CD Pipelines to Pipelines in the project settings -merge_request: -author: diff --git a/changelogs/unreleased/enable-auto-cancelling-by-default.yml b/changelogs/unreleased/enable-auto-cancelling-by-default.yml deleted file mode 100644 index 8b1659bf38b..00000000000 --- a/changelogs/unreleased/enable-auto-cancelling-by-default.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable cancelling non-HEAD pending pipelines by default for all projects -merge_request: 11023 -author: diff --git a/changelogs/unreleased/environment-detail-view.yml b/changelogs/unreleased/environment-detail-view.yml deleted file mode 100644 index c74f70ea86d..00000000000 --- a/changelogs/unreleased/environment-detail-view.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make environment tables responsive -merge_request: -author: diff --git a/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml b/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml deleted file mode 100644 index 4796f8e918b..00000000000 --- a/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Expand/collapse backlog & closed lists in issue boards -merge_request: -author: diff --git a/changelogs/unreleased/feature-flags-flipper.yml b/changelogs/unreleased/feature-flags-flipper.yml deleted file mode 100644 index 5be5c44166d..00000000000 --- a/changelogs/unreleased/feature-flags-flipper.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add feature toggles and API endpoints for admins -merge_request: 11747 -author: diff --git a/changelogs/unreleased/feature-gb-persist-pipeline-stages.yml b/changelogs/unreleased/feature-gb-persist-pipeline-stages.yml deleted file mode 100644 index 1404b342359..00000000000 --- a/changelogs/unreleased/feature-gb-persist-pipeline-stages.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Persist pipeline stages in the database -merge_request: 11790 -author: diff --git a/changelogs/unreleased/feature-print-go-version-in-env-info.yml b/changelogs/unreleased/feature-print-go-version-in-env-info.yml deleted file mode 100644 index 34c19b06eda..00000000000 --- a/changelogs/unreleased/feature-print-go-version-in-env-info.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Print Go version in rake gitlab:env:info -merge_request: 11241 -author: diff --git a/changelogs/unreleased/feature-rss-scoped-token.yml b/changelogs/unreleased/feature-rss-scoped-token.yml deleted file mode 100644 index 740d8778be2..00000000000 --- a/changelogs/unreleased/feature-rss-scoped-token.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Expose atom links with an RSS token instead of using the private token -merge_request: 11647 -author: Alexis Reigel diff --git a/changelogs/unreleased/fix-33259.yml b/changelogs/unreleased/fix-33259.yml deleted file mode 100644 index c68e42c02cf..00000000000 --- a/changelogs/unreleased/fix-33259.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix GitHub importer performance on branch existence check -merge_request: -author: diff --git a/changelogs/unreleased/fix-34019.yml b/changelogs/unreleased/fix-34019.yml new file mode 100644 index 00000000000..77ebb18fda6 --- /dev/null +++ b/changelogs/unreleased/fix-34019.yml @@ -0,0 +1,4 @@ +--- +title: Perform project housekeeping after importing projects +merge_request: +author: diff --git a/changelogs/unreleased/fix-counter-cache-for-acts-as-taggable.yml b/changelogs/unreleased/fix-counter-cache-for-acts-as-taggable.yml deleted file mode 100644 index e40668546c0..00000000000 --- a/changelogs/unreleased/fix-counter-cache-for-acts-as-taggable.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix counter cache for acts as taggable -merge_request: -author: diff --git a/changelogs/unreleased/fix-encoding-binary-issue.yml b/changelogs/unreleased/fix-encoding-binary-issue.yml deleted file mode 100644 index ac9aff64a88..00000000000 --- a/changelogs/unreleased/fix-encoding-binary-issue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix binary encoding error on MR diffs -merge_request: 11929 -author: diff --git a/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml b/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml deleted file mode 100644 index a16fc775b5e..00000000000 --- a/changelogs/unreleased/fix-gb-exclude-manual-actions-from-cancelable-jobs.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Exclude manual actions when checking if pipeline can be canceled -merge_request: 11562 -author: diff --git a/changelogs/unreleased/fix-gb-fix-skipped-pipeline-with-allowed-to-fail-jobs.yml b/changelogs/unreleased/fix-gb-fix-skipped-pipeline-with-allowed-to-fail-jobs.yml new file mode 100644 index 00000000000..f59c6ecd90c --- /dev/null +++ b/changelogs/unreleased/fix-gb-fix-skipped-pipeline-with-allowed-to-fail-jobs.yml @@ -0,0 +1,4 @@ +--- +title: Fix CI/CD status in case there are only allowed to failed jobs in the pipeline +merge_request: 11166 +author: diff --git a/changelogs/unreleased/fix-github-clone-wiki.yml b/changelogs/unreleased/fix-github-clone-wiki.yml deleted file mode 100644 index eadd90e1390..00000000000 --- a/changelogs/unreleased/fix-github-clone-wiki.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Github - Fix token interpolation when cloning wiki repository -merge_request: -author: diff --git a/changelogs/unreleased/fix-github-import.yml b/changelogs/unreleased/fix-github-import.yml deleted file mode 100644 index 3a57152f7a8..00000000000 --- a/changelogs/unreleased/fix-github-import.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix token interpolation when setting the Github remote -merge_request: -author: diff --git a/changelogs/unreleased/fix-n-plus-one-queries-for-user-access.yml b/changelogs/unreleased/fix-n-plus-one-queries-for-user-access.yml deleted file mode 100644 index c2671a96b83..00000000000 --- a/changelogs/unreleased/fix-n-plus-one-queries-for-user-access.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix N+1 queries for non-members in comment threads -merge_request: -author: diff --git a/changelogs/unreleased/fix-support-for-external-ci-services.yml b/changelogs/unreleased/fix-support-for-external-ci-services.yml deleted file mode 100644 index eecb4519259..00000000000 --- a/changelogs/unreleased/fix-support-for-external-ci-services.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix support for external CI services -merge_request: 11176 -author: diff --git a/changelogs/unreleased/fix_commits_page.yml b/changelogs/unreleased/fix_commits_page.yml deleted file mode 100644 index a2afaf6e626..00000000000 --- a/changelogs/unreleased/fix_commits_page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix duplication of commits header on commits page -merge_request: 11006 -author: @blackst0ne diff --git a/changelogs/unreleased/fix_diff_line_comments.yml b/changelogs/unreleased/fix_diff_line_comments.yml deleted file mode 100644 index bdb0539b49d..00000000000 --- a/changelogs/unreleased/fix_diff_line_comments.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Fix: A diff comment on a change at last line of a file shows as two comments - in discussion' -merge_request: -author: diff --git a/changelogs/unreleased/gitaly-local-branches.yml b/changelogs/unreleased/gitaly-local-branches.yml deleted file mode 100644 index adcc0fa6280..00000000000 --- a/changelogs/unreleased/gitaly-local-branches.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add suport for find_local_branches GRPC from Gitaly -merge_request: 10059 -author: diff --git a/changelogs/unreleased/gitaly-opt-out.yml b/changelogs/unreleased/gitaly-opt-out.yml deleted file mode 100644 index 2f89e0bfc9a..00000000000 --- a/changelogs/unreleased/gitaly-opt-out.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable Gitaly by default in installations from source -merge_request: 11796 -author: diff --git a/changelogs/unreleased/instrument-merge-request-diff-load-commits.yml b/changelogs/unreleased/instrument-merge-request-diff-load-commits.yml deleted file mode 100644 index 916b182a48b..00000000000 --- a/changelogs/unreleased/instrument-merge-request-diff-load-commits.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Instrument MergeRequestDiff#load_commits -merge_request: -author: diff --git a/changelogs/unreleased/introduce-source-to-pipelines.yml b/changelogs/unreleased/introduce-source-to-pipelines.yml deleted file mode 100644 index 7898bd31b39..00000000000 --- a/changelogs/unreleased/introduce-source-to-pipelines.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Introduce source to Pipeline entity -merge_request: -author: diff --git a/changelogs/unreleased/issuable-form-create-label-sub-groups.yml b/changelogs/unreleased/issuable-form-create-label-sub-groups.yml deleted file mode 100644 index 54b818d6d5e..00000000000 --- a/changelogs/unreleased/issuable-form-create-label-sub-groups.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed create new label form in issue form not working for sub-group projects -merge_request: -author: diff --git a/changelogs/unreleased/issue-23254.yml b/changelogs/unreleased/issue-23254.yml deleted file mode 100644 index 568a7a41c30..00000000000 --- a/changelogs/unreleased/issue-23254.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed style on unsubscribe page -merge_request: -author: Gustav Ernberg diff --git a/changelogs/unreleased/issue-edit-inline.yml b/changelogs/unreleased/issue-edit-inline.yml deleted file mode 100644 index db03d1bdac4..00000000000 --- a/changelogs/unreleased/issue-edit-inline.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enables inline editing for an issues title & description -merge_request: -author: diff --git a/changelogs/unreleased/issue-inline-edit-quick-submit.yml b/changelogs/unreleased/issue-inline-edit-quick-submit.yml new file mode 100644 index 00000000000..4407bae3e6f --- /dev/null +++ b/changelogs/unreleased/issue-inline-edit-quick-submit.yml @@ -0,0 +1,4 @@ +--- +title: Fixed ctrl+enter not submit issue edit form +merge_request: +author: diff --git a/changelogs/unreleased/issue-template-reproduce-in-example-project.yml b/changelogs/unreleased/issue-template-reproduce-in-example-project.yml deleted file mode 100644 index 8116007b459..00000000000 --- a/changelogs/unreleased/issue-template-reproduce-in-example-project.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Ask for an example project for bug reports -merge_request: -author: diff --git a/changelogs/unreleased/issue-templates-summary-lines.yml b/changelogs/unreleased/issue-templates-summary-lines.yml deleted file mode 100644 index 0c8c3d884ce..00000000000 --- a/changelogs/unreleased/issue-templates-summary-lines.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add summary lines for collapsed details in the bug report template -merge_request: -author: diff --git a/changelogs/unreleased/issue_19262.yml b/changelogs/unreleased/issue_19262.yml deleted file mode 100644 index 7bcbc647fcb..00000000000 --- a/changelogs/unreleased/issue_19262.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent commits from upstream repositories to be re-processed by forks -merge_request: -author: diff --git a/changelogs/unreleased/issue_27166_2.yml b/changelogs/unreleased/issue_27166_2.yml deleted file mode 100644 index 9b9906e03dd..00000000000 --- a/changelogs/unreleased/issue_27166_2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Avoid repeated queries for pipeline builds on merge requests -merge_request: -author: diff --git a/changelogs/unreleased/issue_27168_2.yml b/changelogs/unreleased/issue_27168_2.yml deleted file mode 100644 index c67692493e0..00000000000 --- a/changelogs/unreleased/issue_27168_2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Preloads head pipeline for merge request collection -merge_request: -author: diff --git a/changelogs/unreleased/issue_32225_2.yml b/changelogs/unreleased/issue_32225_2.yml deleted file mode 100644 index 320b9fe00b8..00000000000 --- a/changelogs/unreleased/issue_32225_2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Handle head pipeline when creating merge requests -merge_request: -author: diff --git a/changelogs/unreleased/jouve-gitlab-ce-admin_keys.yml b/changelogs/unreleased/jouve-gitlab-ce-admin_keys.yml deleted file mode 100644 index df4de9f4e21..00000000000 --- a/changelogs/unreleased/jouve-gitlab-ce-admin_keys.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Redirect to user's keys index instead of user's index after a key is deleted - in the admin -merge_request: 10227 -author: Cyril Jouve diff --git a/changelogs/unreleased/mabes-gitlab-ce-bypass-auto-login.yml b/changelogs/unreleased/mabes-gitlab-ce-bypass-auto-login.yml deleted file mode 100644 index a321ed9d7d8..00000000000 --- a/changelogs/unreleased/mabes-gitlab-ce-bypass-auto-login.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow manual bypass of auto_sign_in_with_provider with a new param -merge_request: 10187 -author: Maxime Besson diff --git a/changelogs/unreleased/migrate-artifacts-to-a-new-path.yml b/changelogs/unreleased/migrate-artifacts-to-a-new-path.yml deleted file mode 100644 index bd022a3a91b..00000000000 --- a/changelogs/unreleased/migrate-artifacts-to-a-new-path.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Migrate artifacts to a new path -merge_request: -author: diff --git a/changelogs/unreleased/mk-fix-breadcrumb-order-33938.yml b/changelogs/unreleased/mk-fix-breadcrumb-order-33938.yml new file mode 100644 index 00000000000..790af692b92 --- /dev/null +++ b/changelogs/unreleased/mk-fix-breadcrumb-order-33938.yml @@ -0,0 +1,4 @@ +--- +title: Fix reversed breadcrumb order for nested groups +merge_request: 12322 +author: diff --git a/changelogs/unreleased/mk-fix-git-over-http-rejections.yml b/changelogs/unreleased/mk-fix-git-over-http-rejections.yml deleted file mode 100644 index e75740e913f..00000000000 --- a/changelogs/unreleased/mk-fix-git-over-http-rejections.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Git-over-HTTP error statuses and improve error messages -merge_request: 11398 -author: diff --git a/changelogs/unreleased/mk-fix-issue-34068.yml b/changelogs/unreleased/mk-fix-issue-34068.yml new file mode 100644 index 00000000000..af0a9139568 --- /dev/null +++ b/changelogs/unreleased/mk-fix-issue-34068.yml @@ -0,0 +1,4 @@ +--- +title: Fix 500 when failing to create private group +merge_request: 12394 +author: diff --git a/changelogs/unreleased/mrchrisw-catch-openssl.yml b/changelogs/unreleased/mrchrisw-catch-openssl.yml deleted file mode 100644 index a8b433fb0cd..00000000000 --- a/changelogs/unreleased/mrchrisw-catch-openssl.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rescue OpenSSL::SSL::SSLError in JiraService & IssueTrackerService -merge_request: -author: diff --git a/changelogs/unreleased/omega-submodules.yml b/changelogs/unreleased/omega-submodules.yml deleted file mode 100644 index 1488eb72174..00000000000 --- a/changelogs/unreleased/omega-submodules.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Repository browser: handle in-repository submodule urls' -merge_request: -author: David Turner diff --git a/changelogs/unreleased/prevent-project-transfer.yml b/changelogs/unreleased/prevent-project-transfer.yml deleted file mode 100644 index a5c74676aab..00000000000 --- a/changelogs/unreleased/prevent-project-transfer.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent project transfers if a new group is not selected -merge_request: -author: diff --git a/changelogs/unreleased/projects-api-import-status.yml b/changelogs/unreleased/projects-api-import-status.yml deleted file mode 100644 index 06603c0adec..00000000000 --- a/changelogs/unreleased/projects-api-import-status.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Expose import_status in Projects API -merge_request: 11851 -author: Robin Bobbitt diff --git a/changelogs/unreleased/protected-branches-no-one-merge.yml b/changelogs/unreleased/protected-branches-no-one-merge.yml deleted file mode 100644 index 52d93793f3d..00000000000 --- a/changelogs/unreleased/protected-branches-no-one-merge.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow 'no one' as an option for allowed to merge on a procted branch -merge_request: -author: diff --git a/changelogs/unreleased/reduce-sidekiq-wait-timings.yml b/changelogs/unreleased/reduce-sidekiq-wait-timings.yml deleted file mode 100644 index 4d23accc82e..00000000000 --- a/changelogs/unreleased/reduce-sidekiq-wait-timings.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Reduce time spent waiting for certain Sidekiq jobs to complete -merge_request: -author: diff --git a/changelogs/unreleased/refactor-projects-finder-init-collection.yml b/changelogs/unreleased/refactor-projects-finder-init-collection.yml deleted file mode 100644 index c8113419f21..00000000000 --- a/changelogs/unreleased/refactor-projects-finder-init-collection.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Refactor ProjectsFinder#init_collection to produce more efficient queries for - retrieving projects -merge_request: -author: diff --git a/changelogs/unreleased/remove-old-isobject.yml b/changelogs/unreleased/remove-old-isobject.yml deleted file mode 100644 index 67b18642253..00000000000 --- a/changelogs/unreleased/remove-old-isobject.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove unused code and uses underscore -merge_request: -author: diff --git a/changelogs/unreleased/rename-builds-controller.yml b/changelogs/unreleased/rename-builds-controller.yml deleted file mode 100644 index 7f6872ccf95..00000000000 --- a/changelogs/unreleased/rename-builds-controller.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Change /builds in the URL to /-/jobs. Backward URLs were also added -merge_request: 11407 -author: diff --git a/changelogs/unreleased/replace_spinach_spec_profile_notifications-feature.yml b/changelogs/unreleased/replace_spinach_spec_profile_notifications-feature.yml new file mode 100644 index 00000000000..38227ebfa7a --- /dev/null +++ b/changelogs/unreleased/replace_spinach_spec_profile_notifications-feature.yml @@ -0,0 +1,4 @@ +--- +title: Replace 'profile/notifications.feature' spinach test with an rspec analog +merge_request: 12345 +author: @blackst0ne diff --git a/changelogs/unreleased/rework-authorizations-performance.yml b/changelogs/unreleased/rework-authorizations-performance.yml deleted file mode 100644 index f64257a6f56..00000000000 --- a/changelogs/unreleased/rework-authorizations-performance.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: > - Project authorizations are calculated much faster when using PostgreSQL, and - nested groups support for MySQL has been removed -merge_request: 10885 -author: diff --git a/changelogs/unreleased/search-restrict-projects-to-group.yml b/changelogs/unreleased/search-restrict-projects-to-group.yml deleted file mode 100644 index ac134bc5bce..00000000000 --- a/changelogs/unreleased/search-restrict-projects-to-group.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Restricts search projects dropdown to group projects when group is selected -merge_request: -author: diff --git a/changelogs/unreleased/sh-fix-container-registry-s3-redirects.yml b/changelogs/unreleased/sh-fix-container-registry-s3-redirects.yml deleted file mode 100644 index 1e783811b66..00000000000 --- a/changelogs/unreleased/sh-fix-container-registry-s3-redirects.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Properly handle container registry redirects to fix metadata stored on a S3 backend -merge_request: -author: diff --git a/changelogs/unreleased/sh-fix-refactor-uploader-work-dir.yml b/changelogs/unreleased/sh-fix-refactor-uploader-work-dir.yml deleted file mode 100644 index 255608bd89a..00000000000 --- a/changelogs/unreleased/sh-fix-refactor-uploader-work-dir.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Set artifact working directory to be in the destination store to prevent unnecessary I/O -merge_request: -author: diff --git a/changelogs/unreleased/sync-email-from-omniauth.yml b/changelogs/unreleased/sync-email-from-omniauth.yml deleted file mode 100644 index ed14a95a5f1..00000000000 --- a/changelogs/unreleased/sync-email-from-omniauth.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Sync email address from specified omniauth provider -merge_request: 11268 -author: Robin Bobbitt diff --git a/changelogs/unreleased/task-list-2.yml b/changelogs/unreleased/task-list-2.yml deleted file mode 100644 index cbae8178081..00000000000 --- a/changelogs/unreleased/task-list-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update task_list to version 2.0.0 -merge_request: 11525 -author: Jared Deckard <jared.deckard@gmail.com> diff --git a/changelogs/unreleased/tc-cache-trackable-attributes.yml b/changelogs/unreleased/tc-cache-trackable-attributes.yml deleted file mode 100644 index 4a2cf50893a..00000000000 --- a/changelogs/unreleased/tc-cache-trackable-attributes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Limit User's trackable attributes, like `current_sign_in_at`, to update at most once/hour" -merge_request: 11053 -author: diff --git a/changelogs/unreleased/tc-clean-pending-delete-projects.yml b/changelogs/unreleased/tc-clean-pending-delete-projects.yml deleted file mode 100644 index 31b43999c31..00000000000 --- a/changelogs/unreleased/tc-clean-pending-delete-projects.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add post-deploy migration to clean up projects in `pending_delete` state -merge_request: 11044 -author: diff --git a/changelogs/unreleased/tc-improve-project-api-perf.yml b/changelogs/unreleased/tc-improve-project-api-perf.yml deleted file mode 100644 index 7e88466c058..00000000000 --- a/changelogs/unreleased/tc-improve-project-api-perf.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve performance of ProjectFinder used in /projects API endpoint -merge_request: 11666 -author: diff --git a/changelogs/unreleased/tc-refactor-projects-finder-init-collection.yml b/changelogs/unreleased/tc-refactor-projects-finder-init-collection.yml new file mode 100644 index 00000000000..7bcbd6468c7 --- /dev/null +++ b/changelogs/unreleased/tc-refactor-projects-finder-init-collection.yml @@ -0,0 +1,4 @@ +--- +title: Add User#full_private_access? to check if user has access to all private groups & projects +merge_request: 12373 +author: diff --git a/changelogs/unreleased/up-arrow-focus-discussion-comment.yml b/changelogs/unreleased/up-arrow-focus-discussion-comment.yml deleted file mode 100644 index 5457dab6d3d..00000000000 --- a/changelogs/unreleased/up-arrow-focus-discussion-comment.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix up arrow not editing last discussion comment -merge_request: -author: diff --git a/changelogs/unreleased/update-admin-health-page.yml b/changelogs/unreleased/update-admin-health-page.yml deleted file mode 100644 index 51aa6682b49..00000000000 --- a/changelogs/unreleased/update-admin-health-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added application readiness endpoints to the monitoring health check admin - view -merge_request: -author: diff --git a/changelogs/unreleased/use_relative_path_for_project_avatars.yml b/changelogs/unreleased/use_relative_path_for_project_avatars.yml deleted file mode 100644 index e3d0c0e1187..00000000000 --- a/changelogs/unreleased/use_relative_path_for_project_avatars.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use relative paths for group/project/user avatars -merge_request: 11001 -author: blackst0ne diff --git a/changelogs/unreleased/wait-for-ajax-handling-all-js-requests.yml b/changelogs/unreleased/wait-for-ajax-handling-all-js-requests.yml deleted file mode 100644 index 14aebe792c2..00000000000 --- a/changelogs/unreleased/wait-for-ajax-handling-all-js-requests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use wait_for_requests for both ajax and Vue requests -merge_request: -author: diff --git a/changelogs/unreleased/winh-current-user-filter.yml b/changelogs/unreleased/winh-current-user-filter.yml deleted file mode 100644 index e5409827b31..00000000000 --- a/changelogs/unreleased/winh-current-user-filter.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show current user immediately in issuable filters -merge_request: 11630 -author: diff --git a/changelogs/unreleased/winh-pipeline-author-link.yml b/changelogs/unreleased/winh-pipeline-author-link.yml deleted file mode 100644 index 1b903d1e357..00000000000 --- a/changelogs/unreleased/winh-pipeline-author-link.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Link to commit author user page from pipelines -merge_request: 11100 -author: diff --git a/changelogs/unreleased/winh-styled-people-search-bar.yml b/changelogs/unreleased/winh-styled-people-search-bar.yml deleted file mode 100644 index a088af37d8d..00000000000 --- a/changelogs/unreleased/winh-styled-people-search-bar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Style people in issuable search bar -merge_request: 11402 -author: diff --git a/changelogs/unreleased/zj-clean-up-ci-variables-table.yml b/changelogs/unreleased/zj-clean-up-ci-variables-table.yml deleted file mode 100644 index ea2db40d590..00000000000 --- a/changelogs/unreleased/zj-clean-up-ci-variables-table.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Cleanup ci_variables schema and table -merge_request: -author: diff --git a/changelogs/unreleased/zj-faster-charts-page.yml b/changelogs/unreleased/zj-faster-charts-page.yml new file mode 100644 index 00000000000..9afcf111328 --- /dev/null +++ b/changelogs/unreleased/zj-faster-charts-page.yml @@ -0,0 +1,4 @@ +--- +title: Improve performance of the pipeline charts page +merge_request: 12378 +author: diff --git a/changelogs/unreleased/zj-i18n-pipeline-schedules.yml b/changelogs/unreleased/zj-i18n-pipeline-schedules.yml deleted file mode 100644 index 51c82a16359..00000000000 --- a/changelogs/unreleased/zj-i18n-pipeline-schedules.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow translation of Pipeline Schedules -merge_request: -author: diff --git a/changelogs/unreleased/zj-job-view-goes-real-time.yml b/changelogs/unreleased/zj-job-view-goes-real-time.yml deleted file mode 100644 index 376c9dfa65f..00000000000 --- a/changelogs/unreleased/zj-job-view-goes-real-time.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Job details page update real time -merge_request: 11651 -author: diff --git a/changelogs/unreleased/zj-pipeline-schedule-owner.yml b/changelogs/unreleased/zj-pipeline-schedule-owner.yml deleted file mode 100644 index be704e173ab..00000000000 --- a/changelogs/unreleased/zj-pipeline-schedule-owner.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add foreign key for pipeline schedule owner -merge_request: 11233 -author: diff --git a/changelogs/unreleased/zj-prom-pipeline-count.yml b/changelogs/unreleased/zj-prom-pipeline-count.yml deleted file mode 100644 index 191e4f2f949..00000000000 --- a/changelogs/unreleased/zj-prom-pipeline-count.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add prometheus metrics on pipeline creation -merge_request: -author: diff --git a/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml b/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml deleted file mode 100644 index 57a5f4e44c0..00000000000 --- a/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix etag route not being a match for environments -merge_request: -author: diff --git a/changelogs/unreleased/zj-read-registry-pat.yml b/changelogs/unreleased/zj-read-registry-pat.yml deleted file mode 100644 index d36159bbdf5..00000000000 --- a/changelogs/unreleased/zj-read-registry-pat.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow pulling of container images using personal access tokens -merge_request: 11845 -author: diff --git a/changelogs/unreleased/zj-realtime-env-list.yml b/changelogs/unreleased/zj-realtime-env-list.yml deleted file mode 100644 index 6460d17edc9..00000000000 --- a/changelogs/unreleased/zj-realtime-env-list.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make environment table realtime -merge_request: 11333 -author: diff --git a/changelogs/unreleased/zj-sort-env-folders.yml b/changelogs/unreleased/zj-sort-env-folders.yml deleted file mode 100644 index b3ca97aef94..00000000000 --- a/changelogs/unreleased/zj-sort-env-folders.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Sort folder for environments -merge_request: -author: diff --git a/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb b/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb index 4d6a61bd614..5336b036bca 100644 --- a/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb +++ b/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb @@ -2,6 +2,8 @@ class SetMissingStageOnCiBuilds < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers + disable_ddl_transaction! + def up update_column_in_batches(:ci_builds, :stage, :test) do |table, query| query.where(table[:stage].eq(nil)) diff --git a/db/migrate/20160721081015_drop_and_readd_has_external_wiki_in_projects.rb b/db/migrate/20160721081015_drop_and_readd_has_external_wiki_in_projects.rb index b2a2ce41391..abe8e701e23 100644 --- a/db/migrate/20160721081015_drop_and_readd_has_external_wiki_in_projects.rb +++ b/db/migrate/20160721081015_drop_and_readd_has_external_wiki_in_projects.rb @@ -5,6 +5,8 @@ class DropAndReaddHasExternalWikiInProjects < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:projects, :has_external_wiki, nil) do |table, query| query.where(table[:has_external_wiki].not_eq(nil)) diff --git a/db/migrate/20160901141443_set_confidential_issues_events_on_webhooks.rb b/db/migrate/20160901141443_set_confidential_issues_events_on_webhooks.rb index febd2c0e65e..f8486e3e1a6 100644 --- a/db/migrate/20160901141443_set_confidential_issues_events_on_webhooks.rb +++ b/db/migrate/20160901141443_set_confidential_issues_events_on_webhooks.rb @@ -4,6 +4,8 @@ class SetConfidentialIssuesEventsOnWebhooks < ActiveRecord::Migration DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:web_hooks, :confidential_issues_events, true) do |table, query| query.where(table[:issues_events].eq(true)) diff --git a/db/migrate/20160919144305_add_type_to_labels.rb b/db/migrate/20160919144305_add_type_to_labels.rb index 2d2725ccf59..d08b339cd27 100644 --- a/db/migrate/20160919144305_add_type_to_labels.rb +++ b/db/migrate/20160919144305_add_type_to_labels.rb @@ -5,6 +5,8 @@ class AddTypeToLabels < ActiveRecord::Migration DOWNTIME = true DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.' + disable_ddl_transaction! + def change add_column :labels, :type, :string diff --git a/db/migrate/20161018124658_make_project_owners_masters.rb b/db/migrate/20161018124658_make_project_owners_masters.rb index fe11699c196..cb93b449067 100644 --- a/db/migrate/20161018124658_make_project_owners_masters.rb +++ b/db/migrate/20161018124658_make_project_owners_masters.rb @@ -4,6 +4,8 @@ class MakeProjectOwnersMasters < ActiveRecord::Migration DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:members, :access_level, 40) do |table, query| query.where(table[:access_level].eq(50).and(table[:source_type].eq('Project'))) diff --git a/db/migrate/20161227192806_rename_slack_and_mattermost_notification_services.rb b/db/migrate/20161227192806_rename_slack_and_mattermost_notification_services.rb index c7cada6dfc5..6b15e5caccf 100644 --- a/db/migrate/20161227192806_rename_slack_and_mattermost_notification_services.rb +++ b/db/migrate/20161227192806_rename_slack_and_mattermost_notification_services.rb @@ -4,6 +4,8 @@ class RenameSlackAndMattermostNotificationServices < ActiveRecord::Migration DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:services, :type, 'SlackService') do |table, query| query.where(table[:type].eq('SlackNotificationService')) diff --git a/db/post_migrate/20170309171644_reset_relative_position_for_issue.rb b/db/post_migrate/20170309171644_reset_relative_position_for_issue.rb index b1c9eed1148..01fff680183 100644 --- a/db/post_migrate/20170309171644_reset_relative_position_for_issue.rb +++ b/db/post_migrate/20170309171644_reset_relative_position_for_issue.rb @@ -4,6 +4,8 @@ class ResetRelativePositionForIssue < ActiveRecord::Migration DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:issues, :relative_position, nil) do |table, query| query.where(table[:relative_position].not_eq(nil)) @@ -11,5 +13,6 @@ class ResetRelativePositionForIssue < ActiveRecord::Migration end def down + # noop end end diff --git a/db/post_migrate/20170317162059_update_upload_paths_to_system.rb b/db/post_migrate/20170317162059_update_upload_paths_to_system.rb index 9a77b0bbdfb..ca2912f8dce 100644 --- a/db/post_migrate/20170317162059_update_upload_paths_to_system.rb +++ b/db/post_migrate/20170317162059_update_upload_paths_to_system.rb @@ -7,6 +7,8 @@ class UpdateUploadPathsToSystem < ActiveRecord::Migration DOWNTIME = false AFFECTED_MODELS = %w(User Project Note Namespace Appearance) + disable_ddl_transaction! + def up update_column_in_batches(:uploads, :path, replace_sql(arel_table[:path], base_directory, new_upload_dir)) do |_table, query| query.where(uploads_to_switch_to_new_path) diff --git a/db/post_migrate/20170406142253_migrate_user_project_view.rb b/db/post_migrate/20170406142253_migrate_user_project_view.rb index 22f0f2ac200..c4e910b3b44 100644 --- a/db/post_migrate/20170406142253_migrate_user_project_view.rb +++ b/db/post_migrate/20170406142253_migrate_user_project_view.rb @@ -7,6 +7,8 @@ class MigrateUserProjectView < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = false + disable_ddl_transaction! + def up update_column_in_batches(:users, :project_view, 2) do |table, query| query.where(table[:project_view].eq(0)) diff --git a/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb b/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb index 0a4a2d3867a..f77078ddd70 100644 --- a/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb +++ b/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb @@ -3,6 +3,8 @@ class AddHeadPipelineForEachMergeRequest < ActiveRecord::Migration DOWNTIME = false + disable_ddl_transaction! + def up disable_statement_timeout diff --git a/doc/ci/examples/deployment/composer-npm-deploy.md b/doc/ci/examples/deployment/composer-npm-deploy.md index 8b0d8a003fd..b9f0485290e 100644 --- a/doc/ci/examples/deployment/composer-npm-deploy.md +++ b/doc/ci/examples/deployment/composer-npm-deploy.md @@ -20,12 +20,12 @@ before_script: - php -r "unlink('composer-setup.php');" ``` -This will make sure we have all requirements ready. Next, we want to run `composer update` to fetch all PHP dependencies and `npm install` to load node packages, then run the `npm` script. We need to append them into `before_script` section: +This will make sure we have all requirements ready. Next, we want to run `composer install` to fetch all PHP dependencies and `npm install` to load node packages, then run the `npm` script. We need to append them into `before_script` section: ```yaml before_script: # ... - - php composer.phar update + - php composer.phar install - npm install - npm run deploy ``` @@ -133,7 +133,7 @@ before_script: - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - php composer-setup.php - php -r "unlink('composer-setup.php');" - - php composer.phar update + - php composer.phar install - npm install - npm run deploy - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 41cae58782d..88e53ff40e8 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -155,7 +155,7 @@ Find more information about different Runners in the [Runners](../runners/README.md) documentation. You can find whether any Runners are assigned to your project by going to -**Settings âž” CI/CD Pipelines**. Setting up a Runner is easy and straightforward. The +**Settings âž” Pipelines**. Setting up a Runner is easy and straightforward. The official Runner supported by GitLab is written in Go and its documentation can be found at <https://docs.gitlab.com/runner/>. @@ -168,7 +168,7 @@ Follow the links above to set up your own Runner or use a Shared Runner as described in the next section. Once the Runner has been set up, you should see it on the Runners page of your -project, following **Settings âž” CI/CD Pipelines**. +project, following **Settings âž” Pipelines**. ![Activated runners](img/runners_activated.png) @@ -181,7 +181,7 @@ These are special virtual machines that run on GitLab's infrastructure and can build any project. To enable the **Shared Runners** you have to go to your project's -**Settings âž” CI/CD Pipelines** and click **Enable shared runners**. +**Settings âž” Pipelines** and click **Enable shared runners**. [Read more on Shared Runners](../runners/README.md). diff --git a/doc/development/fe_guide/style_guide_js.md b/doc/development/fe_guide/style_guide_js.md index d2d89517241..ae844fa1051 100644 --- a/doc/development/fe_guide/style_guide_js.md +++ b/doc/development/fe_guide/style_guide_js.md @@ -463,20 +463,24 @@ A forEach will cause side effects, it will be mutating the array being iterated. 1. `destroyed` #### Vue and Boostrap -1. Tooltips: Do not rely on `has-tooltip` class name for vue components +1. Tooltips: Do not rely on `has-tooltip` class name for Vue components ```javascript // bad - <span class="has-tooltip"> + <span + class="has-tooltip" + title="Some tooltip text"> Text </span> // good - <span data-toggle="tooltip"> + <span + v-tooltip + title="Some tooltip text"> Text </span> ``` -1. Tooltips: When using a tooltip, include the tooltip mixin +1. Tooltips: When using a tooltip, include the tooltip directive, `./app/assets/javascripts/vue_shared/directives/tooltip.js` 1. Don't change `data-original-title`. ```javascript diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 643fe5b686b..a3d676433e6 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -95,15 +95,16 @@ installation (e.g. the number of users, projects, etc). We currently support the following databases: - PostgreSQL (highly recommended) -- MySQL/MariaDB (doesn't support all features) +- MySQL/MariaDB (strongly discouraged, not all GitLab features are supported, no support for [MySQL/MariaDB GTID](https://mariadb.com/kb/en/mariadb/gtid/)) -We **highly recommend** the use of PostgreSQL instead of MySQL/MariaDB as not all +We highly recommend the use of PostgreSQL instead of MySQL/MariaDB as not all features of GitLab work with MySQL/MariaDB: 1. MySQL support for subgroups was [dropped with GitLab 9.3][post]. See [issue #30472][30472] for more information. 1. GitLab Geo does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication). 1. [Zero downtime migrations][zero] do not work with MySQL +1. We expect this list to grow over time. Existing users using GitLab with MySQL/MariaDB are advised to [migrate to PostgreSQL](../update/mysql_to_postgresql.md) instead. diff --git a/doc/user/project/pipelines/settings.md b/doc/user/project/pipelines/settings.md index 1d2eba4f74b..a992a348c0f 100644 --- a/doc/user/project/pipelines/settings.md +++ b/doc/user/project/pipelines/settings.md @@ -1,7 +1,7 @@ # Pipelines settings To reach the pipelines settings navigate to your project's -**Settings âž” CI/CD Pipelines**. +**Settings âž” Pipelines**. The following settings can be configured per project. diff --git a/features/profile/notifications.feature b/features/profile/notifications.feature deleted file mode 100644 index ef8743932f5..00000000000 --- a/features/profile/notifications.feature +++ /dev/null @@ -1,15 +0,0 @@ -@profile -Feature: Profile Notifications - Background: - Given I sign in as a user - And I own project "Shop" - - Scenario: I visit notifications tab - When I visit profile notifications page - Then I should see global notifications settings - - @javascript - Scenario: I edit Project Notifications - Given I visit profile notifications page - When I select Mention setting from dropdown - Then I should see Notification saved message diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 25bb374b868..0aedc422563 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -5,7 +5,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps include SharedUser step 'I should see group "Owned"' do - expect(page).to have_content '@owned' + expect(page).to have_content 'Owned' end step 'I am a signed out user' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 80aa3a047a0..9ed4f8ea1f9 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -369,7 +369,6 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps expect(page).to have_content 'Permalink' expect(page).not_to have_content 'Edit' expect(page).not_to have_content 'Blame' - expect(page).not_to have_content 'Annotate' expect(page).to have_content 'Delete' expect(page).to have_content 'Replace' end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 479ee16a611..f1c79970ba4 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -132,8 +132,11 @@ module API return { success: false, message: 'Two-factor authentication is not enabled for this user' } end - codes = user.generate_otp_backup_codes! - user.save! + codes = nil + + ::Users::UpdateService.new(user).execute! do |user| + codes = user.generate_otp_backup_codes! + end { success: true, recovery_codes: codes } end diff --git a/lib/api/notification_settings.rb b/lib/api/notification_settings.rb index 992ea5dc24d..5d113c94b22 100644 --- a/lib/api/notification_settings.rb +++ b/lib/api/notification_settings.rb @@ -34,7 +34,10 @@ module API notification_setting.transaction do new_notification_email = params.delete(:notification_email) - current_user.update(notification_email: new_notification_email) if new_notification_email + if new_notification_email + ::Users::UpdateService.new(current_user, notification_email: new_notification_email).execute + end + notification_setting.update(declared_params(include_missing: false)) end rescue ArgumentError => e # catch level enum error diff --git a/lib/api/users.rb b/lib/api/users.rb index c10e3364382..f9555842daf 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -98,7 +98,7 @@ module API authenticated_as_admin! params = declared_params(include_missing: false) - user = ::Users::CreateService.new(current_user, params).execute + user = ::Users::CreateService.new(current_user, params).execute(skip_authorization: true) if user.persisted? present user, with: Entities::UserPublic @@ -156,7 +156,9 @@ module API user_params[:password_expires_at] = Time.now if user_params[:password].present? - if user.update_attributes(user_params.except(:extern_uid, :provider)) + result = ::Users::UpdateService.new(user, user_params.except(:extern_uid, :provider)).execute + + if result[:status] == :success present user, with: Entities::UserPublic else render_validation_error!(user) @@ -234,9 +236,9 @@ module API user = User.find_by(id: params.delete(:id)) not_found!('User') unless user - email = user.emails.new(declared_params(include_missing: false)) + email = Emails::CreateService.new(user, declared_params(include_missing: false)).execute - if email.save + if email.errors.blank? NotificationService.new.new_email(email) present email, with: Entities::Email else @@ -274,8 +276,7 @@ module API email = user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email - email.destroy - user.update_secondary_emails! + Emails::DestroyService.new(user, email: email.email).execute end desc 'Delete a user. Available only for admins.' do @@ -487,9 +488,9 @@ module API requires :email, type: String, desc: 'The new email' end post "emails" do - email = current_user.emails.new(declared_params) + email = Emails::CreateService.new(current_user, declared_params).execute - if email.save + if email.errors.blank? NotificationService.new.new_email(email) present email, with: Entities::Email else @@ -505,8 +506,7 @@ module API email = current_user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email - email.destroy - current_user.update_secondary_emails! + Emails::DestroyService.new(current_user, email: email.email).execute end desc 'Get a list of user activities' diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb index 6063d6f45e8..872e418c788 100644 --- a/lib/ci/charts.rb +++ b/lib/ci/charts.rb @@ -3,7 +3,7 @@ module Ci module DailyInterval def grouped_count(query) query - .group("DATE(#{Ci::Build.table_name}.created_at)") + .group("DATE(#{Ci::Pipeline.table_name}.created_at)") .count(:created_at) .transform_keys { |date| date.strftime(@format) } end @@ -17,12 +17,12 @@ module Ci def grouped_count(query) if Gitlab::Database.postgresql? query - .group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')") + .group("to_char(#{Ci::Pipeline.table_name}.created_at, '01 Month YYYY')") .count(:created_at) .transform_keys(&:squish) else query - .group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')") + .group("DATE_FORMAT(#{Ci::Pipeline.table_name}.created_at, '01 %M %Y')") .count(:created_at) end end @@ -33,21 +33,21 @@ module Ci end class Chart - attr_reader :labels, :total, :success, :project, :build_times + attr_reader :labels, :total, :success, :project, :pipeline_times def initialize(project) @labels = [] @total = [] @success = [] - @build_times = [] + @pipeline_times = [] @project = project collect end def collect - query = project.builds - .where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from) + query = project.pipelines + .where("? > #{Ci::Pipeline.table_name}.created_at AND #{Ci::Pipeline.table_name}.created_at > ?", @to, @from) totals_count = grouped_count(query) success_count = grouped_count(query.success) @@ -101,14 +101,14 @@ module Ci end end - class BuildTime < Chart + class PipelineTime < Chart def collect commits = project.pipelines.last(30) commits.each do |commit| @labels << commit.short_sha duration = commit.duration || 0 - @build_times << (duration / 60) + @pipeline_times << (duration / 60) end end end diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 60cce9c6d9e..0643c56db9b 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -222,6 +222,12 @@ module Gitlab # # rubocop: disable Metrics/AbcSize def update_column_in_batches(table, column, value) + if transaction_open? + raise 'update_column_in_batches can not be run inside a transaction, ' \ + 'you can disable transactions by calling disable_ddl_transaction! ' \ + 'in the body of your migration class' + end + table = Arel::Table.new(table) count_arel = table.project(Arel.star.count.as('count')) diff --git a/lib/gitlab/dependency_linker/requirements_txt_linker.rb b/lib/gitlab/dependency_linker/requirements_txt_linker.rb index 2e197e5cd94..9c9620bc36a 100644 --- a/lib/gitlab/dependency_linker/requirements_txt_linker.rb +++ b/lib/gitlab/dependency_linker/requirements_txt_linker.rb @@ -6,7 +6,7 @@ module Gitlab private def link_dependencies - link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=;\[]+)/) do |name| + link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=~!;\[]+)/) do |name| "https://pypi.python.org/pypi/#{name}" end diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 54a5b1d31cd..8779577258b 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -16,8 +16,8 @@ module Gitlab def self.allowed?(user) self.open(user) do |access| if access.allowed? - user.last_credential_check_at = Time.now - user.save + Users::UpdateService.new(user, last_credential_check_a: Time.now).execute + true else false diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 7307f8c2c87..b3f453e506d 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -32,7 +32,7 @@ module Gitlab block_after_save = needs_blocking? - gl_user.save! + Users::UpdateService.new(gl_user).execute! gl_user.block if block_after_save diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index 36e5b5041a6..48f3d950779 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -28,7 +28,7 @@ module Gitlab def levels_for_user(user = nil) return [PUBLIC] unless user - if user.admin? + if user.full_private_access? [PRIVATE, INTERNAL, PUBLIC] elsif user.external? [PUBLIC] diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb index 7b3aa0491c7..a5f544b4f92 100644 --- a/spec/controllers/profiles/preferences_controller_spec.rb +++ b/spec/controllers/profiles/preferences_controller_spec.rb @@ -43,7 +43,8 @@ describe Profiles::PreferencesController do dashboard: 'stars' }.with_indifferent_access - expect(user).to receive(:update_attributes).with(prefs) + expect(user).to receive(:assign_attributes).with(prefs) + expect(user).to receive(:save) go params: prefs end @@ -51,7 +52,7 @@ describe Profiles::PreferencesController do context 'on failed update' do it 'sets the flash' do - expect(user).to receive(:update_attributes).and_return(false) + expect(user).to receive(:save).and_return(false) go diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb index 5ad777248ec..56e163ec4d0 100644 --- a/spec/features/groups/group_settings_spec.rb +++ b/spec/features/groups/group_settings_spec.rb @@ -18,14 +18,14 @@ feature 'Edit group settings', feature: true do update_path(new_group_path) visit new_group_full_path expect(current_path).to eq(new_group_full_path) - expect(find('h1.group-title')).to have_content(new_group_path) + expect(find('h1.group-title')).to have_content(group.name) end scenario 'the old group path redirects to the new path' do update_path(new_group_path) visit old_group_full_path expect(current_path).to eq(new_group_full_path) - expect(find('h1.group-title')).to have_content(new_group_path) + expect(find('h1.group-title')).to have_content(group.name) end context 'with a subgroup' do @@ -37,14 +37,14 @@ feature 'Edit group settings', feature: true do update_path(new_group_path) visit new_subgroup_full_path expect(current_path).to eq(new_subgroup_full_path) - expect(find('h1.group-title')).to have_content(subgroup.path) + expect(find('h1.group-title')).to have_content(subgroup.name) end scenario 'the old subgroup path redirects to the new path' do update_path(new_group_path) visit old_subgroup_full_path expect(current_path).to eq(new_subgroup_full_path) - expect(find('h1.group-title')).to have_content(subgroup.path) + expect(find('h1.group-title')).to have_content(subgroup.name) end end diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb index 2d36f3d020f..86c9df5ff86 100644 --- a/spec/features/profiles/password_spec.rb +++ b/spec/features/profiles/password_spec.rb @@ -25,7 +25,7 @@ describe 'Profile > Password', feature: true do end end - it 'does not contains the current password field after an error' do + it 'does not contain the current password field after an error' do fill_passwords('mypassword', 'mypassword2') expect(page).to have_no_field('user[current_password]') diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb new file mode 100644 index 00000000000..e98cec79d87 --- /dev/null +++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +feature 'User visits the notifications tab', js: true do + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + + before do + project.team << [user, :master] + sign_in(user) + visit(profile_notifications_path) + end + + it 'changes the project notifications setting' do + expect(page).to have_content('Notifications') + + first('#notifications-button').trigger('click') + click_link('On mention') + + expect(page).to have_content('On mention') + end +end diff --git a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb index 53c5a52ce3a..d94204230f6 100644 --- a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb +++ b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb @@ -55,7 +55,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, end end - describe 'Click "Annotate" button' do + describe 'Click "Blame" button' do it 'works with no initial line number fragment hash' do visit_blob diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 83883dba0ba..cf4d996a32d 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -151,7 +151,7 @@ feature 'Environments page', :feature, :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(action.name.humanize) - expect { find('.js-manual-action-link').click } + expect { find('.js-manual-action-link').trigger('click') } .not_to change { Ci::Pipeline.count } end diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index 2a82c3ac179..34aef958ec6 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -12,7 +12,7 @@ feature 'user browses project', feature: true, js: true do scenario "can see blame of '.gitignore'" do click_link ".gitignore" - click_link 'Annotate' + click_link 'Blame' expect(page).to have_content "*.rb" expect(page).to have_content "Dmitriy Zaporozhets" diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index a7c06e577a2..84a60ce13fc 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe GroupsHelper do + include ApplicationHelper + describe 'group_icon' do avatar_file_path = File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') @@ -81,4 +83,15 @@ describe GroupsHelper do end end end + + describe 'group_title' do + let(:group) { create(:group) } + let(:nested_group) { create(:group, parent: group) } + let(:deep_nested_group) { create(:group, parent: nested_group) } + let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) } + + it 'outputs the groups in the correct order' do + expect(group_title(very_deep_nested_group)).to match(/>#{group.name}<\/a>.*>#{nested_group.name}<\/a>.*>#{deep_nested_group.name}<\/a>/) + end + end end diff --git a/spec/javascripts/environments/environment_actions_spec.js b/spec/javascripts/environments/environment_actions_spec.js index 596d812c724..ea40a1fcd4b 100644 --- a/spec/javascripts/environments/environment_actions_spec.js +++ b/spec/javascripts/environments/environment_actions_spec.js @@ -32,9 +32,16 @@ describe('Actions Component', () => { }).$mount(); }); + describe('computed', () => { + it('title', () => { + expect(component.title).toEqual('Deploy to...'); + }); + }); + it('should render a dropdown button with icon and title attribute', () => { expect(component.$el.querySelector('.fa-caret-down')).toBeDefined(); - expect(component.$el.querySelector('.dropdown-new').getAttribute('title')).toEqual('Deploy to...'); + expect(component.$el.querySelector('.dropdown-new').getAttribute('data-original-title')).toEqual('Deploy to...'); + expect(component.$el.querySelector('.dropdown-new').getAttribute('aria-label')).toEqual('Deploy to...'); }); it('should render a dropdown with the provided list of actions', () => { diff --git a/spec/javascripts/environments/environment_monitoring_spec.js b/spec/javascripts/environments/environment_monitoring_spec.js index 0f3dba66230..f8d8223967a 100644 --- a/spec/javascripts/environments/environment_monitoring_spec.js +++ b/spec/javascripts/environments/environment_monitoring_spec.js @@ -3,21 +3,30 @@ import monitoringComp from '~/environments/components/environment_monitoring.vue describe('Monitoring Component', () => { let MonitoringComponent; + let component; + + const monitoringUrl = 'https://gitlab.com'; beforeEach(() => { MonitoringComponent = Vue.extend(monitoringComp); - }); - it('should render a link to environment monitoring page', () => { - const monitoringUrl = 'https://gitlab.com'; - const component = new MonitoringComponent({ + component = new MonitoringComponent({ propsData: { monitoringUrl, }, }).$mount(); + }); + describe('computed', () => { + it('title', () => { + expect(component.title).toEqual('Monitoring'); + }); + }); + + it('should render a link to environment monitoring page', () => { expect(component.$el.getAttribute('href')).toEqual(monitoringUrl); expect(component.$el.querySelector('.fa-area-chart')).toBeDefined(); - expect(component.$el.getAttribute('title')).toEqual('Monitoring'); + expect(component.$el.getAttribute('data-original-title')).toEqual('Monitoring'); + expect(component.$el.getAttribute('aria-label')).toEqual('Monitoring'); }); }); diff --git a/spec/javascripts/environments/environment_stop_spec.js b/spec/javascripts/environments/environment_stop_spec.js index 8131f1e5b11..3f95faf466a 100644 --- a/spec/javascripts/environments/environment_stop_spec.js +++ b/spec/javascripts/environments/environment_stop_spec.js @@ -17,8 +17,15 @@ describe('Stop Component', () => { }).$mount(); }); + describe('computed', () => { + it('title', () => { + expect(component.title).toEqual('Stop'); + }); + }); + it('should render a button to stop the environment', () => { expect(component.$el.tagName).toEqual('BUTTON'); - expect(component.$el.getAttribute('title')).toEqual('Stop'); + expect(component.$el.getAttribute('data-original-title')).toEqual('Stop'); + expect(component.$el.getAttribute('aria-label')).toEqual('Stop'); }); }); diff --git a/spec/javascripts/environments/environment_terminal_button_spec.js b/spec/javascripts/environments/environment_terminal_button_spec.js index 858472af4b6..f1576b19d1b 100644 --- a/spec/javascripts/environments/environment_terminal_button_spec.js +++ b/spec/javascripts/environments/environment_terminal_button_spec.js @@ -16,9 +16,16 @@ describe('Stop Component', () => { }).$mount(); }); + describe('computed', () => { + it('title', () => { + expect(component.title).toEqual('Terminal'); + }); + }); + it('should render a link to open a web terminal with the provided path', () => { expect(component.$el.tagName).toEqual('A'); - expect(component.$el.getAttribute('title')).toEqual('Terminal'); + expect(component.$el.getAttribute('data-original-title')).toEqual('Terminal'); + expect(component.$el.getAttribute('aria-label')).toEqual('Terminal'); expect(component.$el.getAttribute('href')).toEqual(terminalPath); }); }); diff --git a/spec/javascripts/issue_show/components/fields/description_spec.js b/spec/javascripts/issue_show/components/fields/description_spec.js index f5b35b1e8b0..df8189d9290 100644 --- a/spec/javascripts/issue_show/components/fields/description_spec.js +++ b/spec/javascripts/issue_show/components/fields/description_spec.js @@ -1,6 +1,8 @@ import Vue from 'vue'; +import eventHub from '~/issue_show/event_hub'; import Store from '~/issue_show/stores'; import descriptionField from '~/issue_show/components/fields/description.vue'; +import { keyboardDownEvent } from '../../helpers'; describe('Description field component', () => { let vm; @@ -18,6 +20,8 @@ describe('Description field component', () => { document.body.appendChild(el); + spyOn(eventHub, '$emit'); + vm = new Component({ el, propsData: { @@ -53,4 +57,20 @@ describe('Description field component', () => { document.activeElement, ).toBe(vm.$refs.textarea); }); + + it('triggers update with meta+enter', () => { + vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, true)); + + expect( + eventHub.$emit, + ).toHaveBeenCalled(); + }); + + it('triggers update with ctrl+enter', () => { + vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, false, true)); + + expect( + eventHub.$emit, + ).toHaveBeenCalled(); + }); }); diff --git a/spec/javascripts/issue_show/components/fields/title_spec.js b/spec/javascripts/issue_show/components/fields/title_spec.js index 53ae038a6a2..a03b462689f 100644 --- a/spec/javascripts/issue_show/components/fields/title_spec.js +++ b/spec/javascripts/issue_show/components/fields/title_spec.js @@ -1,6 +1,8 @@ import Vue from 'vue'; +import eventHub from '~/issue_show/event_hub'; import Store from '~/issue_show/stores'; import titleField from '~/issue_show/components/fields/title.vue'; +import { keyboardDownEvent } from '../../helpers'; describe('Title field component', () => { let vm; @@ -15,6 +17,8 @@ describe('Title field component', () => { }); store.formState.title = 'test'; + spyOn(eventHub, '$emit'); + vm = new Component({ propsData: { formState: store.formState, @@ -27,4 +31,20 @@ describe('Title field component', () => { vm.$el.querySelector('.form-control').value, ).toBe('test'); }); + + it('triggers update with meta+enter', () => { + vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, true)); + + expect( + eventHub.$emit, + ).toHaveBeenCalled(); + }); + + it('triggers update with ctrl+enter', () => { + vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, false, true)); + + expect( + eventHub.$emit, + ).toHaveBeenCalled(); + }); }); diff --git a/spec/javascripts/issue_show/helpers.js b/spec/javascripts/issue_show/helpers.js new file mode 100644 index 00000000000..5d2ced98ae4 --- /dev/null +++ b/spec/javascripts/issue_show/helpers.js @@ -0,0 +1,10 @@ +// eslint-disable-next-line import/prefer-default-export +export const keyboardDownEvent = (code, metaKey = false, ctrlKey = false) => { + const e = new CustomEvent('keydown'); + + e.keyCode = code; + e.metaKey = metaKey; + e.ctrlKey = ctrlKey; + + return e; +}; diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 075b72f35b2..d4e134583c7 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -7,6 +7,10 @@ import '~/commons'; import Vue from 'vue'; import VueResource from 'vue-resource'; +const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent); +Vue.config.devtools = !isHeadlessChrome; +Vue.config.productionTip = false; + Vue.use(VueResource); // enable test fixtures diff --git a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js index f3b4adc0b70..b4c1f70ed1e 100644 --- a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js +++ b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js @@ -22,7 +22,6 @@ describe('Time ago with tooltip component', () => { }).$mount(); expect(vm.$el.tagName).toEqual('TIME'); - expect(vm.$el.classList.contains('js-vue-timeago')).toEqual(true); expect( vm.$el.getAttribute('data-original-title'), ).toEqual(gl.utils.formatDate('2017-05-08T14:57:39.781Z')); diff --git a/spec/javascripts/vue_shared/directives/tooltip_spec.js b/spec/javascripts/vue_shared/directives/tooltip_spec.js new file mode 100644 index 00000000000..b1b3071527b --- /dev/null +++ b/spec/javascripts/vue_shared/directives/tooltip_spec.js @@ -0,0 +1,63 @@ +import Vue from 'vue'; +import tooltip from '~/vue_shared/directives/tooltip'; + +describe('Tooltip directive', () => { + let vm; + + afterEach(() => { + if (vm) { + vm.$destroy(); + } + }); + + describe('with a single tooltip', () => { + beforeEach(() => { + const SomeComponent = Vue.extend({ + directives: { + tooltip, + }, + template: ` + <div + v-tooltip + title="foo"> + </div> + `, + }); + + vm = new SomeComponent().$mount(); + }); + + it('should have tooltip plugin applied', () => { + expect($(vm.$el).data('bs.tooltip')).toBeDefined(); + }); + }); + + describe('with multiple tooltips', () => { + beforeEach(() => { + const SomeComponent = Vue.extend({ + directives: { + tooltip, + }, + template: ` + <div> + <div + v-tooltip + class="js-look-for-tooltip" + title="foo"> + </div> + <div + v-tooltip + title="bar"> + </div> + </div> + `, + }); + + vm = new SomeComponent().$mount(); + }); + + it('should have tooltip plugin applied to all instances', () => { + expect($(vm.$el).find('.js-look-for-tooltip').data('bs.tooltip')).toBeDefined(); + }); + }); +}); diff --git a/spec/lib/ci/charts_spec.rb b/spec/lib/ci/charts_spec.rb index fb6cc398307..51cbfd2a848 100644 --- a/spec/lib/ci/charts_spec.rb +++ b/spec/lib/ci/charts_spec.rb @@ -1,21 +1,21 @@ require 'spec_helper' describe Ci::Charts, lib: true do - context "build_times" do + context "pipeline_times" do let(:project) { create(:empty_project) } - let(:chart) { Ci::Charts::BuildTime.new(project) } + let(:chart) { Ci::Charts::PipelineTime.new(project) } - subject { chart.build_times } + subject { chart.pipeline_times } before do create(:ci_empty_pipeline, project: project, duration: 120) end - it 'returns build times in minutes' do + it 'returns pipeline times in minutes' do is_expected.to contain_exactly(2) end - it 'handles nil build times' do + it 'handles nil pipeline times' do create(:ci_empty_pipeline, project: project, duration: nil) is_expected.to contain_exactly(2, 0) diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 6a0485112c1..4259be3f522 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -262,39 +262,53 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end describe '#update_column_in_batches' do - before do - create_list(:empty_project, 5) - end + context 'when running outside of a transaction' do + before do + expect(model).to receive(:transaction_open?).and_return(false) - it 'updates all the rows in a table' do - model.update_column_in_batches(:projects, :import_error, 'foo') + create_list(:empty_project, 5) + end - expect(Project.where(import_error: 'foo').count).to eq(5) - end + it 'updates all the rows in a table' do + model.update_column_in_batches(:projects, :import_error, 'foo') - it 'updates boolean values correctly' do - model.update_column_in_batches(:projects, :archived, true) + expect(Project.where(import_error: 'foo').count).to eq(5) + end - expect(Project.where(archived: true).count).to eq(5) - end + it 'updates boolean values correctly' do + model.update_column_in_batches(:projects, :archived, true) + + expect(Project.where(archived: true).count).to eq(5) + end + + context 'when a block is supplied' do + it 'yields an Arel table and query object to the supplied block' do + first_id = Project.first.id - context 'when a block is supplied' do - it 'yields an Arel table and query object to the supplied block' do - first_id = Project.first.id + model.update_column_in_batches(:projects, :archived, true) do |t, query| + query.where(t[:id].eq(first_id)) + end - model.update_column_in_batches(:projects, :archived, true) do |t, query| - query.where(t[:id].eq(first_id)) + expect(Project.where(archived: true).count).to eq(1) end + end + + context 'when the value is Arel.sql (Arel::Nodes::SqlLiteral)' do + it 'updates the value as a SQL expression' do + model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1')) - expect(Project.where(archived: true).count).to eq(1) + expect(Project.sum(:star_count)).to eq(2 * Project.count) + end end end - context 'when the value is Arel.sql (Arel::Nodes::SqlLiteral)' do - it 'updates the value as a SQL expression' do - model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1')) + context 'when running inside the transaction' do + it 'raises RuntimeError' do + expect(model).to receive(:transaction_open?).and_return(true) - expect(Project.sum(:star_count)).to eq(2 * Project.count) + expect do + model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1')) + end.to raise_error(RuntimeError) end end end @@ -303,7 +317,9 @@ describe Gitlab::Database::MigrationHelpers, lib: true do context 'outside of a transaction' do context 'when a column limit is not set' do before do - expect(model).to receive(:transaction_open?).and_return(false) + expect(model).to receive(:transaction_open?) + .and_return(false) + .at_least(:once) expect(model).to receive(:transaction).and_yield @@ -810,7 +826,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do let!(:user) { create(:user, name: 'Kathy Alice Aliceson') } it 'replaces the correct part of the string' do - model.update_column_in_batches(:users, :name, model.replace_sql(Arel::Table.new(:users)[:name], 'Alice', 'Eve')) + allow(model).to receive(:transaction_open?).and_return(false) + query = model.replace_sql(Arel::Table.new(:users)[:name], 'Alice', 'Eve') + + model.update_column_in_batches(:users, :name, query) + expect(user.reload.name).to eq('Kathy Eve Aliceson') end end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb index a3ab4e3dd9e..5653cfee686 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase do +describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :truncate do let(:migration) { FakeRenameReservedPathMigrationV1.new } let(:subject) { described_class.new(['the-path'], migration) } diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb index aa63f6f9805..8125dedd3fc 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do +describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :truncate do let(:migration) { FakeRenameReservedPathMigrationV1.new } let(:subject) { described_class.new(['the-path'], migration) } diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb index 9a6ed98898d..802f77ad430 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do +describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :truncate do let(:migration) { FakeRenameReservedPathMigrationV1.new } let(:subject) { described_class.new(['the-path'], migration) } diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb index bdd3af4ad44..1d5e58855c1 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb @@ -13,7 +13,7 @@ shared_examples 'renames child namespaces' do |type| end end -describe Gitlab::Database::RenameReservedPathsMigration::V1 do +describe Gitlab::Database::RenameReservedPathsMigration::V1, :truncate do let(:subject) { FakeRenameReservedPathMigrationV1.new } before do diff --git a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb index 4da8821726c..7e32770f95d 100644 --- a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb @@ -54,6 +54,8 @@ describe Gitlab::DependencyLinker::RequirementsTxtLinker, lib: true do Sphinx>=1.3 docutils>=0.7 markupsafe + pytest~=3.0 + foop!=3.0 CONTENT end @@ -78,6 +80,8 @@ describe Gitlab::DependencyLinker::RequirementsTxtLinker, lib: true do expect(subject).to include(link('Sphinx', 'https://pypi.python.org/pypi/Sphinx')) expect(subject).to include(link('docutils', 'https://pypi.python.org/pypi/docutils')) expect(subject).to include(link('markupsafe', 'https://pypi.python.org/pypi/markupsafe')) + expect(subject).to include(link('pytest', 'https://pypi.python.org/pypi/pytest')) + expect(subject).to include(link('foop', 'https://pypi.python.org/pypi/foop')) end it 'links URLs' do diff --git a/spec/lib/gitlab/visibility_level_spec.rb b/spec/lib/gitlab/visibility_level_spec.rb index 84d2484cc8a..db9d2807be6 100644 --- a/spec/lib/gitlab/visibility_level_spec.rb +++ b/spec/lib/gitlab/visibility_level_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::VisibilityLevel, lib: true do describe '.levels_for_user' do it 'returns all levels for an admin' do - user = double(:user, admin?: true) + user = build(:user, :admin) expect(described_class.levels_for_user(user)) .to eq([Gitlab::VisibilityLevel::PRIVATE, @@ -30,7 +30,7 @@ describe Gitlab::VisibilityLevel, lib: true do end it 'returns INTERNAL and PUBLIC for internal users' do - user = double(:user, admin?: false, external?: false) + user = build(:user) expect(described_class.levels_for_user(user)) .to eq([Gitlab::VisibilityLevel::INTERNAL, @@ -38,7 +38,7 @@ describe Gitlab::VisibilityLevel, lib: true do end it 'returns PUBLIC for external users' do - user = double(:user, admin?: false, external?: true) + user = build(:user, :external) expect(described_class.levels_for_user(user)) .to eq([Gitlab::VisibilityLevel::PUBLIC]) diff --git a/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb b/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb index bd5f85b901d..65bea662b02 100644 --- a/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb +++ b/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20170508170547_add_head_pipeline_for_each_merge_request.rb') -describe AddHeadPipelineForEachMergeRequest do +describe AddHeadPipelineForEachMergeRequest, :truncate do let(:migration) { described_class.new } let!(:project) { create(:empty_project) } diff --git a/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb b/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb index 1db9bc002ae..e3b42b5eac8 100644 --- a/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb +++ b/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20170324160416_migrate_user_activities_to_users_last_activity_on.rb') -describe MigrateUserActivitiesToUsersLastActivityOn, :redis do +describe MigrateUserActivitiesToUsersLastActivityOn, :redis, :truncate do let(:migration) { described_class.new } let!(:user_active_1) { create(:user) } let!(:user_active_2) { create(:user) } diff --git a/spec/migrations/migrate_user_project_view_spec.rb b/spec/migrations/migrate_user_project_view_spec.rb index 70f8e0d6082..afaa5d836a7 100644 --- a/spec/migrations/migrate_user_project_view_spec.rb +++ b/spec/migrations/migrate_user_project_view_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20170406142253_migrate_user_project_view.rb') -describe MigrateUserProjectView do +describe MigrateUserProjectView, :truncate do let(:migration) { described_class.new } let!(:user) { create(:user) } diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 9262ce08987..1e074c7ad26 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -284,6 +284,41 @@ describe CommitStatus, :models do end end + describe '.status' do + context 'when there are multiple statuses present' do + before do + create_status(status: 'running') + create_status(status: 'success') + create_status(allow_failure: true, status: 'failed') + end + + it 'returns a correct compound status' do + expect(described_class.all.status).to eq 'running' + end + end + + context 'when there are only allowed to fail commit statuses present' do + before do + create_status(allow_failure: true, status: 'failed') + end + + it 'returns status that indicates success' do + expect(described_class.all.status).to eq 'success' + end + end + + context 'when using a scope to select latest statuses' do + before do + create_status(name: 'test', retried: true, status: 'failed') + create_status(allow_failure: true, name: 'test', status: 'failed') + end + + it 'returns status according to the scope' do + expect(described_class.latest.status).to eq 'success' + end + end + end + describe '#before_sha' do subject { commit_status.before_sha } diff --git a/spec/models/concerns/has_status_spec.rb b/spec/models/concerns/has_status_spec.rb index 101567998c9..a38f2553eb1 100644 --- a/spec/models/concerns/has_status_spec.rb +++ b/spec/models/concerns/has_status_spec.rb @@ -48,7 +48,7 @@ describe HasStatus do [create(type, status: :failed, allow_failure: true)] end - it { is_expected.to eq 'skipped' } + it { is_expected.to eq 'success' } end context 'success and canceled' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 314f8781867..8e895ec6634 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1733,6 +1733,20 @@ describe User, models: true do end end + describe '#full_private_access?' do + it 'returns false for regular user' do + user = build(:user) + + expect(user.full_private_access?).to be_falsy + end + + it 'returns true for admin user' do + user = build(:user, :admin) + + expect(user.full_private_access?).to be_truthy + end + end + describe '.ghost' do it "creates a ghost user if one isn't already present" do ghost = User.ghost diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 18000d91795..c0174b304c8 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -364,6 +364,7 @@ describe API::Users do it "updates user with new bio" do put api("/users/#{user.id}", admin), { bio: 'new test bio' } + expect(response).to have_http_status(200) expect(json_response['bio']).to eq('new test bio') expect(user.reload.bio).to eq('new test bio') @@ -396,13 +397,22 @@ describe API::Users do it 'updates user with his own email' do put api("/users/#{user.id}", admin), email: user.email + expect(response).to have_http_status(200) expect(json_response['email']).to eq(user.email) expect(user.reload.email).to eq(user.email) end + it 'updates user with a new email' do + put api("/users/#{user.id}", admin), email: 'new@email.com' + + expect(response).to have_http_status(200) + expect(user.reload.notification_email).to eq('new@email.com') + end + it 'updates user with his own username' do put api("/users/#{user.id}", admin), username: user.username + expect(response).to have_http_status(200) expect(json_response['username']).to eq(user.username) expect(user.reload.username).to eq(user.username) @@ -410,12 +420,14 @@ describe API::Users do it "updates user's existing identity" do put api("/users/#{omniauth_user.id}", admin), provider: 'ldapmain', extern_uid: '654321' + expect(response).to have_http_status(200) expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321') end it 'updates user with new identity' do put api("/users/#{user.id}", admin), provider: 'github', extern_uid: 'john' + expect(response).to have_http_status(200) expect(user.reload.identities.first.extern_uid).to eq('john') expect(user.reload.identities.first.provider).to eq('github') @@ -423,12 +435,14 @@ describe API::Users do it "updates admin status" do put api("/users/#{user.id}", admin), { admin: true } + expect(response).to have_http_status(200) expect(user.reload.admin).to eq(true) end it "updates external status" do put api("/users/#{user.id}", admin), { external: true } + expect(response.status).to eq 200 expect(json_response['external']).to eq(true) expect(user.reload.external?).to be_truthy @@ -436,6 +450,7 @@ describe API::Users do it "does not update admin status" do put api("/users/#{admin_user.id}", admin), { can_create_group: false } + expect(response).to have_http_status(200) expect(admin_user.reload.admin).to eq(true) expect(admin_user.can_create_group).to eq(false) @@ -443,6 +458,7 @@ describe API::Users do it "does not allow invalid update" do put api("/users/#{user.id}", admin), { email: 'invalid email' } + expect(response).to have_http_status(400) expect(user.reload.email).not_to eq('invalid email') end @@ -459,6 +475,7 @@ describe API::Users do it "returns 404 for non-existing user" do put api("/users/999999", admin), { bio: 'update should fail' } + expect(response).to have_http_status(404) expect(json_response['message']).to eq('404 User Not Found') end @@ -509,6 +526,7 @@ describe API::Users do it 'returns 409 conflict error if email address exists' do put api("/users/#{@user.id}", admin), email: 'test@example.com' + expect(response).to have_http_status(409) expect(@user.reload.email).to eq(@user.email) end @@ -516,6 +534,7 @@ describe API::Users do it 'returns 409 conflict error if username taken' do @user_id = User.all.last.id put api("/users/#{@user.id}", admin), username: 'test' + expect(response).to have_http_status(409) expect(@user.reload.username).to eq(@user.username) end diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index 1557cb3c938..efcaccc254e 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -62,6 +62,10 @@ describe Ci::ProcessPipelineService, '#execute', :services do fail_running_or_pending expect(builds_statuses).to eq %w(failed pending) + + fail_running_or_pending + + expect(pipeline.reload).to be_success end end diff --git a/spec/services/emails/create_service_spec.rb b/spec/services/emails/create_service_spec.rb new file mode 100644 index 00000000000..c1f477f551e --- /dev/null +++ b/spec/services/emails/create_service_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Emails::CreateService, services: true do + let(:user) { create(:user) } + let(:opts) { { email: 'new@email.com' } } + + subject(:service) { described_class.new(user, opts) } + + describe '#execute' do + it 'creates an email with valid attributes' do + expect { service.execute }.to change { Email.count }.by(1) + expect(Email.where(opts)).not_to be_empty + end + + it 'has the right user association' do + service.execute + + expect(user.emails).to eq(Email.where(opts)) + end + end +end diff --git a/spec/services/emails/destroy_service_spec.rb b/spec/services/emails/destroy_service_spec.rb new file mode 100644 index 00000000000..5e7ab4a40af --- /dev/null +++ b/spec/services/emails/destroy_service_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Emails::DestroyService, services: true do + let!(:user) { create(:user) } + let!(:email) { create(:email, user: user) } + + subject(:service) { described_class.new(user, email: email.email) } + + describe '#execute' do + it 'removes an email' do + expect { service.execute }.to change { user.emails.count }.by(-1) + end + end +end diff --git a/spec/services/users/update_service_spec.rb b/spec/services/users/update_service_spec.rb new file mode 100644 index 00000000000..0b2f840c462 --- /dev/null +++ b/spec/services/users/update_service_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe Users::UpdateService, services: true do + let(:user) { create(:user) } + + describe '#execute' do + it 'updates the name' do + result = update_user(user, name: 'New Name') + + expect(result).to eq(status: :success) + expect(user.name).to eq('New Name') + end + + it 'returns an error result when record cannot be updated' do + expect do + update_user(user, { email: 'invalid' }) + end.not_to change { user.reload.email } + end + + def update_user(user, opts) + described_class.new(user, opts).execute + end + end + + describe '#execute!' do + it 'updates the name' do + result = update_user(user, name: 'New Name') + + expect(result).to be true + expect(user.name).to eq('New Name') + end + + it 'raises an error when record cannot be updated' do + expect do + update_user(user, email: 'invalid') + end.to raise_error(ActiveRecord::RecordInvalid) + end + + def update_user(user, opts) + described_class.new(user, opts).execute! + end + end +end |