diff options
author | Stan Hu <stanhu@gmail.com> | 2018-08-29 10:54:24 -0700 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2018-08-29 10:54:24 -0700 |
commit | 14105b5ee9fe83313f3410dd717836fd36497696 (patch) | |
tree | 8ae8aa434551642126df3089864a05f25abb693e | |
parent | 7e7e52536b876a9381c6efb4d858d3a49d1f9640 (diff) | |
parent | 380c7169cbcc67b4046bc63b62fd1c452c76ad12 (diff) | |
download | gitlab-ce-14105b5ee9fe83313f3410dd717836fd36497696.tar.gz |
Merge branch 'master' into sh-add-object-storage-qa
1134 files changed, 6133 insertions, 3438 deletions
diff --git a/.flayignore b/.flayignore index 4b6f7ba693a..87411516a2a 100644 --- a/.flayignore +++ b/.flayignore @@ -6,6 +6,7 @@ app/controllers/projects/approvers_controller.rb app/controllers/projects/protected_branches/merge_access_levels_controller.rb app/controllers/projects/protected_branches/push_access_levels_controller.rb app/controllers/projects/protected_tags/create_access_levels_controller.rb +app/helpers/system_note_helper.rb app/policies/project_policy.rb app/models/concerns/relative_positioning.rb app/workers/stuck_merge_jobs_worker.rb diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 797a20ef16e..23d71675ae4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -131,7 +131,7 @@ stages: .single-script-job: &single-script-job image: ruby:2.4-alpine before_script: [] - stage: build + stage: test cache: {} dependencies: [] variables: &single-script-job-variables diff --git a/.gitlab/issue_templates/Test plan.md b/.gitlab/issue_templates/Test plan.md new file mode 100644 index 00000000000..580fab206b3 --- /dev/null +++ b/.gitlab/issue_templates/Test plan.md @@ -0,0 +1,96 @@ +# Test Plan + +<!-- This issue outlines testing activities related to a particular issue or epic. + +[Here is an example test plan](https://gitlab.com/gitlab-org/gitlab-ce/issues/50353) + +This and other comments should be removed as you write the plan --> + +## Introduction + +<!-- Briefly outline what is being tested + +Mention the issue(s) this test plan is related to --> + +## Scope + +<!-- State any limits on aspects of the feature being tested +Outline the types of data to be included +Outline the types of tests to be performed (functional, security, performance, +database, automated, etc) --> + +## ACC Matrix + +<!-- Use the matrix below as a template to identify the Attributes, Components, and +Capabilities relevant to the scope of this test plan. Add or remove Attributes +and Components as required and list Capabilities in the next section + +Attributes (columns) are adverbs or adjectives that describe (at a high level) +the qualities testing is meant to ensure Components have. + +Components (rows) are nouns that define major parts of the product being tested. + +Capabilities link Attributes and Components. They are what your product needs to +do to make sure a Component fulfills an Attribute + +For more information see the [Google Testing Blog article about the 10 minute +test plan](https://testing.googleblog.com/2011/09/10-minute-test-plan.html) and +[this wiki page from an open-source tool that implements the ACC +model](https://code.google.com/archive/p/test-analytics/wikis/AccExplained.wiki). --> + +| | Simple | Secure | Responsive | Obvious | Stable | +|------------|:------:|:------:|:----------:|:-------:|:------:| +| Admin | | | | | | +| Groups | | | | | | +| Project | | | | | | +| Repository | | | | | | +| Issues | | | | | | +| MRs | | | | | | +| CI/CD | | | | | | +| Ops | | | | | | +| Registry | | | | | | +| Wiki | | | | | | +| Snippets | | | | | | +| Settings | | | | | | +| Tracking | | | | | | +| API | | | | | | + +## Capabilities + +<!-- Use the ACC matrix above to help you identify Capabilities at each relevant +intersection of Components and Attributes. + +Some features might be simple enough that they only involve one Component, while +more complex features could involve multiple or even all. + +Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353): +* Respository is + * Simple + * It's easy to select the desired file template + * It doesn't require unnecessary actions to save the change + * It's easy to undo the change after selecting a template + * Responsive + * The list of templates can be restricted to allow a user to find a specific template among many + * Once a template is selected the file content updates quickly and smoothly +--> + +## Test Plan + +<!-- If the scope is small enough you may not need to write a list of tests to +perform. It might be enough to use the Capabilities to guide your testing. + +If the feature is more complex, especially if it involves multiple Components, +briefly outline a set of tests here. When identifying tests to perform be sure +to consider risk. Note inherent/known levels of risk so that testing can focus +on high risk areas first. + +New end-to-end and integration tests (Selenium and API) should be added to the +[Test Coverage sheet](https://docs.google.com/spreadsheets/d/1RlLfXGboJmNVIPP9jgFV5sXIACGfdcFq1tKd7xnlb74/) + +Please note if automated tests already exist. + +When adding new automated tests, please keep [testing levels](https://docs.gitlab.com/ce/development/testing_guide/testing_levels.html) +in mind. +--> + +/label ~Quality
\ No newline at end of file diff --git a/.haml-lint.yml b/.haml-lint.yml index 32c7de0fb78..fcdc47af60f 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -70,14 +70,15 @@ linters: enabled: false RuboCop: - enabled: false + enabled: true # These cops are incredibly noisy when it comes to HAML templates, so we # ignore them. ignored_cops: - - Lint/BlockAlignment - - Lint/EndAlignment + - Layout/BlockAlignment + - Layout/EndAlignment - Lint/Void - Metrics/LineLength + - Naming/FileName - Style/AlignParameters - Style/BlockNesting - Style/ElseAlignment @@ -91,6 +92,52 @@ linters: - Style/TrailingWhitespace - Style/WhileUntilModifier + # These cops should eventually get enabled + - Cop/LineBreakAfterGuardClauses + - Cop/LineBreakAroundConditionalBlock + - Cop/ProjectPathHelper + - GitlabSecurity/PublicSend + - Layout/LeadingCommentSpace + - Layout/SpaceAfterColon + - Layout/SpaceAfterComma + - Layout/SpaceAroundOperators + - Layout/SpaceBeforeBlockBraces + - Layout/SpaceBeforeComma + - Layout/SpaceBeforeFirstArg + - Layout/SpaceInsideArrayLiteralBrackets + - Layout/SpaceInsideHashLiteralBraces + - Layout/SpaceInsideStringInterpolation + - Layout/TrailingBlankLines + - Lint/BooleanSymbol + - Lint/LiteralInInterpolation + - Lint/ParenthesesAsGroupedExpression + - Lint/RedundantWithIndex + - Lint/Syntax + - Lint/UselessAssignment + - Metrics/BlockNesting + - Naming/VariableName + - Performance/RedundantMatch + - Performance/StringReplacement + - Rails/Presence + - Rails/RequestReferer + - Style/AndOr + - Style/ColonMethodCall + - Style/ConditionalAssignment + - Style/HashSyntax + - Style/IdenticalConditionalBranches + - Style/NegatedIf + - Style/NestedTernaryOperator + - Style/Not + - Style/ParenthesesAroundCondition + - Style/RedundantParentheses + - Style/SelfAssignment + - Style/Semicolon + - Style/TernaryParentheses + - Style/TrailingCommaInHashLiteral + - Style/UnlessElse + - Style/WordArray + - Style/ZeroLengthPredicate + RubyComments: enabled: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7be28a9ac0e..5e022b7e52b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,288 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 11.2.3 (2018-08-28) + +- No changes. + +## 11.2.2 (2018-08-27) + +### Security (3 changes) + +- Fixed persistent XSS rendering/escaping of diff location lines. +- Adding CSRF protection to Hooks resend action. +- Block link-local addresses in URLBlocker. + + +## 11.2.1 (2018-08-22) + +### Fixed (2 changes) + +- Fix wrong commit count in push event payload. !21338 +- Fix broken Git over HTTP clones with LDAP users. !21352 + +### Performance (1 change) + +- Eliminate unnecessary and duplicate system hook fires. !21337 + + +## 11.2.0 (2018-08-22) + +### Security (5 changes) + +- Bump Gitaly to 0.117.1 for Rouge update. !21277 +- Fix symlink vulnerability in project import. +- Bump rugged to 0.27.4 for security fixes. +- Fixed XSS in branch name in Web IDE. +- Adding CSRF protection to Hooks test action. + +### Removed (1 change) + +- Remove gitlab:user:check_repos, gitlab:check_repo, gitlab:git:prune, gitlab:git:gc, and gitlab:git:repack. !20806 + +### Fixed (81 changes, 26 of them are from the community) + +- Fix namespace move callback behavior, especially to fix Geo replication of namespace moves during certain exceptions. !19297 +- Fix breadcrumbs in Admin/User interface. !19608 (Robin Naundorf) +- Remove changes_count from MR API documentation where necessary. !19745 (Jan Beckmann) +- Fix email confirmation bug when user adds additional email to account. !20084 (muhammadn) +- Add support for daylight savings time to pipleline schedules. !20145 +- Fixing milestone date change when editing. !20279 (Orlando Del Aguila) +- Add missing maximum_timeout parameter. !20355 (gfyoung) +- [Rails5] Fix 'Invalid single-table inheritance type: Group is not a subclass of Gitlab::BackgroundMigration::FixCrossProjectLabelLinks::Namespace'. !20462 (@blackst0ne) +- Rails5 fix mysql milliseconds problem in specs. !20464 (Jasper Maes) +- Update Gemfile.rails5.lock with latest Gemfile.lock changes. !20466 (Jasper Maes) +- Rails5 mysql fix milliseconds problem in pull request importer spec. !20475 (Jasper Maes) +- Rails5 MySQL fix rename_column as part of cleanup_concurrent_column_type_change. !20514 (Jasper Maes) +- Process commits as normal in forks when the upstream project is deleted. !20534 +- Fix project visibility tooltip. !20535 (Jamie Schembri) +- Fix archived parameter for projects API. !20566 (Peter Marko) +- Limit maximum project build timeout setting to 1 month. !20591 +- Fix GitLab project imports not loading due to API timeouts. !20599 +- Avoid process deadlock in popen by consuming input pipes. !20600 +- Disable SAML and Bitbucket if OmniAuth is disabled. !20608 +- Support multiple scopes when authing container registry scopes. !20617 +- Adds the ability to view group milestones on the dashboard milestone page. !20618 +- Allow issues API to receive an internal ID (iid) on create. !20626 (Jamie Schembri) +- Fix typo in CSS transform property for Memory Graph component. !20650 +- Update design for system metrics popovers. !20655 +- Toggle Show / Hide Button for Kubernetes Password. !20659 (gfyoung) +- Board label edit dropdown shows incorrect selected labels summary. !20673 +- Resolve "Unable to save user profile update with Safari". !20676 +- Escape username and password in UrlSanitizer#full_url. !20684 +- Remove background color from card-body style. !20689 (George Tsiolis) +- Update total storage size when changing size of artifacts. !20697 (Peter Marko) +- Rails5 fix user sees revert modal spec. !20706 (Jasper Maes) +- Fix Web IDE crashing on directories named 'blob'. !20712 +- Fix accessing imported pipeline builds. !20713 +- Fixed bug with invalid repository reference using the wiki search. !20722 +- Resolve Copy diff file path as GFM is broken. !20725 +- Chart versions for applications installed by one click install buttons should be version locked. !20765 +- Fix misalignment of broadcast message on login page. !20794 (Robin Naundorf) +- Fix Vue datatype errors for markdownVersion parsing. !20800 +- Fix authorization for interactive web terminals. !20811 +- Increase width of Web IDE sidebar resize handles. !20818 +- Fix new MR card styles. !20822 +- Fix link color in markdown code brackets. !20841 +- Rails5 update Gemfile.rails5.lock. !20858 (Jasper Maes) +- fix height of full-width Metrics charts on large screens. !20866 +- Fix sorting by name on milestones page. !20881 +- Permit concurrent loads in gpg keychain mutex. !20894 (Jasper Maes) +- Prevent editing and updating wiki pages with non UTF-8 encoding via web interface. !20906 +- Retrieve merge request closing issues from database cache. !20911 +- Fix LFS uploads not working with git-lfs 2.5.0. !20923 +- Fix bug setting http headers in Files API. !20938 +- Rails5: fix flaky spec. !20953 (Jasper Maes) +- Fixed list of projects not loading in group boards. !20955 +- Fix autosave and ESC confirmation issues for MR discussions. !20968 +- Fix navigation to First and Next discussion on MR Changes tab. !20968 +- Fix rendering of the context lines in MR diffs page. !20968 +- fix error caused when using the search bar while unauthenticated. !20970 +- Fix GPG status badge loading regressions. !20987 +- Ensure links in notifications footer are not escaped. !21000 +- Rails5: update Rails5 lock for forgotten gem rouge. !21010 (Jasper Maes) +- Fix UI error whereby prometheus application status is updated. !21029 +- Solves group dashboard line height is too tall for group names. !21033 +- Fix rendering of pipeline failure view when directly navigationg to it. !21043 +- Fix missing and duplicates on project milestone listing page. !21058 +- Fix merge requests not showing any diff files for big patches. !21125 +- Auto-DevOps.gitlab-ci.yml: Update glibc package signing key URL. !21182 (sgerrand) +- Fix issue stopping Instance Statistics javascript to be executed. !21211 +- Fix broken JavaScript in IE11. !21214 +- Improve JUnit test reports in merge request widgets. !49966 +- Properly handle colons in URL passwords. +- Renders test reports for resolved failures and resets error state. +- Fix handling of annotated tags when Gitaly is not in use. +- Fix serialization of LegacyDiffNote. +- Escapes milestone and label's names on flash notice when promoting them. +- Allow to toggle notifications for issues due soon. +- Sanitize git URL in import errors. (Jamie Schembri) +- Add missing predefined variable and fix docs. +- Allow updating a project's avatar without other params. (Jamie Schembri) +- Fix the UI for listing system-level labels. +- Update hamlit to fix ruby 2.5 incompatibilities, fixes #42045. (Matthew Dawson) +- Fix updated_at if created_at is set for Note API. +- Fix search bar text input alignment. + +### Changed (32 changes, 7 of them are from the community) + +- Rack attack is now disabled by default. !16669 +- Include full image URL in webhooks for uploaded images. !18109 (Satish Perala) +- Enable hashed storage for all newly created or renamed projects. !19747 +- Support manually stopping any environment from the UI. !20077 +- Close revert and cherry pick modal on escape keypress. !20341 (George Tsiolis) +- Adds with_projects optional parameter to GET /groups/:id API endpoint. !20494 +- Improve feedback when a developer is unable to push to an empty repository. !20519 +- Display GPG status on repository and blob pages. !20524 +- Updated design of new entry dropdown in Web IDE. !20526 +- UX improvements to top nav search bar. !20537 +- Update issue closing pattern. !20554 (George Tsiolis) +- Add merge request header branch actions left margin. !20643 (George Tsiolis) +- Rubix, scikit-learn, tensorflow & other useful libraries pre-installed with JupyterHub. !20714 (Amit Rathi) +- Show decimal place up to single digit in Stacked Progress Bar. !20776 +- Wrap job name on pipeline job sidebar. !20804 (George Tsiolis) +- Redesign Web IDE back button and context header. !20850 +- Removes "show all" on reports and adds an actionButtons slot. !20855 +- Put fallback reply-key address first in the References header. !20871 +- Allow non-admins to view instance statistics (if permitted by the instance admins). !20874 +- Adds the project and group name to the return type for project and group milestones. !20890 +- Restyle status message input on profile settings. !20903 +- Ensure installed Helm Tiller For GitLab Managed Apps Is protected by mutual auth. !20928 +- Allow multiple JIRA transition ids. !20939 +- Use Helm 2.7.2 for GitLab Managed Apps. !20956 +- Create branch and MR picker for Web IDE. !20978 +- Update commit message styles with monospace font and overflow-x. !20988 +- Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes. !20991 +- Update design of project templates. !21012 +- Update to Rouge 3.2.1, which includes a critical fix to the Perl Lexer. !21263 +- Add a 10 ms bucket for SQL timings. +- Show one digit after dot in commit_per_day value in charts page. (msdundar) +- Redesign GCP offer banner. + +### Performance (30 changes, 10 of them are from the community) + +- Stop dynamically creating project and namespace routes. !20313 +- Tracking the number of repositories and wikis with a cached counter for site-wide statistics. !20413 +- Optimize ProjectWiki#empty? check. !20573 +- Delete UserActivities and related workers. !20597 +- Enable frozen string in app/services/**/*.rb. !20656 (gfyoung) +- Enable more frozen string in app/services/**/*.rb. !20677 (gfyoung) +- Limit the TTL for anonymous sessions to 1 hour. !20700 +- Enable even more frozen string in app/services/**/*.rb. !20702 (gfyoung) +- Enable frozen string in app/serializers/**/*.rb. !20726 (gfyoung) +- Enable frozen string in newly added files to previously processed directories. !20763 (gfyoung) +- Use limit parameter to retrieve Wikis from Gitaly. !20764 +- Add Dangerfile for frozen_string_literal. !20767 (gfyoung) +- Remove method instrumentation for Banzai filters and reference parsers. !20770 +- Enable frozen strings in lib/banzai/filter/*.rb. !20775 +- Enable frozen strings in remaining lib/banzai/filter/*.rb files. !20777 +- DNS prefetching if asset_host for CDN hosting is set. !20781 +- Bump nokogiri to 1.8.4 and sanitize to 4.6.6 for performance. !20795 +- Enable frozen string in app/presenters and app/policies. !20819 (gfyoung) +- Bump haml gem to 5.0.4. !20847 +- Enable frozen string in app/models/*.rb. !20851 (gfyoung) +- Performing Commit GPG signature calculation in bulk. !20870 +- Fix /admin/jobs failing to load due to statement timeout. !20909 +- refactor pipeline job log animation to reduce CPU usage. !20915 +- Improve performance when fetching collapsed diffs and commenting in merge requests. !20940 +- Enable frozen string for app/models/**/*.rb. !21001 (gfyoung) +- Don't set gon variables in JSON requests. !21016 (Peter Leitzen) +- Improve performance and memory footprint of Changes tab of Merge Requests. !21028 +- Avoid N+1 on MRs page when metrics merging date cannot be found. !21053 +- Bump Gitaly to 0.117.0. !21055 +- Access metadata directly from Object Storage. + +### Added (41 changes, 18 of them are from the community) + +- Show repository languages for projects. !19480 +- Adds API endpoint /api/v4/(project/group)/:id/members/all to list also inherited members. !19748 (Jacopo Beschi @jacopo-beschi) +- Added live preview for JavaScript projects in the Web IDE. !19764 +- Add support for SSH certificate authentication. !19911 (Ævar Arnfjörð Bjarmason) +- Add Hangouts Chat integration. !20290 (Kukovskii Vladimir) +- Add ability to import multiple repositories by uploading a manifest file. !20304 +- Show Project ID on project home panel. !20305 (Tuğçe Nur Taş) +- Add an option to have a private profile on GitLab. !20387 (jxterry) +- Extend gitlab-ci.yml to request junit.xml test reports. !20390 +- Add the first mutations for merge requests to GraphQL. !20443 +- Add /-/health basic health check endpoint. !20456 +- Add filter for minimal access level in groups and projects API. !20478 (Marko, Peter) +- Add download button for single file (including raw files) in repository. !20480 (Kia Mei Somabes) +- Gitaly Servers link into Admin > Overview navigation menu. !20550 +- Adds foreign key to notification_settings.user_id. !20567 (Jacopo Beschi @jacopo-beschi) +- JUnit XML Test Summary In MR widget. !20576 +- Cleans up display of Deploy Tokens to match Personal Access Tokens. !20578 (Marcel Amirault) +- Users can set a status message and emoji. !20614 (niedermyer & davamr) +- Add emails delivery Prometheus metrics. !20638 +- Verify runner feature set. !20664 +- Add more comprehensive metrics tracking authentication activity. !20668 +- Add support for tar.gz AUTO_DEVOPS_CHART charts (#49324). !20691 (@kondi1) +- Adds Vuex store for reports section in MR widget. !20709 +- Redirect commits to root if no ref is provided (31576). !20738 (Kia Mei Somabes) +- Search for labels by title or description on project labels page. !20749 +- Add object storage logic to project import. !20773 +- Enable renaming files and folders in Web IDE. !20835 +- Warn user when reload IDE with staged changes. !20857 +- Add local project uploads cleanup task. !20863 +- Improve error message when adding invalid user to a project. !20885 (Jacopo Beschi @jacopo-beschi) +- Add link to homepage on static http status pages (404, 500, etc). !20898 (Jason Funk) +- Clean orphaned files in object storage. !20918 +- Adds frontend support to render test reports on the MR widget. !20936 +- Trigger system hooks when project is archived/unarchived. !20995 +- Custom Wiki Sidebar Support Issue 14995. (Josh Sooter) +- Emails on push recipients now accepts formats like John Doe <johndoe@example.com>. (George Thomas) +- Add new model for tracking label events. +- Improve danger confirmation modals by focusing input field. (Jamie Schembri) +- Clicking CI icon in Web IDE now opens up pipelines panel. +- Enabled deletion of files in the Web IDE. +- Added button to regenerate 2FA codes. (Luke Picciau) + +### Other (26 changes, 7 of them are from the community) + +- Update specific runners help URL. !20213 (George Tsiolis) +- Enable frozen string in apps/uploaders/*.rb. !20401 (gfyoung) +- Update docs of Helm Tiller. !20515 (Takuya Noguchi) +- Persist 'Auto DevOps' banner dismissal globally. !20540 +- Move xterm to a node dependency and remove it from vendor's folder. !20588 +- Upgrade grape-path-helpers to 1.0.6. !20601 +- Delete todos when user loses access to read the target. !20665 +- Remove tooltips from commit author avatar and name in commit lists. !20674 +- Allow cloning LFS repositories through DeployTokens. !20729 +- Replace 'Sidekiq::Testing.inline!' with 'perform_enqueued_jobs'. !20768 (@blackst0ne) +- Replace author_link snake case in stylesheets, specs, and helpers. !20797 (George Tsiolis) +- Replace snake case in SCSS variables. !20799 (George Tsiolis) +- Add rbtrace to Gemfile. !20831 +- Add support for searching users by confirmed e-mails. !20893 +- Changes poll.js to keep polling on any 2xx http status code. !20904 +- Remove todos of users without access to targets migration. !20927 +- Improve and simplify Auto DevOps settings flow. !20946 +- Keep admin settings sections open after submitting forms. !21040 +- CE port of "List groups with developer maintainer access on project creation". !21051 +- Update git rerere link in docs. !21060 (gfyoung) +- Add 'tabindex' attribute support on Icon component to show BS4 popover on trigger type 'focus'. !21066 +- Add a Gitlab::Profiler.print_by_total_time convenience method for profiling from a Rails console. +- Automatically expand runner's settings block when linking to the runner's settings page. +- Increases title column on modal for reports. +- Disables toggle comments button if diff has no discussions. +- Moves help_popover component to a common location. + + +## 11.1.6 (2018-08-28) + +- No changes. + +## 11.1.5 (2018-08-27) + +### Security (3 changes) + +- Fixed persistent XSS rendering/escaping of diff location lines. +- Adding CSRF protection to Hooks resend action. +- Block link-local addresses in URLBlocker. + +### Fixed (1 change, 1 of them is from the community) + +- Sanitize git URL in import errors. (Jamie Schembri) + + ## 11.1.4 (2018-07-30) ### Fixed (4 changes, 1 of them is from the community) @@ -284,6 +566,19 @@ entry. - Use monospaced font for MR diff commit link ref on GFM. +## 11.0.6 (2018-08-27) + +### Security (3 changes) + +- Fixed persistent XSS rendering/escaping of diff location lines. +- Adding CSRF protection to Hooks resend action. +- Block link-local addresses in URLBlocker. + +### Fixed (1 change, 1 of them is from the community) + +- Sanitize git URL in import errors. (Jamie Schembri) + + ## 11.0.5 (2018-07-26) ### Security (4 changes) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb7c0c88629..1b9e9d4a5a3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -314,7 +314,7 @@ This [documentation](doc/development/contributing/merge_request_workflow.md) has ## Definition of done -This [documentation](doc/development/contributing/merge_request_workflow.md)) has been moved. +This [documentation](doc/development/contributing/merge_request_workflow.md) has been moved. ## Style guides @@ -116,14 +116,14 @@ gem 'dropzonejs-rails', '~> 0.7.1' # for backups gem 'fog-aws', '~> 2.0.1' gem 'fog-core', '~> 1.44' -gem 'fog-google', '~> 1.3.3' +gem 'fog-google', '~> 1.7.1' gem 'fog-local', '~> 0.3' gem 'fog-openstack', '~> 0.1' gem 'fog-rackspace', '~> 0.1.1' gem 'fog-aliyun', '~> 0.2.0' # for Google storage -gem 'google-api-client', '~> 0.19.8' +gem 'google-api-client', '~> 0.23' # for aws storage gem 'unf', '~> 0.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 15a105579fb..77effb63d2e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -239,11 +239,11 @@ GEM builder excon (~> 0.58) formatador (~> 0.2) - fog-google (1.3.3) + fog-google (1.7.1) fog-core fog-json fog-xml - google-api-client (~> 0.19.1) + google-api-client (~> 0.23.0) fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) @@ -329,7 +329,7 @@ GEM actionpack (>= 3.0) multi_json request_store (>= 1.0) - google-api-client (0.19.8) + google-api-client (0.23.4) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.5, < 0.7.0) httpclient (>= 2.8.1, < 3.0) @@ -738,7 +738,7 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - retriable (3.1.1) + retriable (3.1.2) rinku (2.0.0) rotp (2.1.2) rouge (3.2.1) @@ -1031,7 +1031,7 @@ DEPENDENCIES fog-aliyun (~> 0.2.0) fog-aws (~> 2.0.1) fog-core (~> 1.44) - fog-google (~> 1.3.3) + fog-google (~> 1.7.1) fog-local (~> 0.3) fog-openstack (~> 0.1) fog-rackspace (~> 0.1.1) @@ -1051,7 +1051,7 @@ DEPENDENCIES gitlab-styles (~> 2.4) gitlab_omniauth-ldap (~> 2.0.4) gon (~> 6.2) - google-api-client (~> 0.19.8) + google-api-client (~> 0.23) google-protobuf (= 3.5.1) gpgme grape (~> 1.0) diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock index 7803d12c6b4..63b450d3f62 100644 --- a/Gemfile.rails5.lock +++ b/Gemfile.rails5.lock @@ -126,7 +126,7 @@ GEM numerizer (~> 0.1.1) chunky_png (1.3.5) citrus (3.0.2) - coderay (1.1.1) + coderay (1.1.2) coercible (1.0.0) descendants_tracker (~> 0.0.1) commonmarker (0.17.8) @@ -242,11 +242,11 @@ GEM builder excon (~> 0.58) formatador (~> 0.2) - fog-google (1.3.3) + fog-google (1.7.1) fog-core fog-json fog-xml - google-api-client (~> 0.19.1) + google-api-client (~> 0.23.0) fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) @@ -332,7 +332,7 @@ GEM actionpack (>= 3.0) multi_json request_store (>= 1.0) - google-api-client (0.19.8) + google-api-client (0.23.4) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.5, < 0.7.0) httpclient (>= 2.8.1, < 3.0) @@ -495,7 +495,7 @@ GEM memoist (0.16.0) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) - method_source (0.8.2) + method_source (0.9.0) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) @@ -638,12 +638,11 @@ GEM unparser procto (0.0.3) prometheus-client-mmap (0.9.4) - pry (0.10.4) + pry (0.11.3) coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - pry-byebug (3.4.2) - byebug (~> 9.0) + method_source (~> 0.9.0) + pry-byebug (3.4.3) + byebug (>= 9.0, < 9.1) pry (~> 0.10) pry-rails (0.3.5) pry (>= 0.9.10) @@ -748,10 +747,10 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - retriable (3.1.1) + retriable (3.1.2) rinku (2.0.0) rotp (2.1.2) - rouge (3.2.0) + rouge (3.2.1) rqrcode (0.7.0) chunky_png rqrcode-rails3 (0.1.7) @@ -817,7 +816,7 @@ GEM rubyzip (1.2.1) rufus-scheduler (3.4.0) et-orbi (~> 1.0) - rugged (0.27.2) + rugged (0.27.4) safe_yaml (1.0.4) sanitize (4.6.6) crass (~> 1.0.2) @@ -878,7 +877,6 @@ GEM simplecov-html (~> 0.10.0) simplecov-html (0.10.0) slack-notifier (1.5.1) - slop (3.6.0) spring (2.0.1) activesupport (>= 4.2) spring-commands-rspec (1.0.4) @@ -1043,7 +1041,7 @@ DEPENDENCIES fog-aliyun (~> 0.2.0) fog-aws (~> 2.0.1) fog-core (~> 1.44) - fog-google (~> 1.3.3) + fog-google (~> 1.7.1) fog-local (~> 0.3) fog-openstack (~> 0.1) fog-rackspace (~> 0.1.1) @@ -1063,7 +1061,7 @@ DEPENDENCIES gitlab-styles (~> 2.4) gitlab_omniauth-ldap (~> 2.0.4) gon (~> 6.2) - google-api-client (~> 0.19.8) + google-api-client (~> 0.23) google-protobuf (= 3.5.1) gpgme grape (~> 1.0) @@ -1 +1 @@ -11.2.0-pre +11.3.0-pre diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 25fe2ae553e..cd800d75f7a 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -15,6 +15,7 @@ const Api = { mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes', mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions', groupLabelsPath: '/groups/:namespace_path/-/labels', + templatesPath: '/api/:version/templates/:key', licensePath: '/api/:version/templates/licenses/:key', gitignorePath: '/api/:version/templates/gitignores/:key', gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key', @@ -265,6 +266,12 @@ const Api = { }); }, + templates(key, params = {}) { + const url = Api.buildUrl(this.templatesPath).replace(':key', key); + + return axios.get(url, { params }); + }, + buildUrl(url) { let urlRoot = ''; if (gon.relative_url_root != null) { diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index e34db893989..5b0c4285339 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -109,8 +109,6 @@ export class AwardsHandler { } const $menu = $(`.${this.menuClass}`); - const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent(); - const $userAuthored = this.isUserAuthored($addBtn); if ($menu.length) { if ($menu.is('.is-visible')) { $addBtn.removeClass('is-active'); @@ -134,9 +132,6 @@ export class AwardsHandler { }, 200); }); } - - $thumbsBtn.toggleClass('disabled', $userAuthored); - $thumbsBtn.prop('disabled', $userAuthored); } // Create the emoji menu with the first category of emojis. @@ -364,10 +359,6 @@ export class AwardsHandler { return $emojiButton.hasClass('active'); } - isUserAuthored($button) { - return $button.hasClass('js-user-authored'); - } - decrementCounter($emojiButton, emoji) { const counter = $('.js-counter', $emojiButton); const counterNumber = parseInt(counter.text(), 10); @@ -474,20 +465,16 @@ export class AwardsHandler { } postEmoji($emojiButton, awardUrl, emoji, callback) { - if (this.isUserAuthored($emojiButton)) { - this.userAuthored($emojiButton); - } else { - axios - .post(awardUrl, { - name: emoji, - }) - .then(({ data }) => { - if (data.ok) { - callback(); - } - }) - .catch(() => flash(__('Something went wrong on our end.'))); - } + axios + .post(awardUrl, { + name: emoji, + }) + .then(({ data }) => { + if (data.ok) { + callback(); + } + }) + .catch(() => flash(__('Something went wrong on our end.'))); } findEmojiIcon(votesBlock, emoji) { diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js new file mode 100644 index 00000000000..43237a29466 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js @@ -0,0 +1,82 @@ +import Api from '~/api'; +import { __ } from '~/locale'; +import * as types from './mutation_types'; + +export const requestTemplateTypes = ({ commit }) => commit(types.REQUEST_TEMPLATE_TYPES); +export const receiveTemplateTypesError = ({ commit, dispatch }) => { + commit(types.RECEIVE_TEMPLATE_TYPES_ERROR); + dispatch( + 'setErrorMessage', + { + text: __('Error loading template types.'), + action: () => + dispatch('fetchTemplateTypes').then(() => + dispatch('setErrorMessage', null, { root: true }), + ), + actionText: __('Please try again'), + }, + { root: true }, + ); +}; +export const receiveTemplateTypesSuccess = ({ commit }, templates) => + commit(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, templates); + +export const fetchTemplateTypes = ({ dispatch, state }) => { + if (!Object.keys(state.selectedTemplateType).length) return Promise.reject(); + + dispatch('requestTemplateTypes'); + + return Api.templates(state.selectedTemplateType.key) + .then(({ data }) => dispatch('receiveTemplateTypesSuccess', data)) + .catch(() => dispatch('receiveTemplateTypesError')); +}; + +export const setSelectedTemplateType = ({ commit }, type) => + commit(types.SET_SELECTED_TEMPLATE_TYPE, type); + +export const receiveTemplateError = ({ dispatch }, template) => { + dispatch( + 'setErrorMessage', + { + text: __('Error loading template.'), + action: payload => + dispatch('fetchTemplateTypes', payload).then(() => + dispatch('setErrorMessage', null, { root: true }), + ), + actionText: __('Please try again'), + actionPayload: template, + }, + { root: true }, + ); +}; + +export const fetchTemplate = ({ dispatch, state }, template) => { + if (template.content) { + return dispatch('setFileTemplate', template); + } + + return Api.templates(`${state.selectedTemplateType.key}/${template.key || template.name}`) + .then(({ data }) => { + dispatch('setFileTemplate', data); + }) + .catch(() => dispatch('receiveTemplateError', template)); +}; + +export const setFileTemplate = ({ dispatch, commit, rootGetters }, template) => { + dispatch( + 'changeFileContent', + { path: rootGetters.activeFile.path, content: template.content }, + { root: true }, + ); + commit(types.SET_UPDATE_SUCCESS, true); +}; + +export const undoFileTemplate = ({ dispatch, commit, rootGetters }) => { + const file = rootGetters.activeFile; + + dispatch('changeFileContent', { path: file.path, content: file.raw }, { root: true }); + commit(types.SET_UPDATE_SUCCESS, false); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js new file mode 100644 index 00000000000..38318fd49bf --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js @@ -0,0 +1,23 @@ +export const templateTypes = () => [ + { + name: '.gitlab-ci.yml', + key: 'gitlab_ci_ymls', + }, + { + name: '.gitignore', + key: 'gitignores', + }, + { + name: 'LICENSE', + key: 'licenses', + }, + { + name: 'Dockerfile', + key: 'dockerfiles', + }, +]; + +export const showFileTemplatesBar = (_, getters) => name => + getters.templateTypes.find(t => t.name === name); + +export default () => {}; diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/index.js b/app/assets/javascripts/ide/stores/modules/file_templates/index.js new file mode 100644 index 00000000000..dfa5ef54413 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/index.js @@ -0,0 +1,12 @@ +import createState from './state'; +import * as actions from './actions'; +import * as getters from './getters'; +import mutations from './mutations'; + +export default { + namespaced: true, + actions, + state: createState(), + getters, + mutations, +}; diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js b/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js new file mode 100644 index 00000000000..cf4499c0264 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js @@ -0,0 +1,7 @@ +export const REQUEST_TEMPLATE_TYPES = 'REQUEST_TEMPLATE_TYPES'; +export const RECEIVE_TEMPLATE_TYPES_ERROR = 'RECEIVE_TEMPLATE_TYPES_ERROR'; +export const RECEIVE_TEMPLATE_TYPES_SUCCESS = 'RECEIVE_TEMPLATE_TYPES_SUCCESS'; + +export const SET_SELECTED_TEMPLATE_TYPE = 'SET_SELECTED_TEMPLATE_TYPE'; + +export const SET_UPDATE_SUCCESS = 'SET_UPDATE_SUCCESS'; diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js new file mode 100644 index 00000000000..e413e61eaaa --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js @@ -0,0 +1,21 @@ +/* eslint-disable no-param-reassign */ +import * as types from './mutation_types'; + +export default { + [types.REQUEST_TEMPLATE_TYPES](state) { + state.isLoading = true; + }, + [types.RECEIVE_TEMPLATE_TYPES_ERROR](state) { + state.isLoading = false; + }, + [types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, templates) { + state.isLoading = false; + state.templates = templates; + }, + [types.SET_SELECTED_TEMPLATE_TYPE](state, type) { + state.selectedTemplateType = type; + }, + [types.SET_UPDATE_SUCCESS](state, success) { + state.updateSuccess = success; + }, +}; diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/state.js b/app/assets/javascripts/ide/stores/modules/file_templates/state.js new file mode 100644 index 00000000000..bd4b7d7bc52 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/file_templates/state.js @@ -0,0 +1,6 @@ +export default () => ({ + isLoading: false, + templates: [], + selectedTemplateType: {}, + updateSuccess: false, +}); diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index 56a8d9430c7..0347f803757 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -146,13 +146,7 @@ export default { staged: false, prevPath: '', moved: false, - lastCommit: Object.assign(state.entries[file.path].lastCommit, { - id: lastCommit.commit.id, - url: lastCommit.commit_path, - message: lastCommit.commit.message, - author: lastCommit.commit.author_name, - updatedAt: lastCommit.commit.authored_date, - }), + lastCommitSha: lastCommit.commit.id, }); if (prevPath) { diff --git a/app/assets/javascripts/jobs/components/environments_block.vue b/app/assets/javascripts/jobs/components/environments_block.vue new file mode 100644 index 00000000000..ca6386595c7 --- /dev/null +++ b/app/assets/javascripts/jobs/components/environments_block.vue @@ -0,0 +1,118 @@ +<script> + import _ from 'underscore'; + import CiIcon from '~/vue_shared/components/ci_icon.vue'; + import { sprintf, __ } from '../../locale'; + + export default { + components: { + CiIcon, + }, + props: { + deploymentStatus: { + type: Object, + required: true, + }, + }, + computed: { + environment() { + let environmentText; + switch (this.deploymentStatus.status) { + case 'latest': + environmentText = sprintf( + __('This job is the most recent deployment to %{link}.'), + { link: this.environmentLink }, + false, + ); + break; + case 'out_of_date': + if (this.hasLastDeployment) { + environmentText = sprintf( + __( + 'This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}.', + ), + { + environmentLink: this.environmentLink, + deploymentLink: this.deploymentLink, + }, + false, + ); + } else { + environmentText = sprintf( + __('This job is an out-of-date deployment to %{environmentLink}.'), + { environmentLink: this.environmentLink }, + false, + ); + } + + break; + case 'failed': + environmentText = sprintf( + __('The deployment of this job to %{environmentLink} did not succeed.'), + { environmentLink: this.environmentLink }, + false, + ); + break; + case 'creating': + if (this.hasLastDeployment) { + environmentText = sprintf( + __( + 'This job is creating a deployment to %{environmentLink} and will overwrite the last %{deploymentLink}.', + ), + { + environmentLink: this.environmentLink, + deploymentLink: this.deploymentLink, + }, + false, + ); + } else { + environmentText = sprintf( + __('This job is creating a deployment to %{environmentLink}.'), + { environmentLink: this.environmentLink }, + false, + ); + } + break; + default: + break; + } + return environmentText; + }, + environmentLink() { + return sprintf( + '%{startLink}%{name}%{endLink}', + { + startLink: `<a href="${this.deploymentStatus.environment.path}">`, + name: _.escape(this.deploymentStatus.environment.name), + endLink: '</a>', + }, + false, + ); + }, + deploymentLink() { + return sprintf( + '%{startLink}%{name}%{endLink}', + { + startLink: `<a href="${this.lastDeployment.path}">`, + name: _.escape(this.lastDeployment.name), + endLink: '</a>', + }, + false, + ); + }, + hasLastDeployment() { + return this.deploymentStatus.environment.last_deployment; + }, + lastDeployment() { + return this.deploymentStatus.environment.last_deployment; + }, + }, + }; +</script> +<template> + <div class="prepend-top-default js-environment-container"> + <div class="environment-information"> + <ci-icon :status="deploymentStatus.icon" /> + <p v-html="environment"></p> + </div> + </div> +</template> diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue index 225d9f18612..e111d3b9ac2 100644 --- a/app/assets/javascripts/notes/components/note_awards_list.vue +++ b/app/assets/javascripts/notes/components/note_awards_list.vue @@ -82,29 +82,17 @@ export default { getAwardHTML(name) { return glEmojiTag(name); }, - getAwardClassBindings(awardList, awardName) { + getAwardClassBindings(awardList) { return { active: this.hasReactionByCurrentUser(awardList), - disabled: !this.canInteractWithEmoji(awardList, awardName), + disabled: !this.canInteractWithEmoji(), }; }, - canInteractWithEmoji(awardList, awardName) { - let isAllowed = true; - const restrictedEmojis = ['thumbsup', 'thumbsdown']; - - // Users can not add :+1: and :-1: to their own notes - if ( - this.getUserData.id === this.noteAuthorId && - restrictedEmojis.indexOf(awardName) > -1 - ) { - isAllowed = false; - } - - return this.getUserData.id && isAllowed; + canInteractWithEmoji() { + return this.getUserData.id; }, hasReactionByCurrentUser(awardList) { - return awardList.filter(award => award.user.id === this.getUserData.id) - .length; + return awardList.filter(award => award.user.id === this.getUserData.id).length; }, awardTitle(awardsList) { const hasReactionByCurrentUser = this.hasReactionByCurrentUser( @@ -197,7 +185,7 @@ export default { v-tooltip v-for="(awardList, awardName, index) in groupedAwards" :key="index" - :class="getAwardClassBindings(awardList, awardName)" + :class="getAwardClassBindings(awardList)" :title="awardTitle(awardList)" class="btn award-control" data-boundary="viewport" diff --git a/app/assets/javascripts/pages/groups/milestones/show/index.js b/app/assets/javascripts/pages/groups/milestones/show/index.js index 74cc4ba42c1..ebaea5ef3dc 100644 --- a/app/assets/javascripts/pages/groups/milestones/show/index.js +++ b/app/assets/javascripts/pages/groups/milestones/show/index.js @@ -1,8 +1,10 @@ import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show'; +import initDeleteMilestoneModal from '~/pages/milestones/shared/delete_milestone_modal_init'; + import Milestone from '~/milestone'; document.addEventListener('DOMContentLoaded', () => { initMilestonesShow(); - + initDeleteMilestoneModal(); Milestone.initDeprecationMessage(); }); diff --git a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue index 4061c11ba8f..48668562f09 100644 --- a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue +++ b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue @@ -40,8 +40,8 @@ if (this.issueCount === 0 && this.mergeRequestCount === 0) { return sprintf( s__(`Milestones| -You’re about to permanently delete the milestone %{milestoneTitle} from this project. -%{milestoneTitle} is not currently used in any issues or merge requests.`), +You’re about to permanently delete the milestone %{milestoneTitle}. +This milestone is not currently used in any issues or merge requests.`), { milestoneTitle, }, @@ -51,7 +51,7 @@ You’re about to permanently delete the milestone %{milestoneTitle} from this p return sprintf( s__(`Milestones| -You’re about to permanently delete the milestone %{milestoneTitle} from this project and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. +You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered.`), { milestoneTitle, diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js index 949219a0837..aea7b649c20 100644 --- a/app/assets/javascripts/pages/profiles/show/index.js +++ b/app/assets/javascripts/pages/profiles/show/index.js @@ -3,15 +3,22 @@ import createFlash from '~/flash'; import GfmAutoComplete from '~/gfm_auto_complete'; import EmojiMenu from './emoji_menu'; +const defaultStatusEmoji = 'speech_balloon'; + document.addEventListener('DOMContentLoaded', () => { const toggleEmojiMenuButtonSelector = '.js-toggle-emoji-menu'; const toggleEmojiMenuButton = document.querySelector(toggleEmojiMenuButtonSelector); const statusEmojiField = document.getElementById('js-status-emoji-field'); const statusMessageField = document.getElementById('js-status-message-field'); - const findNoEmojiPlaceholder = () => document.getElementById('js-no-emoji-placeholder'); + const toggleNoEmojiPlaceholder = (isVisible) => { + const placeholderElement = document.getElementById('js-no-emoji-placeholder'); + placeholderElement.classList.toggle('hidden', !isVisible); + }; + + const findStatusEmoji = () => toggleEmojiMenuButton.querySelector('gl-emoji'); const removeStatusEmoji = () => { - const statusEmoji = toggleEmojiMenuButton.querySelector('gl-emoji'); + const statusEmoji = findStatusEmoji(); if (statusEmoji) { statusEmoji.remove(); } @@ -19,7 +26,7 @@ document.addEventListener('DOMContentLoaded', () => { const selectEmojiCallback = (emoji, emojiTag) => { statusEmojiField.value = emoji; - findNoEmojiPlaceholder().classList.add('hidden'); + toggleNoEmojiPlaceholder(false); removeStatusEmoji(); toggleEmojiMenuButton.innerHTML += emojiTag; }; @@ -29,7 +36,7 @@ document.addEventListener('DOMContentLoaded', () => { statusEmojiField.value = ''; statusMessageField.value = ''; removeStatusEmoji(); - findNoEmojiPlaceholder().classList.remove('hidden'); + toggleNoEmojiPlaceholder(true); }); const emojiAutocomplete = new GfmAutoComplete(); @@ -44,6 +51,23 @@ document.addEventListener('DOMContentLoaded', () => { selectEmojiCallback, ); emojiMenu.bindEvents(); + + const defaultEmojiTag = Emoji.glEmojiTag(defaultStatusEmoji); + statusMessageField.addEventListener('input', () => { + const hasStatusMessage = statusMessageField.value.trim() !== ''; + const statusEmoji = findStatusEmoji(); + if (hasStatusMessage && statusEmoji) { + return; + } + + if (hasStatusMessage) { + toggleNoEmojiPlaceholder(false); + toggleEmojiMenuButton.innerHTML += defaultEmojiTag; + } else if (statusEmoji.dataset.name === defaultStatusEmoji) { + toggleNoEmojiPlaceholder(true); + removeStatusEmoji(); + } + }); }) .catch(() => createFlash('Failed to load emoji list!')); }); diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js index 41880d27516..6e5ef0ac0b2 100644 --- a/app/assets/javascripts/performance_bar/index.js +++ b/app/assets/javascripts/performance_bar/index.js @@ -1,5 +1,4 @@ import Vue from 'vue'; -import Flash from '../flash'; import PerformanceBarService from './services/performance_bar_service'; import PerformanceBarStore from './stores/performance_bar_store'; @@ -46,7 +45,8 @@ export default ({ container }) => this.store.addRequestDetails(requestId, res.data.data); }) .catch(() => - Flash(`Error getting performance bar results for ${requestId}`), + // eslint-disable-next-line no-console + console.warn(`Error getting performance bar results for ${requestId}`), ); }, }, diff --git a/app/assets/javascripts/performance_bar/services/performance_bar_service.js b/app/assets/javascripts/performance_bar/services/performance_bar_service.js index bc71911ae35..60d9ba62570 100644 --- a/app/assets/javascripts/performance_bar/services/performance_bar_service.js +++ b/app/assets/javascripts/performance_bar/services/performance_bar_service.js @@ -11,13 +11,10 @@ export default class PerformanceBarService { static registerInterceptor(peekUrl, callback) { const interceptor = response => { - const requestId = response.headers['x-request-id']; - // Get the request URL from response.config for Axios, and response for - // Vue Resource. - const requestUrl = (response.config || response).url; - const cachedResponse = response.headers['x-gitlab-from-cache'] === 'true'; + const [fireCallback, requestId, requestUrl] = + PerformanceBarService.callbackParams(response, peekUrl); - if (requestUrl !== peekUrl && requestId && !cachedResponse) { + if (fireCallback) { callback(requestId, requestUrl); } @@ -38,4 +35,16 @@ export default class PerformanceBarService { vueResourceInterceptor, ); } + + static callbackParams(response, peekUrl) { + const requestId = response.headers && response.headers['x-request-id']; + // Get the request URL from response.config for Axios, and response for + // Vue Resource. + const requestUrl = (response.config || response).url; + const apiRequest = requestUrl && requestUrl.match(/^\/api\//); + const cachedResponse = response.headers && response.headers['x-gitlab-from-cache'] === 'true'; + const fireCallback = requestUrl !== peekUrl && requestId && !apiRequest && !cachedResponse; + + return [fireCallback, requestId, requestUrl]; + } } 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 8487c8036ee..2ad66f4fe86 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -1,6 +1,5 @@ <script> import $ from 'jquery'; -import _ from 'underscore'; import JobNameComponent from './job_name_component.vue'; import JobComponent from './job_component.vue'; import tooltip from '../../../vue_shared/directives/tooltip'; @@ -47,7 +46,7 @@ export default { computed: { tooltipText() { - return _.escape(`${this.job.name} - ${this.job.status.label}`); + return `${this.job.name} - ${this.job.status.label}`; }, }, diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index 66f95147193..9ac16b7e541 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -1,5 +1,4 @@ <script> -import _ from 'underscore'; import ActionComponent from './action_component.vue'; import JobNameComponent from './job_name_component.vue'; import tooltip from '../../../vue_shared/directives/tooltip'; @@ -62,7 +61,7 @@ export default { const textBuilder = []; if (this.job.name) { - textBuilder.push(_.escape(this.job.name)); + textBuilder.push(this.job.name); } if (this.job.name && this.status.tooltip) { @@ -106,7 +105,6 @@ export default { :class="cssClassJobName" :data-boundary="tooltipBoundary" data-container="body" - data-html="true" class="js-pipeline-graph-job-link" > @@ -122,7 +120,6 @@ export default { :title="tooltipText" :class="cssClassJobName" class="js-job-component-tooltip non-details-job-component" - data-html="true" data-container="body" > diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue index 804822a3ea8..29b347824de 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue @@ -330,7 +330,7 @@ export default { <pipelines-artifacts-component v-if="pipeline.details.artifacts.length" :artifacts="pipeline.details.artifacts" - class="d-none d-sm-none d-md-block" + class="d-md-block" /> <loading-button diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue index 21f21232596..d530ab2767b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue @@ -1,5 +1,6 @@ <script> import Icon from '~/vue_shared/components/icon.vue'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import timeagoMixin from '../../vue_shared/mixins/timeago'; import tooltip from '../../vue_shared/directives/tooltip'; import LoadingButton from '../../vue_shared/components/loading_button.vue'; @@ -16,6 +17,7 @@ export default { MemoryUsage, StatusIcon, Icon, + TooltipOnTruncate, }, directives: { tooltip, @@ -88,14 +90,20 @@ export default { <span> Deployed to </span> - <a - :href="deployment.url" - target="_blank" - rel="noopener noreferrer nofollow" - class="deploy-link js-deploy-meta" + <tooltip-on-truncate + :title="deployment.name" + truncate-target="child" + class="deploy-link label-truncate" > - {{ deployment.name }} - </a> + <a + :href="deployment.url" + target="_blank" + rel="noopener noreferrer nofollow" + class="js-deploy-meta" + > + {{ deployment.name }} + </a> + </tooltip-on-truncate> </template> <span v-tooltip diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue index a4c2289c590..72bd28ae03f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue @@ -1,18 +1,17 @@ <script> -import tooltip from '~/vue_shared/directives/tooltip'; -import { n__ } from '~/locale'; +import _ from 'underscore'; +import { n__, s__, sprintf } from '~/locale'; import { mergeUrlParams, webIDEUrl } from '~/lib/utils/url_utility'; import Icon from '~/vue_shared/components/icon.vue'; import clipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; export default { name: 'MRWidgetHeader', - directives: { - tooltip, - }, components: { Icon, clipboardButton, + TooltipOnTruncate, }, props: { mr: { @@ -24,8 +23,12 @@ export default { shouldShowCommitsBehindText() { return this.mr.divergedCommitsCount > 0; }, - commitsText() { - return n__('%d commit behind', '%d commits behind', this.mr.divergedCommitsCount); + commitsBehindText() { + return sprintf(s__('mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch'), { + commitsBehindLinkStart: `<a href="${_.escape(this.mr.targetBranchPath)}">`, + commitsBehind: n__('%d commit behind', '%d commits behind', this.mr.divergedCommitsCount), + commitsBehindLinkEnd: '</a>', + }, false); }, branchNameClipboardData() { // This supports code in app/assets/javascripts/copy_to_clipboard.js that @@ -36,12 +39,6 @@ export default { gfm: `\`${this.mr.sourceBranch}\``, }); }, - isSourceBranchLong() { - return this.isBranchTitleLong(this.mr.sourceBranch); - }, - isTargetBranchLong() { - return this.isBranchTitleLong(this.mr.targetBranch); - }, webIdePath() { return mergeUrlParams({ target_project: this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath ? @@ -49,11 +46,6 @@ export default { }, webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`)); }, }, - methods: { - isBranchTitleLong(branchTitle) { - return branchTitle.length > 32; - }, - }, }; </script> <template> @@ -65,30 +57,21 @@ export default { <div class="normal"> <strong> {{ s__("mrWidget|Request to merge") }} - <span - :class="{ 'label-truncated': isSourceBranchLong }" - :title="isSourceBranchLong ? mr.sourceBranch : ''" - :v-tooltip="isSourceBranchLong" - class="label-branch js-source-branch" - data-placement="bottom" + <tooltip-on-truncate + :title="mr.sourceBranch" + truncate-target="child" + class="label-branch label-truncate js-source-branch" v-html="mr.sourceBranchLink" - > - </span> - - <clipboard-button + /><clipboard-button :text="branchNameClipboardData" :title="__('Copy branch name to clipboard')" css-class="btn-default btn-transparent btn-clipboard" /> - {{ s__("mrWidget|into") }} - - <span - :v-tooltip="isTargetBranchLong" - :class="{ 'label-truncatedtooltip': isTargetBranchLong }" - :title="isTargetBranchLong ? mr.targetBranch : ''" - class="label-branch" - data-placement="bottom" + <tooltip-on-truncate + :title="mr.targetBranch" + truncate-target="child" + class="label-branch label-truncate" > <a :href="mr.targetBranchTreePath" @@ -96,15 +79,13 @@ export default { > {{ mr.targetBranch }} </a> - </span> + </tooltip-on-truncate> </strong> <div v-if="shouldShowCommitsBehindText" class="diverged-commits-count" + v-html="commitsBehindText" > - <span class="monospace">{{ mr.sourceBranch }}</span> - is {{ commitsText }} - <span class="monospace">{{ mr.targetBranch }}</span> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index 4a3fd01fa39..fee41b239e8 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -3,6 +3,7 @@ import PipelineStage from '~/pipelines/components/stage.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; import Icon from '~/vue_shared/components/icon.vue'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; export default { name: 'MRWidgetPipeline', @@ -10,6 +11,7 @@ export default { PipelineStage, CiIcon, Icon, + TooltipOnTruncate, }, props: { pipeline: { @@ -30,6 +32,10 @@ export default { type: String, required: false, }, + sourceBranch: { + type: String, + required: false, + }, }, computed: { hasPipeline() { @@ -107,11 +113,12 @@ export default { > {{ pipeline.commit.short_id }}</a> on - <span - class="label-branch" + <tooltip-on-truncate + :title="sourceBranch" + truncate-target="child" + class="label-branch label-truncate" v-html="sourceBranchLink" - > - </span> + /> </template> </div> <div diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 80593d1f34a..dc6be025f11 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -254,6 +254,7 @@ export default { :pipeline="mr.pipeline" :ci-status="mr.ciStatus" :has-ci="mr.hasCI" + :source-branch="mr.sourceBranch" :source-branch-link="mr.sourceBranchLink" /> <deployment diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue index f44d361c47e..78fde463507 100644 --- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue +++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue @@ -71,7 +71,11 @@ export default { }, methods: { getPercent(count) { - return roundOffFloat((count / this.totalCount) * 100, 1); + const percent = roundOffFloat((count / this.totalCount) * 100, 1); + if (percent > 0 && percent < 1) { + return '< 1'; + } + return percent; }, barStyle(percent) { return `width: ${percent}%;`; diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue new file mode 100644 index 00000000000..125826da6c3 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue @@ -0,0 +1,67 @@ +<script> +import _ from 'underscore'; +import tooltip from '../directives/tooltip'; + +export default { + directives: { + tooltip, + }, + props: { + title: { + type: String, + required: false, + default: '', + }, + placement: { + type: String, + required: false, + default: 'top', + }, + truncateTarget: { + type: [String, Function], + required: false, + default: '', + }, + }, + data() { + return { + showTooltip: false, + }; + }, + mounted() { + const target = this.selectTarget(); + + if (target && target.scrollWidth > target.offsetWidth) { + this.showTooltip = true; + } + }, + methods: { + selectTarget() { + if (_.isFunction(this.truncateTarget)) { + return this.truncateTarget(this.$el); + } else if (this.truncateTarget === 'child') { + return this.$el.childNodes[0]; + } + + return this.$el; + }, + }, +}; +</script> + +<template> + <span + v-tooltip + v-if="showTooltip" + :title="title" + :data-placement="placement" + class="js-show-tooltip" + > + <slot></slot> + </span> + <span + v-else + > + <slot></slot> + </span> +</template> diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index e8e707cf90c..c91f5e279ea 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -4,11 +4,11 @@ $text-color: $gl-text-color; -$brand-primary: $gl-primary; -$brand-success: $gl-success; -$brand-info: $gl-info; -$brand-warning: $gl-warning; -$brand-danger: $gl-danger; +$brand-primary: $blue-500; +$brand-success: $green-500; +$brand-info: $blue-500; +$brand-warning: $orange-500; +$brand-danger: $red-500; $border-radius-base: 3px !default; diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index 4c7c399a3ca..9dd0384a228 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -8,7 +8,7 @@ float: left; margin-right: 15px; border-radius: $avatar-radius; - border: 1px solid $avatar-border; + border: 1px solid $gray-normal; &.s16 { @include avatar-size(16px, 6px); } &.s18 { @include avatar-size(18px, 6px); } &.s19 { @include avatar-size(19px, 6px); } @@ -36,7 +36,7 @@ width: 40px; height: 40px; padding: 0; - background: $avatar-background; + background: $gray-lightest; overflow: hidden; &.avatar-inline { @@ -62,7 +62,7 @@ } &:not([href]):hover { - border-color: darken($avatar-border, 10%); + border-color: darken($gray-normal, 10%); } } @@ -70,7 +70,7 @@ text-align: center; vertical-align: top; color: $identicon-fg-color; - background-color: $identicon-gray; + background-color: $gray-darker; // Sizes &.s16 { font-size: 12px; line-height: 1.33; } @@ -94,7 +94,7 @@ &.bg4 { background-color: $identicon-blue; } &.bg5 { background-color: $identicon-teal; } &.bg6 { background-color: $identicon-orange; } - &.bg7 { background-color: $identicon-gray; } + &.bg7 { background-color: $gray-darker; } } .avatar-container { @@ -122,7 +122,7 @@ .avatar-counter { background-color: $gray-darkest; color: $white-light; - border: 1px solid $avatar-border; + border: 1px solid $gray-normal; border-radius: 1em; font-family: $regular-font; font-size: 9px; diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss index 57df9b969c3..c6060161dec 100644 --- a/app/assets/stylesheets/framework/badges.scss +++ b/app/assets/stylesheets/framework/badges.scss @@ -1,6 +1,6 @@ .badge.badge-pill { font-weight: $gl-font-weight-normal; background-color: $badge-bg; - color: $badge-color; + color: $gl-text-color-secondary; vertical-align: baseline; } diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 0dc7aa4ef68..72b4ed0ac33 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -452,14 +452,14 @@ } .btn-missing { - color: $notes-light-color; + color: $gl-text-color-secondary; border: 1px dashed $border-gray-normal-dashed; border-radius: $border-radius-default; &:hover, &:active, &:focus { - color: $notes-light-color; + color: $gl-text-color-secondary; background-color: $white-normal; } } diff --git a/app/assets/stylesheets/framework/callout.scss b/app/assets/stylesheets/framework/callout.scss index 1bd94c0acba..bdd7f09d926 100644 --- a/app/assets/stylesheets/framework/callout.scss +++ b/app/assets/stylesheets/framework/callout.scss @@ -25,25 +25,25 @@ /* Variations */ .bs-callout-danger { - background-color: $callout-danger-bg; - border-color: $callout-danger-border; - color: $callout-danger-color; + background-color: $red-100; + border-color: $red-200; + color: $red-700; } .bs-callout-warning { - background-color: $callout-warning-bg; - border-color: $callout-warning-border; - color: $callout-warning-color; + background-color: $orange-100; + border-color: $orange-200; + color: $orange-700; } .bs-callout-info { - background-color: $callout-info-bg; - border-color: $callout-info-border; - color: $callout-info-color; + background-color: $blue-100; + border-color: $blue-200; + color: $blue-700; } .bs-callout-success { - background-color: $callout-success-bg; - border-color: $callout-success-border; - color: $callout-success-color; + background-color: $green-100; + border-color: $green-200; + color: $green-700; } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 79ca6e61e9a..72e27f9ad16 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -1,8 +1,8 @@ /** COLORS **/ -.cgray { color: $common-gray; } +.cgray { color: $gl-text-color; } .clgray { color: $common-gray-light; } -.cred { color: $common-red; } -.cgreen { color: $common-green; } +.cred { color: $red-500; } +.cgreen { color: $green-600; } .cdark { color: $common-gray-dark; } .text-plain, @@ -44,10 +44,10 @@ } .hint { font-style: italic; color: $hint-color; } -.light { color: $common-gray; } +.light { color: $gl-text-color; } .slead { - color: $common-gray; + color: $gl-text-color; font-size: 14px; margin-bottom: 12px; font-weight: $gl-font-weight-normal; @@ -352,7 +352,7 @@ img.emoji { border-color: $border-color !important; .dz-upload { - background: $gl-success !important; + background: $green-500 !important; } } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 83bc3776178..8a224dc517e 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -147,7 +147,7 @@ } @mixin dropdown-item-hover { - background-color: $dropdown-item-hover-bg; + background-color: $gray-darker; color: $gl-text-color; outline: 0; @@ -195,7 +195,7 @@ text-decoration: none; .badge.badge-pill { - background-color: darken($dropdown-link-hover-bg, 5%); + background-color: darken($blue-50, 5%); } } @@ -233,7 +233,7 @@ font-weight: $gl-font-weight-normal; padding: 8px 0; background-color: $white-light; - border: 1px solid $dropdown-border-color; + border: 1px solid $border-color; border-radius: $border-radius-base; box-shadow: 0 2px 4px $dropdown-shadow-color; @@ -874,7 +874,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu { overflow-y: auto; li.section-empty.section-failure { - color: $callout-danger-color; + color: $red-700; } .frequent-items-list-item-container a { diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss index cad915bc86f..85cabf43e9e 100644 --- a/app/assets/stylesheets/framework/feature_highlight.scss +++ b/app/assets/stylesheets/framework/feature_highlight.scss @@ -72,11 +72,11 @@ .feature-highlight-popover { width: 240px; padding: 0; - border: 1px solid $dropdown-border-color; + border: 1px solid $border-color; box-shadow: 0 2px 4px $dropdown-shadow-color; &.right > .arrow { - border-right-color: $dropdown-border-color; + border-right-color: $border-color; } .popover-body { diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 3bdf5bfc93a..1d3512bbb4c 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -312,11 +312,11 @@ span.idiff { text-decoration: none; .new-file { - color: $notify-new-file; + color: $green-600; } .deleted-file { - color: $notify-deleted-file; + color: $red-700; } } } diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 9b09ed0ed0a..abfe350677e 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -206,7 +206,7 @@ &.focus, &.focus:hover { border-color: $blue-300; - box-shadow: 0 0 4px $search-input-focus-shadow-color; + box-shadow: 0 0 4px $dropdown-input-focus-shadow; } gl-emoji { diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index a70eece8f68..afd888af672 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -8,7 +8,7 @@ input { input[type='text'].danger { background: $input-danger-bg !important; - border-color: $input-danger-border; + border-color: $red-400; text-shadow: 0 1px 1px $white-light; } diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index e7e13d35d8e..11a30d83f03 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -554,7 +554,7 @@ float: left; margin-right: 5px; border-radius: 50%; - border: 1px solid $avatar-border; + border: 1px solid $gray-normal; } .with-performance-bar .navbar-gitlab { diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss index d1f7ff4438b..f002edced8a 100644 --- a/app/assets/stylesheets/framework/icons.scss +++ b/app/assets/stylesheets/framework/icons.scss @@ -11,7 +11,7 @@ .ci-status-icon-failed { svg { - fill: $gl-danger; + fill: $red-500; } &.add-border { diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss index da5f80d9d37..2d672e62e08 100644 --- a/app/assets/stylesheets/framework/issue_box.scss +++ b/app/assets/stylesheets/framework/issue_box.scss @@ -26,12 +26,12 @@ &.status-box-closed, &.status-box-mr-closed { - background-color: $gl-danger; + background-color: $red-500; } &.status-box-issue-closed, &.status-box-mr-merged { - background-color: $gl-primary; + background-color: $blue-500; } &.status-box-open { diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index 88d2f0aaf85..3ae2c7078d6 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -58,7 +58,7 @@ .select2-drop.select2-drop-above { box-shadow: 0 2px 4px $dropdown-shadow-color; border-radius: $border-radius-base; - border: 1px solid $dropdown-border-color; + border: 1px solid $border-color; min-width: 175px; color: $gl-text-color; z-index: 999; @@ -69,7 +69,7 @@ } .select2-drop.select2-drop-above.select2-drop-active { - border-top: 1px solid $dropdown-border-color; + border-top: 1px solid $border-color; margin-top: -6px; } @@ -193,7 +193,7 @@ color: $gl-text-color; .select2-result-label { - background: $dropdown-item-hover-bg; + background: $gray-darker; } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 96508a71bd8..2781d910b8d 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -297,19 +297,9 @@ $tanuki-yellow: #fca326; /* * State colors: */ -$gl-primary: $blue-500; -$gl-success: $green-500; -$gl-success-focus: rgba($gl-success, 0.4); -$gl-info: $blue-500; -$gl-warning: $orange-500; -$gl-danger: $red-500; +$green-500-focus: rgba($green-500, 0.4); $gl-btn-active-background: rgba(0, 0, 0, 0.16); $gl-btn-active-gradient: inset 0 2px 3px $gl-btn-active-background; -// Bootstrap override states -$success: $gl-success; -$info: $gl-info; -$warning: $gl-warning; -$danger: $gl-danger; /* * Commit Diff Colors @@ -329,10 +319,9 @@ $line-select-yellow-dark: #f0e2bd; $dark-diff-match-bg: rgba(255, 255, 255, 0.3); $dark-diff-match-color: rgba(255, 255, 255, 0.1); $file-mode-changed: #777; -$file-mode-changed: #777; -$diff-image-info-color: grey; +$diff-image-info-color: gray; $diff-swipe-border: #999; -$diff-view-modes-color: grey; +$diff-view-modes-color: gray; $diff-view-modes-border: #c1c1c1; $diff-jagged-border-gradient-color: darken($white-normal, 8%); @@ -352,9 +341,7 @@ $dropdown-min-height: 40px; $dropdown-max-height: 312px; $dropdown-vertical-offset: 4px; $dropdown-link-color: #555; -$dropdown-link-hover-bg: $blue-50; $dropdown-empty-row-bg: rgba(#000, 0.04); -$dropdown-border-color: $border-color; $dropdown-shadow-color: rgba(#000, 0.1); $dropdown-divider-color: rgba(#000, 0.1); $dropdown-title-btn-color: #bfbfbf; @@ -364,7 +351,6 @@ $dropdown-input-focus-shadow: rgba($blue-300, 0.4); $dropdown-loading-bg: rgba(#fff, 0.6); $dropdown-chevron-size: 10px; $dropdown-toggle-active-border-color: darken($border-color, 14%); -$dropdown-item-hover-bg: $gray-darker; $dropdown-fade-mask-height: 32px; $dropdown-member-form-control-width: 163px; @@ -372,7 +358,6 @@ $dropdown-member-form-control-width: 163px; * Filtered Search */ $filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09); -$dropdown-hover-color: $blue-400; /* * Contextual Sidebar @@ -387,7 +372,7 @@ $sidebar-milestone-toggle-bottom-margin: 10px; * Buttons */ $btn-active-gray: #ececec; -$btn-active-gray-light: e4e7ed; +$btn-active-gray-light: #e4e7ed; $btn-white-active: #848484; $gl-btn-padding: 10px; $gl-btn-line-height: 16px; @@ -398,7 +383,6 @@ $gl-btn-horz-padding: 12px; * Badges */ $badge-bg: rgba(0, 0, 0, 0.07); -$badge-color: $gl-text-color-secondary; /* * Pagination @@ -406,21 +390,12 @@ $badge-color: $gl-text-color-secondary; $pagination-padding-y: 6px; $pagination-padding-x: 16px; $pagination-line-height: 20px; -$pagination-border-color: $border-color; -$pagination-active-bg: $blue-600; -$pagination-active-border-color: $blue-600; -$pagination-hover-bg: $blue-50; -$pagination-hover-border-color: $border-color; -$pagination-hover-color: $gl-text-color; $pagination-disabled-color: #cdcdcd; -$pagination-disabled-bg: $gray-light; -$pagination-disabled-border-color: $border-color; /* * Status icons */ $status-icon-size: 22px; -$status-icon-margin: $gl-btn-padding; /* * Award emoji @@ -433,16 +408,13 @@ $award-emoji-positive-add-lines: #bb9c13; * Search Box */ $search-input-border-color: rgba($blue-400, 0.8); -$search-input-focus-shadow-color: $dropdown-input-focus-shadow; $search-input-width: 240px; $search-input-active-width: 320px; -$location-badge-active-bg: $blue-500; $location-icon-color: #e7e9ed; /* * Notes */ -$notes-light-color: $gl-text-color-secondary; $note-disabled-comment-color: #b2b2b2; $note-targe3-outside: #fffff0; $note-targe3-inside: #ffffd3; @@ -463,7 +435,6 @@ $identicon-indigo: #e8eaf6; $identicon-blue: #e3f2fd; $identicon-teal: #e0f2f1; $identicon-orange: #fbe9e7; -$identicon-gray: $gray-darker; $identicon-fg-color: #555555; /* @@ -479,7 +450,6 @@ $calendar-user-contrib-text: #959494; $cycle-analytics-box-padding: 30px; $cycle-analytics-box-text-color: #8c8c8c; $cycle-analytics-big-font: 19px; -$cycle-analytics-dark-text: $gl-text-color; $cycle-analytics-light-gray: #bfbfbf; $cycle-analytics-dismiss-icon-color: #b2b2b2; @@ -507,9 +477,6 @@ $issue-board-list-difference-md: $issue-board-list-difference-sm + $issue-boards * Avatar */ $avatar-radius: 50%; -$avatar-border: $gray-normal; -$avatar-border-hover: $gray-darker; -$avatar-background: $gray-lightest; $gl-avatar-size: 40px; /* @@ -525,22 +492,6 @@ $blame-blue: #254e77; $builds-trace-bg: #111; /* -* Callout -*/ -$callout-danger-bg: $red-100; -$callout-danger-border: $red-200; -$callout-danger-color: $red-700; -$callout-warning-bg: $orange-100; -$callout-warning-border: $orange-200; -$callout-warning-color: $orange-700; -$callout-info-bg: $blue-100; -$callout-info-border: $blue-200; -$callout-info-color: $blue-700; -$callout-success-bg: $green-100; -$callout-success-border: $green-200; -$callout-success-color: $green-700; - -/* * Commit Page */ $commit-max-width-marker-color: rgba(0, 0, 0, 0); @@ -549,16 +500,8 @@ $commit-message-text-area-bg: rgba(0, 0, 0, 0); /* * Common */ -$common-gray: $gl-text-color; $common-gray-light: #bbb; $common-gray-dark: #444; -$common-red: $red-500; -$common-green: $green-600; - -/* -* Editor -*/ -$editor-cancel-color: $red-600; /* * Events @@ -579,7 +522,6 @@ $logs-p-color: #333; */ $input-height: 34px; $input-danger-bg: #f2dede; -$input-danger-border: $red-400; $input-group-addon-bg: #f7f8fa; $gl-field-focus-shadow: rgba(0, 0, 0, 0.075); $gl-field-focus-shadow-error: rgba($red-500, 0.6); @@ -626,16 +568,9 @@ $fade-mask-transition-duration: 0.1s; $fade-mask-transition-curve: ease-in-out; /* -* Lint -*/ -$lint-incorrect-color: $red-500; -$lint-correct-color: $green-500; - -/* * Login */ $login-brand-holder-color: #888; -$login-devise-error-color: $red-700; /* * Nav @@ -648,15 +583,12 @@ $nav-toggle-gray: #666; */ $notify-details: #777; $notify-footer: #777; -$notify-new-file: $green-600; -$notify-deleted-file: $red-700; /* * Projects */ $project-option-descr-color: #54565b; $project-breadcrumb-color: #999; -$project-private-forks-notice-odd: $green-600; $project-network-controls-color: #888; $feature-toggle-color: #fff; @@ -665,21 +597,10 @@ $feature-toggle-color-disabled: #999; $feature-toggle-color-enabled: #4a8bee; /* -* Runners -*/ -$runner-state-shared-bg: $green-400; -$runner-state-specific-bg: $blue-400; -$runner-status-online-color: $green-600; -$runner-status-offline-color: $gray-darkest; -$runner-status-paused-color: $red-500; - -/* Stat Graph */ $stat-graph-common-bg: #f3f3f3; -$stat-graph-area-fill: $green-500; $stat-graph-axis-fill: #aaa; -$stat-graph-orange-fill: $orange-500; $stat-graph-selection-fill: #333; $stat-graph-selection-stroke: #333; @@ -692,7 +613,6 @@ $select2-drop-shadow2: rgba(31, 37, 50, 0.317647); /* * Todo */ -$todo-alert-blue: $blue-500; $todo-body-pre-color: #777; $todo-body-border: #ddd; @@ -715,7 +635,6 @@ $ui-dev-kit-example-border: #ddd; /* Pipeline Graph */ -$stage-hover-bg: $gray-darker; $ci-action-icon-size: 22px; $ci-action-icon-size-lg: 24px; $pipeline-dropdown-line-height: 20px; @@ -743,13 +662,6 @@ Animation Functions $dropdown-animation-timing: cubic-bezier(0.23, 1, 0.32, 1); /* -Convdev Index -*/ -$color-high-score: $green-400; -$color-average-score: $orange-400; -$color-low-score: $red-400; - -/* Performance Bar */ $perf-bar-text: #999; @@ -790,9 +702,5 @@ Modals */ $modal-body-height: 134px; -/* -Prometheus -*/ -$prometheus-table-row-highlight-color: $theme-gray-100; $priority-label-empty-state-width: 114px; diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss index b9c343fa2e9..7d90452e1f4 100644 --- a/app/assets/stylesheets/framework/variables_overrides.scss +++ b/app/assets/stylesheets/framework/variables_overrides.scss @@ -14,3 +14,7 @@ $btn-line-height: 20px; $table-accent-bg: $gray-light; $card-border-color: $border-color; $card-cap-bg: $gray-light; +$success: $green-500; +$info: $blue-500; +$warning: $orange-500; +$danger: $red-500; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 1696d18584d..14ba8b1df83 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -397,7 +397,7 @@ } &:hover { - background-color: $dropdown-item-hover-bg; + background-color: $gray-darker; } .icon-retry { diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss index bd338326154..52fcdf4a405 100644 --- a/app/assets/stylesheets/pages/convdev_index.scss +++ b/app/assets/stylesheets/pages/convdev_index.scss @@ -80,7 +80,7 @@ $space-between-cards: 8px; } .convdev-card-low { - border-top-color: $color-low-score; + border-top-color: $red-400; .board-card-score-big { background-color: $red-50; @@ -88,7 +88,7 @@ $space-between-cards: 8px; } .convdev-card-average { - border-top-color: $color-average-score; + border-top-color: $orange-400; .board-card-score-big { background-color: $orange-50; @@ -96,7 +96,7 @@ $space-between-cards: 8px; } .convdev-card-high { - border-top-color: $color-high-score; + border-top-color: $green-400; .board-card-score-big { background-color: $green-50; @@ -243,13 +243,13 @@ $space-between-cards: 8px; } .convdev-high-score { - color: $color-high-score; + color: $green-400; } .convdev-average-score { - color: $color-average-score; + color: $orange-400; } .convdev-low-score { - color: $color-low-score; + color: $red-400; } diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index bc4c90711d7..f0228768b5a 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -285,7 +285,7 @@ .total-time { font-size: $cycle-analytics-big-font; - color: $cycle-analytics-dark-text; + color: $gl-text-color; span { color: $gl-text-color; diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 892da152b5f..04570c057d1 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -23,10 +23,10 @@ } .cancel-btn { - color: $editor-cancel-color; + color: $red-600; &:hover { - color: $editor-cancel-color; + color: $red-600; } } diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 179c0964567..196f6ae6d8c 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -501,5 +501,5 @@ } .prometheus-table-row-highlight { - background-color: $prometheus-table-row-highlight-color; + background-color: $theme-gray-100; } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 6f0f82964c8..9ac47a771a5 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -144,7 +144,7 @@ color: $blue-800; .avatar { - border-color: rgba($avatar-border, .2); + border-color: rgba($gray-normal, .2); } } @@ -231,7 +231,7 @@ } a.edit-link:not([href]):hover { - color: rgba($avatar-border, .2); + color: rgba($gray-normal, .2); } .lock-edit, // uses same style, different js behaviour diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index d32943fceec..d2b9470be69 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -67,7 +67,7 @@ .dropdown-labels-error { padding: 5px 10px; margin-bottom: 10px; - background-color: $gl-danger; + background-color: $red-500; color: $white-light; } @@ -117,7 +117,7 @@ color: $blue-600; &.remove-row { - color: $gl-danger; + color: $red-500; } } } diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 8a4a2caa6c9..c9e5fb9c579 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -186,7 +186,7 @@ h2 { margin-top: 0; font-size: 14px; - color: $login-devise-error-color; + color: $red-700; } } } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 621321101cd..7b8cad254c7 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -195,12 +195,13 @@ .ci-widget-content { display: flex; align-items: center; + flex: 1; } } .mr-widget-icon { font-size: 22px; - margin-right: $status-icon-margin; + margin-right: $gl-btn-padding; } .ci-status-icon svg { @@ -222,6 +223,7 @@ .normal { flex: 1; + flex-basis: auto; } .capitalize { @@ -235,22 +237,23 @@ font-weight: normal; overflow: hidden; word-break: break-all; + } - &.label-truncated { - position: relative; - display: inline-block; - width: 250px; - margin-bottom: -3px; - white-space: nowrap; - text-overflow: clip; - line-height: 14px; - - &::after { - position: absolute; - content: '...'; - right: 0; - font-family: $regular-font; - background-color: $gray-light; + .deploy-link, + .label-branch { + &.label-truncate { + // NOTE: This selector targets its children because some of the HTML comes from + // 'source_branch_link'. Once this external HTML is no longer used, we could + // simplify this. + > a, + > span { + display: inline-block; + max-width: 12.5em; + margin-bottom: -3px; + white-space: nowrap; + text-overflow: ellipsis; + line-height: 14px; + overflow: hidden; } } } @@ -281,7 +284,7 @@ margin-bottom: 0; &.has-conflicts .fa-exclamation-triangle { - color: $gl-warning; + color: $orange-500; } time { @@ -313,7 +316,7 @@ } .danger { - color: $gl-danger; + color: $red-500; } .spacing, @@ -514,7 +517,7 @@ } .mr-links { - padding-left: $status-icon-size + $status-icon-margin; + padding-left: $status-icon-size + $gl-btn-padding; } .mr-info-list { @@ -582,7 +585,7 @@ @include media-breakpoint-down(md) { flex-direction: column; - align-items: flex-start; + align-items: stretch; .branch-actions { margin-top: 16px; @@ -593,13 +596,13 @@ .branch-actions { align-self: center; margin-left: $gl-padding; + white-space: nowrap; } } } .diverged-commits-count { color: $gl-text-color-secondary; - font-size: 12px; } } @@ -918,7 +921,7 @@ flex: 1; flex-direction: row; - @include media-breakpoint-down(md) { + @include media-breakpoint-down(sm) { flex-direction: column; .stage-cell .stage-container { diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 4f861d43f55..ac7b701c2e2 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -74,13 +74,13 @@ } &.is-dropzone-hover { - border-color: $gl-success; + border-color: $green-500; box-shadow: 0 0 2px $black-transparent, - 0 0 4px $gl-success-focus; + 0 0 4px $green-500-focus; .comment-toolbar, .nav-links { - border-color: $gl-success; + border-color: $green-500; } } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 2e1b2126887..fce04c58c24 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -443,7 +443,7 @@ ul.notes { .note-headline-light, .discussion-headline-light { - color: $notes-light-color; + color: $gl-text-color-secondary; } .discussion-headline-light { diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index ad057ed3c83..8bb8b83dc5e 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -19,7 +19,7 @@ background-color: $white-light; &:hover { - background-color: $stage-hover-bg; + background-color: $gray-darker; border: 1px solid $dropdown-toggle-active-border-color; color: $gl-text-color; } @@ -595,7 +595,7 @@ a.build-content:hover, button.build-content:hover { - background-color: $stage-hover-bg; + background-color: $gray-darker; border: 1px solid $dropdown-toggle-active-border-color; } @@ -668,7 +668,7 @@ display: block; &:hover { - background-color: $stage-hover-bg; + background-color: $gray-darker; border: 1px solid $dropdown-toggle-active-border-color; svg { @@ -835,7 +835,7 @@ button.mini-pipeline-graph-dropdown-toggle { display: block; &:hover { - background-color: $stage-hover-bg; + background-color: $gray-darker; border: 1px solid $dropdown-toggle-active-border-color; svg { @@ -934,7 +934,7 @@ button.mini-pipeline-graph-dropdown-toggle { &:focus { outline: none; text-decoration: none; - background-color: $stage-hover-bg; + background-color: $gray-darker; } } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index c11916454c8..a95e78931b1 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -394,23 +394,23 @@ } .vs-public { - color: $gl-primary; + color: $blue-500; } .vs-internal { - color: $gl-warning; + color: $orange-500; } .vs-private { - color: $gl-success; + color: $green-500; } .lfs-enabled { - color: $gl-success; + color: $green-500; } .lfs-disabled { - color: $gl-warning; + color: $orange-500; } .breadcrumb.repo-breadcrumb { @@ -731,7 +731,7 @@ background-color: transparent; font-size: $gl-font-size; line-height: $gl-btn-line-height; - color: $notes-light-color; + color: $gl-text-color-secondary; } .stat-link { @@ -900,7 +900,7 @@ pre.light-well { .private-forks-notice .private-fork-icon { i:nth-child(1) { - color: $project-private-forks-notice-odd; + color: $green-600; } i:nth-child(2) { @@ -1128,12 +1128,12 @@ pre.light-well { .project-ci-body { .incorrect-syntax { font-size: 18px; - color: $lint-incorrect-color; + color: $red-500; } .correct-syntax { font-size: 18px; - color: $lint-correct-color; + color: $green-500; } } diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss index 2734faec558..59f01f3e958 100644 --- a/app/assets/stylesheets/pages/runners.scss +++ b/app/assets/stylesheets/pages/runners.scss @@ -4,24 +4,24 @@ color: $white-light; &.runner-state-shared { - background: $runner-state-shared-bg; + background: $green-400; } &.runner-state-specific { - background: $runner-state-specific-bg; + background: $blue-400; } } .runner-status-online { - color: $runner-status-online-color; + color: $green-600; } .runner-status-offline { - color: $runner-status-offline-color; + color: $gray-darkest; } .runner-status-paused { - color: $runner-status-paused-color; + color: $red-500; } .runner { diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 5b3a468cd1c..77119aea9e2 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -24,12 +24,12 @@ $search-avatar-size: 16px; .form-control:hover, :not[readonly] { border-color: lighten($blue-300, 20%); - box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%); + box-shadow: 0 0 4px lighten($dropdown-input-focus-shadow, 20%); } input[type='checkbox']:hover { - box-shadow: 0 0 2px 2px lighten($search-input-focus-shadow-color, 20%), - 0 0 0 1px lighten($search-input-focus-shadow-color, 20%); + box-shadow: 0 0 2px 2px lighten($dropdown-input-focus-shadow, 20%), + 0 0 0 1px lighten($dropdown-input-focus-shadow, 20%); } .search { @@ -181,7 +181,7 @@ input[type='checkbox']:hover { width: $search-avatar-size; height: $search-avatar-size; border-radius: 50%; - border: 1px solid $avatar-border; + border: 1px solid $gray-normal; } } diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 5aa4cdec9c3..e351dd7c0bb 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -120,11 +120,11 @@ } .warning-title { - color: $gl-warning; + color: $orange-500; } .danger-title { - color: $gl-danger; + color: $red-500; } .integration-settings-form { diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss index 3f6f5f06075..d331edaa302 100644 --- a/app/assets/stylesheets/pages/stat_graph.scss +++ b/app/assets/stylesheets/pages/stat_graph.scss @@ -5,7 +5,7 @@ } .area { - fill: $stat-graph-area-fill; + fill: $green-500; fill-opacity: 0.5; } @@ -54,7 +54,7 @@ } .area-contributor { - fill: $stat-graph-orange-fill; + fill: $orange-500; } } } diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index 2ef2ee76855..22b39f47bf0 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -107,11 +107,15 @@ module IssuableCollections end def set_sort_order_from_cookie - key = 'issuable_sort' + cookies[remember_sorting_key] = params[:sort] if params[:sort].present? + # fallback to legacy cookie value for backward compatibility + cookies[remember_sorting_key] ||= cookies['issuable_sort'] + cookies[remember_sorting_key] = update_cookie_value(cookies[remember_sorting_key]) + params[:sort] = cookies[remember_sorting_key] + end - cookies[key] = params[:sort] if params[:sort].present? - cookies[key] = update_cookie_value(cookies[key]) - params[:sort] = cookies[key] + def remember_sorting_key + @remember_sorting_key ||= "#{collection_type.downcase}_sort" end def default_sort_order @@ -140,16 +144,14 @@ module IssuableCollections end def finder - strong_memoize(:finder) do - issuable_finder_for(finder_type) - end + @finder ||= issuable_finder_for(finder_type) end def collection_type - @collection_type ||= case finder - when IssuesFinder + @collection_type ||= case finder_type.name + when 'IssuesFinder' 'Issue' - when MergeRequestsFinder + when 'MergeRequestsFinder' 'MergeRequest' end end diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb index fb41dc1e8a8..b1c9b1e532f 100644 --- a/app/controllers/concerns/renders_commits.rb +++ b/app/controllers/concerns/renders_commits.rb @@ -1,4 +1,24 @@ module RendersCommits + def limited_commits(commits) + if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE + [ + commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE), + commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE + ] + else + [commits, 0] + end + end + + # This is used as a helper method in a controller. + # rubocop: disable Gitlab/ModuleWithInstanceVariables + def set_commits_for_rendering(commits) + @total_commit_count = commits.size + limited, @hidden_commit_count = limited_commits(commits) + prepare_commits_for_rendering(limited) + end + # rubocop: enable Gitlab/ModuleWithInstanceVariables + def prepare_commits_for_rendering(commits) Banzai::CommitRenderer.render(commits, @project, current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index ba5b7d33f87..ae0b815f85e 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -5,7 +5,7 @@ module ToggleAwardEmoji authenticate_user! name = params.require(:name) - if awardable.user_can_award?(current_user, name) + if awardable.user_can_award?(current_user) awardable.toggle_award_emoji(name, current_user) todoable = to_todoable(awardable) diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 9bd51de7e97..6bdc0f79ef2 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -2,8 +2,8 @@ class Groups::MilestonesController < Groups::ApplicationController include MilestoneActions before_action :group_projects - before_action :milestone, only: [:edit, :show, :update, :merge_requests, :participants, :labels] - before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update] + before_action :milestone, only: [:edit, :show, :update, :merge_requests, :participants, :labels, :destroy] + before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy] def index respond_to do |format| @@ -56,10 +56,21 @@ class Groups::MilestonesController < Groups::ApplicationController redirect_to milestone_path end + def destroy + return render_404 if @milestone.legacy_group_milestone? + + Milestones::DestroyService.new(group, current_user).execute(@milestone) + + respond_to do |format| + format.html { redirect_to group_milestones_path(group), status: :see_other } + format.js { head :ok } + end + end + private def authorize_admin_milestones! - return render_404 unless can?(current_user, :admin_milestones, group) + return render_404 unless can?(current_user, :admin_milestone, group) end def milestone_params diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 44b176d304e..53637780a07 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -101,7 +101,7 @@ class Projects::CommitController < Projects::ApplicationController @branch_name = create_new_branch? ? @commit.cherry_pick_branch_name : @start_branch - create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked.", + create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked into #{@branch_name}.", success_path: -> { successful_change_path }, failure_path: failed_change_path) end diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 36faea8056e..5546bef850b 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -63,7 +63,7 @@ class Projects::CommitsController < Projects::ApplicationController end @commits = @commits.with_pipeline_status - @commits = prepare_commits_for_rendering(@commits) + @commits = set_commits_for_rendering(@commits) end # Rails 5 sets request.format from the extension. diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index f93e500a07a..a1e12821caf 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -78,7 +78,7 @@ class Projects::CompareController < Projects::ApplicationController end def define_commits - @commits = compare.present? ? prepare_commits_for_rendering(compare.commits) : [] + @commits = compare.present? ? set_commits_for_rendering(@compare.commits) : [] end def define_diffs diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index ef8159aa553..c3ac8e107fb 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -113,7 +113,7 @@ class Projects::IssuesController < Projects::ApplicationController end def referenced_merge_requests - @merge_requests, @closed_by_merge_requests = ::Issues::FetchReferencedMergeRequestsService.new(project, current_user).execute(issue) + @merge_requests, @closed_by_merge_requests = ::Issues::ReferencedMergeRequestsService.new(project, current_user).execute(issue) respond_to do |format| format.json do diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index 81129456ad8..03d0290ac1d 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -101,7 +101,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap @target_project = @merge_request.target_project @source_project = @merge_request.source_project - @commits = prepare_commits_for_rendering(@merge_request.commits) + @commits = set_commits_for_rendering(@merge_request.commits) @commit = @merge_request.diff_head_commit @labels = LabelsFinder.new(current_user, project_id: @project.id).execute diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 1b069fe507b..d31b58972ca 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -79,7 +79,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo # Get commits from repository # or from cache if already merged @commits = - prepare_commits_for_rendering(@merge_request.commits.with_pipeline_status) + set_commits_for_rendering(@merge_request.commits.with_pipeline_status) render json: { html: view_to_html_string('projects/merge_requests/_commits') } end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 89fe90fd801..7a942c44ac4 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -210,17 +210,6 @@ module CommitsHelper Sanitize.clean(string, remove_contents: true) end - def limited_commits(commits) - if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - [ - commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE), - commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE - ] - else - [commits, 0] - end - end - def commit_path(project, commit, merge_request: nil) if merge_request&.persisted? diffs_project_merge_request_path(project, merge_request, commit_id: commit.id) diff --git a/app/helpers/import_helper.rb b/app/helpers/import_helper.rb index 4664b1728c4..c65f1565425 100644 --- a/app/helpers/import_helper.rb +++ b/app/helpers/import_helper.rb @@ -5,6 +5,10 @@ module ImportHelper false end + def sanitize_project_name(name) + name.gsub(/[^\w\-]/, '-') + end + def import_project_target(owner, name) namespace = current_user.can_create_group? ? owner : current_user.namespace_path "#{namespace}/#{name}" diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 96dc7ae1185..5b27d1d9404 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -92,14 +92,6 @@ module IssuesHelper end end - def award_user_authored_class(award) - if award == 'thumbsdown' || award == 'thumbsup' - 'user-authored js-user-authored' - else - '' - end - end - def awards_sort(awards) awards.sort_by do |award, award_emojis| if award == "thumbsup" diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6b4079b4113..18b3badda8d 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -447,7 +447,7 @@ module ProjectsHelper end def project_permissions_panel_data(project) - data = { + { currentSettings: project_permissions_settings(project), canChangeVisibilityLevel: can_change_visibility_level?(project, current_user), allowedVisibilityOptions: project_allowed_visibility_levels(project), @@ -457,8 +457,10 @@ module ProjectsHelper lfsAvailable: Gitlab.config.lfs.enabled, lfsHelpPath: help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs') } + end - data.to_json.html_safe + def project_permissions_panel_data_json(project) + project_permissions_panel_data(project).to_json.html_safe end def project_allowed_visibility_levels(project) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index e4aed76f611..526bf7af99b 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -649,8 +649,7 @@ module Ci def keep_around_commits return unless project - project.repository.keep_around(self.sha) - project.repository.keep_around(self.before_sha) + project.repository.keep_around(self.sha, self.before_sha) end def valid_source diff --git a/app/models/commit.rb b/app/models/commit.rb index 27fbdc3e386..594972ad344 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -193,6 +193,7 @@ class Commit # otherwise returns commit message without first line def description return safe_message if full_title.length >= 100 + return no_commit_message if safe_message.blank? safe_message.split("\n", 2)[1].try(:chomp) end diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index 49981db0d80..4200253053a 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -76,12 +76,8 @@ module Awardable true end - def awardable_votes?(name) - AwardEmoji::UPVOTE_NAME == name || AwardEmoji::DOWNVOTE_NAME == name - end - - def user_can_award?(current_user, name) - awardable_by_user?(current_user, name) && Ability.allowed?(current_user, :award_emoji, self) + def user_can_award?(current_user) + Ability.allowed?(current_user, :award_emoji, self) end def user_authored?(current_user) @@ -117,12 +113,4 @@ module Awardable def normalize_name(name) Gitlab::Emoji.normalize_emoji_name(name) end - - def awardable_by_user?(current_user, name) - if user_authored?(current_user) - !awardable_votes?(normalize_name(name)) - else - true - end - end end diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 58d949315e0..716cf6574d3 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -191,14 +191,18 @@ class DiffNote < Note end def keep_around_commits - project.repository.keep_around(self.original_position.base_sha) - project.repository.keep_around(self.original_position.start_sha) - project.repository.keep_around(self.original_position.head_sha) + shas = [ + self.original_position.base_sha, + self.original_position.start_sha, + self.original_position.head_sha + ] if self.position != self.original_position - project.repository.keep_around(self.position.base_sha) - project.repository.keep_around(self.position.start_sha) - project.repository.keep_around(self.position.head_sha) + shas << self.position.base_sha + shas << self.position.start_sha + shas << self.position.head_sha end + + project.repository.keep_around(*shas) end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 94cf12f3c2b..d0cd7461daa 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -170,27 +170,6 @@ class Issue < ActiveRecord::Base "#{project.to_reference(from, full: full)}#{reference}" end - def referenced_merge_requests(current_user = nil) - ext = all_references(current_user) - - notes_with_associations.each do |object| - object.all_references(current_user, extractor: ext) - end - - merge_requests = ext.merge_requests.sort_by(&:iid) - - cross_project_filter = -> (merge_requests) do - merge_requests.select { |mr| mr.target_project == project } - end - - Ability.merge_requests_readable_by_user( - merge_requests, current_user, - filters: { - read_cross_project: cross_project_filter - } - ) - end - # All branches containing the current issue's ID, except for # those with a merge request open referencing the current issue. def related_branches(current_user) @@ -198,7 +177,11 @@ class Issue < ActiveRecord::Base branch =~ /\A#{iid}-(?!\d+-stable)/i end - branches_with_merge_request = self.referenced_merge_requests(current_user).map(&:source_branch) + branches_with_merge_request = + Issues::ReferencedMergeRequestsService + .new(project, current_user) + .referenced_merge_requests(self) + .map(&:source_branch) branches_with_iid - branches_with_merge_request end @@ -225,26 +208,6 @@ class Issue < ActiveRecord::Base project end - # From all notes on this issue, we'll select the system notes about linked - # merge requests. Of those, the MRs closing `self` are returned. - def closed_by_merge_requests(current_user = nil) - return [] unless open? - - ext = all_references(current_user) - - notes.system.each do |note| - note.all_references(current_user, extractor: ext) - end - - merge_requests = ext.merge_requests.select(&:open?) - if merge_requests.any? - ids = MergeRequestsClosingIssues.where(merge_request_id: merge_requests.map(&:id), issue_id: id).pluck(:merge_request_id) - merge_requests.select { |mr| mr.id.in?(ids) } - else - [] - end - end - def moved? !moved_to.nil? end diff --git a/app/models/member.rb b/app/models/member.rb index 05c0bc8cb97..d9b4e8d2ac6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -103,7 +103,7 @@ class Member < ActiveRecord::Base def filter_by_2fa(value) case value when 'enabled' - left_join_users.merge(User.with_two_factor_indistinct) + left_join_users.merge(User.with_two_factor) when 'disabled' left_join_users.merge(User.without_two_factor) else diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index d9393b4e545..bbe4f6f7969 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -314,9 +314,7 @@ class MergeRequestDiff < ActiveRecord::Base def keep_around_commits [repository, merge_request.source_project.repository].uniq.each do |repo| - repo.keep_around(start_commit_sha) - repo.keep_around(head_commit_sha) - repo.keep_around(base_commit_sha) + repo.keep_around(start_commit_sha, head_commit_sha, base_commit_sha) end end end diff --git a/app/models/project.rb b/app/models/project.rb index 8f631d7f0ed..67593c9b2fe 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -85,8 +85,7 @@ class Project < ActiveRecord::Base after_create :create_project_feature, unless: :project_feature after_create -> { SiteStatistic.track(STATISTICS_ATTRIBUTE) } - before_destroy ->(project) { project.project_feature.untrack_statistics_for_deletion! } - after_destroy -> { SiteStatistic.untrack(STATISTICS_ATTRIBUTE) } + before_destroy :untrack_site_statistics after_create :create_ci_cd_settings, unless: :ci_cd_settings, @@ -2072,13 +2071,19 @@ class Project < ActiveRecord::Base private def rename_or_migrate_repository! - if Gitlab::CurrentSettings.hashed_storage_enabled? && storage_version != LATEST_STORAGE_VERSION + if Gitlab::CurrentSettings.hashed_storage_enabled? && + storage_upgradable? && + Feature.disabled?(:skip_hashed_storage_upgrade) # kill switch in case we need to disable upgrade behavior ::Projects::HashedStorageMigrationService.new(self, full_path_was).execute else storage.rename_repo end end + def storage_upgradable? + storage_version != LATEST_STORAGE_VERSION + end + def after_rename_repository(full_path_before, path_before) execute_rename_repository_hooks!(full_path_before) @@ -2093,6 +2098,11 @@ class Project < ActiveRecord::Base Gitlab::PagesTransfer.new.rename_project(path_before, self.path, namespace.full_path) end + def untrack_site_statistics + SiteStatistic.untrack(STATISTICS_ATTRIBUTE) + self.project_feature.untrack_statistics_for_deletion! + end + def execute_rename_repository_hooks!(full_path_before) # When we import a project overwriting the original project, there # is a move operation. In that case we don't want to send the instructions. diff --git a/app/models/protected_tag.rb b/app/models/protected_tag.rb index a36f0d36262..94746141945 100644 --- a/app/models/protected_tag.rb +++ b/app/models/protected_tag.rb @@ -4,6 +4,8 @@ class ProtectedTag < ActiveRecord::Base include Gitlab::ShellAdapter include ProtectedRef + validates :name, uniqueness: { scope: :project_id } + protected_ref_access_levels :create def self.protected?(project, ref_name) diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb index 833faf3bc82..c1f53b5da4f 100644 --- a/app/models/remote_mirror.rb +++ b/app/models/remote_mirror.rb @@ -150,6 +150,15 @@ class RemoteMirror < ActiveRecord::Base result.to_s end + def ensure_remote! + return unless project + return unless remote_name && url + + # If this fails or the remote already exists, we won't know due to + # https://gitlab.com/gitlab-org/gitaly/issues/1317 + project.repository.add_remote(remote_name, url) + end + private def raw diff --git a/app/models/repository.rb b/app/models/repository.rb index 69f375dc6f3..cf255c8951f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -247,15 +247,22 @@ class Repository # Git GC will delete commits from the repository that are no longer in any # branches or tags, but we want to keep some of these commits around, for # example if they have comments or CI builds. - def keep_around(sha) - return unless sha.present? && commit_by(oid: sha) + # + # For Geo's sake, pass in multiple shas rather than calling it multiple times, + # to avoid unnecessary syncing. + def keep_around(*shas) + shas.each do |sha| + begin + next unless sha.present? && commit_by(oid: sha) - return if kept_around?(sha) + next if kept_around?(sha) - # This will still fail if the file is corrupted (e.g. 0 bytes) - raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false) - rescue Gitlab::Git::CommandError => ex - Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}" + # This will still fail if the file is corrupted (e.g. 0 bytes) + raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false) + rescue Gitlab::Git::CommandError => ex + Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}" + end + end end def kept_around?(sha) diff --git a/app/models/user.rb b/app/models/user.rb index a6ba90794d6..f21ca1c569f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -289,13 +289,16 @@ class User < ActiveRecord::Base end end - def self.with_two_factor_indistinct - joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") - .where("u2f.id IS NOT NULL OR users.otp_required_for_login = ?", true) - end - def self.with_two_factor - with_two_factor_indistinct.distinct(arel_table[:id]) + with_u2f_registrations = <<-SQL + EXISTS ( + SELECT * + FROM u2f_registrations AS u2f + WHERE u2f.user_id = users.id + ) OR users.otp_required_for_login = ? + SQL + + where(with_u2f_registrations, true) end def self.without_two_factor diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index a8d7a05f509..73c93b22c95 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -53,7 +53,7 @@ class GroupPolicy < BasePolicy rule { has_access }.enable :read_namespace - rule { developer }.enable :admin_milestones + rule { developer }.enable :admin_milestone rule { reporter }.policy do enable :admin_label @@ -72,6 +72,8 @@ class GroupPolicy < BasePolicy enable :admin_namespace enable :admin_group_member enable :change_visibility_level + + enable :set_note_created_at end rule { can?(:read_nested_project_resources) }.policy do diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 00c58f15013..fd6cc504a3b 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -143,6 +143,10 @@ class ProjectPolicy < BasePolicy enable :destroy_merge_request enable :destroy_issue enable :remove_pages + + enable :set_issue_iid + enable :set_issue_created_at + enable :set_note_created_at end rule { can?(:guest_access) }.policy do diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 637c1df4ad9..26e90e8cf8c 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -140,7 +140,6 @@ class GitPushService < BaseService EventCreateService.new.push(project, current_user, build_push_data) Ci::CreatePipelineService.new(project, current_user, build_push_data).execute(:push) - SystemHookPushWorker.perform_async(build_push_data.dup, :push_hooks) project.execute_hooks(build_push_data.dup, :push_hooks) project.execute_services(build_push_data.dup, :push_hooks) @@ -159,7 +158,7 @@ class GitPushService < BaseService end def process_default_branch - offset = [push_commits_count - PROCESS_COMMIT_LIMIT, 0].max + offset = [push_commits_count_for_ref - PROCESS_COMMIT_LIMIT, 0].max @push_commits = project.repository.commits(params[:newrev], offset: offset, limit: PROCESS_COMMIT_LIMIT) project.after_create_default_branch @@ -173,7 +172,7 @@ class GitPushService < BaseService params[:newrev], params[:ref], @push_commits, - commits_count: push_commits_count) + commits_count: commits_count) end def push_to_existing_branch? @@ -214,8 +213,14 @@ class GitPushService < BaseService end end - def push_commits_count - strong_memoize(:push_commits_count) do + def commits_count + return push_commits_count_for_ref if default_branch? && push_to_new_branch? + + Array(@push_commits).size + end + + def push_commits_count_for_ref + strong_memoize(:push_commits_count_for_ref) do project.repository.commit_count_for_ref(params[:ref]) end end diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb index 12aeba4af71..93d84bd8a9c 100644 --- a/app/services/groups/destroy_service.rb +++ b/app/services/groups/destroy_service.rb @@ -12,12 +12,15 @@ module Groups def execute group.prepare_for_destroy - group.projects.each do |project| + group.projects.includes(:project_feature).each do |project| # Execute the destruction of the models immediately to ensure atomic cleanup. success = ::Projects::DestroyService.new(project, current_user).execute raise DestroyError, "Project #{project.id} can't be deleted" unless success end + # reload the relation to prevent triggering destroy hooks on the projects again + group.projects.reload + group.children.each do |group| # This needs to be synchronous since the namespace gets destroyed below DestroyService.new(group, current_user).execute diff --git a/app/services/issues/fetch_referenced_merge_requests_service.rb b/app/services/issues/fetch_referenced_merge_requests_service.rb deleted file mode 100644 index 5e84f3c81c9..00000000000 --- a/app/services/issues/fetch_referenced_merge_requests_service.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Issues - class FetchReferencedMergeRequestsService < Issues::BaseService - def execute(issue) - referenced_merge_requests = issue.referenced_merge_requests(current_user) - referenced_merge_requests = Gitlab::IssuableSorter.sort(project, referenced_merge_requests) { |i| i.iid.to_s } - closed_by_merge_requests = issue.closed_by_merge_requests(current_user) - closed_by_merge_requests = Gitlab::IssuableSorter.sort(project, closed_by_merge_requests) { |i| i.iid.to_s } - - [referenced_merge_requests, closed_by_merge_requests] - end - end -end diff --git a/app/services/issues/referenced_merge_requests_service.rb b/app/services/issues/referenced_merge_requests_service.rb new file mode 100644 index 00000000000..40d78502697 --- /dev/null +++ b/app/services/issues/referenced_merge_requests_service.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Issues + class ReferencedMergeRequestsService < Issues::BaseService + def execute(issue) + referenced = referenced_merge_requests(issue) + closed_by = closed_by_merge_requests(issue) + preloader = ActiveRecord::Associations::Preloader.new + + preloader.preload(referenced + closed_by, + head_pipeline: { project: [:route, { namespace: :route }] }) + + [sort_by_iid(referenced), sort_by_iid(closed_by)] + end + + def referenced_merge_requests(issue) + merge_requests = extract_merge_requests(issue) + + cross_project_filter = -> (merge_requests) do + merge_requests.select { |mr| mr.target_project == project } + end + + Ability.merge_requests_readable_by_user( + merge_requests, + current_user, + filters: { + read_cross_project: cross_project_filter + } + ) + end + + def closed_by_merge_requests(issue) + return [] unless issue.open? + + merge_requests = extract_merge_requests(issue, filter: :system).select(&:open?) + + return [] if merge_requests.empty? + + ids = MergeRequestsClosingIssues.where(merge_request_id: merge_requests.map(&:id), issue_id: issue.id).pluck(:merge_request_id) + merge_requests.select { |mr| mr.id.in?(ids) } + end + + private + + def extract_merge_requests(issue, filter: nil) + ext = issue.all_references(current_user) + notes = issue_notes(issue) + notes = notes.select(&filter) if filter + + notes.each do |note| + note.all_references(current_user, extractor: ext) + end + + ext.merge_requests + end + + def issue_notes(issue) + @issue_notes ||= {} + @issue_notes[issue] ||= issue.notes.includes(:author) + end + + def sort_by_iid(merge_requests) + Gitlab::IssuableSorter.sort(project, merge_requests) { |mr| mr.iid.to_s } + end + end +end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index bc988eb2a26..55750269bb4 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -128,8 +128,7 @@ module MergeRequests # def assign_title_and_description assign_title_and_description_from_single_commit - assign_title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker - + merge_request.title ||= title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker merge_request.title ||= source_branch.titleize.humanize merge_request.title = wip_title if compare_commits.empty? @@ -159,20 +158,18 @@ module MergeRequests merge_request.description ||= commit.description.try(:strip) end - def assign_title_from_issue + def title_from_issue return unless issue - merge_request.title = "Resolve \"#{issue.title}\"" if issue.is_a?(Issue) + return "Resolve \"#{issue.title}\"" if issue.is_a?(Issue) - return if merge_request.title.present? + return if issue_iid.blank? - if issue_iid.present? - title_parts = ["Resolve #{issue.to_reference}"] - branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize + title_parts = ["Resolve #{issue.to_reference}"] + branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize - title_parts << "\"#{branch_title}\"" if branch_title.present? - merge_request.title = title_parts.join(' ') - end + title_parts << "\"#{branch_title}\"" if branch_title.present? + title_parts.join(' ') end def issue_iid diff --git a/app/services/milestones/destroy_service.rb b/app/services/milestones/destroy_service.rb index 15c04525075..7cda802c120 100644 --- a/app/services/milestones/destroy_service.rb +++ b/app/services/milestones/destroy_service.rb @@ -3,8 +3,6 @@ module Milestones class DestroyService < Milestones::BaseService def execute(milestone) - return unless milestone.project_milestone? - Milestone.transaction do update_params = { milestone: nil } @@ -16,15 +14,21 @@ module Milestones MergeRequests::UpdateService.new(parent, current_user, update_params).execute(merge_request) end - event_service.destroy_milestone(milestone, current_user) - - Event.for_milestone_id(milestone.id).each do |event| - event.target_id = nil - event.save - end + log_destroy_event_for(milestone) milestone.destroy end end + + def log_destroy_event_for(milestone) + return if milestone.group_milestone? + + event_service.destroy_milestone(milestone, current_user) + + Event.for_milestone_id(milestone.id).each do |event| + event.target_id = nil + event.save + end + end end end diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 33ad2120a75..cbbb88a9410 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -17,6 +17,14 @@ module Projects link_fork_network(fork_to_project) + # A forked project stores its LFS objects in the `forked_from_project`. + # So the LFS objects become inaccessible, and therefore delete them from + # the database so they'll get cleaned up. + # + # TODO: refactor this to get the correct lfs objects when implementing + # https://gitlab.com/gitlab-org/gitlab-ce/issues/39769 + fork_to_project.lfs_objects_projects.delete_all + fork_to_project end diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb index 4651f7c4f8f..591b38b8151 100644 --- a/app/services/projects/update_remote_mirror_service.rb +++ b/app/services/projects/update_remote_mirror_service.rb @@ -10,6 +10,7 @@ module Projects return success unless remote_mirror.enabled? begin + remote_mirror.ensure_remote! repository.fetch_remote(remote_mirror.remote_name, no_tags: true) opts = {} diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 8838ed06324..a4c4c9e4812 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -402,7 +402,7 @@ module QuickActions match[1] if match end command :award do |name| - if name && issuable.user_can_award?(current_user, name) + if name && issuable.user_can_award?(current_user) @updates[:emoji_award] = name end end diff --git a/app/views/admin/hook_logs/show.html.haml b/app/views/admin/hook_logs/show.html.haml index 2eb3ac85722..86729dbe7bc 100644 --- a/app/views/admin/hook_logs/show.html.haml +++ b/app/views/admin/hook_logs/show.html.haml @@ -4,7 +4,6 @@ %hr -= link_to 'Resend Request', retry_admin_hook_hook_log_path(@hook, @hook_log), class: "btn btn-default float-right prepend-left-10" += link_to 'Resend Request', retry_admin_hook_hook_log_path(@hook, @hook_log), method: :post, class: "btn btn-default float-right prepend-left-10" = render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log } - diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 029efadd75d..a74e052707f 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -39,6 +39,10 @@ %strong= email.email = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-sm btn btn-remove float-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do %i.fa.fa-times + %li + %span.light ID: + %strong + = @user.id %li.two-factor-status %span.light Two-factor Authentication: diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml index 8ca9fb4512e..30d7b21b1b8 100644 --- a/app/views/award_emoji/_awards_block.html.haml +++ b/app/views/award_emoji/_awards_block.html.haml @@ -3,7 +3,7 @@ .awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: toggle_award_url(awardable) } } - awards_sort(grouped_emojis).each do |emoji, awards| %button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button", - class: [(award_state_class(awardable, awards, current_user)), (award_user_authored_class(emoji) if user_authored)], + class: [(award_state_class(awardable, awards, current_user))], data: { placement: "bottom", title: award_user_list(awards, current_user) } } = emoji_icon(emoji) %span.award-control-text.js-counter @@ -13,7 +13,6 @@ .award-menu-holder.js-award-holder %button.btn.award-control.has-tooltip.js-add-award{ type: 'button', 'aria-label': _('Add reaction'), - class: ("js-user-authored" if user_authored), data: { title: _('Add reaction'), placement: "bottom" } } %span{ class: "award-control-icon award-control-icon-neutral" }= custom_icon('emoji_slightly_smiling_face') %span{ class: "award-control-icon award-control-icon-positive" }= custom_icon('emoji_smiley') diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml index 13f96b9747c..c26eb873718 100644 --- a/app/views/ci/runner/_how_to_setup_runner.html.haml +++ b/app/views/ci/runner/_how_to_setup_runner.html.haml @@ -1,6 +1,6 @@ - link = link_to _("Install GitLab Runner"), 'https://docs.gitlab.com/runner/install/', target: '_blank' .append-bottom-10 - %h4= _("Setup a #{type} Runner manually") + %h4= _("Setup a %{type} Runner manually") % { type: type } %ol %li diff --git a/app/views/ci/status/_dropdown_graph_badge.html.haml b/app/views/ci/status/_dropdown_graph_badge.html.haml index 8b0463db000..9de9143e8b1 100644 --- a/app/views/ci/status/_dropdown_graph_badge.html.haml +++ b/app/views/ci/status/_dropdown_graph_badge.html.haml @@ -6,12 +6,12 @@ - tooltip = "#{subject.name} - #{status.status_tooltip}" - if status.has_details? - = link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip, html: 'true', container: 'body' } do + = link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip, container: 'body' } do %span{ class: klass }= sprite_icon(status.icon) %span.ci-build-text= subject.name - else - .menu-item.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' } } + .menu-item.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', title: tooltip, container: 'body' } } %span{ class: klass }= sprite_icon(status.icon) %span.ci-build-text= subject.name diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index f5f621507b8..b6424df55cd 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -5,7 +5,7 @@ .nav-controls = render 'shared/milestones_sort_dropdown' - - if can?(current_user, :admin_milestones, @group) + - if can?(current_user, :admin_milestone, @group) = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new" .milestones diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml index f0d1e837317..f4a29ed18dc 100644 --- a/app/views/import/_githubish_status.html.haml +++ b/app/views/import/_githubish_status.html.haml @@ -45,7 +45,7 @@ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend .input-group-text / - = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true + = text_field_tag :path, sanitize_project_name(repo.name), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true %td.import-actions.job-status = button_tag class: "btn btn-import js-add-to-import" do = has_ci_cd_only_params? ? _('Connect') : _('Import') diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml index a75b7aa9dd2..3b1b5e55302 100644 --- a/app/views/import/bitbucket/status.html.haml +++ b/app/views/import/bitbucket/status.html.haml @@ -63,7 +63,7 @@ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend .input-group-text / - = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true + = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true %td.import-actions.job-status = button_tag class: 'btn btn-import js-add-to-import' do = _('Import') diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml index 3d05a5e696f..ae09e0dfa18 100644 --- a/app/views/import/bitbucket_server/status.html.haml +++ b/app/views/import/bitbucket_server/status.html.haml @@ -61,7 +61,7 @@ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend .input-group-text / - = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true + = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true %td.import-actions.job-status = button_tag class: 'btn btn-import js-add-to-import' do Import diff --git a/app/views/projects/_issuable_by_email.html.haml b/app/views/projects/_issuable_by_email.html.haml index 22adf5b4008..d59191a6f87 100644 --- a/app/views/projects/_issuable_by_email.html.haml +++ b/app/views/projects/_issuable_by_email.html.haml @@ -19,9 +19,16 @@ = text_field_tag :issuable_email, email, class: "monospace js-select-on-focus form-control", readonly: true .input-group-append = clipboard_button(target: '#issuable_email', class: 'btn btn-clipboard input-group-text btn-transparent d-none d-sm-block') + + - if issuable_type == 'issue' + - enter_title_text = _('Enter the issue title') + - enter_description_text = _('Enter the issue description') + - else + - enter_title_text = _('Enter the merge request title') + - enter_description_text = _('Enter the merge request description') = mail_to email, class: 'btn btn-clipboard btn-transparent', - subject: _("Enter the #{name} title"), - body: _("Enter the #{name} description"), + subject: enter_title_text, + body: enter_description_text, title: _('Send email'), data: { toggle: 'tooltip', placement: 'bottom' } do = sprite_icon('mail') diff --git a/app/views/projects/commits/_commit_list.html.haml b/app/views/projects/commits/_commit_list.html.haml index 8f8eb2c3d5a..6ed65d07202 100644 --- a/app/views/projects/commits/_commit_list.html.haml +++ b/app/views/projects/commits/_commit_list.html.haml @@ -1,9 +1,10 @@ -- commits, hidden = limited_commits(@commits) +- commits = @commits +- hidden = @hidden_commit_count - commits = Commit.decorate(commits, @project) .card .card-header - Commits (#{@commits.count}) + Commits (#{@total_commit_count}) - if hidden > 0 %ul.content-list - commits.each do |commit| diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index ac6852751be..ec05ff50f25 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -2,7 +2,8 @@ - project = local_assigns.fetch(:project) { merge_request&.project } - ref = local_assigns.fetch(:ref) { merge_request&.source_branch } -- commits, hidden = limited_commits(@commits) +- commits = @commits +- hidden = @hidden_commit_count - commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits| %li.commit-header.js-commit-header{ data: { day: day } } diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml index cd0fb21f8a7..ffdca500abe 100644 --- a/app/views/projects/diffs/_line.html.haml +++ b/app/views/projects/diffs/_line.html.haml @@ -32,9 +32,9 @@ %a{ href: "##{line_code}", data: { linenumber: link_text } } %td.line_content.noteable_line{ class: type }< - if email - %pre= line.text + %pre= line.rich_text - else - = diff_line_content(line.text) + = diff_line_content(line.rich_text) - if line_discussions&.any? - discussion_expanded = local_assigns.fetch(:discussion_expanded, line_discussions.any?(&:expanded?)) diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml index 1f0ca211074..e47361354f3 100644 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ b/app/views/projects/diffs/_parallel_view.html.haml @@ -24,7 +24,7 @@ - discussion_left = discussions_left.try(:first) - if discussion_left && discussion_left.resolvable? %diff-note-avatars{ "discussion-id" => discussion_left.id } - %td.line_content.parallel.noteable_line.left-side{ id: left_line_code, class: left.type }= diff_line_content(left.text) + %td.line_content.parallel.noteable_line.left-side{ id: left_line_code, class: left.type }= diff_line_content(left.rich_text) - else %td.old_line.diff-line-num.empty-cell %td.line_content.parallel.left-side @@ -45,7 +45,7 @@ - discussion_right = discussions_right.try(:first) - if discussion_right && discussion_right.resolvable? %diff-note-avatars{ "discussion-id" => discussion_right.id } - %td.line_content.parallel.noteable_line.right-side{ id: right_line_code, class: right.type }= diff_line_content(right.text) + %td.line_content.parallel.noteable_line.right-side{ id: right_line_code, class: right.type }= diff_line_content(right.rich_text) - else %td.old_line.diff-line-num.empty-cell %td.line_content.parallel.right-side diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 30544dde451..e37a444c1c9 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -78,7 +78,7 @@ = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f| %input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' } -# haml-lint:disable InlineJavaScript - %script.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data(@project) + %script.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project) .js-project-permissions-form = f.submit 'Save changes', class: "btn btn-save" diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml index e51efa85df0..bd8ca5e7d70 100644 --- a/app/views/projects/hook_logs/show.html.haml +++ b/app/views/projects/hook_logs/show.html.haml @@ -4,6 +4,6 @@ Request details .col-lg-9 - = link_to 'Resend Request', retry_project_hook_hook_log_path(@project, @hook, @hook_log), class: "btn btn-default float-right prepend-left-10" + = link_to 'Resend Request', retry_project_hook_hook_log_path(@project, @hook, @hook_log), method: :post, class: "btn btn-default float-right prepend-left-10" = render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log } diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml index 86b2b8bf2f7..acc1e17b811 100644 --- a/app/views/projects/jobs/_sidebar.html.haml +++ b/app/views/projects/jobs/_sidebar.html.haml @@ -82,7 +82,7 @@ - builds.select{|build| build.status == build_status}.each do |build| .build-job{ class: sidebar_build_class(build, @build), data: { stage: build.stage } } - tooltip = sanitize(build.tooltip_message.dup) - = link_to(project_job_path(@project, build), data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' }) do + = link_to(project_job_path(@project, build), data: { toggle: 'tooltip', title: tooltip, container: 'body' }) do = sprite_icon('arrow-right', size:16, css_class: 'icon-arrow-right') %span{ class: "ci-status-icon-#{build.status}" } = ci_icon_for_status(build.status) diff --git a/app/views/projects/merge_requests/_how_to_merge.html.haml b/app/views/projects/merge_requests/_how_to_merge.html.haml index 62dd21ef6e0..d3871453b9f 100644 --- a/app/views/projects/merge_requests/_how_to_merge.html.haml +++ b/app/views/projects/merge_requests/_how_to_merge.html.haml @@ -1,5 +1,5 @@ #modal_merge_info.modal{ tabindex: '-1' } - .modal-dialog + .modal-dialog.modal-lg .modal-content .modal-header %h3.modal-title Check out, review, and merge locally diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml index f7a5d85500f..d5c4134dee2 100644 --- a/app/views/projects/merge_requests/creations/_new_submit.html.haml +++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml @@ -33,7 +33,7 @@ %li.commits-tab.new-tab = link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do Commits - %span.badge.badge-pill= @commits.size + %span.badge.badge-pill= @total_commit_count - if @pipelines.any? %li.builds-tab = link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tabvue'} do diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 2a9e20c2caa..0a684f9016a 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -43,18 +43,7 @@ - else = link_to 'Reopen milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped" - %button.js-delete-milestone-button.btn.btn-grouped.btn-danger{ data: { toggle: 'modal', - target: '#delete-milestone-modal', - milestone_id: @milestone.id, - milestone_title: markdown_field(@milestone, :title), - milestone_url: project_milestone_path(@project, @milestone), - milestone_issue_count: @milestone.issues.count, - milestone_merge_request_count: @milestone.merge_requests.count }, - disabled: true } - = _('Delete') - = icon('spin spinner', class: 'js-loading-icon hidden' ) - - #delete-milestone-modal + = render 'shared/milestones/delete_button' %a.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ href: "#" } = icon('angle-double-left') diff --git a/app/views/projects/mirrors/_instructions.html.haml b/app/views/projects/mirrors/_instructions.html.haml index e051f9e6331..35a6885318a 100644 --- a/app/views/projects/mirrors/_instructions.html.haml +++ b/app/views/projects/mirrors/_instructions.html.haml @@ -4,7 +4,9 @@ = _('The repository must be accessible over <code>http://</code>, <code>https://</code>, <code>ssh://</code> and <code>git://</code>.').html_safe %li= _('Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>.').html_safe - %li= _("The update action will time out after #{import_will_timeout_message(Gitlab.config.gitlab_shell.git_timeout)} minutes. For big repositories, use a clone/push combination.") + %li + - minutes = Gitlab.config.gitlab_shell.git_timeout / 60 + = _("The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination.") % { number_of_minutes: minutes } %li= _('The Git LFS objects will <strong>not</strong> be synced.').html_safe %li = _('This user will be the author of all events in the activity feed that are the result of an update, diff --git a/app/views/projects/notes/_actions.html.haml b/app/views/projects/notes/_actions.html.haml index b4fe1cabdfd..e9008d60098 100644 --- a/app/views/projects/notes/_actions.html.haml +++ b/app/views/projects/notes/_actions.html.haml @@ -40,7 +40,7 @@ - if note.emoji_awardable? - user_authored = note.user_authored?(current_user) .note-actions-item - = button_tag title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji #{'js-user-authored' if user_authored} has-tooltip btn btn-transparent", data: { position: 'right', container: 'body' } do + = button_tag title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji} has-tooltip btn btn-transparent", data: { position: 'right', container: 'body' } do = icon('spinner spin') %span{ class: 'link-highlight award-control-icon-neutral' }= custom_icon('emoji_slightly_smiling_face') %span{ class: 'link-highlight award-control-icon-positive' }= custom_icon('emoji_smiley') diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml new file mode 100644 index 00000000000..e236c24b088 --- /dev/null +++ b/app/views/shared/milestones/_delete_button.html.haml @@ -0,0 +1,14 @@ +- milestone_url = @milestone.project_milestone? ? project_milestone_path(@project, @milestone) : group_milestone_path(@group, @milestone) + +%button.js-delete-milestone-button.btn.btn-grouped.btn-danger{ data: { toggle: 'modal', + target: '#delete-milestone-modal', + milestone_id: @milestone.id, + milestone_title: markdown_field(@milestone, :title), + milestone_url: milestone_url, + milestone_issue_count: @milestone.issues.count, + milestone_merge_request_count: @milestone.merge_requests.count }, + disabled: true } + = _('Delete') + = icon('spin spinner', class: 'js-loading-icon hidden' ) + +#delete-milestone-modal diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index c559945a9c9..3dd2842be4f 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -16,6 +16,9 @@ = milestone_date_range(milestone) %div = render('shared/milestone_expired', milestone: milestone) + - if milestone.group_milestone? + .label-badge.label-badge-blue.d-inline-block + = milestone.group.full_name - if milestone.legacy_group_milestone? .projects - milestone.milestones.each do |milestone| @@ -49,7 +52,7 @@ - unless milestone.active? = link_to 'Reopen Milestone', project_milestone_path(@project, milestone, {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen" - if @group - - if can?(current_user, :admin_milestones, @group) + - if can?(current_user, :admin_milestone, @group) - if milestone.closed? = link_to 'Reopen Milestone', group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" - else diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml index 320e3788a0f..0499b04a482 100644 --- a/app/views/shared/milestones/_top.html.haml +++ b/app/views/shared/milestones/_top.html.haml @@ -23,7 +23,7 @@ = milestone_date_range(milestone) - if group .float-right - - if can?(current_user, :admin_milestones, group) + - if can?(current_user, :admin_milestone, group) - if milestone.group_milestone? = link_to edit_group_milestone_path(group, milestone), class: "btn btn btn-grouped" do Edit @@ -32,6 +32,9 @@ - else = link_to 'Reopen Milestone', group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen" + - unless is_dynamic_milestone + = render 'shared/milestones/delete_button' + = render 'shared/milestones/deprecation_message' if is_dynamic_milestone .detail-page-description.milestone-detail diff --git a/app/views/snippets/notes/_actions.html.haml b/app/views/snippets/notes/_actions.html.haml index 3a50324770d..e1f7ee80ebb 100644 --- a/app/views/snippets/notes/_actions.html.haml +++ b/app/views/snippets/notes/_actions.html.haml @@ -2,7 +2,7 @@ - if note.emoji_awardable? - user_authored = note.user_authored?(current_user) .note-actions-item - = link_to '#', title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji #{'js-user-authored' if user_authored} has-tooltip", data: { position: 'right' } do + = link_to '#', title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji has-tooltip", data: { position: 'right' } do = icon('spinner spin') %span{ class: 'link-highlight award-control-icon-neutral' }= custom_icon('emoji_slightly_smiling_face') %span{ class: 'link-highlight award-control-icon-positive' }= custom_icon('emoji_smiley') diff --git a/changelogs/unreleased/1756-set-iid-via-api.yml b/changelogs/unreleased/1756-set-iid-via-api.yml deleted file mode 100644 index 680a9464ab4..00000000000 --- a/changelogs/unreleased/1756-set-iid-via-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow issues API to receive an internal ID (iid) on create -merge_request: 20626 -author: Jamie Schembri -type: fixed diff --git a/changelogs/unreleased/21326-avoid-nil-safe-message.yml b/changelogs/unreleased/21326-avoid-nil-safe-message.yml new file mode 100644 index 00000000000..ca1a89191a8 --- /dev/null +++ b/changelogs/unreleased/21326-avoid-nil-safe-message.yml @@ -0,0 +1,5 @@ +--- +title: "Avoid nil safe message" +merge_request: 21326 +author: Yi Siliang +type: fixed diff --git a/changelogs/unreleased/23705-add-single-file-download-in-repo.yml b/changelogs/unreleased/23705-add-single-file-download-in-repo.yml deleted file mode 100644 index f156bfb1101..00000000000 --- a/changelogs/unreleased/23705-add-single-file-download-in-repo.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add download button for single file (including raw files) in repository -merge_request: 20480 -author: Kia Mei Somabes -type: added diff --git a/changelogs/unreleased/25990-improve-web-terminal.yml b/changelogs/unreleased/25990-improve-web-terminal.yml deleted file mode 100644 index 3f8a8c6211c..00000000000 --- a/changelogs/unreleased/25990-improve-web-terminal.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Move xterm to a node dependency and remove it from vendor's folder -merge_request: 20588 -author: -type: other diff --git a/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml b/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml deleted file mode 100644 index 0a2853c20c6..00000000000 --- a/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix authorization for interactive web terminals -merge_request: 20811 -author: -type: fixed diff --git a/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml b/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml deleted file mode 100644 index 55d82c4ee5d..00000000000 --- a/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve feedback when a developer is unable to push to an empty repository -merge_request: 20519 -author: -type: changed diff --git a/changelogs/unreleased/29278-commits-page-tooltips.yml b/changelogs/unreleased/29278-commits-page-tooltips.yml deleted file mode 100644 index d54301a1cf0..00000000000 --- a/changelogs/unreleased/29278-commits-page-tooltips.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove tooltips from commit author avatar and name in commit lists -merge_request: 20674 -author: -type: other diff --git a/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml b/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml deleted file mode 100644 index 21d9d25d342..00000000000 --- a/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Redirect commits to root if no ref is provided (31576) -merge_request: 20738 -author: Kia Mei Somabes -type: added diff --git a/changelogs/unreleased/32783-api-all-members-with-ancestors.yml b/changelogs/unreleased/32783-api-all-members-with-ancestors.yml deleted file mode 100644 index ca53d02845d..00000000000 --- a/changelogs/unreleased/32783-api-all-members-with-ancestors.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Adds API endpoint /api/v4/(project/group)/:id/members/all to list also inherited - members -merge_request: 19748 -author: Jacopo Beschi @jacopo-beschi -type: added diff --git a/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml b/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml deleted file mode 100644 index 587d7209c2f..00000000000 --- a/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve error message when adding invalid user to a project -merge_request: 20885 -author: Jacopo Beschi @jacopo-beschi -type: added diff --git a/changelogs/unreleased/34572-ssh-certificates.yml b/changelogs/unreleased/34572-ssh-certificates.yml deleted file mode 100644 index 76a08a188de..00000000000 --- a/changelogs/unreleased/34572-ssh-certificates.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add support for SSH certificate authentication -merge_request: 19911 -author: Ævar Arnfjörð Bjarmason -type: added diff --git a/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml b/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml deleted file mode 100644 index e1e5c8db046..00000000000 --- a/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Keep admin settings sections open after submitting forms -merge_request: 21040 -author: -type: other diff --git a/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml b/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml deleted file mode 100644 index efa13c9ab3c..00000000000 --- a/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: UX improvements to top nav search bar -merge_request: 20537 -author: -type: changed diff --git a/changelogs/unreleased/38604-add-private-profile.yml b/changelogs/unreleased/38604-add-private-profile.yml deleted file mode 100644 index e40e7d9321e..00000000000 --- a/changelogs/unreleased/38604-add-private-profile.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add an option to have a private profile on GitLab. -merge_request: 20387 -author: jxterry -type: added diff --git a/changelogs/unreleased/40973-disable-rack-attack-by-default.yml b/changelogs/unreleased/40973-disable-rack-attack-by-default.yml deleted file mode 100644 index 681aa761e2a..00000000000 --- a/changelogs/unreleased/40973-disable-rack-attack-by-default.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rack attack is now disabled by default -merge_request: 16669 -author: -type: changed diff --git a/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml b/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml deleted file mode 100644 index b980b719d68..00000000000 --- a/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow non-admins to view instance statistics (if permitted by the instance admins) -merge_request: 20874 -author: -type: changed diff --git a/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml b/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml new file mode 100644 index 00000000000..c23676a3104 --- /dev/null +++ b/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml @@ -0,0 +1,5 @@ +--- +title: Add target branch name to cherrypick confirmation message +merge_request: 20846 +author: George Andrinopoulos +type: other diff --git a/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml b/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml deleted file mode 100644 index c6a0dc4f129..00000000000 --- a/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Fixing milestone date change when editing" -merge_request: 20279 -author: Orlando Del Aguila -type: fixed
\ No newline at end of file diff --git a/changelogs/unreleased/41784-monitoring-graph-popovers.yml b/changelogs/unreleased/41784-monitoring-graph-popovers.yml deleted file mode 100644 index 757445d7e0c..00000000000 --- a/changelogs/unreleased/41784-monitoring-graph-popovers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update design for system metrics popovers -merge_request: 20655 -author: -type: fixed diff --git a/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml b/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml deleted file mode 100644 index cabe5216045..00000000000 --- a/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds with_projects optional parameter to GET /groups/:id API endpoint -merge_request: 20494 -author: -type: changed diff --git a/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml b/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml deleted file mode 100644 index b60aeba860a..00000000000 --- a/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Vue datatype errors for markdownVersion parsing -merge_request: 20800 -author: -type: fixed diff --git a/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml b/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml new file mode 100644 index 00000000000..f4744c868ef --- /dev/null +++ b/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml @@ -0,0 +1,5 @@ +--- +title: Improve performance when fetching related merge requests for an issue +merge_request: 21237 +author: +type: performance diff --git a/changelogs/unreleased/43312-remove_user_activity_workers.yml b/changelogs/unreleased/43312-remove_user_activity_workers.yml deleted file mode 100644 index 6dfd018e350..00000000000 --- a/changelogs/unreleased/43312-remove_user_activity_workers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Delete UserActivities and related workers -merge_request: 20597 -author: -type: performance diff --git a/changelogs/unreleased/43625-increase-modal-checkout.yml b/changelogs/unreleased/43625-increase-modal-checkout.yml new file mode 100644 index 00000000000..877550924c1 --- /dev/null +++ b/changelogs/unreleased/43625-increase-modal-checkout.yml @@ -0,0 +1,5 @@ +--- +title: Increase width of checkout branch modal box +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml b/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml deleted file mode 100644 index de991ef475a..00000000000 --- a/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Board label edit dropdown shows incorrect selected labels summary -merge_request: 20673 -author: -type: fixed diff --git a/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml b/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml deleted file mode 100644 index ddc878ee710..00000000000 --- a/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds foreign key to notification_settings.user_id -merge_request: 20567 -author: Jacopo Beschi @jacopo-beschi -type: added diff --git a/changelogs/unreleased/45318-junit-FE.yml b/changelogs/unreleased/45318-junit-FE.yml deleted file mode 100644 index bbc08f54484..00000000000 --- a/changelogs/unreleased/45318-junit-FE.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds frontend support to render test reports on the MR widget -merge_request: 20936 -author: -type: added diff --git a/changelogs/unreleased/45318-vuex-store.yml b/changelogs/unreleased/45318-vuex-store.yml deleted file mode 100644 index 5ea89034bce..00000000000 --- a/changelogs/unreleased/45318-vuex-store.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds Vuex store for reports section in MR widget -merge_request: 20709 -author: -type: added diff --git a/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml b/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml deleted file mode 100644 index b18f7aec546..00000000000 --- a/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Resolve "Unable to save user profile update with Safari" -merge_request: 20676 -author: -type: fixed diff --git a/changelogs/unreleased/46165-web-ide-branch-picker.yml b/changelogs/unreleased/46165-web-ide-branch-picker.yml deleted file mode 100644 index ff879cb3d37..00000000000 --- a/changelogs/unreleased/46165-web-ide-branch-picker.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Create branch and MR picker for Web IDE -merge_request: 20978 -author: -type: changed diff --git a/changelogs/unreleased/46535-orphaned-uploads.yml b/changelogs/unreleased/46535-orphaned-uploads.yml deleted file mode 100644 index 1cd087a6aad..00000000000 --- a/changelogs/unreleased/46535-orphaned-uploads.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Clean orphaned files in object storage -merge_request: 20918 -author: -type: added diff --git a/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml b/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml deleted file mode 100644 index 5b91c6d5a9f..00000000000 --- a/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Solves group dashboard line height is too tall for group names. -merge_request: 21033 -author: -type: fixed diff --git a/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml b/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml deleted file mode 100644 index d490df58144..00000000000 --- a/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow cloning LFS repositories through DeployTokens -merge_request: 20729 -author: -type: other diff --git a/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml b/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml deleted file mode 100644 index d95714a5267..00000000000 --- a/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix updated_at if created_at is set for Note API -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml b/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml deleted file mode 100644 index 71e523e6de8..00000000000 --- a/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable hashed storage for all newly created or renamed projects -merge_request: 19747 -author: -type: changed diff --git a/changelogs/unreleased/47156-improve-auto-devops-settings.yml b/changelogs/unreleased/47156-improve-auto-devops-settings.yml deleted file mode 100644 index d8993565047..00000000000 --- a/changelogs/unreleased/47156-improve-auto-devops-settings.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve and simplify Auto DevOps settings flow -merge_request: 20946 -author: -type: other diff --git a/changelogs/unreleased/47419-Fix-breadcrumbs.yml b/changelogs/unreleased/47419-Fix-breadcrumbs.yml deleted file mode 100644 index 1a7f8196683..00000000000 --- a/changelogs/unreleased/47419-Fix-breadcrumbs.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix breadcrumbs in Admin/User interface. -merge_request: 19608 -author: Robin Naundorf -type: fixed diff --git a/changelogs/unreleased/47548-monospace-commit-messages.yml b/changelogs/unreleased/47548-monospace-commit-messages.yml deleted file mode 100644 index 7344f72207b..00000000000 --- a/changelogs/unreleased/47548-monospace-commit-messages.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update commit message styles with monospace font and overflow-x -merge_request: 20988 -author: -type: changed diff --git a/changelogs/unreleased/47728-mr-api-documentation-changes.yml b/changelogs/unreleased/47728-mr-api-documentation-changes.yml deleted file mode 100644 index 12720f280a1..00000000000 --- a/changelogs/unreleased/47728-mr-api-documentation-changes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove changes_count from MR API documentation where necessary -merge_request: 19745 -author: Jan Beckmann -type: fixed diff --git a/changelogs/unreleased/47768-web-ide-redesign-header.yml b/changelogs/unreleased/47768-web-ide-redesign-header.yml deleted file mode 100644 index 49133158164..00000000000 --- a/changelogs/unreleased/47768-web-ide-redesign-header.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Redesign Web IDE back button and context header -merge_request: 20850 -author: -type: changed diff --git a/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml b/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml deleted file mode 100644 index 6ff209b5181..00000000000 --- a/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Web IDE crashing on directories named 'blob' -merge_request: 20712 -author: -type: fixed diff --git a/changelogs/unreleased/48055-web-ide-resize-handles.yml b/changelogs/unreleased/48055-web-ide-resize-handles.yml deleted file mode 100644 index 0f650cdda6f..00000000000 --- a/changelogs/unreleased/48055-web-ide-resize-handles.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Increase width of Web IDE sidebar resize handles -merge_request: 20818 -author: -type: fixed diff --git a/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml b/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml deleted file mode 100644 index 43125ef25c4..00000000000 --- a/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Ensure installed Helm Tiller For GitLab Managed Apps Is protected by mutual - auth -merge_request: 20928 -author: -type: changed diff --git a/changelogs/unreleased/48246-osw-load-diffs-improvement.yml b/changelogs/unreleased/48246-osw-load-diffs-improvement.yml deleted file mode 100644 index c4292ab0d29..00000000000 --- a/changelogs/unreleased/48246-osw-load-diffs-improvement.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve performance when fetching collapsed diffs and commenting in merge requests -merge_request: 20940 -author: -type: performance diff --git a/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml b/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml deleted file mode 100644 index b3ccbb121f0..00000000000 --- a/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: fix height of full-width Metrics charts on large screens -merge_request: 20866 -author: -type: fixed diff --git a/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml b/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml deleted file mode 100644 index c34750a3b88..00000000000 --- a/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix the UI for listing system-level labels -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/48537-update-avatar-only-via-api.yml b/changelogs/unreleased/48537-update-avatar-only-via-api.yml deleted file mode 100644 index 9b3ab946cc1..00000000000 --- a/changelogs/unreleased/48537-update-avatar-only-via-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow updating a project's avatar without other params -merge_request: -author: Jamie Schembri -type: fixed diff --git a/changelogs/unreleased/48542-code-link.yml b/changelogs/unreleased/48542-code-link.yml deleted file mode 100644 index 8d8d9bf8d74..00000000000 --- a/changelogs/unreleased/48542-code-link.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix link color in markdown code brackets -merge_request: 20841 -author: -type: fixed diff --git a/changelogs/unreleased/48617-promoting-milestone.yml b/changelogs/unreleased/48617-promoting-milestone.yml deleted file mode 100644 index 7fbc15051cf..00000000000 --- a/changelogs/unreleased/48617-promoting-milestone.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Escapes milestone and label's names on flash notice when promoting them -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/48636-new-mr-card-styles.yml b/changelogs/unreleased/48636-new-mr-card-styles.yml deleted file mode 100644 index 94f62e677fb..00000000000 --- a/changelogs/unreleased/48636-new-mr-card-styles.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix new MR card styles -merge_request: 20822 -author: -type: fixed diff --git a/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml b/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml deleted file mode 100644 index 7ee018ef679..00000000000 --- a/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Persist 'Auto DevOps' banner dismissal globally -merge_request: 20540 -author: -type: other diff --git a/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml b/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml deleted file mode 100644 index f298380b920..00000000000 --- a/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add object storage logic to project import -merge_request: 20773 -author: -type: added diff --git a/changelogs/unreleased/48804-redesign-gcp-banner.yml b/changelogs/unreleased/48804-redesign-gcp-banner.yml deleted file mode 100644 index 729f959badc..00000000000 --- a/changelogs/unreleased/48804-redesign-gcp-banner.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Redesign GCP offer banner -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/48823-copy-gfm.yml b/changelogs/unreleased/48823-copy-gfm.yml deleted file mode 100644 index b6137e2e3f9..00000000000 --- a/changelogs/unreleased/48823-copy-gfm.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Resolve Copy diff file path as GFM is broken -merge_request: 20725 -author: -type: fixed diff --git a/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml b/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml deleted file mode 100644 index d79b95411aa..00000000000 --- a/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Chart versions for applications installed by one click install buttons should - be version locked -merge_request: 20765 -author: -type: fixed diff --git a/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml b/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml deleted file mode 100644 index 0466debea65..00000000000 --- a/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable SAML and Bitbucket if OmniAuth is disabled -merge_request: 20608 -author: -type: fixed diff --git a/changelogs/unreleased/48934.yml b/changelogs/unreleased/48934.yml deleted file mode 100644 index 8e2e53ed198..00000000000 --- a/changelogs/unreleased/48934.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve danger confirmation modals by focusing input field -merge_request: -author: Jamie Schembri -type: added diff --git a/changelogs/unreleased/48976-fix-sti-background-migration.yml b/changelogs/unreleased/48976-fix-sti-background-migration.yml deleted file mode 100644 index e95536b213c..00000000000 --- a/changelogs/unreleased/48976-fix-sti-background-migration.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "[Rails5] Fix 'Invalid single-table inheritance type: Group is not a subclass - of Gitlab::BackgroundMigration::FixCrossProjectLabelLinks::Namespace'" -merge_request: 20462 -author: "@blackst0ne" -type: fixed diff --git a/changelogs/unreleased/49025-docs-kubernetes-tiller.yml b/changelogs/unreleased/49025-docs-kubernetes-tiller.yml deleted file mode 100644 index c4f01490cfa..00000000000 --- a/changelogs/unreleased/49025-docs-kubernetes-tiller.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update docs of Helm Tiller -merge_request: 20515 -author: Takuya Noguchi -type: other diff --git a/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml b/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml deleted file mode 100644 index 541b562adac..00000000000 --- a/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: DNS prefetching if asset_host for CDN hosting is set -merge_request: 20781 -author: -type: performance diff --git a/changelogs/unreleased/49110-update-mr-widget-styles.yml b/changelogs/unreleased/49110-update-mr-widget-styles.yml new file mode 100644 index 00000000000..e54866a0908 --- /dev/null +++ b/changelogs/unreleased/49110-update-mr-widget-styles.yml @@ -0,0 +1,5 @@ +--- +title: Truncate branch names and update "commits behind" text in MR page +merge_request: 21206 +author: +type: changed diff --git a/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml b/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml deleted file mode 100644 index ab320450a1a..00000000000 --- a/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Gitaly Servers link into Admin > Overview navigation menu -merge_request: 20550 -author: -type: added diff --git a/changelogs/unreleased/49161-disable-toggle-comments.yml b/changelogs/unreleased/49161-disable-toggle-comments.yml deleted file mode 100644 index 5ec16191f07..00000000000 --- a/changelogs/unreleased/49161-disable-toggle-comments.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disables toggle comments button if diff has no discussions -merge_request: -author: -type: other diff --git a/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml b/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml deleted file mode 100644 index c757e55f1cd..00000000000 --- a/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Sanitize git URL in import errors -merge_request: -author: Jamie Schembri -type: fixed diff --git a/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml b/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml deleted file mode 100644 index f21bd454e84..00000000000 --- a/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix typo in CSS transform property for Memory Graph component -merge_request: 20650 -author: -type: fixed diff --git a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml new file mode 100644 index 00000000000..69089cfe357 --- /dev/null +++ b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml @@ -0,0 +1,5 @@ +--- +title: Add group name badge under group milestone +merge_request: 21384 +author: +type: added diff --git a/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml b/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml deleted file mode 100644 index a87eef3f7f3..00000000000 --- a/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add support for tar.gz AUTO_DEVOPS_CHART charts (#49324) -merge_request: 20691 -author: '@kondi1' -type: added diff --git a/changelogs/unreleased/49364-fix-broadcast-margin.yml b/changelogs/unreleased/49364-fix-broadcast-margin.yml deleted file mode 100644 index 821fb9df1af..00000000000 --- a/changelogs/unreleased/49364-fix-broadcast-margin.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix misalignment of broadcast message on login page -merge_request: 20794 -author: Robin Naundorf -type: fixed diff --git a/changelogs/unreleased/49375-move-help-popover.yml b/changelogs/unreleased/49375-move-help-popover.yml deleted file mode 100644 index 2547d5768bf..00000000000 --- a/changelogs/unreleased/49375-move-help-popover.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Moves help_popover component to a common location -merge_request: -author: -type: other diff --git a/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml b/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml deleted file mode 100644 index 043698269e2..00000000000 --- a/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed list of projects not loading in group boards -merge_request: 20955 -author: -type: fixed diff --git a/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml b/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml deleted file mode 100644 index 7eb73110d60..00000000000 --- a/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix sorting by name on milestones page -merge_request: 20881 -author: -type: fixed diff --git a/changelogs/unreleased/49747-update-poll-2xx.yml b/changelogs/unreleased/49747-update-poll-2xx.yml deleted file mode 100644 index 359d1b80447..00000000000 --- a/changelogs/unreleased/49747-update-poll-2xx.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Changes poll.js to keep polling on any 2xx http status code -merge_request: 20904 -author: -type: other diff --git a/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml b/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml deleted file mode 100644 index 96da2436a9f..00000000000 --- a/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: refactor pipeline job log animation to reduce CPU usage -merge_request: 20915 -author: -type: performance diff --git a/changelogs/unreleased/49830-use-helm-272.yml b/changelogs/unreleased/49830-use-helm-272.yml deleted file mode 100644 index f6ecc12dbfa..00000000000 --- a/changelogs/unreleased/49830-use-helm-272.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use Helm 2.7.2 for GitLab Managed Apps -merge_request: 20956 -author: -type: changed diff --git a/changelogs/unreleased/49835-increase-width.yml b/changelogs/unreleased/49835-increase-width.yml deleted file mode 100644 index f963c0c5e47..00000000000 --- a/changelogs/unreleased/49835-increase-width.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Increases title column on modal for reports -merge_request: -author: -type: other diff --git a/changelogs/unreleased/49851-link-to-runners.yml b/changelogs/unreleased/49851-link-to-runners.yml deleted file mode 100644 index 89fd6853bc8..00000000000 --- a/changelogs/unreleased/49851-link-to-runners.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Automatically expand runner's settings block when linking to the runner's settings - page -merge_request: -author: -type: other diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml deleted file mode 100644 index ffa4a3bc710..00000000000 --- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix rendering of the context lines in MR diffs page. -merge_request: 20968 -author: -type: fixed diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml deleted file mode 100644 index 42b0e4194f1..00000000000 --- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix autosave and ESC confirmation issues for MR discussions. -merge_request: 20968 -author: -type: fixed diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml deleted file mode 100644 index 29419091d02..00000000000 --- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix navigation to First and Next discussion on MR Changes tab. -merge_request: 20968 -author: -type: fixed diff --git a/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml b/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml deleted file mode 100644 index 30f5002c5b5..00000000000 --- a/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: fix error caused when using the search bar while unauthenticated -merge_request: 20970 -author: -type: fixed diff --git a/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml b/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml deleted file mode 100644 index 856a7c579f3..00000000000 --- a/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Ensure links in notifications footer are not escaped -merge_request: 21000 -author: -type: fixed diff --git a/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml b/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml deleted file mode 100644 index 2fce00a662f..00000000000 --- a/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix merge requests not showing any diff files for big patches -merge_request: 21125 -author: -type: fixed diff --git a/changelogs/unreleased/49966-improve-junit-fe.yml b/changelogs/unreleased/49966-improve-junit-fe.yml deleted file mode 100644 index 48971d3bfd6..00000000000 --- a/changelogs/unreleased/49966-improve-junit-fe.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Renders test reports for resolved failures and resets error state -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml new file mode 100644 index 00000000000..df05bf3f3e2 --- /dev/null +++ b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml @@ -0,0 +1,5 @@ +--- +title: Split remembering sorting for issues and merge requests +merge_request: 21153 +author: Jacopo Beschi @jacopo-beschi +type: fixed diff --git a/changelogs/unreleased/50101-env-block.yml b/changelogs/unreleased/50101-env-block.yml new file mode 100644 index 00000000000..11e603e7a79 --- /dev/null +++ b/changelogs/unreleased/50101-env-block.yml @@ -0,0 +1,5 @@ +--- +title: Creates vue component for environments information in job log view +merge_request: +author: +type: other diff --git a/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml b/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml deleted file mode 100644 index e081dfe6093..00000000000 --- a/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Auto-DevOps.gitlab-ci.yml: Update glibc package signing key URL' -merge_request: 21182 -author: sgerrand -type: fixed diff --git a/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml b/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml deleted file mode 100644 index eb20e34c466..00000000000 --- a/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix broken JavaScript in IE11 -merge_request: 21214 -author: -type: fixed diff --git a/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml b/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml deleted file mode 100644 index 50a3b9c9aff..00000000000 --- a/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix issue stopping Instance Statistics javascript to be executed -merge_request: 21211 -author: -type: fixed diff --git a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml new file mode 100644 index 00000000000..4c5182b843b --- /dev/null +++ b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml @@ -0,0 +1,5 @@ +--- +title: Feature flag to disable Hashed Storage migration when renaming a repository +merge_request: 21291 +author: +type: added diff --git a/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml b/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml new file mode 100644 index 00000000000..3e360f8d6bb --- /dev/null +++ b/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml @@ -0,0 +1,5 @@ +--- +title: Removing a group no longer triggers hooks for project deletion twice +merge_request: 21366 +author: +type: fixed diff --git a/changelogs/unreleased/50524-artifacts-sm.yml b/changelogs/unreleased/50524-artifacts-sm.yml new file mode 100644 index 00000000000..22bd097f911 --- /dev/null +++ b/changelogs/unreleased/50524-artifacts-sm.yml @@ -0,0 +1,5 @@ +--- +title: Shows download artifacts button for pipelines on small screens +merge_request: +author: +type: changed diff --git a/changelogs/unreleased/50584-fix-ide-commit-twice.yml b/changelogs/unreleased/50584-fix-ide-commit-twice.yml new file mode 100644 index 00000000000..92b292cf4ab --- /dev/null +++ b/changelogs/unreleased/50584-fix-ide-commit-twice.yml @@ -0,0 +1,5 @@ +--- +title: Fix Web IDE unable to commit to same file twice +merge_request: 21372 +author: +type: fixed diff --git a/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml b/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml new file mode 100644 index 00000000000..6e57a215367 --- /dev/null +++ b/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml @@ -0,0 +1,5 @@ +--- +title: Don't show flash messages for performance bar errors +merge_request: 21411 +author: +type: other diff --git a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml new file mode 100644 index 00000000000..94098dd0144 --- /dev/null +++ b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml @@ -0,0 +1,6 @@ +--- +title: Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress + Bar +merge_request: 21306 +author: +type: fixed diff --git a/changelogs/unreleased/6860-FE-instance-level-project-templates.yml b/changelogs/unreleased/6860-FE-instance-level-project-templates.yml deleted file mode 100644 index 74e0daee71b..00000000000 --- a/changelogs/unreleased/6860-FE-instance-level-project-templates.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update design of project templates -merge_request: 21012 -author: -type: changed diff --git a/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml b/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml deleted file mode 100644 index 97d017613ba..00000000000 --- a/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Emails on push recipients now accepts formats like John Doe <johndoe@example.com> -merge_request: -author: George Thomas -type: added diff --git a/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml b/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml deleted file mode 100644 index 08376014ad7..00000000000 --- a/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add support for daylight savings time to pipleline schedules -merge_request: 20145 -author: -type: fixed diff --git a/changelogs/unreleased/add-homepage-link-to-status-pages.yml b/changelogs/unreleased/add-homepage-link-to-status-pages.yml deleted file mode 100644 index 0e7375f2061..00000000000 --- a/changelogs/unreleased/add-homepage-link-to-status-pages.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add link to homepage on static http status pages (404, 500, etc) -merge_request: 20898 -author: Jason Funk -type: added diff --git a/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml b/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml deleted file mode 100644 index 4f9a551d13e..00000000000 --- a/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add merge request header branch actions left margin -merge_request: 20643 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml b/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml deleted file mode 100644 index 37a4e31896e..00000000000 --- a/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Add a Gitlab::Profiler.print_by_total_time convenience method for profiling - from a Rails console -merge_request: -author: -type: other diff --git a/changelogs/unreleased/api-empty-commit-message.yml b/changelogs/unreleased/api-empty-commit-message.yml new file mode 100644 index 00000000000..34ddc020644 --- /dev/null +++ b/changelogs/unreleased/api-empty-commit-message.yml @@ -0,0 +1,5 @@ +--- +title: 'API: Catch empty commit messages' +merge_request: 21322 +author: Robert Schilling +type: fixed diff --git a/changelogs/unreleased/api-empty-project-snippets.yml b/changelogs/unreleased/api-empty-project-snippets.yml new file mode 100644 index 00000000000..7b8c7c9e48d --- /dev/null +++ b/changelogs/unreleased/api-empty-project-snippets.yml @@ -0,0 +1,5 @@ +--- +title: 'API: Catch empty code content for project snippets' +merge_request: 21325 +author: Robert Schilling +type: fixed diff --git a/changelogs/unreleased/api-minimal-access-level.yml b/changelogs/unreleased/api-minimal-access-level.yml deleted file mode 100644 index 43cab246d69..00000000000 --- a/changelogs/unreleased/api-minimal-access-level.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add filter for minimal access level in groups and projects API -merge_request: 20478 -author: Marko, Peter -type: added diff --git a/changelogs/unreleased/api-protected-tags.yml b/changelogs/unreleased/api-protected-tags.yml new file mode 100644 index 00000000000..6e7ecf24b6e --- /dev/null +++ b/changelogs/unreleased/api-protected-tags.yml @@ -0,0 +1,5 @@ +--- +title: 'API: Protected tags' +merge_request: 14986 +author: Robert Schilling +type: added diff --git a/changelogs/unreleased/api-shared_group_expires-at.yml b/changelogs/unreleased/api-shared_group_expires-at.yml new file mode 100644 index 00000000000..3d569de65fa --- /dev/null +++ b/changelogs/unreleased/api-shared_group_expires-at.yml @@ -0,0 +1,5 @@ +--- +title: 'API: Add expiration date for shared projects to the project entity' +merge_request: 21104 +author: Robert Schilling +type: added diff --git a/changelogs/unreleased/arguments-keyword-sast.yml b/changelogs/unreleased/arguments-keyword-sast.yml new file mode 100644 index 00000000000..2ecbc5e8174 --- /dev/null +++ b/changelogs/unreleased/arguments-keyword-sast.yml @@ -0,0 +1,5 @@ +--- +title: Don't use arguments keyword in gettext script +merge_request: 21296 +author: gfyoung +type: fixed diff --git a/changelogs/unreleased/artifact-format-v2-with-parser.yml b/changelogs/unreleased/artifact-format-v2-with-parser.yml deleted file mode 100644 index e1a779cf6dd..00000000000 --- a/changelogs/unreleased/artifact-format-v2-with-parser.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: JUnit XML Test Summary In MR widget -merge_request: 20576 -author: -type: added diff --git a/changelogs/unreleased/artifact-format-v2.yml b/changelogs/unreleased/artifact-format-v2.yml deleted file mode 100644 index e264e0a9fa1..00000000000 --- a/changelogs/unreleased/artifact-format-v2.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Extend gitlab-ci.yml to request junit.xml test reports -merge_request: 20390 -author: -type: added diff --git a/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml b/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml deleted file mode 100644 index 69e6b7d815a..00000000000 --- a/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Replace 'Sidekiq::Testing.inline!' with 'perform_enqueued_jobs' -merge_request: 20768 -author: "@blackst0ne" -type: other diff --git a/changelogs/unreleased/bvl-add-galician.yml b/changelogs/unreleased/bvl-add-galician.yml new file mode 100644 index 00000000000..e7035901ace --- /dev/null +++ b/changelogs/unreleased/bvl-add-galician.yml @@ -0,0 +1,5 @@ +--- +title: Add Galician as an available language. +merge_request: 21202 +author: +type: added diff --git a/changelogs/unreleased/bvl-graphql-wip-mutation.yml b/changelogs/unreleased/bvl-graphql-wip-mutation.yml deleted file mode 100644 index 00aa1c48677..00000000000 --- a/changelogs/unreleased/bvl-graphql-wip-mutation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add the first mutations for merge requests to GraphQL -merge_request: 20443 -author: -type: added diff --git a/changelogs/unreleased/bvl-user-status-message-35463.yml b/changelogs/unreleased/bvl-user-status-message-35463.yml deleted file mode 100644 index c844e7ea0e4..00000000000 --- a/changelogs/unreleased/bvl-user-status-message-35463.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Users can set a status message and emoji -merge_request: 20614 -author: niedermyer & davamr -type: added diff --git a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml new file mode 100644 index 00000000000..12ef6e3f790 --- /dev/null +++ b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml @@ -0,0 +1,5 @@ +--- +title: Allow author to vote on their own issue and MRs +merge_request: 21203 +author: +type: changed diff --git a/changelogs/unreleased/ccr-48800-ping_for_boards.yml b/changelogs/unreleased/ccr-48800-ping_for_boards.yml new file mode 100644 index 00000000000..c08578cddba --- /dev/null +++ b/changelogs/unreleased/ccr-48800-ping_for_boards.yml @@ -0,0 +1,6 @@ +--- +title: Adds count for different board list types (label lists, assignee lists, and + milestone lists) to usage statistics. +merge_request: 21208 +author: +type: changed diff --git a/changelogs/unreleased/ce-5666-backport.yml b/changelogs/unreleased/ce-5666-backport.yml deleted file mode 100644 index 344f1a1983f..00000000000 --- a/changelogs/unreleased/ce-5666-backport.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: CE port of "List groups with developer maintainer access on project creation" -merge_request: 21051 -author: -type: other diff --git a/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml b/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml deleted file mode 100644 index b76437a8773..00000000000 --- a/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Tracking the number of repositories and wikis with a cached counter for site-wide statistics -merge_request: 20413 -author: -type: performance diff --git a/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml b/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml deleted file mode 100644 index 49648cdfcfc..00000000000 --- a/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Close revert and cherry pick modal on escape keypress -merge_request: 20341 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml b/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml deleted file mode 100644 index b87a1e5faf7..00000000000 --- a/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds the ability to view group milestones on the dashboard milestone page. -merge_request: 20618 -author: -type: fixed diff --git a/changelogs/unreleased/cr-add-path-of-group-milestone.yml b/changelogs/unreleased/cr-add-path-of-group-milestone.yml deleted file mode 100644 index 5ce240110ef..00000000000 --- a/changelogs/unreleased/cr-add-path-of-group-milestone.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds the project and group name to the return type for project and group milestones. -merge_request: 20890 -author: -type: changed diff --git a/changelogs/unreleased/custom_wiki_sidebar.yml b/changelogs/unreleased/custom_wiki_sidebar.yml deleted file mode 100644 index 988fccc929c..00000000000 --- a/changelogs/unreleased/custom_wiki_sidebar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Custom Wiki Sidebar Support Issue 14995" -merge_request: -author: Josh Sooter -type: added diff --git a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml new file mode 100644 index 00000000000..67926f3738a --- /dev/null +++ b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml @@ -0,0 +1,5 @@ +--- +title: Fix SQL error when sorting 2FA-enabled users by name in admin area +merge_request: 21324 +author: +type: fixed diff --git a/changelogs/unreleased/dz-labels-search.yml b/changelogs/unreleased/dz-labels-search.yml deleted file mode 100644 index 49c1b6c1a86..00000000000 --- a/changelogs/unreleased/dz-labels-search.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Search for labels by title or description on project labels page -merge_request: 20749 -author: -type: added diff --git a/changelogs/unreleased/dz-manifest-import.yml b/changelogs/unreleased/dz-manifest-import.yml deleted file mode 100644 index b0d29b0869f..00000000000 --- a/changelogs/unreleased/dz-manifest-import.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add ability to import multiple repositories by uploading a manifest file -merge_request: 20304 -author: -type: added diff --git a/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml b/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml new file mode 100644 index 00000000000..0b8ae527214 --- /dev/null +++ b/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml @@ -0,0 +1,5 @@ +--- +title: Expose user's id in /admin/users/ show page +merge_request: +author: Eva Kadlecova +type: changed diff --git a/changelogs/unreleased/feature-gb-email-delivery-metrics.yml b/changelogs/unreleased/feature-gb-email-delivery-metrics.yml deleted file mode 100644 index 9d0d08a471d..00000000000 --- a/changelogs/unreleased/feature-gb-email-delivery-metrics.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add emails delivery Prometheus metrics -merge_request: 20638 -author: -type: added diff --git a/changelogs/unreleased/feature-gb-login-activity-metrics.yml b/changelogs/unreleased/feature-gb-login-activity-metrics.yml deleted file mode 100644 index 5d687b984eb..00000000000 --- a/changelogs/unreleased/feature-gb-login-activity-metrics.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add more comprehensive metrics tracking authentication activity -merge_request: 20668 -author: -type: added diff --git a/changelogs/unreleased/features-show-project-id-on-home-panel.yml b/changelogs/unreleased/features-show-project-id-on-home-panel.yml deleted file mode 100644 index f592be07a52..00000000000 --- a/changelogs/unreleased/features-show-project-id-on-home-panel.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show Project ID on project home panel -merge_request: 20305 -author: Tuğçe Nur Taş -type: added diff --git a/changelogs/unreleased/fix-api-group-createdat.yml b/changelogs/unreleased/fix-api-group-createdat.yml new file mode 100644 index 00000000000..e628facf1bf --- /dev/null +++ b/changelogs/unreleased/fix-api-group-createdat.yml @@ -0,0 +1,5 @@ +--- +title: Allow date parameters on Issues, Notes, and Discussions API for group owners +merge_request: 21342 +author: Florent Dubois +type: fixed diff --git a/changelogs/unreleased/fix-diff-note.yml b/changelogs/unreleased/fix-diff-note.yml deleted file mode 100644 index 6f10f86b9bc..00000000000 --- a/changelogs/unreleased/fix-diff-note.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix serialization of LegacyDiffNote -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-email-confirmation-addtional-email.yml b/changelogs/unreleased/fix-email-confirmation-addtional-email.yml deleted file mode 100644 index 56a2efa4d60..00000000000 --- a/changelogs/unreleased/fix-email-confirmation-addtional-email.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix email confirmation bug when user adds additional email to account -merge_request: 20084 -author: muhammadn -type: fixed diff --git a/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml b/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml deleted file mode 100644 index 7e9e8c33a71..00000000000 --- a/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add missing predefined variable and fix docs -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml b/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml deleted file mode 100644 index 80b069c9251..00000000000 --- a/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix accessing imported pipeline builds -merge_request: 20713 -author: -type: fixed diff --git a/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml b/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml deleted file mode 100644 index adf582e34a2..00000000000 --- a/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Limit maximum project build timeout setting to 1 month -merge_request: 20591 -author: -type: fixed diff --git a/changelogs/unreleased/fix-mr-title-fallback-logic.yml b/changelogs/unreleased/fix-mr-title-fallback-logic.yml new file mode 100644 index 00000000000..5056c38573b --- /dev/null +++ b/changelogs/unreleased/fix-mr-title-fallback-logic.yml @@ -0,0 +1,5 @@ +--- +title: Fix fallback logic for automatic MR title assignment +merge_request: 20930 +author: Franz Liedke +type: fixed diff --git a/changelogs/unreleased/fix-multiple-scopes.yml b/changelogs/unreleased/fix-multiple-scopes.yml deleted file mode 100644 index 24e5172d9a1..00000000000 --- a/changelogs/unreleased/fix-multiple-scopes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Support multiple scopes when authing container registry scopes -merge_request: 20617 -author: -type: fixed diff --git a/changelogs/unreleased/fix-project-api-archived.yml b/changelogs/unreleased/fix-project-api-archived.yml deleted file mode 100644 index 9d119fd3429..00000000000 --- a/changelogs/unreleased/fix-project-api-archived.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix archived parameter for projects API -merge_request: 20566 -author: Peter Marko -type: fixed diff --git a/changelogs/unreleased/fix-prometheus-updated-status.yml b/changelogs/unreleased/fix-prometheus-updated-status.yml deleted file mode 100644 index 7261c3429c8..00000000000 --- a/changelogs/unreleased/fix-prometheus-updated-status.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix UI error whereby prometheus application status is updated -merge_request: 21029 -author: -type: fixed diff --git a/changelogs/unreleased/fix-search-bar.yml b/changelogs/unreleased/fix-search-bar.yml deleted file mode 100644 index d4c0c1efddf..00000000000 --- a/changelogs/unreleased/fix-search-bar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix search bar text input alignment -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml b/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml deleted file mode 100644 index 6a3e1420726..00000000000 --- a/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update total storage size when changing size of artifacts -merge_request: 20697 -author: Peter Marko -type: fixed diff --git a/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml b/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml deleted file mode 100644 index 0b35c5c6786..00000000000 --- a/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Performing Commit GPG signature calculation in bulk -merge_request: 20870 -author: -type: performance diff --git a/changelogs/unreleased/fj-48123-fix-gitlab-import.yml b/changelogs/unreleased/fj-48123-fix-gitlab-import.yml deleted file mode 100644 index 896db2cdcb8..00000000000 --- a/changelogs/unreleased/fj-48123-fix-gitlab-import.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix GitLab project imports not loading due to API timeouts -merge_request: 20599 -author: -type: fixed diff --git a/changelogs/unreleased/fj-49014-wiki-search-error.yml b/changelogs/unreleased/fj-49014-wiki-search-error.yml deleted file mode 100644 index a76805cb7f9..00000000000 --- a/changelogs/unreleased/fj-49014-wiki-search-error.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed bug with invalid repository reference using the wiki search -merge_request: 20722 -author: -type: fixed diff --git a/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml b/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml deleted file mode 100644 index 3af90fff3f6..00000000000 --- a/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Prevent editing and updating wiki pages with non UTF-8 encoding via web interface -merge_request: 20906 -author: -type: fixed diff --git a/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml b/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml deleted file mode 100644 index ba61d378cda..00000000000 --- a/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix bug setting http headers in Files API -merge_request: 20938 -author: -type: fixed diff --git a/changelogs/unreleased/floating-avarage-commit-numbers.yml b/changelogs/unreleased/floating-avarage-commit-numbers.yml deleted file mode 100644 index 7f91ab16af4..00000000000 --- a/changelogs/unreleased/floating-avarage-commit-numbers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show one digit after dot in commit_per_day value in charts page. -merge_request: -author: msdundar -type: changed diff --git a/changelogs/unreleased/frozen-string-danger.yml b/changelogs/unreleased/frozen-string-danger.yml deleted file mode 100644 index 9910139b8a9..00000000000 --- a/changelogs/unreleased/frozen-string-danger.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add Dangerfile for frozen_string_literal -merge_request: 20767 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-models-more.yml b/changelogs/unreleased/frozen-string-enable-app-models-more.yml deleted file mode 100644 index c0466984134..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-models-more.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string for app/models/**/*.rb -merge_request: 21001 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-models.yml b/changelogs/unreleased/frozen-string-enable-app-models.yml deleted file mode 100644 index 4c149ea55ef..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-models.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in app/models/*.rb -merge_request: 20851 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml b/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml deleted file mode 100644 index 5c6b1b1a904..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in app/presenters and app/policies -merge_request: 20819 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-serializers.yml b/changelogs/unreleased/frozen-string-enable-app-serializers.yml deleted file mode 100644 index 40c7b695d39..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-serializers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in app/serializers/**/*.rb -merge_request: 20726 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-services.yml b/changelogs/unreleased/frozen-string-enable-app-services.yml deleted file mode 100644 index cfc1f356e3a..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-services.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in apps/uploaders/*.rb -merge_request: 20401 -author: gfyoung -type: other diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml deleted file mode 100644 index cee790a07ff..00000000000 --- a/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable even more frozen string in app/services/**/*.rb -merge_request: 20702 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml deleted file mode 100644 index ea962cf8edc..00000000000 --- a/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable more frozen string in app/services/**/*.rb -merge_request: 20677 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml deleted file mode 100644 index 16b8ec3908f..00000000000 --- a/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in app/services/**/*.rb -merge_request: 20656 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-vestigial.yml b/changelogs/unreleased/frozen-string-vestigial.yml deleted file mode 100644 index 79e92a19a7a..00000000000 --- a/changelogs/unreleased/frozen-string-vestigial.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in newly added files to previously processed directories -merge_request: 20763 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml b/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml deleted file mode 100644 index b26eb82b6c9..00000000000 --- a/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Removes "show all" on reports and adds an actionButtons slot -merge_request: 20855 -author: -type: changed diff --git a/changelogs/unreleased/git-rerere-link-doc-update.yml b/changelogs/unreleased/git-rerere-link-doc-update.yml deleted file mode 100644 index 06093e8ec13..00000000000 --- a/changelogs/unreleased/git-rerere-link-doc-update.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update git rerere link in docs -merge_request: 21060 -author: gfyoung -type: other diff --git a/changelogs/unreleased/hangouts_chat_integration.yml b/changelogs/unreleased/hangouts_chat_integration.yml deleted file mode 100644 index bf3484a6d02..00000000000 --- a/changelogs/unreleased/hangouts_chat_integration.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add Hangouts Chat integration -merge_request: 20290 -author: Kukovskii Vladimir -type: added diff --git a/changelogs/unreleased/ide-codesandbox-poc.yml b/changelogs/unreleased/ide-codesandbox-poc.yml deleted file mode 100644 index 7da1f4e6472..00000000000 --- a/changelogs/unreleased/ide-codesandbox-poc.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added live preview for JavaScript projects in the Web IDE -merge_request: 19764 -author: -type: added diff --git a/changelogs/unreleased/ide-delete-entries.yml b/changelogs/unreleased/ide-delete-entries.yml deleted file mode 100644 index 8cbc0739406..00000000000 --- a/changelogs/unreleased/ide-delete-entries.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enabled deletion of files in the Web IDE -merge_request: -author: -type: added diff --git a/changelogs/unreleased/ide-pipeline-icon-open.yml b/changelogs/unreleased/ide-pipeline-icon-open.yml deleted file mode 100644 index 3a73ff2170f..00000000000 --- a/changelogs/unreleased/ide-pipeline-icon-open.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Clicking CI icon in Web IDE now opens up pipelines panel -merge_request: -author: -type: added diff --git a/changelogs/unreleased/ide-rename-files.yml b/changelogs/unreleased/ide-rename-files.yml deleted file mode 100644 index c2db284e07c..00000000000 --- a/changelogs/unreleased/ide-rename-files.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable renaming files and folders in Web IDE -merge_request: 20835 -author: -type: added diff --git a/changelogs/unreleased/ide-row-dropdown-design-update.yml b/changelogs/unreleased/ide-row-dropdown-design-update.yml deleted file mode 100644 index e0fe64c944e..00000000000 --- a/changelogs/unreleased/ide-row-dropdown-design-update.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Updated design of new entry dropdown in Web IDE -merge_request: 20526 -author: -type: changed diff --git a/changelogs/unreleased/ide-warn-staged-files.yml b/changelogs/unreleased/ide-warn-staged-files.yml deleted file mode 100644 index ae3c4f392c0..00000000000 --- a/changelogs/unreleased/ide-warn-staged-files.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Warn user when reload IDE with staged changes -merge_request: 20857 -author: -type: added diff --git a/changelogs/unreleased/improve-junit-support-be.yml b/changelogs/unreleased/improve-junit-support-be.yml deleted file mode 100644 index db4d47caa7c..00000000000 --- a/changelogs/unreleased/improve-junit-support-be.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve JUnit test reports in merge request widgets -merge_request: 49966 -author: -type: fixed diff --git a/changelogs/unreleased/improve-metadata-access-performance.yml b/changelogs/unreleased/improve-metadata-access-performance.yml deleted file mode 100644 index b16fa99dd3b..00000000000 --- a/changelogs/unreleased/improve-metadata-access-performance.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Access metadata directly from Object Storage -merge_request: -author: -type: performance diff --git a/changelogs/unreleased/issue_36138.yml b/changelogs/unreleased/issue_36138.yml new file mode 100644 index 00000000000..2fb2eea65f5 --- /dev/null +++ b/changelogs/unreleased/issue_36138.yml @@ -0,0 +1,5 @@ +--- +title: Allow to delete group milestones +merge_request: +author: +type: added diff --git a/changelogs/unreleased/issue_43602.yml b/changelogs/unreleased/issue_43602.yml deleted file mode 100644 index 0482606db0a..00000000000 --- a/changelogs/unreleased/issue_43602.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow multiple JIRA transition ids -merge_request: 20939 -author: -type: changed diff --git a/changelogs/unreleased/issue_44821.yml b/changelogs/unreleased/issue_44821.yml deleted file mode 100644 index b1807e069af..00000000000 --- a/changelogs/unreleased/issue_44821.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Retrieve merge request closing issues from database cache -merge_request: 20911 -author: -type: fixed diff --git a/changelogs/unreleased/issue_47709.yml b/changelogs/unreleased/issue_47709.yml deleted file mode 100644 index c3ef55fd692..00000000000 --- a/changelogs/unreleased/issue_47709.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Allow to toggle notifications for issues due soon' -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/jprovazn-fix-form-uploads.yml b/changelogs/unreleased/jprovazn-fix-form-uploads.yml new file mode 100644 index 00000000000..8bcee335e93 --- /dev/null +++ b/changelogs/unreleased/jprovazn-fix-form-uploads.yml @@ -0,0 +1,5 @@ +--- +title: Accept upload files in public/uplaods/tmp when using accelerated uploads. +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/jprovazn-resource-events.yml b/changelogs/unreleased/jprovazn-resource-events.yml deleted file mode 100644 index 05643150f16..00000000000 --- a/changelogs/unreleased/jprovazn-resource-events.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add new model for tracking label events. -merge_request: -author: -type: added diff --git a/changelogs/unreleased/jr-archive-hook.yml b/changelogs/unreleased/jr-archive-hook.yml deleted file mode 100644 index 56c13f1370e..00000000000 --- a/changelogs/unreleased/jr-archive-hook.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Trigger system hooks when project is archived/unarchived -merge_request: 20995 -author: -type: added diff --git a/changelogs/unreleased/jupyter-image.yml b/changelogs/unreleased/jupyter-image.yml deleted file mode 100644 index 8aeefd603d8..00000000000 --- a/changelogs/unreleased/jupyter-image.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rubix, scikit-learn, tensorflow & other useful libraries pre-installed with JupyterHub -merge_request: 20714 -author: Amit Rathi -type: changed diff --git a/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml b/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml deleted file mode 100644 index c15d73a0c12..00000000000 --- a/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add 'tabindex' attribute support on Icon component to show BS4 popover on trigger type 'focus' -merge_request: 21066 -author: -type: other diff --git a/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml b/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml deleted file mode 100644 index a2fca4c5b91..00000000000 --- a/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show decimal place up to single digit in Stacked Progress Bar -merge_request: 20776 -author: -type: changed diff --git a/changelogs/unreleased/leipert-fix-pipelines-view.yml b/changelogs/unreleased/leipert-fix-pipelines-view.yml deleted file mode 100644 index 7bcc2e84cd2..00000000000 --- a/changelogs/unreleased/leipert-fix-pipelines-view.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix rendering of pipeline failure view when directly navigationg to it -merge_request: 21043 -author: -type: fixed diff --git a/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml b/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml deleted file mode 100644 index 9d38b353a41..00000000000 --- a/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add local project uploads cleanup task -merge_request: 20863 -author: -type: added diff --git a/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml b/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml deleted file mode 100644 index 8e71377d93f..00000000000 --- a/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix namespace move callback behavior, especially to fix Geo replication of namespace moves during certain exceptions. -merge_request: 19297 -author: -type: fixed diff --git a/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml b/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml deleted file mode 100644 index 62416b7f87e..00000000000 --- a/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix missing and duplicates on project milestone listing page -merge_request: 21058 -author: -type: fixed diff --git a/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml b/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml deleted file mode 100644 index dc8148fa1a5..00000000000 --- a/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Avoid N+1 on MRs page when metrics merging date cannot be found -merge_request: 21053 -author: -type: performance diff --git a/changelogs/unreleased/pl-json-gon.yml b/changelogs/unreleased/pl-json-gon.yml deleted file mode 100644 index c0f93006c07..00000000000 --- a/changelogs/unreleased/pl-json-gon.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Don't set gon variables in JSON requests -merge_request: 21016 -author: Peter Leitzen -type: performance diff --git a/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml b/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml deleted file mode 100644 index 6994a238074..00000000000 --- a/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Process commits as normal in forks when the upstream project is deleted -merge_request: 20534 -author: -type: fixed diff --git a/changelogs/unreleased/project-visibility-tooltip.yml b/changelogs/unreleased/project-visibility-tooltip.yml deleted file mode 100644 index 806c93e493a..00000000000 --- a/changelogs/unreleased/project-visibility-tooltip.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix project visibility tooltip -merge_request: 20535 -author: Jamie Schembri -type: fixed diff --git a/changelogs/unreleased/rails5-fix-48977.yml b/changelogs/unreleased/rails5-fix-48977.yml deleted file mode 100644 index bfd86f20e24..00000000000 --- a/changelogs/unreleased/rails5-fix-48977.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 fix mysql milliseconds problem in specs -merge_request: 20464 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml b/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml deleted file mode 100644 index 5f2504c604d..00000000000 --- a/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails5: fix flaky spec' -merge_request: 20953 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml b/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml new file mode 100644 index 00000000000..661bd748333 --- /dev/null +++ b/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml @@ -0,0 +1,5 @@ +--- +title: 'Rails5: fix can''t quote ActiveSupport::HashWithIndifferentAccess' +merge_request: 21397 +author: Jasper Maes +type: other diff --git a/changelogs/unreleased/rails5-fix-revert-modal-spec.yml b/changelogs/unreleased/rails5-fix-revert-modal-spec.yml deleted file mode 100644 index 0637e503ca9..00000000000 --- a/changelogs/unreleased/rails5-fix-revert-modal-spec.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 fix user sees revert modal spec -merge_request: 20706 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-gpg-permit-concurrent.yml b/changelogs/unreleased/rails5-gpg-permit-concurrent.yml deleted file mode 100644 index cf1b0023f86..00000000000 --- a/changelogs/unreleased/rails5-gpg-permit-concurrent.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Permit concurrent loads in gpg keychain mutex -merge_request: 20894 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml b/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml deleted file mode 100644 index afd9865ee45..00000000000 --- a/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 mysql fix milliseconds problem in pull request importer spec -merge_request: 20475 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-mysql-rename-column.yml b/changelogs/unreleased/rails5-mysql-rename-column.yml deleted file mode 100644 index cbae9250744..00000000000 --- a/changelogs/unreleased/rails5-mysql-rename-column.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 MySQL fix rename_column as part of cleanup_concurrent_column_type_change -merge_request: 20514 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-silence-stream.yml b/changelogs/unreleased/rails5-silence-stream.yml new file mode 100644 index 00000000000..df4fd14a077 --- /dev/null +++ b/changelogs/unreleased/rails5-silence-stream.yml @@ -0,0 +1,5 @@ +--- +title: 'Rails 5: replace removed silence_stream' +merge_request: 21387 +author: Jasper Maes +type: other diff --git a/changelogs/unreleased/rails5-update-gemfile-lock-2.yml b/changelogs/unreleased/rails5-update-gemfile-lock-2.yml deleted file mode 100644 index 1f3e9bd2238..00000000000 --- a/changelogs/unreleased/rails5-update-gemfile-lock-2.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 update Gemfile.rails5.lock -merge_request: 20858 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-update-gemfile-lock.yml b/changelogs/unreleased/rails5-update-gemfile-lock.yml index 58931587fff..3891b16e2b8 100644 --- a/changelogs/unreleased/rails5-update-gemfile-lock.yml +++ b/changelogs/unreleased/rails5-update-gemfile-lock.yml @@ -1,5 +1,5 @@ --- -title: Update Gemfile.rails5.lock with latest Gemfile.lock changes -merge_request: 20466 +title: Rails5 update Gemfile.rails5.lock +merge_request: 21388 author: Jasper Maes -type: fixed +type: other diff --git a/changelogs/unreleased/rails5-update-rouge.yml b/changelogs/unreleased/rails5-update-rouge.yml deleted file mode 100644 index 1173b3b7e9a..00000000000 --- a/changelogs/unreleased/rails5-update-rouge.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails5: update Rails5 lock for forgotten gem rouge' -merge_request: 21010 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml b/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml deleted file mode 100644 index fd5a6521882..00000000000 --- a/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Cleans up display of Deploy Tokens to match Personal Access Tokens" -merge_request: 20578 -author: Marcel Amirault -type: added
\ No newline at end of file diff --git a/changelogs/unreleased/regen-2fa-codes.yml b/changelogs/unreleased/regen-2fa-codes.yml deleted file mode 100644 index 596f759df0f..00000000000 --- a/changelogs/unreleased/regen-2fa-codes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added button to regenerate 2FA codes -merge_request: -author: Luke Picciau -type: added diff --git a/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml b/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml deleted file mode 100644 index 8d5ecdfa57e..00000000000 --- a/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Replace snake case in SCSS variables -merge_request: 20799 -author: George Tsiolis -type: other diff --git a/changelogs/unreleased/replace-snake-case-css-classes.yml b/changelogs/unreleased/replace-snake-case-css-classes.yml deleted file mode 100644 index 28ec5ee097f..00000000000 --- a/changelogs/unreleased/replace-snake-case-css-classes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Replace author_link snake case in stylesheets, specs, and helpers -merge_request: 20797 -author: George Tsiolis -type: other diff --git a/changelogs/unreleased/rouge-3-2-0.yml b/changelogs/unreleased/rouge-3-2-0.yml deleted file mode 100644 index 15ac4cc1e76..00000000000 --- a/changelogs/unreleased/rouge-3-2-0.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes -merge_request: 20991 -author: -type: changed diff --git a/changelogs/unreleased/rouge_3-2-1.yml b/changelogs/unreleased/rouge_3-2-1.yml deleted file mode 100644 index b281a4f0e95..00000000000 --- a/changelogs/unreleased/rouge_3-2-1.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update to Rouge 3.2.1, which includes a critical fix to the Perl Lexer -merge_request: 21263 -author: -type: changed diff --git a/changelogs/unreleased/runner-features.yml b/changelogs/unreleased/runner-features.yml deleted file mode 100644 index c5e0fff5a18..00000000000 --- a/changelogs/unreleased/runner-features.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Verify runner feature set -merge_request: 20664 -author: -type: added diff --git a/changelogs/unreleased/runners-max-timeout-param.yml b/changelogs/unreleased/runners-max-timeout-param.yml deleted file mode 100644 index 875f805d849..00000000000 --- a/changelogs/unreleased/runners-max-timeout-param.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add missing maximum_timeout parameter -merge_request: 20355 -author: gfyoung -type: fixed diff --git a/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml b/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml deleted file mode 100644 index 7bfe1b5778f..00000000000 --- a/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Include full image URL in webhooks for uploaded images -merge_request: 18109 -author: Satish Perala -type: changed diff --git a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml new file mode 100644 index 00000000000..dc15d356c1c --- /dev/null +++ b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml @@ -0,0 +1,5 @@ +--- +title: Fixed persistent XSS rendering/escaping of diff location lines +merge_request: +author: +type: security diff --git a/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml b/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml deleted file mode 100644 index fabf48acbbc..00000000000 --- a/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adding CSRF protection to Hooks test action -merge_request: -author: -type: security diff --git a/changelogs/unreleased/security-ide-branch-name-xss.yml b/changelogs/unreleased/security-ide-branch-name-xss.yml deleted file mode 100644 index 51742ffa4e9..00000000000 --- a/changelogs/unreleased/security-ide-branch-name-xss.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed XSS in branch name in Web IDE -merge_request: -author: -type: security diff --git a/changelogs/unreleased/sh-block-link-local-master.yml b/changelogs/unreleased/sh-block-link-local-master.yml new file mode 100644 index 00000000000..0a6017479af --- /dev/null +++ b/changelogs/unreleased/sh-block-link-local-master.yml @@ -0,0 +1,5 @@ +--- +title: Block link-local addresses in URLBlocker +merge_request: +author: +type: security diff --git a/changelogs/unreleased/sh-bump-fog-google.yml b/changelogs/unreleased/sh-bump-fog-google.yml new file mode 100644 index 00000000000..b5fa55e53a5 --- /dev/null +++ b/changelogs/unreleased/sh-bump-fog-google.yml @@ -0,0 +1,5 @@ +--- +title: Bump fog-google to 1.7.0 and google-api-client to 0.23.0 +merge_request: 21295 +author: +type: fixed diff --git a/changelogs/unreleased/sh-bump-gitaly-0-117.yml b/changelogs/unreleased/sh-bump-gitaly-0-117.yml deleted file mode 100644 index 90ca86d076b..00000000000 --- a/changelogs/unreleased/sh-bump-gitaly-0-117.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump Gitaly to 0.117.0 -merge_request: 21055 -author: -type: performance diff --git a/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml b/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml deleted file mode 100644 index 0e748c3a346..00000000000 --- a/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump Gitaly to 0.117.1 for Rouge update -merge_request: 21277 -author: -type: security diff --git a/changelogs/unreleased/sh-bump-haml-5-0-4.yml b/changelogs/unreleased/sh-bump-haml-5-0-4.yml deleted file mode 100644 index 269b1e55417..00000000000 --- a/changelogs/unreleased/sh-bump-haml-5-0-4.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump haml gem to 5.0.4 -merge_request: 20847 -author: -type: performance diff --git a/changelogs/unreleased/sh-bump-rugged-0-27-4.yml b/changelogs/unreleased/sh-bump-rugged-0-27-4.yml deleted file mode 100644 index 50373cb81ad..00000000000 --- a/changelogs/unreleased/sh-bump-rugged-0-27-4.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump rugged to 0.27.4 for security fixes -merge_request: -author: -type: security diff --git a/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml b/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml deleted file mode 100644 index b9444440cb9..00000000000 --- a/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump nokogiri to 1.8.4 and sanitize to 4.6.6 for performance -merge_request: 20795 -author: -type: performance diff --git a/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml b/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml deleted file mode 100644 index 897d673e97d..00000000000 --- a/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen strings in remaining lib/banzai/filter/*.rb files -merge_request: 20777 -author: -type: performance diff --git a/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml b/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml deleted file mode 100644 index e1adebbf076..00000000000 --- a/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix /admin/jobs failing to load due to statement timeout -merge_request: 20909 -author: -type: performance diff --git a/changelogs/unreleased/sh-fix-issue-47797-ce.yml b/changelogs/unreleased/sh-fix-issue-47797-ce.yml deleted file mode 100644 index 456d96acacb..00000000000 --- a/changelogs/unreleased/sh-fix-issue-47797-ce.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix handling of annotated tags when Gitaly is not in use -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-issue-49133.yml b/changelogs/unreleased/sh-fix-issue-49133.yml deleted file mode 100644 index 847220d88b2..00000000000 --- a/changelogs/unreleased/sh-fix-issue-49133.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix symlink vulnerability in project import -merge_request: -author: -type: security diff --git a/changelogs/unreleased/sh-fix-issue-50562.yml b/changelogs/unreleased/sh-fix-issue-50562.yml new file mode 100644 index 00000000000..a207dd28622 --- /dev/null +++ b/changelogs/unreleased/sh-fix-issue-50562.yml @@ -0,0 +1,5 @@ +--- +title: Fix remote mirrors failing if Git remotes have not been added +merge_request: 21351 +author: +type: fixed diff --git a/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml b/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml deleted file mode 100644 index b7366cf2569..00000000000 --- a/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Avoid process deadlock in popen by consuming input pipes -merge_request: 20600 -author: -type: fixed diff --git a/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml b/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml deleted file mode 100644 index 37b397ea49f..00000000000 --- a/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen strings in lib/banzai/filter/*.rb -merge_request: 20775 -author: -type: performance diff --git a/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml b/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml deleted file mode 100644 index 7717d0aab37..00000000000 --- a/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Properly handle colons in URL passwords -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/sh-include-rbtrace.yml b/changelogs/unreleased/sh-include-rbtrace.yml deleted file mode 100644 index 41f0655e3f8..00000000000 --- a/changelogs/unreleased/sh-include-rbtrace.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add rbtrace to Gemfile -merge_request: 20831 -author: -type: other diff --git a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml new file mode 100644 index 00000000000..116929b2f53 --- /dev/null +++ b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml @@ -0,0 +1,5 @@ +--- +title: 'Bitbucket Server importer: Eliminate most idle-in-transaction issues' +merge_request: +author: +type: performance diff --git a/changelogs/unreleased/sh-lfs-fix-content-type.yml b/changelogs/unreleased/sh-lfs-fix-content-type.yml deleted file mode 100644 index a839be9b3ae..00000000000 --- a/changelogs/unreleased/sh-lfs-fix-content-type.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix LFS uploads not working with git-lfs 2.5.0 -merge_request: 20923 -author: -type: fixed diff --git a/changelogs/unreleased/sh-limit-commit-renderering.yml b/changelogs/unreleased/sh-limit-commit-renderering.yml new file mode 100644 index 00000000000..c44c67bcc90 --- /dev/null +++ b/changelogs/unreleased/sh-limit-commit-renderering.yml @@ -0,0 +1,5 @@ +--- +title: Speed up diff comparisons by limiting number of commit messages rendered +merge_request: 21335 +author: +type: performance diff --git a/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml b/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml deleted file mode 100644 index 44a46b4115e..00000000000 --- a/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Limit the TTL for anonymous sessions to 1 hour -merge_request: 20700 -author: -type: performance diff --git a/changelogs/unreleased/sh-normalize-urls.yml b/changelogs/unreleased/sh-normalize-urls.yml deleted file mode 100644 index b0d1120e10b..00000000000 --- a/changelogs/unreleased/sh-normalize-urls.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Escape username and password in UrlSanitizer#full_url -merge_request: 20684 -author: -type: fixed diff --git a/changelogs/unreleased/sh-optimize-wiki-empty-check.yml b/changelogs/unreleased/sh-optimize-wiki-empty-check.yml deleted file mode 100644 index 31ca7497b5a..00000000000 --- a/changelogs/unreleased/sh-optimize-wiki-empty-check.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Optimize ProjectWiki#empty? check -merge_request: 20573 -author: -type: performance diff --git a/changelogs/unreleased/sh-remove-banzai-instrumentation.yml b/changelogs/unreleased/sh-remove-banzai-instrumentation.yml deleted file mode 100644 index 8bb3cd5942b..00000000000 --- a/changelogs/unreleased/sh-remove-banzai-instrumentation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove method instrumentation for Banzai filters and reference parsers -merge_request: 20770 -author: -type: performance diff --git a/changelogs/unreleased/sh-sanitize-project-import-names.yml b/changelogs/unreleased/sh-sanitize-project-import-names.yml new file mode 100644 index 00000000000..6e0284bda08 --- /dev/null +++ b/changelogs/unreleased/sh-sanitize-project-import-names.yml @@ -0,0 +1,5 @@ +--- +title: Use slugs for default project path and sanitize names before import +merge_request: 21367 +author: +type: fixed diff --git a/changelogs/unreleased/sh-simplify-liveness-check.yml b/changelogs/unreleased/sh-simplify-liveness-check.yml deleted file mode 100644 index 225e3dc1378..00000000000 --- a/changelogs/unreleased/sh-simplify-liveness-check.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add /-/health basic health check endpoint -merge_request: 20456 -author: -type: added diff --git a/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml b/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml deleted file mode 100644 index 4b0c8117b3e..00000000000 --- a/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add support for searching users by confirmed e-mails -merge_request: 20893 -author: -type: other diff --git a/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml b/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml deleted file mode 100644 index e8c2e11ad31..00000000000 --- a/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use limit parameter to retrieve Wikis from Gitaly -merge_request: 20764 -author: -type: performance diff --git a/changelogs/unreleased/stop-dynamic-routable-creation.yml b/changelogs/unreleased/stop-dynamic-routable-creation.yml deleted file mode 100644 index 8bfcb5b2d11..00000000000 --- a/changelogs/unreleased/stop-dynamic-routable-creation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Stop dynamically creating project and namespace routes -merge_request: 20313 -author: -type: performance diff --git a/changelogs/unreleased/tc-api-fork-owners.yml b/changelogs/unreleased/tc-api-fork-owners.yml new file mode 100644 index 00000000000..feaa3c1705e --- /dev/null +++ b/changelogs/unreleased/tc-api-fork-owners.yml @@ -0,0 +1,5 @@ +--- +title: Allow project owners to set up forking relation through API +merge_request: 18104 +author: +type: changed diff --git a/changelogs/unreleased/tc-reorder-mail-notify-references.yml b/changelogs/unreleased/tc-reorder-mail-notify-references.yml deleted file mode 100644 index 689afda0259..00000000000 --- a/changelogs/unreleased/tc-reorder-mail-notify-references.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Put fallback reply-key address first in the References header -merge_request: 20871 -author: -type: changed diff --git a/changelogs/unreleased/todos-visibility-change.yml b/changelogs/unreleased/todos-visibility-change.yml deleted file mode 100644 index b7632b94771..00000000000 --- a/changelogs/unreleased/todos-visibility-change.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Delete todos when user loses access to read the target -merge_request: 20665 -author: -type: other diff --git a/changelogs/unreleased/todos-visibility-migration.yml b/changelogs/unreleased/todos-visibility-migration.yml deleted file mode 100644 index 651facc4ec8..00000000000 --- a/changelogs/unreleased/todos-visibility-migration.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove todos of users without access to targets migration -merge_request: 20927 -author: -type: other diff --git a/changelogs/unreleased/toggle-password-cluster.yml b/changelogs/unreleased/toggle-password-cluster.yml deleted file mode 100644 index 1a43c4baa25..00000000000 --- a/changelogs/unreleased/toggle-password-cluster.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Toggle Show / Hide Button for Kubernetes Password -merge_request: 20659 -author: gfyoung -type: fixed diff --git a/changelogs/unreleased/tweak-sql-buckets.yml b/changelogs/unreleased/tweak-sql-buckets.yml deleted file mode 100644 index 00a0f733ee1..00000000000 --- a/changelogs/unreleased/tweak-sql-buckets.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add a 10 ms bucket for SQL timings -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/tz-mr-port-memory-fixes.yml b/changelogs/unreleased/tz-mr-port-memory-fixes.yml deleted file mode 100644 index 61d3c9abf71..00000000000 --- a/changelogs/unreleased/tz-mr-port-memory-fixes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve performance and memory footprint of Changes tab of Merge Requests -merge_request: 21028 -author: -type: performance diff --git a/changelogs/unreleased/update-card-body-style.yml b/changelogs/unreleased/update-card-body-style.yml deleted file mode 100644 index d9197c18502..00000000000 --- a/changelogs/unreleased/update-card-body-style.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove background color from card-body style -merge_request: 20689 -author: George Tsiolis -type: fixed diff --git a/changelogs/unreleased/update-issue-closing-pattern.yml b/changelogs/unreleased/update-issue-closing-pattern.yml deleted file mode 100644 index 95488adf449..00000000000 --- a/changelogs/unreleased/update-issue-closing-pattern.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update issue closing pattern -merge_request: 20554 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/update-specific-runners-help-url.yml b/changelogs/unreleased/update-specific-runners-help-url.yml deleted file mode 100644 index 0ccbc3b2d65..00000000000 --- a/changelogs/unreleased/update-specific-runners-help-url.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update specific runners help URL -merge_request: 20213 -author: George Tsiolis -type: other diff --git a/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml b/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml deleted file mode 100644 index 39e10121507..00000000000 --- a/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Update hamlit to fix ruby 2.5 incompatibilities, fixes #42045' -merge_request: -author: Matthew Dawson -type: fixed diff --git a/changelogs/unreleased/winh-default-status-emoji.yml b/changelogs/unreleased/winh-default-status-emoji.yml new file mode 100644 index 00000000000..00cca4db0a6 --- /dev/null +++ b/changelogs/unreleased/winh-default-status-emoji.yml @@ -0,0 +1,5 @@ +--- +title: Display default status emoji if only message is entered +merge_request: 21330 +author: +type: changed diff --git a/changelogs/unreleased/winh-fix-gpg-regressions.yml b/changelogs/unreleased/winh-fix-gpg-regressions.yml deleted file mode 100644 index 75d28321259..00000000000 --- a/changelogs/unreleased/winh-fix-gpg-regressions.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix GPG status badge loading regressions -merge_request: 20987 -author: -type: fixed diff --git a/changelogs/unreleased/winh-restyle-user-status.yml b/changelogs/unreleased/winh-restyle-user-status.yml deleted file mode 100644 index 90370e87825..00000000000 --- a/changelogs/unreleased/winh-restyle-user-status.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Restyle status message input on profile settings -merge_request: 20903 -author: -type: changed diff --git a/changelogs/unreleased/winh-stop-all-environments.yml b/changelogs/unreleased/winh-stop-all-environments.yml deleted file mode 100644 index 6e5f2f506d9..00000000000 --- a/changelogs/unreleased/winh-stop-all-environments.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Support manually stopping any environment from the UI -merge_request: 20077 -author: -type: changed diff --git a/changelogs/unreleased/winh-tree-view-gpg.yml b/changelogs/unreleased/winh-tree-view-gpg.yml deleted file mode 100644 index 84d63814a47..00000000000 --- a/changelogs/unreleased/winh-tree-view-gpg.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Display GPG status on repository and blob pages -merge_request: 20524 -author: -type: changed diff --git a/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml b/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml deleted file mode 100644 index 62addff1d0f..00000000000 --- a/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Upgrade grape-path-helpers to 1.0.6 -merge_request: 20601 -author: -type: other diff --git a/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml b/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml deleted file mode 100644 index 97fa1592753..00000000000 --- a/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Wrap job name on pipeline job sidebar -merge_request: 20804 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/zj-remove-git-rake-tasks.yml b/changelogs/unreleased/zj-remove-git-rake-tasks.yml deleted file mode 100644 index 8c90fc7d0fe..00000000000 --- a/changelogs/unreleased/zj-remove-git-rake-tasks.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove gitlab:user:check_repos, gitlab:check_repo, gitlab:git:prune, gitlab:git:gc, and gitlab:git:repack -merge_request: 20806 -author: -type: removed diff --git a/changelogs/unreleased/zj-repository-languages.yml b/changelogs/unreleased/zj-repository-languages.yml deleted file mode 100644 index c42ba60be29..00000000000 --- a/changelogs/unreleased/zj-repository-languages.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show repository languages for projects -merge_request: 19480 -author: -type: added diff --git a/config/initializers/fog_google_https_private_urls.rb b/config/initializers/fog_google_https_private_urls.rb index f92e623a5d2..c65a534b536 100644 --- a/config/initializers/fog_google_https_private_urls.rb +++ b/config/initializers/fog_google_https_private_urls.rb @@ -7,7 +7,7 @@ module Fog class GoogleXML class File < Fog::Model module MonkeyPatch - def url(expires) + def url(expires, options = {}) requires :key collection.get_https_url(key, expires) end diff --git a/config/routes.rb b/config/routes.rb index d16a587c5ee..e2e97b46d23 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -27,6 +27,13 @@ Rails.application.routes.draw do authorizations: 'oauth/authorizations' end + # This is here so we can "reserve" the path for the Jira integration in GitLab EE + # Having a non-existent controller here does not affect the scope in any way since all possible routes + # get a 404 proc returned. It is written in this way to minimize merge conflicts with EE + scope path: '/login/oauth', controller: 'oauth/jira/authorizations', as: :oauth_jira do + match ':action', via: [:get, :post], to: proc { [404, {}, ['']] } + end + use_doorkeeper_openid_connect # Autocomplete diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 7ee960970f8..fa1f79a90be 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -59,7 +59,7 @@ namespace :admin do resources :hook_logs, only: [:show] do member do - get :retry + post :retry end end end diff --git a/config/routes/group.rb b/config/routes/group.rb index 25fbb38ba87..d7313e43786 100644 --- a/config/routes/group.rb +++ b/config/routes/group.rb @@ -37,7 +37,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do post :toggle_subscription, on: :member end - resources :milestones, constraints: { id: %r{[^/]+} }, only: [:index, :show, :edit, :update, :new, :create] do + resources :milestones, constraints: { id: %r{[^/]+} } do member do get :merge_requests get :participants diff --git a/config/routes/project.rb b/config/routes/project.rb index 0220e88c819..34f49546983 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -307,7 +307,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do resources :hook_logs, only: [:show] do member do - get :retry + post :retry end end end diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile index a1f94dc6004..713ed95a04c 100644 --- a/danger/changelog/Dangerfile +++ b/danger/changelog/Dangerfile @@ -53,9 +53,11 @@ end changelog_needed = (gitlab.mr_labels & NO_CHANGELOG_LABELS).empty? changelog_found = git.added_files.find { |path| path =~ %r{\A(ee/)?(changelogs/unreleased)(-ee)?/} } +mr_title = gitlab.mr_json["title"].gsub(/^WIP: */, '') + if git.modified_files.include?("CHANGELOG.md") fail "**CHANGELOG.md was edited.** Please remove the additions and create a CHANGELOG entry.\n\n" + - format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: gitlab.mr_json["title"], labels: presented_no_changelog_labels) + format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels) end if changelog_needed @@ -63,6 +65,6 @@ if changelog_needed check_changelog(changelog_found) else warn "**[CHANGELOG missing](https://docs.gitlab.com/ce/development/changelog.html).**\n\n" + - format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: gitlab.mr_json["title"], labels: presented_no_changelog_labels) + format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels) end end diff --git a/db/migrate/20180711103851_drop_duplicate_protected_tags.rb b/db/migrate/20180711103851_drop_duplicate_protected_tags.rb new file mode 100644 index 00000000000..8fa2137551e --- /dev/null +++ b/db/migrate/20180711103851_drop_duplicate_protected_tags.rb @@ -0,0 +1,45 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class DropDuplicateProtectedTags < ActiveRecord::Migration + DOWNTIME = false + + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + class Project < ActiveRecord::Base + self.table_name = 'projects' + + include ::EachBatch + end + + class ProtectedTag < ActiveRecord::Base + self.table_name = 'protected_tags' + end + + def up + Project.each_batch(of: BATCH_SIZE) do |projects| + ids = ProtectedTag + .where(project_id: projects) + .group(:name, :project_id) + .select('max(id)') + + tags = ProtectedTag + .where(project_id: projects) + .where.not(id: ids) + + if Gitlab::Database.postgresql? + tags.delete_all + else + # Workaround needed for MySQL + sql = "SELECT id FROM (#{tags.to_sql}) protected_tags" + + ProtectedTag.where("id IN (#{sql})").delete_all # rubocop:disable GitlabSecurity/SqlInjection + end + end + end + + def down + end +end diff --git a/db/migrate/20180711103922_add_protected_tags_index.rb b/db/migrate/20180711103922_add_protected_tags_index.rb new file mode 100644 index 00000000000..7ed2258ebaf --- /dev/null +++ b/db/migrate/20180711103922_add_protected_tags_index.rb @@ -0,0 +1,18 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddProtectedTagsIndex < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :protected_tags, [:project_id, :name], unique: true + end + + def down + remove_concurrent_index :protected_tags, [:project_id, :name] + end +end diff --git a/db/migrate/20180815175440_add_index_on_list_type.rb b/db/migrate/20180815175440_add_index_on_list_type.rb new file mode 100644 index 00000000000..aad805e436e --- /dev/null +++ b/db/migrate/20180815175440_add_index_on_list_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +class AddIndexOnListType < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :lists, :list_type + end + + def down + remove_concurrent_index :lists, :list_type + end +end diff --git a/db/post_migrate/20180816193530_rename_login_root_namespaces.rb b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb new file mode 100644 index 00000000000..60cec24eed6 --- /dev/null +++ b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +class RenameLoginRootNamespaces < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + include Gitlab::Database::RenameReservedPathsMigration::V1 + + DOWNTIME = false + + # We're taking over the /login namespace as part of a fix for the Jira integration + def up + rename_root_paths 'login' + end + + def down + revert_renames + end +end diff --git a/db/post_migrate/20180826111825_recalculate_site_statistics.rb b/db/post_migrate/20180826111825_recalculate_site_statistics.rb new file mode 100644 index 00000000000..741035a444f --- /dev/null +++ b/db/post_migrate/20180826111825_recalculate_site_statistics.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class RecalculateSiteStatistics < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + transaction do + execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-ce/issues/48967 + + execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)") + end + + transaction do + execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-ce/issues/48967 + + execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)") + end + end + + def down + # No downside in keeping the counter up-to-date + end +end diff --git a/db/schema.rb b/db/schema.rb index 9dc122b54b3..cb8f90efded 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180809195358) do +ActiveRecord::Schema.define(version: 20180826111825) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1135,6 +1135,7 @@ ActiveRecord::Schema.define(version: 20180809195358) do add_index "lists", ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree add_index "lists", ["label_id"], name: "index_lists_on_label_id", using: :btree + add_index "lists", ["list_type"], name: "index_lists_on_list_type", using: :btree create_table "members", force: :cascade do |t| t.integer "access_level", null: false @@ -1740,6 +1741,7 @@ ActiveRecord::Schema.define(version: 20180809195358) do t.datetime "updated_at", null: false end + add_index "protected_tags", ["project_id", "name"], name: "index_protected_tags_on_project_id_and_name", unique: true, using: :btree add_index "protected_tags", ["project_id"], name: "index_protected_tags_on_project_id", using: :btree create_table "push_event_payloads", id: false, force: :cascade do |t| diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png Binary files differindex 11ce324f938..223fd0ac401 100644 --- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png +++ b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png diff --git a/doc/administration/auth/img/crowd_application.png b/doc/administration/auth/img/crowd_application.png Binary files differindex 7deea9dac8e..5029a005667 100644 --- a/doc/administration/auth/img/crowd_application.png +++ b/doc/administration/auth/img/crowd_application.png diff --git a/doc/administration/auth/img/crowd_application_authorisation.png b/doc/administration/auth/img/crowd_application_authorisation.png Binary files differindex 70339891b34..0e0bde1344b 100644 --- a/doc/administration/auth/img/crowd_application_authorisation.png +++ b/doc/administration/auth/img/crowd_application_authorisation.png diff --git a/doc/administration/img/circuitbreaker_config.png b/doc/administration/img/circuitbreaker_config.png Binary files differindex 693b2ee9c69..20233276055 100644 --- a/doc/administration/img/circuitbreaker_config.png +++ b/doc/administration/img/circuitbreaker_config.png diff --git a/doc/administration/img/custom_hooks_error_msg.png b/doc/administration/img/custom_hooks_error_msg.png Binary files differindex 1b3277bef16..845f0de19ce 100644 --- a/doc/administration/img/custom_hooks_error_msg.png +++ b/doc/administration/img/custom_hooks_error_msg.png diff --git a/doc/administration/img/failing_storage.png b/doc/administration/img/failing_storage.png Binary files differindex 82b393a58b2..652d7dcb5d7 100644 --- a/doc/administration/img/failing_storage.png +++ b/doc/administration/img/failing_storage.png diff --git a/doc/administration/img/integration/plantuml-example.png b/doc/administration/img/integration/plantuml-example.png Binary files differindex cb64eca1a8a..3e0d6389cbd 100644 --- a/doc/administration/img/integration/plantuml-example.png +++ b/doc/administration/img/integration/plantuml-example.png diff --git a/doc/administration/img/repository_storages_admin_ui.png b/doc/administration/img/repository_storages_admin_ui.png Binary files differindex 036e708cdac..5f1b4936704 100644 --- a/doc/administration/img/repository_storages_admin_ui.png +++ b/doc/administration/img/repository_storages_admin_ui.png diff --git a/doc/administration/monitoring/performance/img/grafana_dashboard_import.png b/doc/administration/monitoring/performance/img/grafana_dashboard_import.png Binary files differindex 7761ea00522..fd639ee0eb8 100644 --- a/doc/administration/monitoring/performance/img/grafana_dashboard_import.png +++ b/doc/administration/monitoring/performance/img/grafana_dashboard_import.png diff --git a/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png b/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png Binary files differindex 3e749eb8f9d..a98e0ed1e7d 100644 --- a/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png +++ b/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png diff --git a/doc/administration/monitoring/performance/img/grafana_data_source_empty.png b/doc/administration/monitoring/performance/img/grafana_data_source_empty.png Binary files differindex 33fcaaaef64..549ada8343e 100644 --- a/doc/administration/monitoring/performance/img/grafana_data_source_empty.png +++ b/doc/administration/monitoring/performance/img/grafana_data_source_empty.png diff --git a/doc/administration/monitoring/performance/img/grafana_save_icon.png b/doc/administration/monitoring/performance/img/grafana_save_icon.png Binary files differindex c18f2147e9d..68a071f5ae2 100644 --- a/doc/administration/monitoring/performance/img/grafana_save_icon.png +++ b/doc/administration/monitoring/performance/img/grafana_save_icon.png diff --git a/doc/administration/monitoring/performance/img/performance_bar.png b/doc/administration/monitoring/performance/img/performance_bar.png Binary files differindex 48212f6276a..2bf686f9017 100644 --- a/doc/administration/monitoring/performance/img/performance_bar.png +++ b/doc/administration/monitoring/performance/img/performance_bar.png diff --git a/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png Binary files differindex 2d64ef8c5fc..fafc50cd000 100644 --- a/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png +++ b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png diff --git a/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png b/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png Binary files differindex 52176df9ecd..7af6d401d1d 100644 --- a/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png +++ b/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png diff --git a/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png Binary files differindex 7868e2c46d1..a55ce753101 100644 --- a/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png +++ b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png diff --git a/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png Binary files differindex 372ae021f6b..b3219b4fa94 100644 --- a/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png +++ b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png diff --git a/doc/administration/monitoring/performance/img/request_profile_result.png b/doc/administration/monitoring/performance/img/request_profile_result.png Binary files differindex 8ebd74c2d3c..1b06e240fa0 100644 --- a/doc/administration/monitoring/performance/img/request_profile_result.png +++ b/doc/administration/monitoring/performance/img/request_profile_result.png diff --git a/doc/administration/monitoring/performance/img/request_profiling_token.png b/doc/administration/monitoring/performance/img/request_profiling_token.png Binary files differindex 9160407e028..8c4109c17f0 100644 --- a/doc/administration/monitoring/performance/img/request_profiling_token.png +++ b/doc/administration/monitoring/performance/img/request_profiling_token.png diff --git a/doc/administration/operations/img/sidekiq_job_throttling.png b/doc/administration/operations/img/sidekiq_job_throttling.png Binary files differindex dcf40b4bf17..abd09f3b115 100644 --- a/doc/administration/operations/img/sidekiq_job_throttling.png +++ b/doc/administration/operations/img/sidekiq_job_throttling.png diff --git a/doc/administration/operations/img/write_to_authorized_keys_setting.png b/doc/administration/operations/img/write_to_authorized_keys_setting.png Binary files differindex 232765f1917..f6227a6057b 100644 --- a/doc/administration/operations/img/write_to_authorized_keys_setting.png +++ b/doc/administration/operations/img/write_to_authorized_keys_setting.png diff --git a/doc/api/README.md b/doc/api/README.md index 45e926d3b6b..e2a6e87a2c3 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -53,6 +53,7 @@ following locations: - [Project Members](members.md) - [Project Snippets](project_snippets.md) - [Protected Branches](protected_branches.md) +- [Protected Tags](protected_tags.md) - [Repositories](repositories.md) - [Repository Files](repository_files.md) - [Runners](runners.md) diff --git a/doc/api/discussions.md b/doc/api/discussions.md index 65e2f9d6cd9..a1e1ff1419d 100644 --- a/doc/api/discussions.md +++ b/doc/api/discussions.md @@ -136,7 +136,7 @@ Parameters: | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) | | `issue_iid` | integer | yes | The IID of an issue | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/discussions?body=comment @@ -159,7 +159,7 @@ Parameters: | `discussion_id` | integer | yes | The ID of a discussion | | `note_id` | integer | yes | The ID of a discussion note | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment @@ -342,7 +342,7 @@ Parameters: | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) | | `snippet_id` | integer | yes | The ID of an snippet | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions?body=comment @@ -365,7 +365,7 @@ Parameters: | `discussion_id` | integer | yes | The ID of a discussion | | `note_id` | integer | yes | The ID of a discussion note | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment @@ -601,7 +601,7 @@ Parameters: | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) | | `merge_request_iid` | integer | yes | The IID of a merge request | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | | `position` | hash | no | Position when creating a diff note | | `position[base_sha]` | string | yes | Base commit SHA in the source branch | | `position[start_sha]` | string | yes | SHA referencing commit in target branch | @@ -659,7 +659,7 @@ Parameters: | `discussion_id` | integer | yes | The ID of a discussion | | `note_id` | integer | yes | The ID of a discussion note | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment @@ -894,7 +894,7 @@ Parameters: | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) | | `commit_id` | integer | yes | The ID of a commit | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | | `position` | hash | no | Position when creating a diff note | | `position[base_sha]` | string | yes | Base commit SHA in the source branch | | `position[start_sha]` | string | yes | SHA referencing commit in target branch | @@ -930,7 +930,7 @@ Parameters: | `discussion_id` | integer | yes | The ID of a discussion | | `note_id` | integer | yes | The ID of a discussion note | | `body` | string | yes | The content of a discussion | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md index 152929b7614..e396f4411e6 100644 --- a/doc/api/group_milestones.md +++ b/doc/api/group_milestones.md @@ -96,6 +96,19 @@ Parameters: - `start_date` (optional) - The start date of the milestone - `state_event` (optional) - The state event of the milestone (close|activate) +## Delete group milestone + +Only for user with developer access to the group. + +``` +DELETE /groups/:id/milestones/:milestone_id +``` + +Parameters: + +- `id` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user +- `milestone_id` (required) - The ID of the group's milestone + ## Get all issues assigned to a single milestone Gets all issues assigned to a single group milestone. diff --git a/doc/api/groups.md b/doc/api/groups.md index 87be36cc815..64e0d78788d 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -351,12 +351,14 @@ Example response: { "group_id": 4, "group_name": "Twitter", - "group_access_level": 30 + "group_access_level": 30, + "expires_at": null }, { "group_id": 3, "group_name": "Gitlab Org", - "group_access_level": 10 + "group_access_level": 10, + "expires_at": "2018-08-14" } ] } diff --git a/doc/api/issues.md b/doc/api/issues.md index 103eaa5655f..f4c0f4ea65b 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -470,7 +470,7 @@ POST /projects/:id/issues | `assignee_ids` | Array[integer] | no | The ID of the users to assign issue | | `milestone_id` | integer | no | The global ID of a milestone to assign issue | | `labels` | string | no | Comma-separated label names for an issue | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project/group owner rights) | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | | `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values.| | `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. | diff --git a/doc/api/notes.md b/doc/api/notes.md index c271d46688f..44940bdd9e5 100644 --- a/doc/api/notes.md +++ b/doc/api/notes.md @@ -100,7 +100,7 @@ Parameters: - `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) - `issue_id` (required) - The IID of an issue - `body` (required) - The content of a note -- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z +- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note diff --git a/doc/api/projects.md b/doc/api/projects.md index bda4164ee92..0936ff52dae 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -1413,12 +1413,17 @@ DELETE /projects/:id/hooks/:hook_id Note the JSON response differs if the hook is available or not. If the project hook is available before it is returned in the JSON response or an empty response is returned. -## Admin fork relation +## Fork relationship -Allows modification of the forked relationship between existing projects. Available only for admins. +Allows modification of the forked relationship between existing projects. Available only for project owners and admins. ### Create a forked from/to relation between existing projects +CAUTION: **Warning:** +This will destroy the LFS objects stored in the fork. +So to retain the LFS objects, make sure you've pulled them **before** creating the fork relation, +and push them again **after** creating the fork relation. + ``` POST /projects/:id/fork/:forked_from_id ``` diff --git a/doc/api/protected_tags.md b/doc/api/protected_tags.md new file mode 100644 index 00000000000..aa750e467f8 --- /dev/null +++ b/doc/api/protected_tags.md @@ -0,0 +1,128 @@ +# Protected tags API + +>**Note:** This feature was introduced in GitLab 11.3 + +**Valid access levels** + +Currently, these levels are recognized: +``` +0 => No access +30 => Developer access +40 => Maintainer access +``` + +## List protected tags + +Gets a list of protected tags from a project. +This function takes pagination parameters `page` and `per_page` to restrict the list of protected tags. + +``` +GET /projects/:id/protected_tags +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags' +``` + +Example response: + +```json +[ + { + "name": "release-1-0", + "create_access_levels": [ + { + "access_level": 40, + "access_level_description": "Maintainers" + } + ] + }, + ... +] +``` + +## Get a single protected tag or wildcard protected tag + +Gets a single protected tag or wildcard protected tag. +The pagination parameters `page` and `per_page` can be used to restrict the list of protected tags. + +``` +GET /projects/:id/protected_tags/:name +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | +| `name` | string | yes | The name of the tag or wildcard | + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/release-1-0' +``` + +Example response: + +```json +{ + "name": "release-1-0", + "create_access_levels": [ + { + "access_level": 40, + "access_level_description": "Maintainers" + } + ] +} +``` + +## Protect repository tags + +Protects a single repository tag or several project repository +tags using a wildcard protected tag. + +``` +POST /projects/:id/protected_tags +``` + +```bash +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags?name=*-stable&create_access_level=30' +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | +| `name` | string | yes | The name of the tag or wildcard | +| `create_access_level` | string | no | Access levels allowed to create (defaults: `40`, maintainer access level) | + +Example response: + +```json +{ + "name": "*-stable", + "create_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ] +} +``` + +## Unprotect repository tags + +Unprotects the given protected tag or wildcard protected tag. + +``` +DELETE /projects/:id/protected_tags/:name +``` + +```bash +curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/*-stable' +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | +| `name` | string | yes | The name of the tag | diff --git a/doc/ci/autodeploy/img/auto_deploy_btn.png b/doc/ci/autodeploy/img/auto_deploy_btn.png Binary files differindex 25915ed1c9d..ee88e5ce8c0 100644 --- a/doc/ci/autodeploy/img/auto_deploy_btn.png +++ b/doc/ci/autodeploy/img/auto_deploy_btn.png diff --git a/doc/ci/autodeploy/img/auto_deploy_button.png b/doc/ci/autodeploy/img/auto_deploy_button.png Binary files differindex 423e76a6cda..0e84d9c57a1 100644 --- a/doc/ci/autodeploy/img/auto_deploy_button.png +++ b/doc/ci/autodeploy/img/auto_deploy_button.png diff --git a/doc/ci/autodeploy/img/auto_deploy_dropdown.png b/doc/ci/autodeploy/img/auto_deploy_dropdown.png Binary files differindex 5815937a4af..4094f8ebb4e 100644 --- a/doc/ci/autodeploy/img/auto_deploy_dropdown.png +++ b/doc/ci/autodeploy/img/auto_deploy_dropdown.png diff --git a/doc/ci/autodeploy/img/auto_monitoring.png b/doc/ci/autodeploy/img/auto_monitoring.png Binary files differindex 5661b50841b..5a11923d199 100644 --- a/doc/ci/autodeploy/img/auto_monitoring.png +++ b/doc/ci/autodeploy/img/auto_monitoring.png diff --git a/doc/ci/autodeploy/img/guide_connect_cluster.png b/doc/ci/autodeploy/img/guide_connect_cluster.png Binary files differindex b856b81a1d0..703d536f37a 100644 --- a/doc/ci/autodeploy/img/guide_connect_cluster.png +++ b/doc/ci/autodeploy/img/guide_connect_cluster.png diff --git a/doc/ci/autodeploy/img/guide_integration.png b/doc/ci/autodeploy/img/guide_integration.png Binary files differindex 723b2619ea2..ab72de2bba3 100644 --- a/doc/ci/autodeploy/img/guide_integration.png +++ b/doc/ci/autodeploy/img/guide_integration.png diff --git a/doc/ci/autodeploy/img/guide_secret.png b/doc/ci/autodeploy/img/guide_secret.png Binary files differindex 01f5aa49908..8469bee48b7 100644 --- a/doc/ci/autodeploy/img/guide_secret.png +++ b/doc/ci/autodeploy/img/guide_secret.png diff --git a/doc/ci/caching/img/clear_runners_cache.png b/doc/ci/caching/img/clear_runners_cache.png Binary files differindex e5db4a47b3e..4f1171513ad 100644 --- a/doc/ci/caching/img/clear_runners_cache.png +++ b/doc/ci/caching/img/clear_runners_cache.png diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png Binary files differindex 76e0295722b..09eef98202f 100644 --- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png +++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png Binary files differindex 050a97d2726..71ffcdea289 100644 --- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png +++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png Binary files differindex 4ab5d5f401a..a9452577a42 100644 --- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png +++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png Binary files differindex b1406fed6b8..704d43ea52e 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png Binary files differindex 9aae11b8679..763ce48fa5a 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png Binary files differindex a06b6d417cd..f299d6355cb 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png Binary files differindex d357ecda7d2..9c301e1fc8c 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png Binary files differindex baf8dec499c..2f451615a3a 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png Binary files differindex d96c43bcf16..a5fd6b020d1 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png Binary files differindex 997db10189f..1f605504171 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png Binary files differindex 658c0b5bcac..b7906d49dcb 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png Binary files differindex 0f94ac60fee..77b05f55f88 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png Binary files differindex 94828a20f51..04d3dc40fa5 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png Binary files differindex 68503b392ed..63812b41c2c 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png Binary files differindex d73140ccdd9..c0daa1a6a91 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png Binary files differindex 38bfde0a3dd..727995f463c 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png Binary files differindex bfe85c6a10b..50c6ca593c1 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png diff --git a/doc/ci/img/deployments_view.png b/doc/ci/img/deployments_view.png Binary files differindex 436fed5f465..45d882b536c 100644 --- a/doc/ci/img/deployments_view.png +++ b/doc/ci/img/deployments_view.png diff --git a/doc/ci/img/environments_available.png b/doc/ci/img/environments_available.png Binary files differindex 2991a309655..7ab92838ece 100644 --- a/doc/ci/img/environments_available.png +++ b/doc/ci/img/environments_available.png diff --git a/doc/ci/img/environments_dynamic_groups.png b/doc/ci/img/environments_dynamic_groups.png Binary files differindex 45124b3d8d8..37828ccd0c1 100644 --- a/doc/ci/img/environments_dynamic_groups.png +++ b/doc/ci/img/environments_dynamic_groups.png diff --git a/doc/ci/img/environments_link_url_mr.png b/doc/ci/img/environments_link_url_mr.png Binary files differindex 7ce46063062..75d7311b862 100644 --- a/doc/ci/img/environments_link_url_mr.png +++ b/doc/ci/img/environments_link_url_mr.png diff --git a/doc/ci/img/environments_manual_action_deployments.png b/doc/ci/img/environments_manual_action_deployments.png Binary files differindex 93beaa0de54..c5959c0003e 100644 --- a/doc/ci/img/environments_manual_action_deployments.png +++ b/doc/ci/img/environments_manual_action_deployments.png diff --git a/doc/ci/img/environments_manual_action_environments.png b/doc/ci/img/environments_manual_action_environments.png Binary files differindex 9490be63f14..b2ec27cc721 100644 --- a/doc/ci/img/environments_manual_action_environments.png +++ b/doc/ci/img/environments_manual_action_environments.png diff --git a/doc/ci/img/environments_manual_action_jobs.png b/doc/ci/img/environments_manual_action_jobs.png Binary files differindex 9ae223cf77f..d948ee5da9e 100644 --- a/doc/ci/img/environments_manual_action_jobs.png +++ b/doc/ci/img/environments_manual_action_jobs.png diff --git a/doc/ci/img/environments_manual_action_pipelines.png b/doc/ci/img/environments_manual_action_pipelines.png Binary files differindex 129e44f6fb0..332850afb7f 100644 --- a/doc/ci/img/environments_manual_action_pipelines.png +++ b/doc/ci/img/environments_manual_action_pipelines.png diff --git a/doc/ci/img/environments_manual_action_single_pipeline.png b/doc/ci/img/environments_manual_action_single_pipeline.png Binary files differindex 1eeb4379eb7..8c1c0c1d993 100644 --- a/doc/ci/img/environments_manual_action_single_pipeline.png +++ b/doc/ci/img/environments_manual_action_single_pipeline.png diff --git a/doc/ci/img/environments_monitoring.png b/doc/ci/img/environments_monitoring.png Binary files differindex dcffdd1fdb8..63d272ae42a 100644 --- a/doc/ci/img/environments_monitoring.png +++ b/doc/ci/img/environments_monitoring.png diff --git a/doc/ci/img/environments_mr_review_app.png b/doc/ci/img/environments_mr_review_app.png Binary files differindex 4bb643d708f..61b7e9fe77c 100644 --- a/doc/ci/img/environments_mr_review_app.png +++ b/doc/ci/img/environments_mr_review_app.png diff --git a/doc/ci/img/environments_terminal_button_on_index.png b/doc/ci/img/environments_terminal_button_on_index.png Binary files differindex 061bb7c3c87..40110ff325f 100644 --- a/doc/ci/img/environments_terminal_button_on_index.png +++ b/doc/ci/img/environments_terminal_button_on_index.png diff --git a/doc/ci/img/environments_terminal_button_on_show.png b/doc/ci/img/environments_terminal_button_on_show.png Binary files differindex 4d24304bc93..e96ca9c9c7e 100644 --- a/doc/ci/img/environments_terminal_button_on_show.png +++ b/doc/ci/img/environments_terminal_button_on_show.png diff --git a/doc/ci/img/environments_terminal_page.png b/doc/ci/img/environments_terminal_page.png Binary files differindex fde1bf325a6..736b2d01a99 100644 --- a/doc/ci/img/environments_terminal_page.png +++ b/doc/ci/img/environments_terminal_page.png diff --git a/doc/ci/img/job_failure_reason.png b/doc/ci/img/job_failure_reason.png Binary files differindex a60ce1fb21c..d44b8e6d1be 100644 --- a/doc/ci/img/job_failure_reason.png +++ b/doc/ci/img/job_failure_reason.png diff --git a/doc/ci/img/pipelines_grouped.png b/doc/ci/img/pipelines_grouped.png Binary files differindex 06f52e03320..82814754747 100644 --- a/doc/ci/img/pipelines_grouped.png +++ b/doc/ci/img/pipelines_grouped.png diff --git a/doc/ci/img/pipelines_index.png b/doc/ci/img/pipelines_index.png Binary files differindex 3b522a9c5e4..e168e7e23df 100644 --- a/doc/ci/img/pipelines_index.png +++ b/doc/ci/img/pipelines_index.png diff --git a/doc/ci/img/pipelines_mini_graph.png b/doc/ci/img/pipelines_mini_graph.png Binary files differindex 042c8ffeef5..8656b02f60d 100644 --- a/doc/ci/img/pipelines_mini_graph.png +++ b/doc/ci/img/pipelines_mini_graph.png diff --git a/doc/ci/img/pipelines_mini_graph_simple.png b/doc/ci/img/pipelines_mini_graph_simple.png Binary files differindex eb36c09b2d4..d00a8313088 100644 --- a/doc/ci/img/pipelines_mini_graph_simple.png +++ b/doc/ci/img/pipelines_mini_graph_simple.png diff --git a/doc/ci/img/view_on_env_blob.png b/doc/ci/img/view_on_env_blob.png Binary files differindex f4fe99046f0..dd9ca40280a 100644 --- a/doc/ci/img/view_on_env_blob.png +++ b/doc/ci/img/view_on_env_blob.png diff --git a/doc/ci/img/view_on_env_mr.png b/doc/ci/img/view_on_env_mr.png Binary files differindex 47ddb40bdc1..2c0bd25a4f2 100644 --- a/doc/ci/img/view_on_env_mr.png +++ b/doc/ci/img/view_on_env_mr.png diff --git a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png Binary files differindex b59c1b6bc43..0523e62db70 100644 --- a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png +++ b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png diff --git a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png Binary files differindex f92c6df07a1..3ee5e39afc0 100644 --- a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png +++ b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png diff --git a/doc/ci/quick_start/img/build_log.png b/doc/ci/quick_start/img/build_log.png Binary files differindex 3a7248ca772..2bf0992c50e 100644 --- a/doc/ci/quick_start/img/build_log.png +++ b/doc/ci/quick_start/img/build_log.png diff --git a/doc/ci/quick_start/img/builds_status.png b/doc/ci/quick_start/img/builds_status.png Binary files differindex f829240f3b3..58978e23978 100644 --- a/doc/ci/quick_start/img/builds_status.png +++ b/doc/ci/quick_start/img/builds_status.png diff --git a/doc/ci/quick_start/img/new_commit.png b/doc/ci/quick_start/img/new_commit.png Binary files differindex b3dd848b294..507eb93ac0c 100644 --- a/doc/ci/quick_start/img/new_commit.png +++ b/doc/ci/quick_start/img/new_commit.png diff --git a/doc/ci/review_apps/img/review_apps_preview_in_mr.png b/doc/ci/review_apps/img/review_apps_preview_in_mr.png Binary files differindex 0300392f24b..7d0923f198f 100644 --- a/doc/ci/review_apps/img/review_apps_preview_in_mr.png +++ b/doc/ci/review_apps/img/review_apps_preview_in_mr.png diff --git a/doc/ci/runners/img/protected_runners_check_box.png b/doc/ci/runners/img/protected_runners_check_box.png Binary files differindex fb58498c7ce..3c47ebdec29 100644 --- a/doc/ci/runners/img/protected_runners_check_box.png +++ b/doc/ci/runners/img/protected_runners_check_box.png diff --git a/doc/ci/runners/img/shared_runner_ip_address.png b/doc/ci/runners/img/shared_runner_ip_address.png Binary files differindex 3b1542d59d3..527b4f4043d 100644 --- a/doc/ci/runners/img/shared_runner_ip_address.png +++ b/doc/ci/runners/img/shared_runner_ip_address.png diff --git a/doc/ci/runners/img/specific_runner_ip_address.png b/doc/ci/runners/img/specific_runner_ip_address.png Binary files differindex 3b4c3e9f2eb..e08663109ba 100644 --- a/doc/ci/runners/img/specific_runner_ip_address.png +++ b/doc/ci/runners/img/specific_runner_ip_address.png diff --git a/doc/ci/triggers/img/builds_page.png b/doc/ci/triggers/img/builds_page.png Binary files differindex c9cc8f308f4..14d73b140f4 100644 --- a/doc/ci/triggers/img/builds_page.png +++ b/doc/ci/triggers/img/builds_page.png diff --git a/doc/ci/triggers/img/trigger_single_build.png b/doc/ci/triggers/img/trigger_single_build.png Binary files differindex 837bbeffe9f..b760782afdc 100644 --- a/doc/ci/triggers/img/trigger_single_build.png +++ b/doc/ci/triggers/img/trigger_single_build.png diff --git a/doc/customization/branded_login_page/custom_sign_in.png b/doc/customization/branded_login_page/custom_sign_in.png Binary files differindex c0888fe1f18..03ea5281ebe 100644 --- a/doc/customization/branded_login_page/custom_sign_in.png +++ b/doc/customization/branded_login_page/custom_sign_in.png diff --git a/doc/customization/branded_page_and_email_header/appearance.png b/doc/customization/branded_page_and_email_header/appearance.png Binary files differindex abbba6f9ac9..6b79bc47005 100644 --- a/doc/customization/branded_page_and_email_header/appearance.png +++ b/doc/customization/branded_page_and_email_header/appearance.png diff --git a/doc/customization/branded_page_and_email_header/custom_brand_header.png b/doc/customization/branded_page_and_email_header/custom_brand_header.png Binary files differindex 7390f8a5e4e..d779236bbe7 100644 --- a/doc/customization/branded_page_and_email_header/custom_brand_header.png +++ b/doc/customization/branded_page_and_email_header/custom_brand_header.png diff --git a/doc/customization/branded_page_and_email_header/custom_email_header.png b/doc/customization/branded_page_and_email_header/custom_email_header.png Binary files differindex 705698ef4a8..729b166364b 100644 --- a/doc/customization/branded_page_and_email_header/custom_email_header.png +++ b/doc/customization/branded_page_and_email_header/custom_email_header.png diff --git a/doc/customization/favicon/appearance.png b/doc/customization/favicon/appearance.png Binary files differindex 6c41a05fc1f..da1002826dd 100644 --- a/doc/customization/favicon/appearance.png +++ b/doc/customization/favicon/appearance.png diff --git a/doc/customization/favicon/custom_favicon.png b/doc/customization/favicon/custom_favicon.png Binary files differindex fa1b8827a36..20dddfbea33 100644 --- a/doc/customization/favicon/custom_favicon.png +++ b/doc/customization/favicon/custom_favicon.png diff --git a/doc/customization/new_project_page/appearance_settings.png b/doc/customization/new_project_page/appearance_settings.png Binary files differindex 08eea684e14..4fcdd1caa21 100644 --- a/doc/customization/new_project_page/appearance_settings.png +++ b/doc/customization/new_project_page/appearance_settings.png diff --git a/doc/customization/new_project_page/custom_new_project_page.png b/doc/customization/new_project_page/custom_new_project_page.png Binary files differindex 662c715f193..c6f7839e9c3 100644 --- a/doc/customization/new_project_page/custom_new_project_page.png +++ b/doc/customization/new_project_page/custom_new_project_page.png diff --git a/doc/customization/new_project_page/default_new_project_page.png b/doc/customization/new_project_page/default_new_project_page.png Binary files differindex 4a0bcf09903..f5b209ac5ea 100644 --- a/doc/customization/new_project_page/default_new_project_page.png +++ b/doc/customization/new_project_page/default_new_project_page.png diff --git a/doc/development/README.md b/doc/development/README.md index ee9a9852205..20f8fa1d368 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -54,6 +54,7 @@ description: 'Learn how to contribute to GitLab.' - [Performance guidelines](performance.md) - [Merge request performance guidelines](merge_request_performance_guidelines.md) for ensuring merge requests do not negatively impact GitLab performance +- [Profiling](profiling.md) for profiling a URL ## Database guides diff --git a/doc/development/architecture.md b/doc/development/architecture.md index 3e417a44ec1..66d8a4f2f6e 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -70,7 +70,7 @@ The add-on component gitlab-shell serves repositories over SSH. It manages the S Gitaly executes git operations from gitlab-shell and the GitLab web app, and provides an API to the GitLab web app to get attributes from git (e.g. title, branches, tags, other meta data), and to get blobs (e.g. diffs, commits, files). -You may also be interested in the [production architecture of GitLab.com](https://about.gitlab.com/handbook/infrastructure/production-architecture/). +You may also be interested in the [production architecture of GitLab.com](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/). ### Installation Folder Summary diff --git a/doc/development/documentation/img/manual_build_docs.png b/doc/development/documentation/img/manual_build_docs.png Binary files differindex 615facabb5f..e366a2f7ec4 100644 --- a/doc/development/documentation/img/manual_build_docs.png +++ b/doc/development/documentation/img/manual_build_docs.png diff --git a/doc/development/fe_guide/img/boards_diagram.png b/doc/development/fe_guide/img/boards_diagram.png Binary files differindex 7a2cf972fd0..856c9b05bbf 100644 --- a/doc/development/fe_guide/img/boards_diagram.png +++ b/doc/development/fe_guide/img/boards_diagram.png diff --git a/doc/development/fe_guide/img/gl-modal.png b/doc/development/fe_guide/img/gl-modal.png Binary files differindex 47302e857bc..b2d2d637e57 100644 --- a/doc/development/fe_guide/img/gl-modal.png +++ b/doc/development/fe_guide/img/gl-modal.png diff --git a/doc/development/feature_flags.md b/doc/development/feature_flags.md index 09ea8c05be6..702caacc74f 100644 --- a/doc/development/feature_flags.md +++ b/doc/development/feature_flags.md @@ -57,3 +57,15 @@ end Features that are developed and are intended to be merged behind a feature flag should not include a changelog entry. The entry should be added in the merge request removing the feature flags. + +### Specs + +In the test environment `Feature.enabled?` is stubbed to always respond to `true`, +so we make sure behavior under feature flag doesn't go untested in some non-specific +contexts. + +If you need to test the feature flag in a different state, you need to stub it with: + +```ruby +stub_feature_flags(my_feature_flag: false) +``` diff --git a/doc/development/gitlab_architecture_diagram.png b/doc/development/gitlab_architecture_diagram.png Binary files differindex 378f7384574..90e27d5462a 100644 --- a/doc/development/gitlab_architecture_diagram.png +++ b/doc/development/gitlab_architecture_diagram.png diff --git a/doc/development/img/trigger_ss1.png b/doc/development/img/trigger_ss1.png Binary files differindex ccff1009a25..addbc551f73 100644 --- a/doc/development/img/trigger_ss1.png +++ b/doc/development/img/trigger_ss1.png diff --git a/doc/development/img/trigger_ss2.png b/doc/development/img/trigger_ss2.png Binary files differindex 94dfd048793..02ef3810a59 100644 --- a/doc/development/img/trigger_ss2.png +++ b/doc/development/img/trigger_ss2.png diff --git a/doc/development/ux_guide/img/button-close--active.png b/doc/development/ux_guide/img/button-close--active.png Binary files differindex 824bfc8f31b..97a5301fb91 100644 --- a/doc/development/ux_guide/img/button-close--active.png +++ b/doc/development/ux_guide/img/button-close--active.png diff --git a/doc/development/ux_guide/img/button-close--hover.png b/doc/development/ux_guide/img/button-close--hover.png Binary files differindex 0291e121894..6b8fdf5695b 100644 --- a/doc/development/ux_guide/img/button-close--hover.png +++ b/doc/development/ux_guide/img/button-close--hover.png diff --git a/doc/development/ux_guide/img/button-close--resting.png b/doc/development/ux_guide/img/button-close--resting.png Binary files differindex 986d7174ce7..5679b51687c 100644 --- a/doc/development/ux_guide/img/button-close--resting.png +++ b/doc/development/ux_guide/img/button-close--resting.png diff --git a/doc/development/ux_guide/img/button-danger--active.png b/doc/development/ux_guide/img/button-danger--active.png Binary files differindex d3c64424b26..6a9aab0fcc2 100644 --- a/doc/development/ux_guide/img/button-danger--active.png +++ b/doc/development/ux_guide/img/button-danger--active.png diff --git a/doc/development/ux_guide/img/button-danger--hover.png b/doc/development/ux_guide/img/button-danger--hover.png Binary files differindex 8506e093306..13e21c28779 100644 --- a/doc/development/ux_guide/img/button-danger--hover.png +++ b/doc/development/ux_guide/img/button-danger--hover.png diff --git a/doc/development/ux_guide/img/button-danger--resting.png b/doc/development/ux_guide/img/button-danger--resting.png Binary files differindex 69ad6bb796b..0ff192bc463 100644 --- a/doc/development/ux_guide/img/button-danger--resting.png +++ b/doc/development/ux_guide/img/button-danger--resting.png diff --git a/doc/development/ux_guide/img/button-info--active.png b/doc/development/ux_guide/img/button-info--active.png Binary files differindex 23be20b225c..12ecdc72a31 100644 --- a/doc/development/ux_guide/img/button-info--active.png +++ b/doc/development/ux_guide/img/button-info--active.png diff --git a/doc/development/ux_guide/img/button-info--hover.png b/doc/development/ux_guide/img/button-info--hover.png Binary files differindex 4cb4e38558c..3bf93bf2b32 100644 --- a/doc/development/ux_guide/img/button-info--hover.png +++ b/doc/development/ux_guide/img/button-info--hover.png diff --git a/doc/development/ux_guide/img/button-info--resting.png b/doc/development/ux_guide/img/button-info--resting.png Binary files differindex 5883340aa83..a37a37033bf 100644 --- a/doc/development/ux_guide/img/button-info--resting.png +++ b/doc/development/ux_guide/img/button-info--resting.png diff --git a/doc/development/ux_guide/img/button-spam--active.png b/doc/development/ux_guide/img/button-spam--active.png Binary files differindex 55b44898684..a9e115f49c1 100644 --- a/doc/development/ux_guide/img/button-spam--active.png +++ b/doc/development/ux_guide/img/button-spam--active.png diff --git a/doc/development/ux_guide/img/button-spam--hover.png b/doc/development/ux_guide/img/button-spam--hover.png Binary files differindex 3dc8ed34c54..3b2c16430a6 100644 --- a/doc/development/ux_guide/img/button-spam--hover.png +++ b/doc/development/ux_guide/img/button-spam--hover.png diff --git a/doc/development/ux_guide/img/button-spam--resting.png b/doc/development/ux_guide/img/button-spam--resting.png Binary files differindex b6bf10a5b64..4f9f18ca68a 100644 --- a/doc/development/ux_guide/img/button-spam--resting.png +++ b/doc/development/ux_guide/img/button-spam--resting.png diff --git a/doc/development/ux_guide/img/button-success--active.png b/doc/development/ux_guide/img/button-success--active.png Binary files differindex 895a52831cb..b99f6f5e70e 100644 --- a/doc/development/ux_guide/img/button-success--active.png +++ b/doc/development/ux_guide/img/button-success--active.png diff --git a/doc/development/ux_guide/img/button-success--hover.png b/doc/development/ux_guide/img/button-success--hover.png Binary files differindex e4c74bd9778..0d0a61c679a 100644 --- a/doc/development/ux_guide/img/button-success--hover.png +++ b/doc/development/ux_guide/img/button-success--hover.png diff --git a/doc/development/ux_guide/img/button-success--resting.png b/doc/development/ux_guide/img/button-success--resting.png Binary files differindex 2fa971b5347..53b955c650a 100644 --- a/doc/development/ux_guide/img/button-success--resting.png +++ b/doc/development/ux_guide/img/button-success--resting.png diff --git a/doc/development/ux_guide/img/button-success-secondary--active.png b/doc/development/ux_guide/img/button-success-secondary--active.png Binary files differindex e7383b36946..333a91f2217 100644 --- a/doc/development/ux_guide/img/button-success-secondary--active.png +++ b/doc/development/ux_guide/img/button-success-secondary--active.png diff --git a/doc/development/ux_guide/img/button-success-secondary--hover.png b/doc/development/ux_guide/img/button-success-secondary--hover.png Binary files differindex 4af2a68cf1b..0cce59212e3 100644 --- a/doc/development/ux_guide/img/button-success-secondary--hover.png +++ b/doc/development/ux_guide/img/button-success-secondary--hover.png diff --git a/doc/development/ux_guide/img/button-success-secondary--resting.png b/doc/development/ux_guide/img/button-success-secondary--resting.png Binary files differindex a5a4ec512c8..2779a4949f8 100644 --- a/doc/development/ux_guide/img/button-success-secondary--resting.png +++ b/doc/development/ux_guide/img/button-success-secondary--resting.png diff --git a/doc/development/ux_guide/img/button-warning--active.png b/doc/development/ux_guide/img/button-warning--active.png Binary files differindex 5877d46c94d..f5760cd7c12 100644 --- a/doc/development/ux_guide/img/button-warning--active.png +++ b/doc/development/ux_guide/img/button-warning--active.png diff --git a/doc/development/ux_guide/img/button-warning--hover.png b/doc/development/ux_guide/img/button-warning--hover.png Binary files differindex 308e1adc8a3..a1f4c5cbcc6 100644 --- a/doc/development/ux_guide/img/button-warning--hover.png +++ b/doc/development/ux_guide/img/button-warning--hover.png diff --git a/doc/development/ux_guide/img/button-warning--resting.png b/doc/development/ux_guide/img/button-warning--resting.png Binary files differindex 28e5e601520..3d62fed5930 100644 --- a/doc/development/ux_guide/img/button-warning--resting.png +++ b/doc/development/ux_guide/img/button-warning--resting.png diff --git a/doc/development/ux_guide/img/color-blue.png b/doc/development/ux_guide/img/color-blue.png Binary files differindex 844e926f1f5..77c1a2cab31 100644 --- a/doc/development/ux_guide/img/color-blue.png +++ b/doc/development/ux_guide/img/color-blue.png diff --git a/doc/development/ux_guide/img/color-green.png b/doc/development/ux_guide/img/color-green.png Binary files differindex 5c4c23c7067..51600584c96 100644 --- a/doc/development/ux_guide/img/color-green.png +++ b/doc/development/ux_guide/img/color-green.png diff --git a/doc/development/ux_guide/img/color-grey.png b/doc/development/ux_guide/img/color-grey.png Binary files differindex 5247649a0ce..f0f0b9d80bb 100644 --- a/doc/development/ux_guide/img/color-grey.png +++ b/doc/development/ux_guide/img/color-grey.png diff --git a/doc/development/ux_guide/img/color-orange.png b/doc/development/ux_guide/img/color-orange.png Binary files differindex 1103c715225..f16435c0a64 100644 --- a/doc/development/ux_guide/img/color-orange.png +++ b/doc/development/ux_guide/img/color-orange.png diff --git a/doc/development/ux_guide/img/color-red.png b/doc/development/ux_guide/img/color-red.png Binary files differindex 77ecbbc0a20..5008e75da78 100644 --- a/doc/development/ux_guide/img/color-red.png +++ b/doc/development/ux_guide/img/color-red.png diff --git a/doc/development/ux_guide/img/components-anchorlinks.png b/doc/development/ux_guide/img/components-anchorlinks.png Binary files differindex 4a9c730566c..bd8d30f5905 100644 --- a/doc/development/ux_guide/img/components-anchorlinks.png +++ b/doc/development/ux_guide/img/components-anchorlinks.png diff --git a/doc/development/ux_guide/img/components-coverblock.png b/doc/development/ux_guide/img/components-coverblock.png Binary files differindex fb135f9648a..61160de5613 100644 --- a/doc/development/ux_guide/img/components-coverblock.png +++ b/doc/development/ux_guide/img/components-coverblock.png diff --git a/doc/development/ux_guide/img/components-dateexact.png b/doc/development/ux_guide/img/components-dateexact.png Binary files differindex 686ca727293..cc1fb8216bf 100644 --- a/doc/development/ux_guide/img/components-dateexact.png +++ b/doc/development/ux_guide/img/components-dateexact.png diff --git a/doc/development/ux_guide/img/components-fileholder.png b/doc/development/ux_guide/img/components-fileholder.png Binary files differindex ec2911a1232..5bf8565346a 100644 --- a/doc/development/ux_guide/img/components-fileholder.png +++ b/doc/development/ux_guide/img/components-fileholder.png diff --git a/doc/development/ux_guide/img/components-horizontalform.png b/doc/development/ux_guide/img/components-horizontalform.png Binary files differindex c57dceda43a..e6cbc69d20a 100644 --- a/doc/development/ux_guide/img/components-horizontalform.png +++ b/doc/development/ux_guide/img/components-horizontalform.png diff --git a/doc/development/ux_guide/img/components-listinsidepanel.png b/doc/development/ux_guide/img/components-listinsidepanel.png Binary files differindex 3a72d39bb5d..6b773a19954 100644 --- a/doc/development/ux_guide/img/components-listinsidepanel.png +++ b/doc/development/ux_guide/img/components-listinsidepanel.png diff --git a/doc/development/ux_guide/img/components-listwithhover.png b/doc/development/ux_guide/img/components-listwithhover.png Binary files differindex 8521a8ad53e..0826848ff34 100644 --- a/doc/development/ux_guide/img/components-listwithhover.png +++ b/doc/development/ux_guide/img/components-listwithhover.png diff --git a/doc/development/ux_guide/img/components-referencehover.png b/doc/development/ux_guide/img/components-referencehover.png Binary files differindex f80564dbb16..af5405d3e0b 100644 --- a/doc/development/ux_guide/img/components-referencehover.png +++ b/doc/development/ux_guide/img/components-referencehover.png diff --git a/doc/development/ux_guide/img/components-referenceissues.png b/doc/development/ux_guide/img/components-referenceissues.png Binary files differindex 51fb2cf3e43..4e175dc169d 100644 --- a/doc/development/ux_guide/img/components-referenceissues.png +++ b/doc/development/ux_guide/img/components-referenceissues.png diff --git a/doc/development/ux_guide/img/components-referencelabels.png b/doc/development/ux_guide/img/components-referencelabels.png Binary files differindex aba450cc3ba..29a985bbaa0 100644 --- a/doc/development/ux_guide/img/components-referencelabels.png +++ b/doc/development/ux_guide/img/components-referencelabels.png diff --git a/doc/development/ux_guide/img/components-referencemilestone.png b/doc/development/ux_guide/img/components-referencemilestone.png Binary files differindex adf2555ccf8..47c76a9d60f 100644 --- a/doc/development/ux_guide/img/components-referencemilestone.png +++ b/doc/development/ux_guide/img/components-referencemilestone.png diff --git a/doc/development/ux_guide/img/components-referencemrs.png b/doc/development/ux_guide/img/components-referencemrs.png Binary files differindex 6c3375f1ea1..9a5032a1516 100644 --- a/doc/development/ux_guide/img/components-referencemrs.png +++ b/doc/development/ux_guide/img/components-referencemrs.png diff --git a/doc/development/ux_guide/img/components-referencepeople.png b/doc/development/ux_guide/img/components-referencepeople.png Binary files differindex b8dd431e2e6..f9ef11be853 100644 --- a/doc/development/ux_guide/img/components-referencepeople.png +++ b/doc/development/ux_guide/img/components-referencepeople.png diff --git a/doc/development/ux_guide/img/components-searchbox.png b/doc/development/ux_guide/img/components-searchbox.png Binary files differindex a25189296ba..5c19024bfb0 100644 --- a/doc/development/ux_guide/img/components-searchbox.png +++ b/doc/development/ux_guide/img/components-searchbox.png diff --git a/doc/development/ux_guide/img/components-searchboxscoped.png b/doc/development/ux_guide/img/components-searchboxscoped.png Binary files differindex b116d714848..d4a35977658 100644 --- a/doc/development/ux_guide/img/components-searchboxscoped.png +++ b/doc/development/ux_guide/img/components-searchboxscoped.png diff --git a/doc/development/ux_guide/img/components-simplelist.png b/doc/development/ux_guide/img/components-simplelist.png Binary files differindex 858e5064c25..8d11c674e84 100644 --- a/doc/development/ux_guide/img/components-simplelist.png +++ b/doc/development/ux_guide/img/components-simplelist.png diff --git a/doc/development/ux_guide/img/features-contextualnav.png b/doc/development/ux_guide/img/features-contextualnav.png Binary files differindex f8466f28627..aa816776fad 100644 --- a/doc/development/ux_guide/img/features-contextualnav.png +++ b/doc/development/ux_guide/img/features-contextualnav.png diff --git a/doc/development/ux_guide/img/features-emptystates.png b/doc/development/ux_guide/img/features-emptystates.png Binary files differindex 51835a7080b..50f31f5e523 100644 --- a/doc/development/ux_guide/img/features-emptystates.png +++ b/doc/development/ux_guide/img/features-emptystates.png diff --git a/doc/development/ux_guide/img/icon-add.png b/doc/development/ux_guide/img/icon-add.png Binary files differindex bcad5e84591..f66525cc1b4 100644 --- a/doc/development/ux_guide/img/icon-add.png +++ b/doc/development/ux_guide/img/icon-add.png diff --git a/doc/development/ux_guide/img/icon-close.png b/doc/development/ux_guide/img/icon-close.png Binary files differindex dfe1495f5fa..af6c30ebe6a 100644 --- a/doc/development/ux_guide/img/icon-close.png +++ b/doc/development/ux_guide/img/icon-close.png diff --git a/doc/development/ux_guide/img/icon-edit.png b/doc/development/ux_guide/img/icon-edit.png Binary files differindex 50f6f841868..b9649f4aeec 100644 --- a/doc/development/ux_guide/img/icon-edit.png +++ b/doc/development/ux_guide/img/icon-edit.png diff --git a/doc/development/ux_guide/img/icon-notification.png b/doc/development/ux_guide/img/icon-notification.png Binary files differindex 6ddfaa44f66..5cf8f8ab59a 100644 --- a/doc/development/ux_guide/img/icon-notification.png +++ b/doc/development/ux_guide/img/icon-notification.png diff --git a/doc/development/ux_guide/img/icon-rss.png b/doc/development/ux_guide/img/icon-rss.png Binary files differindex b766488b32d..7e2987a2656 100644 --- a/doc/development/ux_guide/img/icon-rss.png +++ b/doc/development/ux_guide/img/icon-rss.png diff --git a/doc/development/ux_guide/img/icon-spec.png b/doc/development/ux_guide/img/icon-spec.png Binary files differindex 56b19610dc1..5bb85c5be98 100644 --- a/doc/development/ux_guide/img/icon-spec.png +++ b/doc/development/ux_guide/img/icon-spec.png diff --git a/doc/development/ux_guide/img/icon-subscribe.png b/doc/development/ux_guide/img/icon-subscribe.png Binary files differindex 650168296c6..7e2f5e6a1c6 100644 --- a/doc/development/ux_guide/img/icon-subscribe.png +++ b/doc/development/ux_guide/img/icon-subscribe.png diff --git a/doc/development/ux_guide/img/icon-trash.png b/doc/development/ux_guide/img/icon-trash.png Binary files differindex b02178ca992..bc46638fb2e 100644 --- a/doc/development/ux_guide/img/icon-trash.png +++ b/doc/development/ux_guide/img/icon-trash.png diff --git a/doc/development/ux_guide/img/illustrations-caps-do.png b/doc/development/ux_guide/img/illustrations-caps-do.png Binary files differindex 7a2c74382f6..f1030769b94 100644 --- a/doc/development/ux_guide/img/illustrations-caps-do.png +++ b/doc/development/ux_guide/img/illustrations-caps-do.png diff --git a/doc/development/ux_guide/img/illustrations-caps-don't.png b/doc/development/ux_guide/img/illustrations-caps-don't.png Binary files differindex 848f72dbe30..ab7abcaaf6f 100644 --- a/doc/development/ux_guide/img/illustrations-caps-don't.png +++ b/doc/development/ux_guide/img/illustrations-caps-don't.png diff --git a/doc/development/ux_guide/img/james-mackey.png b/doc/development/ux_guide/img/james-mackey.png Binary files differindex c8f9097f69f..f51a45c437b 100644 --- a/doc/development/ux_guide/img/james-mackey.png +++ b/doc/development/ux_guide/img/james-mackey.png diff --git a/doc/development/ux_guide/img/karolina-plaskaty.png b/doc/development/ux_guide/img/karolina-plaskaty.png Binary files differindex ae2e98b7bad..d1c9528dd5a 100644 --- a/doc/development/ux_guide/img/karolina-plaskaty.png +++ b/doc/development/ux_guide/img/karolina-plaskaty.png diff --git a/doc/development/ux_guide/img/matthieu-poirier.png b/doc/development/ux_guide/img/matthieu-poirier.png Binary files differindex dd21948ebe2..0ecc2d670d6 100644 --- a/doc/development/ux_guide/img/matthieu-poirier.png +++ b/doc/development/ux_guide/img/matthieu-poirier.png diff --git a/doc/development/ux_guide/img/modals-general-confimation-dialog.png b/doc/development/ux_guide/img/modals-general-confimation-dialog.png Binary files differindex 00a17374a0b..4ea0ea10ca7 100644 --- a/doc/development/ux_guide/img/modals-general-confimation-dialog.png +++ b/doc/development/ux_guide/img/modals-general-confimation-dialog.png diff --git a/doc/development/ux_guide/img/modals-layout-for-modals.png b/doc/development/ux_guide/img/modals-layout-for-modals.png Binary files differindex 6c7bc09e750..c481edd8250 100644 --- a/doc/development/ux_guide/img/modals-layout-for-modals.png +++ b/doc/development/ux_guide/img/modals-layout-for-modals.png diff --git a/doc/development/ux_guide/img/modals-special-confimation-dialog.png b/doc/development/ux_guide/img/modals-special-confimation-dialog.png Binary files differindex bf1e56326c5..d966010158b 100644 --- a/doc/development/ux_guide/img/modals-special-confimation-dialog.png +++ b/doc/development/ux_guide/img/modals-special-confimation-dialog.png diff --git a/doc/development/ux_guide/img/modals-three-buttons.png b/doc/development/ux_guide/img/modals-three-buttons.png Binary files differindex 519439e64e4..157d1b650bf 100644 --- a/doc/development/ux_guide/img/modals-three-buttons.png +++ b/doc/development/ux_guide/img/modals-three-buttons.png diff --git a/doc/development/ux_guide/img/nazim-ramesh.png b/doc/development/ux_guide/img/nazim-ramesh.png Binary files differindex cc3e197679d..dad2b37010b 100644 --- a/doc/development/ux_guide/img/nazim-ramesh.png +++ b/doc/development/ux_guide/img/nazim-ramesh.png diff --git a/doc/development/ux_guide/img/popover-placement-above.png b/doc/development/ux_guide/img/popover-placement-above.png Binary files differindex 1aa044bfc9c..84c9c878ec2 100644 --- a/doc/development/ux_guide/img/popover-placement-above.png +++ b/doc/development/ux_guide/img/popover-placement-above.png diff --git a/doc/development/ux_guide/img/popover-placement-below.png b/doc/development/ux_guide/img/popover-placement-below.png Binary files differindex 2d6ab8a1618..f6f18199ab6 100644 --- a/doc/development/ux_guide/img/popover-placement-below.png +++ b/doc/development/ux_guide/img/popover-placement-below.png diff --git a/doc/development/ux_guide/img/surfaces-contentitemtitle.png b/doc/development/ux_guide/img/surfaces-contentitemtitle.png Binary files differindex 3af0b56c8fb..f6cd212ecfd 100644 --- a/doc/development/ux_guide/img/surfaces-contentitemtitle.png +++ b/doc/development/ux_guide/img/surfaces-contentitemtitle.png diff --git a/doc/development/ux_guide/img/surfaces-systeminformationblock.png b/doc/development/ux_guide/img/surfaces-systeminformationblock.png Binary files differindex 9f42f1d4dd0..f3313add2b8 100644 --- a/doc/development/ux_guide/img/surfaces-systeminformationblock.png +++ b/doc/development/ux_guide/img/surfaces-systeminformationblock.png diff --git a/doc/development/ux_guide/img/surfaces-ux.png b/doc/development/ux_guide/img/surfaces-ux.png Binary files differindex 53208727c64..eaa7f70c0c7 100644 --- a/doc/development/ux_guide/img/surfaces-ux.png +++ b/doc/development/ux_guide/img/surfaces-ux.png diff --git a/doc/development/ux_guide/img/tooltip-placement.png b/doc/development/ux_guide/img/tooltip-placement.png Binary files differindex 061f82e4df0..da49c192878 100644 --- a/doc/development/ux_guide/img/tooltip-placement.png +++ b/doc/development/ux_guide/img/tooltip-placement.png diff --git a/doc/development/ux_guide/img/tooltip-usage.png b/doc/development/ux_guide/img/tooltip-usage.png Binary files differindex 40c4f051cd0..4f5884c4b48 100644 --- a/doc/development/ux_guide/img/tooltip-usage.png +++ b/doc/development/ux_guide/img/tooltip-usage.png diff --git a/doc/gitlab-basics/img/create_new_project_info.png b/doc/gitlab-basics/img/create_new_project_info.png Binary files differindex b4119dc046a..2693a7f9a6d 100644 --- a/doc/gitlab-basics/img/create_new_project_info.png +++ b/doc/gitlab-basics/img/create_new_project_info.png diff --git a/doc/gitlab-basics/img/fork_new.png b/doc/gitlab-basics/img/fork_new.png Binary files differindex fa185fdaca1..7bbc3d8fbae 100644 --- a/doc/gitlab-basics/img/fork_new.png +++ b/doc/gitlab-basics/img/fork_new.png diff --git a/doc/gitlab-basics/img/merge_request_select_branch.png b/doc/gitlab-basics/img/merge_request_select_branch.png Binary files differindex 57ea0e65f34..b1dec975f9b 100644 --- a/doc/gitlab-basics/img/merge_request_select_branch.png +++ b/doc/gitlab-basics/img/merge_request_select_branch.png diff --git a/doc/gitlab-basics/img/profile_settings.png b/doc/gitlab-basics/img/profile_settings.png Binary files differindex aaa1a39313d..b91b698fb18 100644 --- a/doc/gitlab-basics/img/profile_settings.png +++ b/doc/gitlab-basics/img/profile_settings.png diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png Binary files differindex 5e501ec86ef..0b1c64a72f3 100644 --- a/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png +++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png Binary files differindex 7ebb8973ef0..8014f1d5301 100644 --- a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png +++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png Binary files differindex 89a04c17fed..02ca0bf7478 100644 --- a/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png +++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png diff --git a/doc/img/devops_lifecycle.png b/doc/img/devops_lifecycle.png Binary files differindex 0616be46df8..0b15e9619a5 100644 --- a/doc/img/devops_lifecycle.png +++ b/doc/img/devops_lifecycle.png diff --git a/doc/install/google_cloud_platform/img/boot_disk.png b/doc/install/google_cloud_platform/img/boot_disk.png Binary files differindex 37b2d9eaae7..b9f7eed6601 100644 --- a/doc/install/google_cloud_platform/img/boot_disk.png +++ b/doc/install/google_cloud_platform/img/boot_disk.png diff --git a/doc/install/google_cloud_platform/img/first_signin.png b/doc/install/google_cloud_platform/img/first_signin.png Binary files differindex 6eb3392d674..1e218abf63d 100644 --- a/doc/install/google_cloud_platform/img/first_signin.png +++ b/doc/install/google_cloud_platform/img/first_signin.png diff --git a/doc/install/google_cloud_platform/img/gcp_landing.png b/doc/install/google_cloud_platform/img/gcp_landing.png Binary files differindex d6390c4dd4f..92a9873728c 100644 --- a/doc/install/google_cloud_platform/img/gcp_landing.png +++ b/doc/install/google_cloud_platform/img/gcp_landing.png diff --git a/doc/install/google_cloud_platform/img/launch_vm.png b/doc/install/google_cloud_platform/img/launch_vm.png Binary files differindex 3fd13f232bb..53cb23277fd 100644 --- a/doc/install/google_cloud_platform/img/launch_vm.png +++ b/doc/install/google_cloud_platform/img/launch_vm.png diff --git a/doc/install/google_cloud_platform/img/ssh_terminal.png b/doc/install/google_cloud_platform/img/ssh_terminal.png Binary files differindex 6a1a418d8e9..171cb572074 100644 --- a/doc/install/google_cloud_platform/img/ssh_terminal.png +++ b/doc/install/google_cloud_platform/img/ssh_terminal.png diff --git a/doc/install/google_cloud_platform/img/vm_created.png b/doc/install/google_cloud_platform/img/vm_created.png Binary files differindex fb467f40838..0ba422af60c 100644 --- a/doc/install/google_cloud_platform/img/vm_created.png +++ b/doc/install/google_cloud_platform/img/vm_created.png diff --git a/doc/install/google_cloud_platform/img/vm_details.png b/doc/install/google_cloud_platform/img/vm_details.png Binary files differindex 2d230416a4b..85b9ca066c8 100644 --- a/doc/install/google_cloud_platform/img/vm_details.png +++ b/doc/install/google_cloud_platform/img/vm_details.png diff --git a/doc/install/installation.md b/doc/install/installation.md index a310f12b29e..2d657163721 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -457,11 +457,35 @@ GitLab-Pages uses [GNU Make](https://www.gnu.org/software/make/). This step is o sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_PAGES_VERSION) sudo -u git -H make +### Install Gitaly + + # Fetch Gitaly source with Git and compile with Go + sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly]" RAILS_ENV=production + +You can specify a different Git repository by providing it as an extra parameter: + + sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,https://example.com/gitaly.git]" RAILS_ENV=production + +Next, make sure gitaly configured: + + # Restrict Gitaly socket access + sudo chmod 0700 /home/git/gitlab/tmp/sockets/private + sudo chown git /home/git/gitlab/tmp/sockets/private + + # If you are using non-default settings you need to update config.toml + cd /home/git/gitaly + sudo -u git -H editor config.toml + +For more information about configuring Gitaly see +[doc/administration/gitaly](../administration/gitaly). + ### Initialize Database and Activate Advanced Features sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production - # Type 'yes' to create the database tables. + + # or you can skip the question by adding force=yes + sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production force=yes # When done you see 'Administrator account created:' @@ -491,28 +515,6 @@ Make GitLab start on boot: sudo update-rc.d gitlab defaults 21 -### Install Gitaly - - # Fetch Gitaly source with Git and compile with Go - sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories]" RAILS_ENV=production - -You can specify a different Git repository by providing it as an extra parameter: - - sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories,https://example.com/gitaly.git]" RAILS_ENV=production - -Next, make sure gitaly configured: - - # Restrict Gitaly socket access - sudo chmod 0700 /home/git/gitlab/tmp/sockets/private - sudo chown git /home/git/gitlab/tmp/sockets/private - - # If you are using non-default settings you need to update config.toml - cd /home/git/gitaly - sudo -u git -H editor config.toml - -For more information about configuring Gitaly see -[doc/administration/gitaly](../administration/gitaly). - ### Setup Logrotate sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab diff --git a/doc/install/kubernetes/gitlab_chart.md b/doc/install/kubernetes/gitlab_chart.md index 692f81dd7cd..5a6f26319c7 100644 --- a/doc/install/kubernetes/gitlab_chart.md +++ b/doc/install/kubernetes/gitlab_chart.md @@ -1,11 +1,12 @@ # GitLab Helm Chart -> **Note:** The chart is currently **beta**, if you encounter any problems please [open an issue](https://gitlab.com/charts/gitlab/issues/new). -For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview). +This is the official and recommended way to install GitLab on a cloud native environment. +For more information on other available GitLab Helm Charts, see the [charts overview](index.md#chart-overview). ## Introduction -The `gitlab` chart is the best way to operate GitLab on Kubernetes. This chart contains all the required components to get started, and can scale to large deployments. +The `gitlab` chart is the best way to operate GitLab on Kubernetes. This chart +contains all the required components to get started, and can scale to large deployments. The default deployment includes: @@ -14,78 +15,94 @@ The default deployment includes: - An auto-scaling, unprivileged [GitLab Runner](https://docs.gitlab.com/runner/) using the Kubernetes executor - Automatically provisioned SSL via [Let's Encrypt](https://letsencrypt.org/). -### Limitations +## Limitations -Some features and functions are not currently available in the beta release. -For details, see [known issues and limitations](https://gitlab.com/charts/gitlab/blob/master/doc/architecture/beta.md#known-issues-and-limitations) in the charts repository. +Some features of GitLab are not currently available: -## Prerequisites +- [GitLab Pages](https://gitlab.com/charts/gitlab/issues/37) +- [GitLab Geo](https://gitlab.com/charts/gitlab/issues/8) +- [No in-cluster HA database](https://gitlab.com/charts/gitlab/issues/48) +- MySQL will not be supported, as support is [deprecated within GitLab](https://docs.gitlab.com/omnibus/settings/database.html#using-a-mysql-database-management-server-enterprise-edition-only) -In order to deploy GitLab on Kubernetes, a few prerequisites are required. +## Installing GitLab using the Helm Chart + +The `gitlab` chart includes all required dependencies, and takes a few minutes +to deploy. + +TIP: **Tip:** +For production deployments, we strongly recommend using the +[detailed installation instructions](https://gitlab.com/charts/gitlab/blob/master/doc/installation/README.md) +utilizing [external Postgres, Redis, and object storage](https://gitlab.com/charts/gitlab/tree/master/doc/advanced) services. + +### Requirements + +In order to deploy GitLab on Kubernetes, the following are required: 1. `helm` and `kubectl` [installed on your computer](preparation/tools_installation.md). 1. A Kubernetes cluster, version 1.8 or higher. 6vCPU and 16GB of RAM is recommended. - * [Google GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster) - * [Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) - * [Microsoft AKS](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal) + - [Google GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster) + - [Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) + - [Microsoft AKS](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal) 1. A [wildcard DNS entry and external IP address](preparation/networking.md) 1. [Authenticate and connect](preparation/connect.md) to the cluster 1. Configure and initialize [Helm Tiller](preparation/tiller.md). -## Configuring and Installing GitLab +### Deployment of GitLab to Kubernetes -> **Note**: For deployments to Amazon EKS, there are [additional configuration requirements](preparation/eks.md). +To deploy GitLab, the following three parameters are required: -For simple deployments, running all services within Kubernetes, only three parameters are required: -- `global.hosts.domain`: the [base domain](preparation/networking.md) of the wildcard host entry. For example, `mycompany.io` if the wild card entry is `*.mycompany.io`. -- `global.hosts.externalIP`: the [external IP](preparation/networking.md) which the wildcard DNS resolves to. -- `certmanager-issuer.email`: Email address to use when requesting new SSL certificates from Let's Encrypt. +- `global.hosts.domain`: the [base domain](preparation/networking.md) of the + wildcard host entry. For example, `exampe.com` if the wild card entry is + `*.example.com`. +- `global.hosts.externalIP`: the [external IP](preparation/networking.md) which + the wildcard DNS resolves to. +- `certmanager-issuer.email`: the email address to use when requesting new SSL + certificates from Let's Encrypt. -For enterprise deployments, or to utilize advanced settings, please use the instructions in the [`gitlab` chart project](https://gitlab.com/charts/gitlab) for the most up to date directions. -- [External Postgres, Redis, and other dependencies](https://gitlab.com/charts/gitlab/tree/master/doc/advanced) -- [Persistence settings](https://gitlab.com/charts/gitlab/blob/master/doc/installation/storage.md) -- [Manual TLS certificates](https://gitlab.com/charts/gitlab/blob/master/doc/installation/tls.md) -- [Manual secret creation](https://gitlab.com/charts/gitlab/blob/master/doc/installation/secrets.md) +NOTE: **Note:** +For deployments to Amazon EKS, there are +[additional configuration requirements](preparation/eks.md). A full list of +configuration options is [also available](https://gitlab.com/charts/gitlab/blob/master/doc/installation/command-line-options.md). -For additional configuration options, consult the [full list of settings](https://gitlab.com/charts/gitlab/blob/master/doc/installation/command-line-options.md). +Once you have all of your configuration options collected, you can get any +dependencies and run helm. In this example, the helm release is named "gitlab": -## Installing GitLab using the Helm Chart - -Once you have all of your configuration options collected, we can get any dependencies and -run helm. In this example, we've named our helm release "gitlab". - -``` +```sh helm repo add gitlab https://charts.gitlab.io/ -helm update +helm repo update helm upgrade --install gitlab gitlab/gitlab \ --timeout 600 \ - --set global.hosts.domain=example.local \ + --set global.hosts.domain=example.com \ --set global.hosts.externalIP=10.10.10.10 \ - --set certmanager-issuer.email=me@example.local + --set certmanager-issuer.email=email@example.com ``` ### Monitoring the Deployment -This will output the list of resources installed once the deployment finishes which may take 5-10 minutes. +This will output the list of resources installed once the deployment finishes, +which may take 5-10 minutes. -The status of the deployment can be checked by running `helm status gitlab` which can also be done while -the deployment is taking place if you run the command in another terminal. +The status of the deployment can be checked by running `helm status gitlab` +which can also be done while the deployment is taking place if you run the +command in another terminal. ### Initial login -You can access the GitLab instance by visiting the domain name beginning with `gitlab.` followed by the domain specified during installation. From the example above, the URL would be `https://gitlab.example.local`. +You can access the GitLab instance by visiting the domain name beginning with +`gitlab.` followed by the domain specified during installation. From the example +above, the URL would be `https://gitlab.example.com`. If you manually created the secret for initial root password, you can use that to sign in as `root` user. If not, Gitlab automatically created a random password for `root` user. This can be extracted by the following command (replace `<name>` by name of the release - which is `gitlab` -if you used the command above). +if you used the command above): -``` -kubectl get secret <name>-gitlab-initial-root-password -ojsonpath={.data.password} | base64 --decode +```sh +kubectl get secret <name>-gitlab-initial-root-password -ojsonpath={.data.password} | base64 --decode ; echo ``` -## Outgoing email +### Outgoing email By default outgoing email is disabled. To enable it, provide details for your SMTP server using the `global.smtp` and `global.email` settings. You can find details for these settings in the @@ -95,14 +112,14 @@ If your SMTP server requires authentication make sure to read the section on pro your password in the [secrets documentation](https://gitlab.com/charts/gitlab/blob/master/doc/installation/secrets.md#smtp-password). You can disable authentication settings with `--set global.smtp.authentication=""`. -If your Kubernetes cluster is on GKE, be aware that smtp [ports 25, 465, and 587 +If your Kubernetes cluster is on GKE, be aware that SMTP ports [25, 465, and 587 are blocked](https://cloud.google.com/compute/docs/tutorials/sending-mail/#using_standard_email_ports). -## Deploying the Community Edition +### Deploying the Community Edition To deploy the Community Edition, include these options in your `helm install` command: -```shell +```sh --set gitlab.migrations.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-rails-ce --set gitlab.sidekiq.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-sidekiq-ce --set gitlab.unicorn.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-unicorn-ce @@ -113,15 +130,15 @@ To deploy the Community Edition, include these options in your `helm install` co Once your GitLab Chart is installed, configuration changes and chart updates should be done using `helm upgrade`: -```bash -helm upgrade -f values.yaml gitlab gitlab/gitlab +```sh +helm upgrade --reuse-values gitlab gitlab/gitlab ``` ## Uninstalling GitLab using the Helm Chart To uninstall the GitLab Chart, run the following: -```bash +```sh helm delete gitlab ``` diff --git a/doc/install/kubernetes/gitlab_omnibus.md b/doc/install/kubernetes/gitlab_omnibus.md index c2c8a7a92fd..d80cb6ad374 100644 --- a/doc/install/kubernetes/gitlab_omnibus.md +++ b/doc/install/kubernetes/gitlab_omnibus.md @@ -1,18 +1,24 @@ # GitLab-Omnibus Helm Chart -> **Note:**. -* This chart has been tested on Google Kubernetes Engine and Azure Container Service. -**[This chart is beta](#limitations), and is the best way to install GitLab on Kubernetes today.** A new [cloud native GitLab chart](index.md#cloud-native-gitlab-chart) is in development with increased scalability and resilience, among other benefits. Once available, the cloud native chart will be the recommended installation method for Kubernetes, and this chart will be deprecated. +CAUTION: **Caution:** +This chart is **deprecated**. We recommend using the [`gitlab` chart](gitlab_chart.md) +instead. A comparison of the two charts is available in [this video](https://youtu.be/Z6jWR8Z8dv8). -For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview). +For more information on available GitLab Helm Charts, see the [charts overview](index.md#chart-overview). -This work is based partially on: https://github.com/lwolf/kubernetes-gitlab/. GitLab would like to thank Sergey Nuzhdin for his work. +- This GitLab-Omnibus chart has been tested on Google Kubernetes Engine and Azure Container Service. +- This work is based partially on: https://github.com/lwolf/kubernetes-gitlab/. GitLab would like to thank Sergey Nuzhdin for his work. ## Introduction -This chart provides an easy way to get started with GitLab, provisioning an installation with nearly all functionality enabled. SSL is automatically provisioned via [Let's Encrypt](https://letsencrypt.org/). +This chart provides an easy way to get started with GitLab, provisioning an +installation with nearly all functionality enabled. SSL is automatically +provisioned via [Let's Encrypt](https://letsencrypt.org/). -This Helm chart is in beta, and is suited for small to medium deployments. It will be deprecated by the [cloud native GitLab chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md) once available. Due to the significant architectural changes, migrating will require backing up data out of this instance and importing it into the new deployment. +This Helm chart is suited for small to medium deployments and is **deprecated** +and replaced by the [cloud native GitLab chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md). +Due to the significant architectural changes, migrating will require backing up +data out of this instance and importing it into the new deployment. The deployment includes: @@ -23,14 +29,12 @@ The deployment includes: - [NGINX Ingress](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress) - Persistent Volume Claims for Data, Registry, Postgres, and Redis -### Limitations +## Limitations -* This chart is in beta, and suited for small to medium size deployments. [High Availability](https://docs.gitlab.com/ee/administration/high_availability/) and [Geo](https://docs.gitlab.com/ee/gitlab-geo/README.html) are not supported. -* A new generation [cloud native GitLab chart](index.md#cloud-native-gitlab-chart) is in development, and will deprecate this chart. Due to the difficulty in supporting upgrades to the new architecture, migrating will require exporting data out of this instance and importing it into the new deployment. We plan to release the new chart in beta by the end of 2017. +[High Availability](../../administration/high_availability/README.md) and +[Geo](https://docs.gitlab.com/ee/gitlab-geo/README.html) are not supported. -For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview). - -## Prerequisites +## Requirements - _At least_ 4 GB of RAM available on your cluster. 41GB of storage and 2 CPU are also required. - Kubernetes 1.4+ with Beta APIs enabled @@ -39,43 +43,65 @@ For more information on available GitLab Helm Charts, please see our [overview]( - The `kubectl` CLI installed locally and authenticated for the cluster - The [Helm client](https://github.com/kubernetes/helm/blob/master/docs/quickstart.md) installed locally on your machine -### Networking Prerequisites +### Networking requirements -This chart configures a GitLab server and Kubernetes cluster which can support dynamic [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/index.html), as well as services like the integrated [Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html) and [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/). +This chart configures a GitLab server and Kubernetes cluster which can support +dynamic [Review Apps](../../ci/review_apps/index.md), as well as services like +the integrated [Container Registry](../../user/project/container_registry.md) +and [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/). -To support the GitLab services and dynamic environments, a wildcard DNS entry is required which resolves to the [Load Balancer](#load-balancer-ip) or [External IP](#external-ip). Configuration of the DNS entry will depend upon the DNS service being used. +To support the GitLab services and dynamic environments, a wildcard DNS entry +is required which resolves to the [load balancer](#load-balancer-ip) or +[external IP](#external-ip). Configuration of the DNS entry will depend upon +the DNS service being used. -#### External IP (Recommended) +#### External IP (recommended) -To provision an external IP on GCP and Azure, simply request a new address from the Networking section. Ensure that the region matches the region your container cluster is created in. Note, it is important that the IP is not assigned at this point in time. It will be automatically assigned once the Helm chart is installed, and assigned to the Load Balancer. +To provision an external IP on GCP and Azure, simply request a new address from +the Networking section. Ensure that the region matches the region your container +cluster is created in. It is important that the IP is not assigned at this point +in time. It will be automatically assigned once the Helm chart is installed, +and assigned to the Load Balancer. -Now that an external IP address has been allocated, ensure that the wildcard DNS entry you would like to use resolves to this IP. Please consult the documentation for your DNS service for more information on creating DNS records. +Now that an external IP address has been allocated, ensure that the wildcard +DNS entry you would like to use resolves to this IP. Please consult the +documentation for your DNS service for more information on creating DNS records. -Finally, set the `baseIP` setting to this IP address when [deploying GitLab](#configuring-and-installing-gitlab). +Finally, set the `baseIP` setting to this IP address when +[deploying GitLab](#configuring-and-installing-gitlab). #### Load Balancer IP -If you do not specify a `baseIP`, an IP will be assigned to the Load Balancer or Ingress. You can retrieve this IP by running the following command *after* deploying GitLab: +If you do not specify a `baseIP`, an IP will be assigned to the Load Balancer or +Ingress. You can retrieve this IP by running the following command *after* deploying GitLab: -`kubectl get svc -w --namespace nginx-ingress nginx` +```sh +kubectl get svc -w --namespace nginx-ingress nginx +``` -The IP address will be displayed in the `EXTERNAL-IP` field, and should be used to configure the Wildcard DNS entry. For more information on creating a wildcard DNS entry, consult the documentation for the DNS server you are using. +The IP address will be displayed in the `EXTERNAL-IP` field, and should be used +to configure the Wildcard DNS entry. For more information on creating a wildcard +DNS entry, consult the documentation for the DNS server you are using. -For production deployments of GitLab, we strongly recommend using an [External IP](#external-ip). +For production deployments of GitLab, we strongly recommend using a +[external IP](#external-ip). ## Configuring and Installing GitLab -For most installations, only two parameters are required: +For most installations, two parameters are required: + - `baseDomain`: the [base domain](#networking-prerequisites) of the wildcard host entry. For example, `mycompany.io` if the wild card entry is `*.mycompany.io`. - `legoEmail`: Email address to use when requesting new SSL certificates from Let's Encrypt. Other common configuration options: + - `baseIP`: the desired [external IP address](#external-ip-recommended) - `gitlab`: Choose the [desired edition](https://about.gitlab.com/pricing), either `ee` or `ce`. `ce` is the default. - `gitlabEELicense`: For Enterprise Edition, the [license](https://docs.gitlab.com/ee/user/admin_area/license.html) can be installed directly via the Chart - `provider`: Optimizes the deployment for a cloud provider. The default is `gke` for [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), with `acs` also supported for the [Azure Container Service](https://azure.microsoft.com/en-us/services/container-service/). -For additional configuration options, consult the [values.yaml](https://gitlab.com/charts/charts.gitlab.io/blob/master/charts/gitlab-omnibus/values.yaml). +For additional configuration options, consult the +[`values.yaml`](https://gitlab.com/charts/charts.gitlab.io/blob/master/charts/gitlab-omnibus/values.yaml). ### Choosing a different GitLab release version @@ -92,13 +118,14 @@ The different images can be found in the [gitlab-ce](https://hub.docker.com/r/gi repositories on Docker Hub. ### Persistent storage -> **Note:** -If you are using a machine type with support for less than 4 attached disks, like an Azure trial, you should disable dedicated storage for Postgres and Redis. -By default, persistent storage is enabled for GitLab and the charts it depends -on (Redis and PostgreSQL). +NOTE: **Note:** +If you are using a machine type with support for less than 4 attached disks, +like an Azure trial, you should disable dedicated storage for Postgres and Redis. -Components can have their claim size set from your `values.yaml`, along with whether to provision separate storage for Postgres and Redis. +By default, persistent storage is enabled for GitLab and the charts it depends +on (Redis and PostgreSQL). Components can have their claim size set from your +`values.yaml`, along with whether to provision separate storage for Postgres and Redis. Basic configuration: @@ -117,14 +144,23 @@ gitlabConfigStorageSize: 1Gi ### Routing and SSL -Ingress routing and SSL are automatically configured within this Chart. An NGINX ingress is provisioned and configured, and will route traffic to any service. SSL certificates are automatically created and configured by [kube-lego](https://github.com/kubernetes/charts/tree/master/stable/kube-lego). +Ingress routing and SSL are automatically configured within this Chart. An NGINX +ingress is provisioned and configured, and will route traffic to any service. +SSL certificates are automatically created and configured by +[kube-lego](https://github.com/kubernetes/charts/tree/master/stable/kube-lego). -> **Note:** -Let's Encrypt limits a single TLD to five certificate requests within a single week. This means that common DNS wildcard services like [nip.io](http://nip.io) are unlikely to work. +NOTE: **Note:** +Let's Encrypt limits a single TLD to five certificate requests within a single +week. This means that common DNS wildcard services like [nip.io](http://nip.io) +and [xip.io](http://xip.io) are unlikely to work. ## Installing GitLab using the Helm Chart -> **Note:** -You may see a temporary error message `SchedulerPredicates failed due to PersistentVolumeClaim is not bound` while storage provisions. Once the storage provisions, the pods will automatically start. This may take a couple minutes depending on your cloud provider. If the error persists, please review the [prerequisites](#prerequisites) to ensure you have enough RAM, CPU, and storage. + +NOTE: **Note:** +You may see a temporary error message `SchedulerPredicates failed due to PersistentVolumeClaim is not bound` +while storage provisions. Once the storage provisions, the pods will automatically start. +This may take a couple minutes depending on your cloud provider. If the error persists, +please review the [requirements sections](#requirements) to ensure you have enough RAM, CPU, and storage. Add the GitLab Helm repository and initialize Helm: @@ -133,15 +169,15 @@ helm init helm repo add gitlab https://charts.gitlab.io ``` -Once you have reviewed the [configuration settings](#configuring-and-installing-gitlab) you can install the chart. We recommending saving your configuration options in a `values.yaml` file for easier upgrades in the future. - -For example: +Once you have reviewed the [configuration settings](#configuring-and-installing-gitlab), +you can install the chart. We recommending saving your configuration options in a +`values.yaml` file for easier upgrades in the future: ```bash helm install --name gitlab -f values.yaml gitlab/gitlab-omnibus ``` -or passing them on the command line: +Or you can pass them on the command line: ```bash helm install --name gitlab --set baseDomain=gitlab.io,baseIP=192.0.2.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus @@ -149,8 +185,11 @@ helm install --name gitlab --set baseDomain=gitlab.io,baseIP=192.0.2.1,gitlab=ee ## Updating GitLab using the Helm Chart ->**Note**: If you are upgrading from a previous version to 0.1.35 or above, you will need to change the access mode values for GitLab's storage. To do this, set the following in `values.yaml` or on the CLI: -``` +If you are upgrading from a previous version to 0.1.35 or above, you will need to +change the access mode values for GitLab's storage. To do this, set the following +in `values.yaml` or on the CLI: + +```sh gitlabDataAccessMode=ReadWriteMany gitlabRegistryAccessMode=ReadWriteMany gitlabConfigAccessMode=ReadWriteMany @@ -159,15 +198,20 @@ gitlabConfigAccessMode=ReadWriteMany Once your GitLab Chart is installed, configuration changes and chart updates should be done using `helm upgrade`: -```bash +```sh helm upgrade -f values.yaml gitlab gitlab/gitlab-omnibus ``` ## Upgrading from CE to EE using the Helm Chart -If you have installed the Community Edition using this chart, upgrading to Enterprise Edition is easy. +If you have installed the Community Edition using this chart, upgrading to +Enterprise Edition is easy. -If you are using a `values.yaml` file to specify the configuration options, edit the file and set `gitlab=ee`. If you would like to run a specific version of GitLab EE, set `gitlabEEImage` to be the desired GitLab [docker image](https://hub.docker.com/r/gitlab/gitlab-ee/tags/). Then you can use `helm upgrade` to update your GitLab instance to EE: +If you are using a `values.yaml` file to specify the configuration options, edit +the file and set `gitlab=ee`. If you would like to run a specific version of +GitLab EE, set `gitlabEEImage` to be the desired GitLab +[docker image](https://hub.docker.com/r/gitlab/gitlab-ee/tags/). Then you can +use `helm upgrade` to update your GitLab instance to EE: ```bash helm upgrade -f values.yaml gitlab gitlab/gitlab-omnibus @@ -191,9 +235,12 @@ helm delete gitlab ### Storage errors when updating `gitlab-omnibus` versions prior to 0.1.35 -Users upgrading `gitlab-omnibus` from a version prior to 0.1.35, may see an error like: `Error: UPGRADE FAILED: PersistentVolumeClaim "gitlab-gitlab-config-storage" is invalid: spec: Forbidden: field is immutable after creation`. +Users upgrading `gitlab-omnibus` from a version prior to 0.1.35, may see an error +like: `Error: UPGRADE FAILED: PersistentVolumeClaim "gitlab-gitlab-config-storage" is invalid: spec: Forbidden: field is immutable after creation`. -This is due to a change in the access mode for GitLab storage in version 0.1.35. To successfully upgrade, the access mode flags must be set to `ReadWriteMany` as detailed in the [update section](#updating-gitlab-using-the-helm-chart). +This is due to a change in the access mode for GitLab storage in version 0.1.35. +To successfully upgrade, the access mode flags must be set to `ReadWriteMany` +as detailed in the [update section](#updating-gitlab-using-the-helm-chart). [kube-srv]: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types [storageclass]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#storageclasses diff --git a/doc/install/kubernetes/index.md b/doc/install/kubernetes/index.md index 6419a9dcb69..e67d5ba4d4c 100644 --- a/doc/install/kubernetes/index.md +++ b/doc/install/kubernetes/index.md @@ -4,7 +4,8 @@ description: 'Read through the different methods to deploy GitLab on Kubernetes. # Installing GitLab on Kubernetes -> **Note**: These charts have been tested on Google Kubernetes Engine. Other Kubernetes installations may work as well, if not please [open an issue](https://gitlab.com/charts/issues). +NOTE: **Note**: These charts have been tested on Google Kubernetes Engine. Other +Kubernetes installations may work as well, if not please [open an issue](https://gitlab.com/charts/issues). The easiest method to deploy GitLab on [Kubernetes](https://kubernetes.io/) is to take advantage of GitLab's Helm charts. [Helm] is a package @@ -14,30 +15,31 @@ should be deployed, upgraded, and configured. ## Chart Overview -* **[GitLab Chart](gitlab_chart.html)**: The recommended GitLab chart, currently in beta. Supports large deployments with horizontal scaling of individual GitLab components, and does not require NFS. -* **[GitLab Runner Chart](gitlab_runner_chart.md)**: For deploying just the GitLab Runner. -* Other Charts - * [GitLab-Omnibus](gitlab_omnibus.md): Chart based on the Omnibus GitLab linux package, only suitable for small deployments. The chart will be deprecated by the [GitLab chart](#gitlab-chart) when it is GA. - * [Community Contributed Charts](#community-contributed-charts): Community contributed charts, deprecated by the official GitLab chart. +- **[GitLab Chart](gitlab_chart.html)**: Deploys GitLab on Kubernetes. Includes all the required components to get started, and can scale to large deployments. +- **[GitLab Runner Chart](gitlab_runner_chart.md)**: For deploying just the GitLab Runner. +- Other Charts + - [GitLab-Omnibus](gitlab_omnibus.md): Chart based on the Omnibus GitLab package, only suitable for small deployments. Deprecated, we strongly recommend using the [gitlab](#gitlab-chart) chart. + - [Community contributed charts](#community-contributed-charts): Community contributed charts. ## GitLab Chart -> **Note**: This chart is **beta**, while we work on the [remaining items for GA](https://gitlab.com/groups/charts/-/epics/15). +This chart contains all the required components to get started, and can scale to +large deployments. It offers a number of benefits: -The best way to operate GitLab on Kubernetes. This chart contains all the required components to get started, and can scale to large deployments. +- Horizontal scaling of individual components +- No requirement for shared storage to scale +- Containers do not need `root` permissions +- Automatic SSL with Let's Encrypt +- and plenty more. -This chart offers a number of benefits: -* Horizontal scaling of individual components -* No requirement for shared storage to scale -* Containers do not need `root` permissions -* Automatic SSL with Let's Encrypt -* and plenty more. - -Learn more about the [GitLab chart here](gitlab_chart.md) and [here [Video]](https://youtu.be/Z6jWR8Z8dv8). +Learn more about the [GitLab chart](gitlab_chart.md). ## GitLab Runner Chart -If you already have a GitLab instance running, inside or outside of Kubernetes, and you'd like to leverage the Runner's [Kubernetes capabilities](https://docs.gitlab.com/runner/executors/kubernetes.html), it can be deployed with the GitLab Runner chart. +If you already have a GitLab instance running, inside or outside of Kubernetes, +and you'd like to leverage the Runner's +[Kubernetes capabilities](https://docs.gitlab.com/runner/executors/kubernetes.html), +it can be deployed with the GitLab Runner chart. Learn more about [gitlab-runner chart](gitlab_runner_chart.md). @@ -45,11 +47,18 @@ Learn more about [gitlab-runner chart](gitlab_runner_chart.md). ### GitLab-Omnibus Chart -> **Note**: This chart is beta, and **will be deprecated** when the [`gitlab`](#gitlab-chart) chart is GA. +CAUTION: **Deprecated:** +This chart is **deprecated**. We recommend using the [GitLab Chart](gitlab_chart.md) +instead. A comparison of the two charts is available in [this video](https://youtu.be/Z6jWR8Z8dv8). -It deploys and configures nearly all features of GitLab, including: a [Runner](https://docs.gitlab.com/runner/), [Container Registry](../../user/project/container_registry.html#gitlab-container-registry), [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/), [automatic SSL](https://github.com/kubernetes/charts/tree/master/stable/kube-lego), and a [load balancer](https://github.com/kubernetes/ingress/tree/master/controllers/nginx). It is based on our [GitLab Omnibus Docker Images](https://docs.gitlab.com/omnibus/docker/README.html). +This chart is based on the [GitLab Omnibus Docker images](https://docs.gitlab.com/omnibus/docker/). +It deploys and configures nearly all features of GitLab, including: -Once the [GitLab chart](#gitlab-chart) is GA, this chart will be deprecated. Migrating to the `gitlab` chart will require exporting data out of this instance and importing it into a new deployment. +- a [GitLab Runner](https://docs.gitlab.com/runner/) +- [Container Registry](../../user/project/container_registry.html#gitlab-container-registry) +- [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/) +- [automatic SSL](https://github.com/kubernetes/charts/tree/master/stable/kube-lego) +- and an [NGINX load balancer](https://github.com/kubernetes/ingress/tree/master/controllers/nginx). Learn more about the [gitlab-omnibus chart](gitlab_omnibus.md). diff --git a/doc/install/kubernetes/preparation/connect.md b/doc/install/kubernetes/preparation/connect.md index fb633c456f5..a3a0cba4bf2 100644 --- a/doc/install/kubernetes/preparation/connect.md +++ b/doc/install/kubernetes/preparation/connect.md @@ -2,19 +2,14 @@ In order to deploy software and settings to a cluster, you must connect and authenticate to it. -* [GKE cluster](#connect-to-gke-cluster) -* [EKS cluster](#connect-to-eks-cluster) -* [Local minikube cluster](#connect-to-local-minikube-cluster) - ## Connect to GKE cluster -The command for connection to the cluster can be obtained from the [Google Cloud Platform Console](https://console.cloud.google.com/kubernetes/list) by the individual cluster. - -Look for the **Connect** button in the clusters list page. - -**Or** +The command for connection to the cluster can be obtained from the +[Google Cloud Platform Console](https://console.cloud.google.com/kubernetes/list) +by the individual cluster. -Use the command below, filling in your cluster's informtion: +Look for the **Connect** button in the clusters list page or use the command below, +filling in your cluster's information: ``` gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project-id> @@ -22,7 +17,8 @@ gcloud container clusters get-credentials <cluster-name> --zone <zone> --project ## Connect to EKS cluster -For the most up to date instructions, follow the Amazon EKS documentation on [connecting to a cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#eks-configure-kubectl). +For the most up to date instructions, follow the Amazon EKS documentation on +[connecting to a cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#eks-configure-kubectl). ## Connect to local minikube cluster diff --git a/doc/install/kubernetes/preparation/networking.md b/doc/install/kubernetes/preparation/networking.md index b157cf31aa9..34a6130de27 100644 --- a/doc/install/kubernetes/preparation/networking.md +++ b/doc/install/kubernetes/preparation/networking.md @@ -1,6 +1,8 @@ # Networking Prerequisites -> **Note**: Amazon EKS utilizes Elastic Load Balancers, which are addressed by DNS name and cannot be known ahead of time. Skip this section. +NOTE: **Note:** +Amazon EKS utilizes Elastic Load Balancers, which are addressed by DNS name and +cannot be known ahead of time. If you're using EKS, you can skip this section. The `gitlab` chart configures a GitLab server and Kubernetes cluster which can support dynamic [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/index.html), as well as services like the integrated [Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html). @@ -30,7 +32,7 @@ Now that an external IP address has been allocated, ensure that the wildcard DNS Please consult the documentation for your DNS service for more information on creating DNS records: -* [Google Domains](https://support.google.com/domains/answer/3290350?hl=en) -* [GoDaddy](https://www.godaddy.com/help/add-an-a-record-19238) +- [Google Domains](https://support.google.com/domains/answer/3290350?hl=en) +- [GoDaddy](https://www.godaddy.com/help/add-an-a-record-19238) Set `global.hosts.domain` to this DNS name when [deploying GitLab](../gitlab_chart.md#configuring-and-installing-gitlab). diff --git a/doc/install/kubernetes/preparation/rbac.md b/doc/install/kubernetes/preparation/rbac.md index 240893526d3..c5f8d7a7e9e 100644 --- a/doc/install/kubernetes/preparation/rbac.md +++ b/doc/install/kubernetes/preparation/rbac.md @@ -1,16 +1,20 @@ # Role Based Access Control -Until Kubernetes 1.7, there were no permissions within a cluster. With the launch of 1.7, there is now a role based access control system ([RBAC](https://kubernetes.io/docs/admin/authorization/rbac/)) which determines what services can perform actions within a cluster. +Until Kubernetes 1.7, there were no permissions within a cluster. With the launch +of 1.7, there is now a [role based access control system (RBAC)](https://kubernetes.io/docs/admin/authorization/rbac/) +which determines what services can perform actions within a cluster. RBAC affects a few different aspects of GitLab: -* [Installation of GitLab using Helm](tiller.md#preparing-for-helm-with-rbac) -* Prometheus monitoring -* GitLab Runner -## Checking that RBAC is enabled +- [Installation of GitLab using Helm](tiller.md#preparing-for-helm-with-rbac) +- Prometheus monitoring +- GitLab Runner -Try listing the current cluster roles, if it fails then `RBAC` is disabled +## Checking that RBAC is enabled -This command will output `false` if `RBAC` is disabled and `true` otherwise +Try listing the current cluster roles, if it fails then `RBAC` is disabled. +The following command will output `false` if `RBAC` is disabled and `true` otherwise: -`kubectl get clusterroles > /dev/null 2>&1 && echo true || echo false` +```sh +kubectl get clusterroles > /dev/null 2>&1 && echo true || echo false +``` diff --git a/doc/install/kubernetes/preparation/tiller.md b/doc/install/kubernetes/preparation/tiller.md index 016aac2abeb..107df074b3b 100644 --- a/doc/install/kubernetes/preparation/tiller.md +++ b/doc/install/kubernetes/preparation/tiller.md @@ -1,10 +1,15 @@ # Configuring and initializing Helm Tiller -To make use of Helm, you must have a [Kubernetes][k8s-io] cluster. Ensure you can access your cluster using `kubectl`. +To make use of Helm, you must have a [Kubernetes][k8s-io] cluster. Ensure you can +access your cluster using `kubectl`. Helm consists of two parts, the `helm` client and a `tiller` server inside Kubernetes. -> **Note**: If you are not able to run Tiller in your cluster, for example on OpenShift, it is possible to use [Tiller locally](https://gitlab.com/charts/gitlab/tree/master/doc/helm#local-tiller) and avoid deploying it into the cluster. This should only be used when Tiller cannot be normally deployed. +NOTE: **Note:** +If you are not able to run Tiller in your cluster, for example on OpenShift, it +is possible to use [Tiller locally](https://gitlab.com/charts/gitlab/tree/master/doc/helm#local-tiller) +and avoid deploying it into the cluster. This should only be used when Tiller +cannot be normally deployed. ## Initialize Helm and Tiller diff --git a/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png b/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png Binary files differindex fcad4e59ae3..5b6059dd022 100644 --- a/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png +++ b/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png diff --git a/doc/install/openshift_and_gitlab/img/add-to-project.png b/doc/install/openshift_and_gitlab/img/add-to-project.png Binary files differindex bd915a229f6..f9b00431d00 100644 --- a/doc/install/openshift_and_gitlab/img/add-to-project.png +++ b/doc/install/openshift_and_gitlab/img/add-to-project.png diff --git a/doc/install/openshift_and_gitlab/img/create-project-ui.png b/doc/install/openshift_and_gitlab/img/create-project-ui.png Binary files differindex e72866f252a..43b151264c5 100644 --- a/doc/install/openshift_and_gitlab/img/create-project-ui.png +++ b/doc/install/openshift_and_gitlab/img/create-project-ui.png diff --git a/doc/install/openshift_and_gitlab/img/gitlab-logs.png b/doc/install/openshift_and_gitlab/img/gitlab-logs.png Binary files differindex 1e24080c7df..8b90b2f74ac 100644 --- a/doc/install/openshift_and_gitlab/img/gitlab-logs.png +++ b/doc/install/openshift_and_gitlab/img/gitlab-logs.png diff --git a/doc/install/openshift_and_gitlab/img/gitlab-overview.png b/doc/install/openshift_and_gitlab/img/gitlab-overview.png Binary files differindex 3c5df0ea101..3a7bec7c2bc 100644 --- a/doc/install/openshift_and_gitlab/img/gitlab-overview.png +++ b/doc/install/openshift_and_gitlab/img/gitlab-overview.png diff --git a/doc/install/openshift_and_gitlab/img/gitlab-running.png b/doc/install/openshift_and_gitlab/img/gitlab-running.png Binary files differindex c7db691cb30..0fcd9f00d08 100644 --- a/doc/install/openshift_and_gitlab/img/gitlab-running.png +++ b/doc/install/openshift_and_gitlab/img/gitlab-running.png diff --git a/doc/install/openshift_and_gitlab/img/gitlab-scale.png b/doc/install/openshift_and_gitlab/img/gitlab-scale.png Binary files differindex 4903c7d7498..ebae8b588b1 100644 --- a/doc/install/openshift_and_gitlab/img/gitlab-scale.png +++ b/doc/install/openshift_and_gitlab/img/gitlab-scale.png diff --git a/doc/install/openshift_and_gitlab/img/gitlab-settings.png b/doc/install/openshift_and_gitlab/img/gitlab-settings.png Binary files differindex db4360ffef0..0dd1e1f5b8e 100644 --- a/doc/install/openshift_and_gitlab/img/gitlab-settings.png +++ b/doc/install/openshift_and_gitlab/img/gitlab-settings.png diff --git a/doc/install/openshift_and_gitlab/img/no-resources.png b/doc/install/openshift_and_gitlab/img/no-resources.png Binary files differindex 480fb766468..1ef0a0b31e5 100644 --- a/doc/install/openshift_and_gitlab/img/no-resources.png +++ b/doc/install/openshift_and_gitlab/img/no-resources.png diff --git a/doc/install/openshift_and_gitlab/img/openshift-infra-project.png b/doc/install/openshift_and_gitlab/img/openshift-infra-project.png Binary files differindex 8b9f85aa341..e31dda1461c 100644 --- a/doc/install/openshift_and_gitlab/img/openshift-infra-project.png +++ b/doc/install/openshift_and_gitlab/img/openshift-infra-project.png diff --git a/doc/install/openshift_and_gitlab/img/pods-overview.png b/doc/install/openshift_and_gitlab/img/pods-overview.png Binary files differindex e1cf08bd217..65927f65f4f 100644 --- a/doc/install/openshift_and_gitlab/img/pods-overview.png +++ b/doc/install/openshift_and_gitlab/img/pods-overview.png diff --git a/doc/install/openshift_and_gitlab/img/rc-name.png b/doc/install/openshift_and_gitlab/img/rc-name.png Binary files differindex 889e34adbec..16d967b8460 100644 --- a/doc/install/openshift_and_gitlab/img/rc-name.png +++ b/doc/install/openshift_and_gitlab/img/rc-name.png diff --git a/doc/install/openshift_and_gitlab/img/running-pods.png b/doc/install/openshift_and_gitlab/img/running-pods.png Binary files differindex 3fd4e56662f..e08487c881c 100644 --- a/doc/install/openshift_and_gitlab/img/running-pods.png +++ b/doc/install/openshift_and_gitlab/img/running-pods.png diff --git a/doc/install/openshift_and_gitlab/img/storage-volumes.png b/doc/install/openshift_and_gitlab/img/storage-volumes.png Binary files differindex ae1e5381faa..3fd092919bb 100644 --- a/doc/install/openshift_and_gitlab/img/storage-volumes.png +++ b/doc/install/openshift_and_gitlab/img/storage-volumes.png diff --git a/doc/install/openshift_and_gitlab/img/web-console.png b/doc/install/openshift_and_gitlab/img/web-console.png Binary files differindex aa1425d4f94..012d7703c73 100644 --- a/doc/install/openshift_and_gitlab/img/web-console.png +++ b/doc/install/openshift_and_gitlab/img/web-console.png diff --git a/doc/integration/img/bitbucket_oauth_keys.png b/doc/integration/img/bitbucket_oauth_keys.png Binary files differindex 6dd2c7d744e..2f0c0eff784 100644 --- a/doc/integration/img/bitbucket_oauth_keys.png +++ b/doc/integration/img/bitbucket_oauth_keys.png diff --git a/doc/integration/img/enable_trello_powerup.png b/doc/integration/img/enable_trello_powerup.png Binary files differindex 65d01f1c38c..f80d0eadc0b 100644 --- a/doc/integration/img/enable_trello_powerup.png +++ b/doc/integration/img/enable_trello_powerup.png diff --git a/doc/integration/img/enabled-oauth-sign-in-sources.png b/doc/integration/img/enabled-oauth-sign-in-sources.png Binary files differindex f145aeae75c..e83f9d5cfdf 100644 --- a/doc/integration/img/enabled-oauth-sign-in-sources.png +++ b/doc/integration/img/enabled-oauth-sign-in-sources.png diff --git a/doc/integration/img/facebook_api_keys.png b/doc/integration/img/facebook_api_keys.png Binary files differindex 9463ec1e7a3..7480b144091 100644 --- a/doc/integration/img/facebook_api_keys.png +++ b/doc/integration/img/facebook_api_keys.png diff --git a/doc/integration/img/facebook_website_url.png b/doc/integration/img/facebook_website_url.png Binary files differindex 67d78d13951..7873c9905f1 100644 --- a/doc/integration/img/facebook_website_url.png +++ b/doc/integration/img/facebook_website_url.png diff --git a/doc/integration/img/gitlab_app.png b/doc/integration/img/gitlab_app.png Binary files differindex 8d6a4456fc4..228e8a01305 100644 --- a/doc/integration/img/gitlab_app.png +++ b/doc/integration/img/gitlab_app.png diff --git a/doc/integration/img/google_app.png b/doc/integration/img/google_app.png Binary files differindex 9fda06dabb1..08f230452b4 100644 --- a/doc/integration/img/google_app.png +++ b/doc/integration/img/google_app.png diff --git a/doc/integration/img/oauth_provider_admin_application.png b/doc/integration/img/oauth_provider_admin_application.png Binary files differindex c8ecce129c8..353114fea30 100644 --- a/doc/integration/img/oauth_provider_admin_application.png +++ b/doc/integration/img/oauth_provider_admin_application.png diff --git a/doc/integration/img/oauth_provider_application_form.png b/doc/integration/img/oauth_provider_application_form.png Binary files differindex 954681e054e..c4546d8b3f5 100644 --- a/doc/integration/img/oauth_provider_application_form.png +++ b/doc/integration/img/oauth_provider_application_form.png diff --git a/doc/integration/img/oauth_provider_application_id_secret.png b/doc/integration/img/oauth_provider_application_id_secret.png Binary files differindex 65cca5f1e1b..21e442b5d04 100644 --- a/doc/integration/img/oauth_provider_application_id_secret.png +++ b/doc/integration/img/oauth_provider_application_id_secret.png diff --git a/doc/integration/img/oauth_provider_authorized_application.png b/doc/integration/img/oauth_provider_authorized_application.png Binary files differindex ed99db3476d..ebff8529b4e 100644 --- a/doc/integration/img/oauth_provider_authorized_application.png +++ b/doc/integration/img/oauth_provider_authorized_application.png diff --git a/doc/integration/img/submit_issue.png b/doc/integration/img/submit_issue.png Binary files differindex 8accb78faf3..e794eac189e 100644 --- a/doc/integration/img/submit_issue.png +++ b/doc/integration/img/submit_issue.png diff --git a/doc/integration/img/twitter_app_api_keys.png b/doc/integration/img/twitter_app_api_keys.png Binary files differindex 34e3c3ba001..c6a3245b1b1 100644 --- a/doc/integration/img/twitter_app_api_keys.png +++ b/doc/integration/img/twitter_app_api_keys.png diff --git a/doc/monitoring/performance/img/grafana_dashboard_import.png b/doc/monitoring/performance/img/grafana_dashboard_import.png Binary files differindex 7761ea00522..fd639ee0eb8 100644 --- a/doc/monitoring/performance/img/grafana_dashboard_import.png +++ b/doc/monitoring/performance/img/grafana_dashboard_import.png diff --git a/doc/monitoring/performance/img/grafana_data_source_configuration.png b/doc/monitoring/performance/img/grafana_data_source_configuration.png Binary files differindex 3e749eb8f9d..a98e0ed1e7d 100644 --- a/doc/monitoring/performance/img/grafana_data_source_configuration.png +++ b/doc/monitoring/performance/img/grafana_data_source_configuration.png diff --git a/doc/monitoring/performance/img/grafana_data_source_empty.png b/doc/monitoring/performance/img/grafana_data_source_empty.png Binary files differindex 33fcaaaef64..549ada8343e 100644 --- a/doc/monitoring/performance/img/grafana_data_source_empty.png +++ b/doc/monitoring/performance/img/grafana_data_source_empty.png diff --git a/doc/monitoring/performance/img/grafana_save_icon.png b/doc/monitoring/performance/img/grafana_save_icon.png Binary files differindex c18f2147e9d..68a071f5ae2 100644 --- a/doc/monitoring/performance/img/grafana_save_icon.png +++ b/doc/monitoring/performance/img/grafana_save_icon.png diff --git a/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png b/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png Binary files differindex d96a18ebc04..b9563a00e97 100644 --- a/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png +++ b/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png diff --git a/doc/public_access/img/restrict_visibility_levels.png b/doc/public_access/img/restrict_visibility_levels.png Binary files differindex c7d4d87981f..e9315cfb701 100644 --- a/doc/public_access/img/restrict_visibility_levels.png +++ b/doc/public_access/img/restrict_visibility_levels.png diff --git a/doc/raketasks/backup_hrz.png b/doc/raketasks/backup_hrz.png Binary files differindex c9595b236ee..32690b2904c 100644 --- a/doc/raketasks/backup_hrz.png +++ b/doc/raketasks/backup_hrz.png diff --git a/doc/security/img/outbound_requests_section.png b/doc/security/img/outbound_requests_section.png Binary files differindex 95c9c6ee771..f7783f34cdd 100644 --- a/doc/security/img/outbound_requests_section.png +++ b/doc/security/img/outbound_requests_section.png diff --git a/doc/security/img/ssh_keys_restrictions_settings.png b/doc/security/img/ssh_keys_restrictions_settings.png Binary files differindex 2e918fd4b3f..94258af3bf9 100644 --- a/doc/security/img/ssh_keys_restrictions_settings.png +++ b/doc/security/img/ssh_keys_restrictions_settings.png diff --git a/doc/security/img/two_factor_authentication_group_settings.png b/doc/security/img/two_factor_authentication_group_settings.png Binary files differindex a1b3c58bfdc..05d95554fd9 100644 --- a/doc/security/img/two_factor_authentication_group_settings.png +++ b/doc/security/img/two_factor_authentication_group_settings.png diff --git a/doc/security/img/two_factor_authentication_settings.png b/doc/security/img/two_factor_authentication_settings.png Binary files differindex 6d89be1eb04..2a2208f98bd 100644 --- a/doc/security/img/two_factor_authentication_settings.png +++ b/doc/security/img/two_factor_authentication_settings.png diff --git a/doc/topics/autodevops/img/guide_environments.png b/doc/topics/autodevops/img/guide_environments.png Binary files differindex 1d8d5614e64..404db17c57a 100644 --- a/doc/topics/autodevops/img/guide_environments.png +++ b/doc/topics/autodevops/img/guide_environments.png diff --git a/doc/topics/autodevops/img/guide_ide_commit.png b/doc/topics/autodevops/img/guide_ide_commit.png Binary files differindex 188f60f2a4b..d7be66f4049 100644 --- a/doc/topics/autodevops/img/guide_ide_commit.png +++ b/doc/topics/autodevops/img/guide_ide_commit.png diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png Binary files differindex 9a80c211c99..d8dc9fc8097 100644 --- a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png +++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png Binary files differindex ac7ea9ecddc..6506de209f4 100644 --- a/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png +++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png Binary files differindex 13b3a35ca45..040f8118d72 100644 --- a/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png +++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png diff --git a/doc/university/high-availability/aws/README.md b/doc/university/high-availability/aws/README.md index 8f7bb8636c5..4e7eae19844 100644 --- a/doc/university/high-availability/aws/README.md +++ b/doc/university/high-availability/aws/README.md @@ -30,7 +30,7 @@ we'll be using to configure our cloud infrastructure. ### Reference Architecture -![Reference Architecture](img/reference-arch.png) +![Reference Architecture](img/reference-arch2.png) *** diff --git a/doc/university/high-availability/aws/img/auto-scaling-det.png b/doc/university/high-availability/aws/img/auto-scaling-det.png Binary files differindex 1e125f301bc..cf32c024bf8 100644 --- a/doc/university/high-availability/aws/img/auto-scaling-det.png +++ b/doc/university/high-availability/aws/img/auto-scaling-det.png diff --git a/doc/university/high-availability/aws/img/db-subnet-group.png b/doc/university/high-availability/aws/img/db-subnet-group.png Binary files differindex 590a02b8dbe..875184af310 100644 --- a/doc/university/high-availability/aws/img/db-subnet-group.png +++ b/doc/university/high-availability/aws/img/db-subnet-group.png diff --git a/doc/university/high-availability/aws/img/ig.png b/doc/university/high-availability/aws/img/ig.png Binary files differindex d4fc2d12de8..2798d4beac3 100644 --- a/doc/university/high-availability/aws/img/ig.png +++ b/doc/university/high-availability/aws/img/ig.png diff --git a/doc/university/high-availability/aws/img/instance_specs.png b/doc/university/high-availability/aws/img/instance_specs.png Binary files differindex 650f375ab3c..2a2b80103fb 100644 --- a/doc/university/high-availability/aws/img/instance_specs.png +++ b/doc/university/high-availability/aws/img/instance_specs.png diff --git a/doc/university/high-availability/aws/img/new_vpc.png b/doc/university/high-availability/aws/img/new_vpc.png Binary files differindex e51c066cee2..d872554fab7 100644 --- a/doc/university/high-availability/aws/img/new_vpc.png +++ b/doc/university/high-availability/aws/img/new_vpc.png diff --git a/doc/university/high-availability/aws/img/policies.png b/doc/university/high-availability/aws/img/policies.png Binary files differindex afcd9e4af9b..e99497a52a2 100644 --- a/doc/university/high-availability/aws/img/policies.png +++ b/doc/university/high-availability/aws/img/policies.png diff --git a/doc/university/high-availability/aws/img/rds-net-opt.png b/doc/university/high-availability/aws/img/rds-net-opt.png Binary files differindex 651cc23b1ab..13130ac96b8 100644 --- a/doc/university/high-availability/aws/img/rds-net-opt.png +++ b/doc/university/high-availability/aws/img/rds-net-opt.png diff --git a/doc/university/high-availability/aws/img/rds-sec-group.png b/doc/university/high-availability/aws/img/rds-sec-group.png Binary files differindex c6d1bc350e4..a88caba62c2 100644 --- a/doc/university/high-availability/aws/img/rds-sec-group.png +++ b/doc/university/high-availability/aws/img/rds-sec-group.png diff --git a/doc/university/high-availability/aws/img/reference-arch.png b/doc/university/high-availability/aws/img/reference-arch.png Binary files differdeleted file mode 100644 index 271ee5bc614..00000000000 --- a/doc/university/high-availability/aws/img/reference-arch.png +++ /dev/null diff --git a/doc/university/high-availability/aws/img/reference-arch2.png b/doc/university/high-availability/aws/img/reference-arch2.png Binary files differnew file mode 100644 index 00000000000..9f50b2f5171 --- /dev/null +++ b/doc/university/high-availability/aws/img/reference-arch2.png diff --git a/doc/university/high-availability/aws/img/subnet.png b/doc/university/high-availability/aws/img/subnet.png Binary files differindex de910edc948..681c29bf07a 100644 --- a/doc/university/high-availability/aws/img/subnet.png +++ b/doc/university/high-availability/aws/img/subnet.png diff --git a/doc/university/training/gitlab_flow/production_branch.png b/doc/university/training/gitlab_flow/production_branch.png Binary files differindex 66456cc51af..956761d7eb8 100644 --- a/doc/university/training/gitlab_flow/production_branch.png +++ b/doc/university/training/gitlab_flow/production_branch.png diff --git a/doc/university/training/gitlab_flow/release_branches.png b/doc/university/training/gitlab_flow/release_branches.png Binary files differindex 5661e36c4e2..dcb5f97dff0 100644 --- a/doc/university/training/gitlab_flow/release_branches.png +++ b/doc/university/training/gitlab_flow/release_branches.png diff --git a/doc/update/10.7-to-10.8.md b/doc/update/10.7-to-10.8.md index 13101a987f4..7bb628f9740 100644 --- a/doc/update/10.7-to-10.8.md +++ b/doc/update/10.7-to-10.8.md @@ -38,16 +38,16 @@ You can check which version you are running with `ruby -v`. Download Ruby and compile it: - ```bash - mkdir /tmp/ruby && cd /tmp/ruby - curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz - echo '540996fec64984ab6099e34d2f5820b14904f15a ruby-2.3.7.tar.gz' | shasum -c - && tar xzf ruby-2.3.7.tar.gz - cd ruby-2.3.7 - - ./configure --disable-install-rdoc - make - sudo make install - ``` +```bash +mkdir /tmp/ruby && cd /tmp/ruby +curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz +echo '540996fec64984ab6099e34d2f5820b14904f15a ruby-2.3.7.tar.gz' | shasum -c - && tar xzf ruby-2.3.7.tar.gz +cd ruby-2.3.7 + +./configure --disable-install-rdoc +make +sudo make install +``` Install Bundler: diff --git a/doc/user/admin_area/monitoring/img/health_check_token.png b/doc/user/admin_area/monitoring/img/health_check_token.png Binary files differindex 182549fc484..8d4cf710176 100644 --- a/doc/user/admin_area/monitoring/img/health_check_token.png +++ b/doc/user/admin_area/monitoring/img/health_check_token.png diff --git a/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png b/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png Binary files differindex 50a86ede56b..723be23e77b 100644 --- a/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png +++ b/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png diff --git a/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png b/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png Binary files differindex 33fd29e2039..3f827f1f7a3 100644 --- a/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png +++ b/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png diff --git a/doc/user/admin_area/settings/img/domain_blacklist.png b/doc/user/admin_area/settings/img/domain_blacklist.png Binary files differindex dedd3be1e8f..a7e972b7c0a 100644 --- a/doc/user/admin_area/settings/img/domain_blacklist.png +++ b/doc/user/admin_area/settings/img/domain_blacklist.png diff --git a/doc/user/admin_area/settings/img/restricted_url.png b/doc/user/admin_area/settings/img/restricted_url.png Binary files differindex 67abd13f741..c71abf0a226 100644 --- a/doc/user/admin_area/settings/img/restricted_url.png +++ b/doc/user/admin_area/settings/img/restricted_url.png diff --git a/doc/user/admin_area/settings/img/update-available.png b/doc/user/admin_area/settings/img/update-available.png Binary files differindex 0dafdad618e..9887e06c7dc 100644 --- a/doc/user/admin_area/settings/img/update-available.png +++ b/doc/user/admin_area/settings/img/update-available.png diff --git a/doc/user/discussions/img/automatically_resolve_outdated_discussions.png b/doc/user/discussions/img/automatically_resolve_outdated_discussions.png Binary files differindex 9a798ddd178..ba129e7a618 100644 --- a/doc/user/discussions/img/automatically_resolve_outdated_discussions.png +++ b/doc/user/discussions/img/automatically_resolve_outdated_discussions.png diff --git a/doc/user/discussions/img/btn_new_issue_for_all_discussions.png b/doc/user/discussions/img/btn_new_issue_for_all_discussions.png Binary files differindex b15447ec290..3306bf2e60e 100644 --- a/doc/user/discussions/img/btn_new_issue_for_all_discussions.png +++ b/doc/user/discussions/img/btn_new_issue_for_all_discussions.png diff --git a/doc/user/discussions/img/discussion_comment.png b/doc/user/discussions/img/discussion_comment.png Binary files differindex 8f66d138922..206ddebf54b 100644 --- a/doc/user/discussions/img/discussion_comment.png +++ b/doc/user/discussions/img/discussion_comment.png diff --git a/doc/user/discussions/img/discussion_lock_system_notes.png b/doc/user/discussions/img/discussion_lock_system_notes.png Binary files differindex 8e8e8e0bc3d..44a47e3f097 100644 --- a/doc/user/discussions/img/discussion_lock_system_notes.png +++ b/doc/user/discussions/img/discussion_lock_system_notes.png diff --git a/doc/user/discussions/img/discussion_view.png b/doc/user/discussions/img/discussion_view.png Binary files differindex 2ee1db2eab3..3a2b766ed7e 100644 --- a/doc/user/discussions/img/discussion_view.png +++ b/doc/user/discussions/img/discussion_view.png diff --git a/doc/user/discussions/img/lock_form_member.png b/doc/user/discussions/img/lock_form_member.png Binary files differindex 01c6308d24c..7bfcb4faae6 100644 --- a/doc/user/discussions/img/lock_form_member.png +++ b/doc/user/discussions/img/lock_form_member.png diff --git a/doc/user/discussions/img/lock_form_non_member.png b/doc/user/discussions/img/lock_form_non_member.png Binary files differindex 3bb70b69580..59e5fd89499 100644 --- a/doc/user/discussions/img/lock_form_non_member.png +++ b/doc/user/discussions/img/lock_form_non_member.png diff --git a/doc/user/discussions/img/new_issue_for_discussion.png b/doc/user/discussions/img/new_issue_for_discussion.png Binary files differindex 93c9dad8921..819d872a9a2 100644 --- a/doc/user/discussions/img/new_issue_for_discussion.png +++ b/doc/user/discussions/img/new_issue_for_discussion.png diff --git a/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png b/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png Binary files differindex bcdc0250d7c..9044926b0eb 100644 --- a/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png +++ b/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png diff --git a/doc/user/discussions/img/preview_issue_for_discussion.png b/doc/user/discussions/img/preview_issue_for_discussion.png Binary files differindex 2ee0653b2ba..30c273ca4c5 100644 --- a/doc/user/discussions/img/preview_issue_for_discussion.png +++ b/doc/user/discussions/img/preview_issue_for_discussion.png diff --git a/doc/user/discussions/img/preview_issue_for_discussions.png b/doc/user/discussions/img/preview_issue_for_discussions.png Binary files differindex 3fe0a666678..3d906e1b0b0 100644 --- a/doc/user/discussions/img/preview_issue_for_discussions.png +++ b/doc/user/discussions/img/preview_issue_for_discussions.png diff --git a/doc/user/discussions/img/resolve_comment_button.png b/doc/user/discussions/img/resolve_comment_button.png Binary files differindex 70340108874..7c19fac31a2 100644 --- a/doc/user/discussions/img/resolve_comment_button.png +++ b/doc/user/discussions/img/resolve_comment_button.png diff --git a/doc/user/discussions/img/resolve_discussion_issue_notice.png b/doc/user/discussions/img/resolve_discussion_issue_notice.png Binary files differindex e0ee6a39ffd..ed50dc1de91 100644 --- a/doc/user/discussions/img/resolve_discussion_issue_notice.png +++ b/doc/user/discussions/img/resolve_discussion_issue_notice.png diff --git a/doc/user/discussions/img/resolve_discussion_open_issue.png b/doc/user/discussions/img/resolve_discussion_open_issue.png Binary files differindex 98d63278326..9d0a14671d6 100644 --- a/doc/user/discussions/img/resolve_discussion_open_issue.png +++ b/doc/user/discussions/img/resolve_discussion_open_issue.png diff --git a/doc/user/discussions/img/turn_off_lock.png b/doc/user/discussions/img/turn_off_lock.png Binary files differindex dd05b398a8b..aae1def6f72 100644 --- a/doc/user/discussions/img/turn_off_lock.png +++ b/doc/user/discussions/img/turn_off_lock.png diff --git a/doc/user/discussions/img/turn_on_lock.png b/doc/user/discussions/img/turn_on_lock.png Binary files differindex 9597da4e14d..f36ffc8831b 100644 --- a/doc/user/discussions/img/turn_on_lock.png +++ b/doc/user/discussions/img/turn_on_lock.png diff --git a/doc/user/group/img/add_new_members.png b/doc/user/group/img/add_new_members.png Binary files differindex 53f5596de23..99b8e52ea13 100644 --- a/doc/user/group/img/add_new_members.png +++ b/doc/user/group/img/add_new_members.png diff --git a/doc/user/group/img/create_new_group_info.png b/doc/user/group/img/create_new_group_info.png Binary files differindex 8d2501d9f7a..1ac26fb08d9 100644 --- a/doc/user/group/img/create_new_group_info.png +++ b/doc/user/group/img/create_new_group_info.png diff --git a/doc/user/group/img/create_new_project_from_group.png b/doc/user/group/img/create_new_project_from_group.png Binary files differindex c35234660db..553cd0759aa 100644 --- a/doc/user/group/img/create_new_project_from_group.png +++ b/doc/user/group/img/create_new_project_from_group.png diff --git a/doc/user/group/img/group_settings.png b/doc/user/group/img/group_settings.png Binary files differindex 629cd0729aa..1705bf4ce8e 100644 --- a/doc/user/group/img/group_settings.png +++ b/doc/user/group/img/group_settings.png diff --git a/doc/user/group/img/groups.png b/doc/user/group/img/groups.png Binary files differindex 3173ddce7ff..efdfd5f82cd 100644 --- a/doc/user/group/img/groups.png +++ b/doc/user/group/img/groups.png diff --git a/doc/user/group/img/membership_lock.png b/doc/user/group/img/membership_lock.png Binary files differindex d31fbb43375..c9ad82c90f2 100644 --- a/doc/user/group/img/membership_lock.png +++ b/doc/user/group/img/membership_lock.png diff --git a/doc/user/group/img/new_group_form.png b/doc/user/group/img/new_group_form.png Binary files differindex 91727ab5336..1c4d3ec6ceb 100644 --- a/doc/user/group/img/new_group_form.png +++ b/doc/user/group/img/new_group_form.png diff --git a/doc/user/group/img/new_group_from_groups.png b/doc/user/group/img/new_group_from_groups.png Binary files differindex 9c5dd7ebd8b..ffafac1b1cd 100644 --- a/doc/user/group/img/new_group_from_groups.png +++ b/doc/user/group/img/new_group_from_groups.png diff --git a/doc/user/group/img/new_group_from_other_pages.png b/doc/user/group/img/new_group_from_other_pages.png Binary files differindex 77427224447..f84501d1ff2 100644 --- a/doc/user/group/img/new_group_from_other_pages.png +++ b/doc/user/group/img/new_group_from_other_pages.png diff --git a/doc/user/group/img/request_access_button.png b/doc/user/group/img/request_access_button.png Binary files differindex f1aae6afed7..54b490a3bb2 100644 --- a/doc/user/group/img/request_access_button.png +++ b/doc/user/group/img/request_access_button.png diff --git a/doc/user/group/img/select_group_dropdown.png b/doc/user/group/img/select_group_dropdown.png Binary files differindex 68fc950304c..79eca5d94d5 100644 --- a/doc/user/group/img/select_group_dropdown.png +++ b/doc/user/group/img/select_group_dropdown.png diff --git a/doc/user/group/img/share_with_group_lock.png b/doc/user/group/img/share_with_group_lock.png Binary files differindex c0f25389eaf..77b00d8a248 100644 --- a/doc/user/group/img/share_with_group_lock.png +++ b/doc/user/group/img/share_with_group_lock.png diff --git a/doc/user/group/img/withdraw_access_request_button.png b/doc/user/group/img/withdraw_access_request_button.png Binary files differindex c5d8ef6c04f..4365f7fa788 100644 --- a/doc/user/group/img/withdraw_access_request_button.png +++ b/doc/user/group/img/withdraw_access_request_button.png diff --git a/doc/user/group/subgroups/img/group_members.png b/doc/user/group/subgroups/img/group_members.png Binary files differindex b95fe6263bf..830ccafa794 100644 --- a/doc/user/group/subgroups/img/group_members.png +++ b/doc/user/group/subgroups/img/group_members.png diff --git a/doc/user/group/subgroups/img/mention_subgroups.png b/doc/user/group/subgroups/img/mention_subgroups.png Binary files differindex 8e6bed0111b..ec370add4f9 100644 --- a/doc/user/group/subgroups/img/mention_subgroups.png +++ b/doc/user/group/subgroups/img/mention_subgroups.png diff --git a/doc/user/img/award_emoji_comment_picker.png b/doc/user/img/award_emoji_comment_picker.png Binary files differindex 3ad1bab3119..07f90c898ed 100644 --- a/doc/user/img/award_emoji_comment_picker.png +++ b/doc/user/img/award_emoji_comment_picker.png diff --git a/doc/user/img/award_emoji_select.png b/doc/user/img/award_emoji_select.png Binary files differindex 496acb29eec..269282b94b0 100644 --- a/doc/user/img/award_emoji_select.png +++ b/doc/user/img/award_emoji_select.png diff --git a/doc/user/img/award_emoji_votes_sort_options.png b/doc/user/img/award_emoji_votes_sort_options.png Binary files differindex dd84b7f4f64..dc02d5169e0 100644 --- a/doc/user/img/award_emoji_votes_sort_options.png +++ b/doc/user/img/award_emoji_votes_sort_options.png diff --git a/doc/user/img/markdown_logo.png b/doc/user/img/markdown_logo.png Binary files differindex bb3faaaec76..5184851b6cf 100644 --- a/doc/user/img/markdown_logo.png +++ b/doc/user/img/markdown_logo.png diff --git a/doc/user/instance_statistics/img/convdev_index.png b/doc/user/instance_statistics/img/convdev_index.png Binary files differindex 191295c918b..bee1317438d 100644 --- a/doc/user/instance_statistics/img/convdev_index.png +++ b/doc/user/instance_statistics/img/convdev_index.png diff --git a/doc/user/profile/img/active_sessions_list.png b/doc/user/profile/img/active_sessions_list.png Binary files differindex 76a52220bcd..5d94dca69cc 100644 --- a/doc/user/profile/img/active_sessions_list.png +++ b/doc/user/profile/img/active_sessions_list.png diff --git a/doc/user/profile/img/personal_access_tokens.png b/doc/user/profile/img/personal_access_tokens.png Binary files differindex 6aa63dbe342..d29f4cb0a20 100644 --- a/doc/user/profile/img/personal_access_tokens.png +++ b/doc/user/profile/img/personal_access_tokens.png diff --git a/doc/user/profile/img/profil-preferences-navigation-theme.png b/doc/user/profile/img/profil-preferences-navigation-theme.png Binary files differindex 7adaec33b60..335a19ac290 100644 --- a/doc/user/profile/img/profil-preferences-navigation-theme.png +++ b/doc/user/profile/img/profil-preferences-navigation-theme.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png b/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png Binary files differindex 9a0559a19d4..94ec83f1514 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png b/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png Binary files differindex 657ab0d9fa9..61ed85e5cd9 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/create_project.png b/doc/user/project/clusters/eks_and_gitlab/img/create_project.png Binary files differindex f3446131419..b02ab4b9064 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/create_project.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/create_project.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png b/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png Binary files differindex d6c3b1b3a94..0d9fcc838d9 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/environment.png b/doc/user/project/clusters/eks_and_gitlab/img/environment.png Binary files differindex 77d711ba8f6..4714c447026 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/environment.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/environment.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png b/doc/user/project/clusters/eks_and_gitlab/img/new_project.png Binary files differindex d401c4ac2bf..02afc099f10 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/new_project.png diff --git a/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png b/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png Binary files differindex 5f9c9815c24..0eb00d0faa7 100644 --- a/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png +++ b/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png diff --git a/doc/user/project/deploy_tokens/img/deploy_tokens.png b/doc/user/project/deploy_tokens/img/deploy_tokens.png Binary files differindex 7e2d67a3120..55c537fd1d3 100644 --- a/doc/user/project/deploy_tokens/img/deploy_tokens.png +++ b/doc/user/project/deploy_tokens/img/deploy_tokens.png diff --git a/doc/user/project/img/bulk-editing.png b/doc/user/project/img/bulk-editing.png Binary files differindex f6b163f55d9..8ae649e5020 100644 --- a/doc/user/project/img/bulk-editing.png +++ b/doc/user/project/img/bulk-editing.png diff --git a/doc/user/project/img/cycle_analytics_landing_page.png b/doc/user/project/img/cycle_analytics_landing_page.png Binary files differindex 316612c0da0..8b17fae5e05 100644 --- a/doc/user/project/img/cycle_analytics_landing_page.png +++ b/doc/user/project/img/cycle_analytics_landing_page.png diff --git a/doc/user/project/img/issue_board_assignee_lists.png b/doc/user/project/img/issue_board_assignee_lists.png Binary files differindex 1ec94d22e33..f2660cd8f80 100644 --- a/doc/user/project/img/issue_board_assignee_lists.png +++ b/doc/user/project/img/issue_board_assignee_lists.png diff --git a/doc/user/project/img/issue_board_creation.png b/doc/user/project/img/issue_board_creation.png Binary files differindex 9dc4925b0a5..099fe6eee21 100644 --- a/doc/user/project/img/issue_board_creation.png +++ b/doc/user/project/img/issue_board_creation.png diff --git a/doc/user/project/img/issue_board_edit_button.png b/doc/user/project/img/issue_board_edit_button.png Binary files differindex 23883175344..a0dc6f41592 100644 --- a/doc/user/project/img/issue_board_edit_button.png +++ b/doc/user/project/img/issue_board_edit_button.png diff --git a/doc/user/project/img/issue_board_move_issue_card_list.png b/doc/user/project/img/issue_board_move_issue_card_list.png Binary files differindex cce252234c1..13750a63766 100644 --- a/doc/user/project/img/issue_board_move_issue_card_list.png +++ b/doc/user/project/img/issue_board_move_issue_card_list.png diff --git a/doc/user/project/img/issue_board_view_scope.png b/doc/user/project/img/issue_board_view_scope.png Binary files differindex 4e03cecbc2d..d173679a0e7 100644 --- a/doc/user/project/img/issue_board_view_scope.png +++ b/doc/user/project/img/issue_board_view_scope.png diff --git a/doc/user/project/img/issue_boards_add_issues_modal.png b/doc/user/project/img/issue_boards_add_issues_modal.png Binary files differindex 625a4304eaf..ecddf6709d0 100644 --- a/doc/user/project/img/issue_boards_add_issues_modal.png +++ b/doc/user/project/img/issue_boards_add_issues_modal.png diff --git a/doc/user/project/img/issue_boards_multiple.png b/doc/user/project/img/issue_boards_multiple.png Binary files differindex 4b2b8d457f1..7bb088aad0b 100644 --- a/doc/user/project/img/issue_boards_multiple.png +++ b/doc/user/project/img/issue_boards_multiple.png diff --git a/doc/user/project/img/issue_boards_remove_issue.png b/doc/user/project/img/issue_boards_remove_issue.png Binary files differindex 9a2fad2cc7f..7050e6c3ede 100644 --- a/doc/user/project/img/issue_boards_remove_issue.png +++ b/doc/user/project/img/issue_boards_remove_issue.png diff --git a/doc/user/project/img/koding_build-in-progress.png b/doc/user/project/img/koding_build-in-progress.png Binary files differindex 79b7b2f10a2..118b97c07e1 100644 --- a/doc/user/project/img/koding_build-in-progress.png +++ b/doc/user/project/img/koding_build-in-progress.png diff --git a/doc/user/project/img/koding_build-success.png b/doc/user/project/img/koding_build-success.png Binary files differindex a2342cfd324..0f3b954abf5 100644 --- a/doc/user/project/img/koding_build-success.png +++ b/doc/user/project/img/koding_build-success.png diff --git a/doc/user/project/img/koding_commit-koding.yml.png b/doc/user/project/img/koding_commit-koding.yml.png Binary files differindex 16842410ae2..d921c73dc73 100644 --- a/doc/user/project/img/koding_commit-koding.yml.png +++ b/doc/user/project/img/koding_commit-koding.yml.png diff --git a/doc/user/project/img/koding_edit-on-ide.png b/doc/user/project/img/koding_edit-on-ide.png Binary files differindex ab861281d3e..25ca7694fe0 100644 --- a/doc/user/project/img/koding_edit-on-ide.png +++ b/doc/user/project/img/koding_edit-on-ide.png diff --git a/doc/user/project/img/koding_enable-koding.png b/doc/user/project/img/koding_enable-koding.png Binary files differindex 0b6fcfadcc5..7e6c1735df2 100644 --- a/doc/user/project/img/koding_enable-koding.png +++ b/doc/user/project/img/koding_enable-koding.png diff --git a/doc/user/project/img/koding_landing.png b/doc/user/project/img/koding_landing.png Binary files differindex 1eeddcd3813..ac880376e09 100644 --- a/doc/user/project/img/koding_landing.png +++ b/doc/user/project/img/koding_landing.png diff --git a/doc/user/project/img/koding_run-in-ide.png b/doc/user/project/img/koding_run-in-ide.png Binary files differindex d22e5023c59..fb5825a4010 100644 --- a/doc/user/project/img/koding_run-in-ide.png +++ b/doc/user/project/img/koding_run-in-ide.png diff --git a/doc/user/project/img/koding_stack-import.png b/doc/user/project/img/koding_stack-import.png Binary files differindex 245ccb07ba3..483bfad7d6a 100644 --- a/doc/user/project/img/koding_stack-import.png +++ b/doc/user/project/img/koding_stack-import.png diff --git a/doc/user/project/img/koding_start-build.png b/doc/user/project/img/koding_start-build.png Binary files differindex 3f5c16d5d2f..c09a6d669f0 100644 --- a/doc/user/project/img/koding_start-build.png +++ b/doc/user/project/img/koding_start-build.png diff --git a/doc/user/project/img/labels_generate_default.png b/doc/user/project/img/labels_generate_default.png Binary files differindex fca2a06e04f..982a4df999c 100644 --- a/doc/user/project/img/labels_generate_default.png +++ b/doc/user/project/img/labels_generate_default.png diff --git a/doc/user/project/img/labels_group_issues.png b/doc/user/project/img/labels_group_issues.png Binary files differindex 29dcf7ff45e..cea1d304d31 100644 --- a/doc/user/project/img/labels_group_issues.png +++ b/doc/user/project/img/labels_group_issues.png diff --git a/doc/user/project/img/labels_list.png b/doc/user/project/img/labels_list.png Binary files differindex 12c47ea9766..6878349fc0c 100644 --- a/doc/user/project/img/labels_list.png +++ b/doc/user/project/img/labels_list.png diff --git a/doc/user/project/img/labels_prioritized.png b/doc/user/project/img/labels_prioritized.png Binary files differindex 57dcfe89b3d..7ce2d08b38c 100644 --- a/doc/user/project/img/labels_prioritized.png +++ b/doc/user/project/img/labels_prioritized.png diff --git a/doc/user/project/img/labels_project_list_search.png b/doc/user/project/img/labels_project_list_search.png Binary files differindex ff9bf92e1c3..512d7767e6e 100644 --- a/doc/user/project/img/labels_project_list_search.png +++ b/doc/user/project/img/labels_project_list_search.png diff --git a/doc/user/project/img/labels_promotion.png b/doc/user/project/img/labels_promotion.png Binary files differindex 8a5efd210a2..762a3773692 100644 --- a/doc/user/project/img/labels_promotion.png +++ b/doc/user/project/img/labels_promotion.png diff --git a/doc/user/project/img/labels_sidebar.png b/doc/user/project/img/labels_sidebar.png Binary files differindex 7349c6d4f0c..454a0ca3f07 100644 --- a/doc/user/project/img/labels_sidebar.png +++ b/doc/user/project/img/labels_sidebar.png diff --git a/doc/user/project/img/labels_sidebar_assign.png b/doc/user/project/img/labels_sidebar_assign.png Binary files differindex 61e8d04fc85..5b7fb78b032 100644 --- a/doc/user/project/img/labels_sidebar_assign.png +++ b/doc/user/project/img/labels_sidebar_assign.png diff --git a/doc/user/project/img/labels_sidebar_inline.png b/doc/user/project/img/labels_sidebar_inline.png Binary files differindex 31fa397761d..2186f14ea92 100644 --- a/doc/user/project/img/labels_sidebar_inline.png +++ b/doc/user/project/img/labels_sidebar_inline.png diff --git a/doc/user/project/img/labels_sort_label_priority.png b/doc/user/project/img/labels_sort_label_priority.png Binary files differindex c8b97639121..faf629ac61d 100644 --- a/doc/user/project/img/labels_sort_label_priority.png +++ b/doc/user/project/img/labels_sort_label_priority.png diff --git a/doc/user/project/img/labels_sort_priority.png b/doc/user/project/img/labels_sort_priority.png Binary files differindex a95198e7f72..a6b5fca26f4 100644 --- a/doc/user/project/img/labels_sort_priority.png +++ b/doc/user/project/img/labels_sort_priority.png diff --git a/doc/user/project/img/labels_subscriptions.png b/doc/user/project/img/labels_subscriptions.png Binary files differindex 8bcb3b57f6c..f3c4235d051 100644 --- a/doc/user/project/img/labels_subscriptions.png +++ b/doc/user/project/img/labels_subscriptions.png diff --git a/doc/user/project/img/priority_sort_order.png b/doc/user/project/img/priority_sort_order.png Binary files differindex c558ec23b0e..cd1dd8237c0 100644 --- a/doc/user/project/img/priority_sort_order.png +++ b/doc/user/project/img/priority_sort_order.png diff --git a/doc/user/project/img/project_overview_badges.png b/doc/user/project/img/project_overview_badges.png Binary files differindex 3067a7dfa13..83b9766828a 100644 --- a/doc/user/project/img/project_overview_badges.png +++ b/doc/user/project/img/project_overview_badges.png diff --git a/doc/user/project/img/project_repository_settings.png b/doc/user/project/img/project_repository_settings.png Binary files differindex aa4d4452c87..69d36753a58 100644 --- a/doc/user/project/img/project_repository_settings.png +++ b/doc/user/project/img/project_repository_settings.png diff --git a/doc/user/project/img/protected_branches_delete.png b/doc/user/project/img/protected_branches_delete.png Binary files differindex cfdfe6c6c29..8910ae9e39d 100644 --- a/doc/user/project/img/protected_branches_delete.png +++ b/doc/user/project/img/protected_branches_delete.png diff --git a/doc/user/project/img/protected_branches_devs_can_push.png b/doc/user/project/img/protected_branches_devs_can_push.png Binary files differindex 320e6eb7fee..b537839c00b 100644 --- a/doc/user/project/img/protected_branches_devs_can_push.png +++ b/doc/user/project/img/protected_branches_devs_can_push.png diff --git a/doc/user/project/img/protected_branches_error_ui.png b/doc/user/project/img/protected_branches_error_ui.png Binary files differindex 3f8e462d3ad..62839e49d89 100644 --- a/doc/user/project/img/protected_branches_error_ui.png +++ b/doc/user/project/img/protected_branches_error_ui.png diff --git a/doc/user/project/img/protected_branches_list.png b/doc/user/project/img/protected_branches_list.png Binary files differindex 1b2936cb711..495ce4d7b6f 100644 --- a/doc/user/project/img/protected_branches_list.png +++ b/doc/user/project/img/protected_branches_list.png diff --git a/doc/user/project/img/protected_branches_page.png b/doc/user/project/img/protected_branches_page.png Binary files differindex 4e5afff3bae..9b10991f62e 100644 --- a/doc/user/project/img/protected_branches_page.png +++ b/doc/user/project/img/protected_branches_page.png diff --git a/doc/user/project/img/protected_tag_matches.png b/doc/user/project/img/protected_tag_matches.png Binary files differindex a36a11a1271..e89d0a47073 100644 --- a/doc/user/project/img/protected_tag_matches.png +++ b/doc/user/project/img/protected_tag_matches.png diff --git a/doc/user/project/img/protected_tags_list.png b/doc/user/project/img/protected_tags_list.png Binary files differindex c5e42dc0705..6c5295e0f4b 100644 --- a/doc/user/project/img/protected_tags_list.png +++ b/doc/user/project/img/protected_tags_list.png diff --git a/doc/user/project/img/protected_tags_page.png b/doc/user/project/img/protected_tags_page.png Binary files differindex 3848d91ebd6..5f8a2106cd1 100644 --- a/doc/user/project/img/protected_tags_page.png +++ b/doc/user/project/img/protected_tags_page.png diff --git a/doc/user/project/img/protected_tags_permissions_dropdown.png b/doc/user/project/img/protected_tags_permissions_dropdown.png Binary files differindex 9e0fc4e2a43..77098eeb591 100644 --- a/doc/user/project/img/protected_tags_permissions_dropdown.png +++ b/doc/user/project/img/protected_tags_permissions_dropdown.png diff --git a/doc/user/project/import/img/bitbucket_server_import_credentials.png b/doc/user/project/import/img/bitbucket_server_import_credentials.png Binary files differindex 70b26e89d49..25bcc3ab6e6 100644 --- a/doc/user/project/import/img/bitbucket_server_import_credentials.png +++ b/doc/user/project/import/img/bitbucket_server_import_credentials.png diff --git a/doc/user/project/import/img/bitbucket_server_import_select_project.png b/doc/user/project/import/img/bitbucket_server_import_select_project.png Binary files differindex e5b1b89e6a3..e7fddef9955 100644 --- a/doc/user/project/import/img/bitbucket_server_import_select_project.png +++ b/doc/user/project/import/img/bitbucket_server_import_select_project.png diff --git a/doc/user/project/import/img/fogbugz_import_login.png b/doc/user/project/import/img/fogbugz_import_login.png Binary files differindex 96bce70b74d..6ba4d443f1a 100644 --- a/doc/user/project/import/img/fogbugz_import_login.png +++ b/doc/user/project/import/img/fogbugz_import_login.png diff --git a/doc/user/project/import/img/fogbugz_import_select_fogbogz.png b/doc/user/project/import/img/fogbugz_import_select_fogbogz.png Binary files differindex b26c652e382..d207646a6f2 100644 --- a/doc/user/project/import/img/fogbugz_import_select_fogbogz.png +++ b/doc/user/project/import/img/fogbugz_import_select_fogbogz.png diff --git a/doc/user/project/import/img/fogbugz_import_select_project.png b/doc/user/project/import/img/fogbugz_import_select_project.png Binary files differindex ccc82f9d4cd..b5e6f497f9b 100644 --- a/doc/user/project/import/img/fogbugz_import_select_project.png +++ b/doc/user/project/import/img/fogbugz_import_select_project.png diff --git a/doc/user/project/import/img/import_projects_from_gitea_new_import.png b/doc/user/project/import/img/import_projects_from_gitea_new_import.png Binary files differindex a3f603cbd0a..41eb4b2bd00 100644 --- a/doc/user/project/import/img/import_projects_from_gitea_new_import.png +++ b/doc/user/project/import/img/import_projects_from_gitea_new_import.png diff --git a/doc/user/project/import/img/import_projects_from_github_select_auth_method.png b/doc/user/project/import/img/import_projects_from_github_select_auth_method.png Binary files differindex 1ccb38a815e..90e6243aec0 100644 --- a/doc/user/project/import/img/import_projects_from_github_select_auth_method.png +++ b/doc/user/project/import/img/import_projects_from_github_select_auth_method.png diff --git a/doc/user/project/import/img/import_projects_from_new_project_page.png b/doc/user/project/import/img/import_projects_from_new_project_page.png Binary files differindex 40402eae226..7c32d3555d1 100644 --- a/doc/user/project/import/img/import_projects_from_new_project_page.png +++ b/doc/user/project/import/img/import_projects_from_new_project_page.png diff --git a/doc/user/project/integrations/img/hangouts_chat_configuration.png b/doc/user/project/integrations/img/hangouts_chat_configuration.png Binary files differindex 33fadbe6547..54aaef6632d 100644 --- a/doc/user/project/integrations/img/hangouts_chat_configuration.png +++ b/doc/user/project/integrations/img/hangouts_chat_configuration.png diff --git a/doc/user/project/integrations/img/issue_configuration.png b/doc/user/project/integrations/img/issue_configuration.png Binary files differindex 2049d60fdd2..5dfd85974d8 100644 --- a/doc/user/project/integrations/img/issue_configuration.png +++ b/doc/user/project/integrations/img/issue_configuration.png diff --git a/doc/user/project/integrations/img/jira_group_access.png b/doc/user/project/integrations/img/jira_group_access.png Binary files differindex 9d64cc57269..448cc55504d 100644 --- a/doc/user/project/integrations/img/jira_group_access.png +++ b/doc/user/project/integrations/img/jira_group_access.png diff --git a/doc/user/project/integrations/img/jira_project_name.png b/doc/user/project/integrations/img/jira_project_name.png Binary files differindex 8540a427461..981c7f7ca18 100644 --- a/doc/user/project/integrations/img/jira_project_name.png +++ b/doc/user/project/integrations/img/jira_project_name.png diff --git a/doc/user/project/integrations/img/jira_project_settings.png b/doc/user/project/integrations/img/jira_project_settings.png Binary files differindex cb6a6ba14ce..d96002b7db8 100644 --- a/doc/user/project/integrations/img/jira_project_settings.png +++ b/doc/user/project/integrations/img/jira_project_settings.png diff --git a/doc/user/project/integrations/img/jira_service.png b/doc/user/project/integrations/img/jira_service.png Binary files differindex 8e073b84ff9..0ae2fa28756 100644 --- a/doc/user/project/integrations/img/jira_service.png +++ b/doc/user/project/integrations/img/jira_service.png diff --git a/doc/user/project/integrations/img/jira_service_close_comment.png b/doc/user/project/integrations/img/jira_service_close_comment.png Binary files differindex bb9cd7e3d13..9af0d38f098 100644 --- a/doc/user/project/integrations/img/jira_service_close_comment.png +++ b/doc/user/project/integrations/img/jira_service_close_comment.png diff --git a/doc/user/project/integrations/img/jira_service_page.png b/doc/user/project/integrations/img/jira_service_page.png Binary files differindex 63aa0e99a50..c75c11888a8 100644 --- a/doc/user/project/integrations/img/jira_service_page.png +++ b/doc/user/project/integrations/img/jira_service_page.png diff --git a/doc/user/project/integrations/img/jira_user_management_link.png b/doc/user/project/integrations/img/jira_user_management_link.png Binary files differindex f81c5b5fc87..5eb9d031c3e 100644 --- a/doc/user/project/integrations/img/jira_user_management_link.png +++ b/doc/user/project/integrations/img/jira_user_management_link.png diff --git a/doc/user/project/integrations/img/mattermost_bot_auth.png b/doc/user/project/integrations/img/mattermost_bot_auth.png Binary files differindex 830b7849f3d..a05d8da1237 100644 --- a/doc/user/project/integrations/img/mattermost_bot_auth.png +++ b/doc/user/project/integrations/img/mattermost_bot_auth.png diff --git a/doc/user/project/integrations/img/mattermost_bot_available_commands.png b/doc/user/project/integrations/img/mattermost_bot_available_commands.png Binary files differindex b51798cf10d..3232ccc3451 100644 --- a/doc/user/project/integrations/img/mattermost_bot_available_commands.png +++ b/doc/user/project/integrations/img/mattermost_bot_available_commands.png diff --git a/doc/user/project/integrations/img/mattermost_configuration.png b/doc/user/project/integrations/img/mattermost_configuration.png Binary files differindex f52acf4ef3b..e0b55b23520 100644 --- a/doc/user/project/integrations/img/mattermost_configuration.png +++ b/doc/user/project/integrations/img/mattermost_configuration.png diff --git a/doc/user/project/integrations/img/mattermost_console_integrations.png b/doc/user/project/integrations/img/mattermost_console_integrations.png Binary files differindex 92a30da5be0..625b57d4dc9 100644 --- a/doc/user/project/integrations/img/mattermost_console_integrations.png +++ b/doc/user/project/integrations/img/mattermost_console_integrations.png diff --git a/doc/user/project/integrations/img/mattermost_gitlab_token.png b/doc/user/project/integrations/img/mattermost_gitlab_token.png Binary files differindex 257018914d2..63140503824 100644 --- a/doc/user/project/integrations/img/mattermost_gitlab_token.png +++ b/doc/user/project/integrations/img/mattermost_gitlab_token.png diff --git a/doc/user/project/integrations/img/mattermost_goto_console.png b/doc/user/project/integrations/img/mattermost_goto_console.png Binary files differindex 3354c2a24b4..8bacbe485f4 100644 --- a/doc/user/project/integrations/img/mattermost_goto_console.png +++ b/doc/user/project/integrations/img/mattermost_goto_console.png diff --git a/doc/user/project/integrations/img/mattermost_slash_command_configuration.png b/doc/user/project/integrations/img/mattermost_slash_command_configuration.png Binary files differindex 12766ab2b34..f9e9de439ca 100644 --- a/doc/user/project/integrations/img/mattermost_slash_command_configuration.png +++ b/doc/user/project/integrations/img/mattermost_slash_command_configuration.png diff --git a/doc/user/project/integrations/img/mattermost_team_integrations.png b/doc/user/project/integrations/img/mattermost_team_integrations.png Binary files differindex 69d4a231e5a..c2b68256e11 100644 --- a/doc/user/project/integrations/img/mattermost_team_integrations.png +++ b/doc/user/project/integrations/img/mattermost_team_integrations.png diff --git a/doc/user/project/integrations/img/merge_request_performance.png b/doc/user/project/integrations/img/merge_request_performance.png Binary files differindex eba6515a6ae..a9cd761cdcb 100644 --- a/doc/user/project/integrations/img/merge_request_performance.png +++ b/doc/user/project/integrations/img/merge_request_performance.png diff --git a/doc/user/project/integrations/img/microsoft_teams_configuration.png b/doc/user/project/integrations/img/microsoft_teams_configuration.png Binary files differindex b5c9efc3dd9..627715d5c18 100644 --- a/doc/user/project/integrations/img/microsoft_teams_configuration.png +++ b/doc/user/project/integrations/img/microsoft_teams_configuration.png diff --git a/doc/user/project/integrations/img/project_services.png b/doc/user/project/integrations/img/project_services.png Binary files differindex 25b6cd5690b..5fed38a349c 100644 --- a/doc/user/project/integrations/img/project_services.png +++ b/doc/user/project/integrations/img/project_services.png diff --git a/doc/user/project/integrations/img/prometheus_dashboard.png b/doc/user/project/integrations/img/prometheus_dashboard.png Binary files differindex bd19f1b44cc..1fa36ca2675 100644 --- a/doc/user/project/integrations/img/prometheus_dashboard.png +++ b/doc/user/project/integrations/img/prometheus_dashboard.png diff --git a/doc/user/project/integrations/img/prometheus_deploy.png b/doc/user/project/integrations/img/prometheus_deploy.png Binary files differindex d39081bcc7b..3f19f23b0cc 100644 --- a/doc/user/project/integrations/img/prometheus_deploy.png +++ b/doc/user/project/integrations/img/prometheus_deploy.png diff --git a/doc/user/project/integrations/img/prometheus_yaml_deploy.png b/doc/user/project/integrations/img/prometheus_yaml_deploy.png Binary files differindex 978cd7eaa50..78dd178a077 100644 --- a/doc/user/project/integrations/img/prometheus_yaml_deploy.png +++ b/doc/user/project/integrations/img/prometheus_yaml_deploy.png diff --git a/doc/user/project/integrations/img/redmine_configuration.png b/doc/user/project/integrations/img/redmine_configuration.png Binary files differindex 7b6dd271401..eb392b848b5 100644 --- a/doc/user/project/integrations/img/redmine_configuration.png +++ b/doc/user/project/integrations/img/redmine_configuration.png diff --git a/doc/user/project/integrations/img/services_templates_redmine_example.png b/doc/user/project/integrations/img/services_templates_redmine_example.png Binary files differindex 379cef9888d..34594dfdd55 100644 --- a/doc/user/project/integrations/img/services_templates_redmine_example.png +++ b/doc/user/project/integrations/img/services_templates_redmine_example.png diff --git a/doc/user/project/integrations/img/slack_configuration.png b/doc/user/project/integrations/img/slack_configuration.png Binary files differindex 527824fc3eb..53b30e0e8cd 100644 --- a/doc/user/project/integrations/img/slack_configuration.png +++ b/doc/user/project/integrations/img/slack_configuration.png diff --git a/doc/user/project/integrations/img/webhook_logs.png b/doc/user/project/integrations/img/webhook_logs.png Binary files differindex 803678db6b6..24bb593c7d0 100644 --- a/doc/user/project/integrations/img/webhook_logs.png +++ b/doc/user/project/integrations/img/webhook_logs.png diff --git a/doc/user/project/integrations/img/webhook_testing.png b/doc/user/project/integrations/img/webhook_testing.png Binary files differindex 176dcec9d8a..acfebf473b9 100644 --- a/doc/user/project/integrations/img/webhook_testing.png +++ b/doc/user/project/integrations/img/webhook_testing.png diff --git a/doc/user/project/integrations/img/webhooks_ssl.png b/doc/user/project/integrations/img/webhooks_ssl.png Binary files differindex 21ddec4ebdf..f023e9665f2 100644 --- a/doc/user/project/integrations/img/webhooks_ssl.png +++ b/doc/user/project/integrations/img/webhooks_ssl.png diff --git a/doc/user/project/issues/img/confidential_issues_index_page.png b/doc/user/project/issues/img/confidential_issues_index_page.png Binary files differindex f3efe0ce04e..16979bf9ac2 100644 --- a/doc/user/project/issues/img/confidential_issues_index_page.png +++ b/doc/user/project/issues/img/confidential_issues_index_page.png diff --git a/doc/user/project/issues/img/delete_issue.png b/doc/user/project/issues/img/delete_issue.png Binary files differindex a356f52044e..87ea65956fc 100644 --- a/doc/user/project/issues/img/delete_issue.png +++ b/doc/user/project/issues/img/delete_issue.png diff --git a/doc/user/project/issues/img/due_dates_create.png b/doc/user/project/issues/img/due_dates_create.png Binary files differindex ece35d44213..392fb3553cb 100644 --- a/doc/user/project/issues/img/due_dates_create.png +++ b/doc/user/project/issues/img/due_dates_create.png diff --git a/doc/user/project/issues/img/group_issues_list_view.png b/doc/user/project/issues/img/group_issues_list_view.png Binary files differindex bba964076d0..c951a9e2dcd 100644 --- a/doc/user/project/issues/img/group_issues_list_view.png +++ b/doc/user/project/issues/img/group_issues_list_view.png diff --git a/doc/user/project/issues/img/issue_board.png b/doc/user/project/issues/img/issue_board.png Binary files differindex 87b1016cc76..df9d6f64985 100644 --- a/doc/user/project/issues/img/issue_board.png +++ b/doc/user/project/issues/img/issue_board.png diff --git a/doc/user/project/issues/img/issue_template.png b/doc/user/project/issues/img/issue_template.png Binary files differindex 0e4c8df897b..6cb2c07d27e 100644 --- a/doc/user/project/issues/img/issue_template.png +++ b/doc/user/project/issues/img/issue_template.png diff --git a/doc/user/project/issues/img/new_issue_from_email.png b/doc/user/project/issues/img/new_issue_from_email.png Binary files differindex 775ea0cdffb..6da899ea37c 100644 --- a/doc/user/project/issues/img/new_issue_from_email.png +++ b/doc/user/project/issues/img/new_issue_from_email.png diff --git a/doc/user/project/issues/img/new_issue_from_issue_board.png b/doc/user/project/issues/img/new_issue_from_issue_board.png Binary files differindex da892eff0a6..30a1ffb9011 100644 --- a/doc/user/project/issues/img/new_issue_from_issue_board.png +++ b/doc/user/project/issues/img/new_issue_from_issue_board.png diff --git a/doc/user/project/issues/img/new_issue_from_projects_dashboard.png b/doc/user/project/issues/img/new_issue_from_projects_dashboard.png Binary files differindex 4b9535f6b15..474ca2b45c0 100644 --- a/doc/user/project/issues/img/new_issue_from_projects_dashboard.png +++ b/doc/user/project/issues/img/new_issue_from_projects_dashboard.png diff --git a/doc/user/project/issues/img/project_issues_list_view.png b/doc/user/project/issues/img/project_issues_list_view.png Binary files differindex 584a81aab8a..c80bd58f5c9 100644 --- a/doc/user/project/issues/img/project_issues_list_view.png +++ b/doc/user/project/issues/img/project_issues_list_view.png diff --git a/doc/user/project/issues/img/sidebar_confidential_issue.png b/doc/user/project/issues/img/sidebar_confidential_issue.png Binary files differindex d99a1ca756e..a320f4dcfe5 100644 --- a/doc/user/project/issues/img/sidebar_confidential_issue.png +++ b/doc/user/project/issues/img/sidebar_confidential_issue.png diff --git a/doc/user/project/issues/img/sidebar_move_issue.png b/doc/user/project/issues/img/sidebar_move_issue.png Binary files differindex 1e688cec894..031284a24b2 100644 --- a/doc/user/project/issues/img/sidebar_move_issue.png +++ b/doc/user/project/issues/img/sidebar_move_issue.png diff --git a/doc/user/project/issues/img/sidebar_not_confidential_issue.png b/doc/user/project/issues/img/sidebar_not_confidential_issue.png Binary files differindex 2e6cbbc5b3a..c09f8204b37 100644 --- a/doc/user/project/issues/img/sidebar_not_confidential_issue.png +++ b/doc/user/project/issues/img/sidebar_not_confidential_issue.png diff --git a/doc/user/project/issues/img/turn_off_confidentiality.png b/doc/user/project/issues/img/turn_off_confidentiality.png Binary files differindex 248ae6522d6..04a85933071 100644 --- a/doc/user/project/issues/img/turn_off_confidentiality.png +++ b/doc/user/project/issues/img/turn_off_confidentiality.png diff --git a/doc/user/project/issues/img/turn_on_confidentiality.png b/doc/user/project/issues/img/turn_on_confidentiality.png Binary files differindex fac4c833699..fac360ca6dc 100644 --- a/doc/user/project/issues/img/turn_on_confidentiality.png +++ b/doc/user/project/issues/img/turn_on_confidentiality.png diff --git a/doc/user/project/members/img/access_requests_management.png b/doc/user/project/members/img/access_requests_management.png Binary files differindex 3693bed869b..8996d9564d7 100644 --- a/doc/user/project/members/img/access_requests_management.png +++ b/doc/user/project/members/img/access_requests_management.png diff --git a/doc/user/project/members/img/add_new_user_to_project_settings.png b/doc/user/project/members/img/add_new_user_to_project_settings.png Binary files differindex 40db600455f..e49ea1a3e3d 100644 --- a/doc/user/project/members/img/add_new_user_to_project_settings.png +++ b/doc/user/project/members/img/add_new_user_to_project_settings.png diff --git a/doc/user/project/members/img/add_user_email_accept.png b/doc/user/project/members/img/add_user_email_accept.png Binary files differindex 763b3ff463d..cbee9e08c70 100644 --- a/doc/user/project/members/img/add_user_email_accept.png +++ b/doc/user/project/members/img/add_user_email_accept.png diff --git a/doc/user/project/members/img/add_user_import_members_from_another_project.png b/doc/user/project/members/img/add_user_import_members_from_another_project.png Binary files differindex 0c32001098e..cb3b70bd4b5 100644 --- a/doc/user/project/members/img/add_user_import_members_from_another_project.png +++ b/doc/user/project/members/img/add_user_import_members_from_another_project.png diff --git a/doc/user/project/members/img/add_user_members_menu.png b/doc/user/project/members/img/add_user_members_menu.png Binary files differindex 8e61d15fe65..6f08088b52f 100644 --- a/doc/user/project/members/img/add_user_members_menu.png +++ b/doc/user/project/members/img/add_user_members_menu.png diff --git a/doc/user/project/members/img/max_access_level.png b/doc/user/project/members/img/max_access_level.png Binary files differindex 63f33f9d91d..42a0416ffbb 100644 --- a/doc/user/project/members/img/max_access_level.png +++ b/doc/user/project/members/img/max_access_level.png diff --git a/doc/user/project/members/img/request_access_button.png b/doc/user/project/members/img/request_access_button.png Binary files differindex 608baccb0ca..e8b490b91b8 100644 --- a/doc/user/project/members/img/request_access_button.png +++ b/doc/user/project/members/img/request_access_button.png diff --git a/doc/user/project/members/img/withdraw_access_request_button.png b/doc/user/project/members/img/withdraw_access_request_button.png Binary files differindex 6edd786b151..6a3172dfcdb 100644 --- a/doc/user/project/members/img/withdraw_access_request_button.png +++ b/doc/user/project/members/img/withdraw_access_request_button.png diff --git a/doc/user/project/merge_requests/img/allow_collaboration.png b/doc/user/project/merge_requests/img/allow_collaboration.png Binary files differindex 75596e7d9ad..3c81e4c27b8 100644 --- a/doc/user/project/merge_requests/img/allow_collaboration.png +++ b/doc/user/project/merge_requests/img/allow_collaboration.png diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png b/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png Binary files differindex 7dc344f8cf6..c98821548f8 100644 --- a/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png +++ b/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png b/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png Binary files differindex 811b0998f85..8b51503419b 100644 --- a/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png +++ b/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png diff --git a/doc/user/project/merge_requests/img/create_from_email.png b/doc/user/project/merge_requests/img/create_from_email.png Binary files differindex 71eb4bf267d..610f0b3d0c1 100644 --- a/doc/user/project/merge_requests/img/create_from_email.png +++ b/doc/user/project/merge_requests/img/create_from_email.png diff --git a/doc/user/project/merge_requests/img/merge_conflict_editor.png b/doc/user/project/merge_requests/img/merge_conflict_editor.png Binary files differindex 6660920c191..f10efbce5f5 100644 --- a/doc/user/project/merge_requests/img/merge_conflict_editor.png +++ b/doc/user/project/merge_requests/img/merge_conflict_editor.png diff --git a/doc/user/project/merge_requests/img/merge_request.png b/doc/user/project/merge_requests/img/merge_request.png Binary files differindex 61b61122b11..c0a62bbaba0 100644 --- a/doc/user/project/merge_requests/img/merge_request.png +++ b/doc/user/project/merge_requests/img/merge_request.png diff --git a/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png b/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png Binary files differindex 4eee734ff8d..ac766c99935 100644 --- a/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png +++ b/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png diff --git a/doc/user/project/merge_requests/img/merge_request_widget.png b/doc/user/project/merge_requests/img/merge_request_widget.png Binary files differindex 43a945c74d9..6c2317b29b5 100644 --- a/doc/user/project/merge_requests/img/merge_request_widget.png +++ b/doc/user/project/merge_requests/img/merge_request_widget.png diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png Binary files differindex d7f0535d3c5..9487264b41a 100644 --- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png +++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png Binary files differindex c43f76b058c..761690d1e0c 100644 --- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png +++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png Binary files differindex 9629ed99838..2a2101719ba 100644 --- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png +++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png Binary files differindex d0691437c65..70fa2efc855 100644 --- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png +++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png diff --git a/doc/user/project/merge_requests/img/project_merge_requests_list_view.png b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png Binary files differindex 702ec1a2949..457716d811c 100644 --- a/doc/user/project/merge_requests/img/project_merge_requests_list_view.png +++ b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png diff --git a/doc/user/project/merge_requests/img/remove_source_branch_status.png b/doc/user/project/merge_requests/img/remove_source_branch_status.png Binary files differindex 1377fab54ec..afd93207e02 100644 --- a/doc/user/project/merge_requests/img/remove_source_branch_status.png +++ b/doc/user/project/merge_requests/img/remove_source_branch_status.png diff --git a/doc/user/project/merge_requests/img/revert_changes_commit.png b/doc/user/project/merge_requests/img/revert_changes_commit.png Binary files differindex a0663e130e9..c9dd0019024 100644 --- a/doc/user/project/merge_requests/img/revert_changes_commit.png +++ b/doc/user/project/merge_requests/img/revert_changes_commit.png diff --git a/doc/user/project/merge_requests/img/revert_changes_mr.png b/doc/user/project/merge_requests/img/revert_changes_mr.png Binary files differindex 8792018ee53..06b841b3002 100644 --- a/doc/user/project/merge_requests/img/revert_changes_mr.png +++ b/doc/user/project/merge_requests/img/revert_changes_mr.png diff --git a/doc/user/project/merge_requests/img/squash_edit_form.png b/doc/user/project/merge_requests/img/squash_edit_form.png Binary files differindex 496c6f44ea7..326d74b68cb 100644 --- a/doc/user/project/merge_requests/img/squash_edit_form.png +++ b/doc/user/project/merge_requests/img/squash_edit_form.png diff --git a/doc/user/project/merge_requests/img/squash_mr_commits.png b/doc/user/project/merge_requests/img/squash_mr_commits.png Binary files differindex 5fc6a8c48bb..dfc1ee38435 100644 --- a/doc/user/project/merge_requests/img/squash_mr_commits.png +++ b/doc/user/project/merge_requests/img/squash_mr_commits.png diff --git a/doc/user/project/merge_requests/img/squash_mr_widget.png b/doc/user/project/merge_requests/img/squash_mr_widget.png Binary files differindex 9cb458b2a35..81334ca9758 100644 --- a/doc/user/project/merge_requests/img/squash_mr_widget.png +++ b/doc/user/project/merge_requests/img/squash_mr_widget.png diff --git a/doc/user/project/merge_requests/img/squash_squashed_commit.png b/doc/user/project/merge_requests/img/squash_squashed_commit.png Binary files differindex 0cf5875f82c..458361c5490 100644 --- a/doc/user/project/merge_requests/img/squash_squashed_commit.png +++ b/doc/user/project/merge_requests/img/squash_squashed_commit.png diff --git a/doc/user/project/merge_requests/img/versions.png b/doc/user/project/merge_requests/img/versions.png Binary files differindex 3883fb4bc1c..8355fd62dcb 100644 --- a/doc/user/project/merge_requests/img/versions.png +++ b/doc/user/project/merge_requests/img/versions.png diff --git a/doc/user/project/merge_requests/img/versions_compare.png b/doc/user/project/merge_requests/img/versions_compare.png Binary files differindex f5bd85dc7c1..0957a0310ac 100644 --- a/doc/user/project/merge_requests/img/versions_compare.png +++ b/doc/user/project/merge_requests/img/versions_compare.png diff --git a/doc/user/project/merge_requests/img/versions_dropdown.png b/doc/user/project/merge_requests/img/versions_dropdown.png Binary files differindex cc70a5bf14b..831c92db2c0 100644 --- a/doc/user/project/merge_requests/img/versions_dropdown.png +++ b/doc/user/project/merge_requests/img/versions_dropdown.png diff --git a/doc/user/project/merge_requests/img/versions_system_note.png b/doc/user/project/merge_requests/img/versions_system_note.png Binary files differindex 90be6298d15..97d552692c9 100644 --- a/doc/user/project/merge_requests/img/versions_system_note.png +++ b/doc/user/project/merge_requests/img/versions_system_note.png diff --git a/doc/user/project/merge_requests/img/wip_blocked_accept_button.png b/doc/user/project/merge_requests/img/wip_blocked_accept_button.png Binary files differindex 0c492aca363..31f23be4d3d 100644 --- a/doc/user/project/merge_requests/img/wip_blocked_accept_button.png +++ b/doc/user/project/merge_requests/img/wip_blocked_accept_button.png diff --git a/doc/user/project/merge_requests/img/wip_mark_as_wip.png b/doc/user/project/merge_requests/img/wip_mark_as_wip.png Binary files differindex e405879b28a..2c2a263b316 100644 --- a/doc/user/project/merge_requests/img/wip_mark_as_wip.png +++ b/doc/user/project/merge_requests/img/wip_mark_as_wip.png diff --git a/doc/user/project/merge_requests/img/wip_unmark_as_wip.png b/doc/user/project/merge_requests/img/wip_unmark_as_wip.png Binary files differindex d7f8c419945..327ad9a8448 100644 --- a/doc/user/project/merge_requests/img/wip_unmark_as_wip.png +++ b/doc/user/project/merge_requests/img/wip_unmark_as_wip.png diff --git a/doc/user/project/milestones/img/milestones_new_group_milestone.png b/doc/user/project/milestones/img/milestones_new_group_milestone.png Binary files differindex b6defab101d..a517f0f7537 100644 --- a/doc/user/project/milestones/img/milestones_new_group_milestone.png +++ b/doc/user/project/milestones/img/milestones_new_group_milestone.png diff --git a/doc/user/project/milestones/img/milestones_new_project_milestone.png b/doc/user/project/milestones/img/milestones_new_project_milestone.png Binary files differindex 9aaff7dfef1..482c73f6568 100644 --- a/doc/user/project/milestones/img/milestones_new_project_milestone.png +++ b/doc/user/project/milestones/img/milestones_new_project_milestone.png diff --git a/doc/user/project/milestones/img/milestones_project_milestone_page.png b/doc/user/project/milestones/img/milestones_project_milestone_page.png Binary files differindex 9717075b8d0..c17bf350aeb 100644 --- a/doc/user/project/milestones/img/milestones_project_milestone_page.png +++ b/doc/user/project/milestones/img/milestones_project_milestone_page.png diff --git a/doc/user/project/milestones/img/milestones_promote_milestone.png b/doc/user/project/milestones/img/milestones_promote_milestone.png Binary files differindex 5e7f94c316f..2ef85c5951d 100644 --- a/doc/user/project/milestones/img/milestones_promote_milestone.png +++ b/doc/user/project/milestones/img/milestones_promote_milestone.png diff --git a/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png b/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png Binary files differindex fa72df66587..0150329d4b2 100644 --- a/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png +++ b/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png diff --git a/doc/user/project/pages/img/pages_create_project.png b/doc/user/project/pages/img/pages_create_project.png Binary files differindex be47f9d2a44..69e84b84984 100644 --- a/doc/user/project/pages/img/pages_create_project.png +++ b/doc/user/project/pages/img/pages_create_project.png diff --git a/doc/user/project/pages/img/pages_dns_details.png b/doc/user/project/pages/img/pages_dns_details.png Binary files differindex 274e98fde4d..3e57f43f7ba 100644 --- a/doc/user/project/pages/img/pages_dns_details.png +++ b/doc/user/project/pages/img/pages_dns_details.png diff --git a/doc/user/project/pages/img/pages_multiple_domains.png b/doc/user/project/pages/img/pages_multiple_domains.png Binary files differindex 6bc92db6b41..76c39101439 100644 --- a/doc/user/project/pages/img/pages_multiple_domains.png +++ b/doc/user/project/pages/img/pages_multiple_domains.png diff --git a/doc/user/project/pages/img/pages_remove.png b/doc/user/project/pages/img/pages_remove.png Binary files differindex b064310380e..10299880247 100644 --- a/doc/user/project/pages/img/pages_remove.png +++ b/doc/user/project/pages/img/pages_remove.png diff --git a/doc/user/project/pages/img/pages_upload_cert.png b/doc/user/project/pages/img/pages_upload_cert.png Binary files differindex dc431ea3fef..64e5f8eced1 100644 --- a/doc/user/project/pages/img/pages_upload_cert.png +++ b/doc/user/project/pages/img/pages_upload_cert.png diff --git a/doc/user/project/pages/img/verify_your_domain.png b/doc/user/project/pages/img/verify_your_domain.png Binary files differindex 89c69cac9a5..d870f9e6505 100644 --- a/doc/user/project/pages/img/verify_your_domain.png +++ b/doc/user/project/pages/img/verify_your_domain.png diff --git a/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png b/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png Binary files differindex 3ccce4f9bb4..983f903ca72 100644 --- a/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png +++ b/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png diff --git a/doc/user/project/pipelines/img/pipeline_schedule_play.png b/doc/user/project/pipelines/img/pipeline_schedule_play.png Binary files differindex f594ceee19d..ec6eb0d156b 100644 --- a/doc/user/project/pipelines/img/pipeline_schedule_play.png +++ b/doc/user/project/pipelines/img/pipeline_schedule_play.png diff --git a/doc/user/project/pipelines/img/pipeline_schedule_variables.png b/doc/user/project/pipelines/img/pipeline_schedule_variables.png Binary files differindex 47a0c6f3697..74692add93a 100644 --- a/doc/user/project/pipelines/img/pipeline_schedule_variables.png +++ b/doc/user/project/pipelines/img/pipeline_schedule_variables.png diff --git a/doc/user/project/pipelines/img/pipeline_schedules_list.png b/doc/user/project/pipelines/img/pipeline_schedules_list.png Binary files differindex 2ab2061db94..541fe4f9b1d 100644 --- a/doc/user/project/pipelines/img/pipeline_schedules_list.png +++ b/doc/user/project/pipelines/img/pipeline_schedules_list.png diff --git a/doc/user/project/pipelines/img/pipeline_schedules_new_form.png b/doc/user/project/pipelines/img/pipeline_schedules_new_form.png Binary files differindex 5a0e5965992..95203ec861b 100644 --- a/doc/user/project/pipelines/img/pipeline_schedules_new_form.png +++ b/doc/user/project/pipelines/img/pipeline_schedules_new_form.png diff --git a/doc/user/project/pipelines/img/pipeline_schedules_ownership.png b/doc/user/project/pipelines/img/pipeline_schedules_ownership.png Binary files differindex 31ed83abb4d..8fc5c5fbc82 100644 --- a/doc/user/project/pipelines/img/pipeline_schedules_ownership.png +++ b/doc/user/project/pipelines/img/pipeline_schedules_ownership.png diff --git a/doc/user/project/repository/branches/img/delete_merged_branches.png b/doc/user/project/repository/branches/img/delete_merged_branches.png Binary files differindex 1856a624f74..649a758b95f 100644 --- a/doc/user/project/repository/branches/img/delete_merged_branches.png +++ b/doc/user/project/repository/branches/img/delete_merged_branches.png diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png Binary files differindex 8e26d98f1b0..6e2ff33eebb 100644 --- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png +++ b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png Binary files differindex 5c14df36d73..ae0a8696c6c 100644 --- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png +++ b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png Binary files differindex 088ecfa6d89..e1d44f15f3f 100644 --- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png +++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png Binary files differindex 4e3392406b1..763a677f94a 100644 --- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png +++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png Binary files differindex 766970dee81..1b6fa3fc2e2 100644 --- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png +++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png diff --git a/doc/user/project/repository/img/compare_branches.png b/doc/user/project/repository/img/compare_branches.png Binary files differindex d7ab587f030..52d5c518c45 100644 --- a/doc/user/project/repository/img/compare_branches.png +++ b/doc/user/project/repository/img/compare_branches.png diff --git a/doc/user/project/repository/img/repository_languages.png b/doc/user/project/repository/img/repository_languages.png Binary files differindex d9fb1278e06..5977ad7faae 100644 --- a/doc/user/project/repository/img/repository_languages.png +++ b/doc/user/project/repository/img/repository_languages.png diff --git a/doc/user/project/repository/img/web_editor_new_branch_dropdown.png b/doc/user/project/repository/img/web_editor_new_branch_dropdown.png Binary files differindex 31edb6bde3a..a6edea1fcce 100644 --- a/doc/user/project/repository/img/web_editor_new_branch_dropdown.png +++ b/doc/user/project/repository/img/web_editor_new_branch_dropdown.png diff --git a/doc/user/project/repository/img/web_editor_new_branch_from_issue.png b/doc/user/project/repository/img/web_editor_new_branch_from_issue.png Binary files differindex 4729f5383c0..4e156b8adc8 100644 --- a/doc/user/project/repository/img/web_editor_new_branch_from_issue.png +++ b/doc/user/project/repository/img/web_editor_new_branch_from_issue.png diff --git a/doc/user/project/repository/img/web_editor_new_branch_page.png b/doc/user/project/repository/img/web_editor_new_branch_page.png Binary files differindex 8d82f981527..7bb8b9e29e3 100644 --- a/doc/user/project/repository/img/web_editor_new_branch_page.png +++ b/doc/user/project/repository/img/web_editor_new_branch_page.png diff --git a/doc/user/project/repository/img/web_editor_new_directory_dialog.png b/doc/user/project/repository/img/web_editor_new_directory_dialog.png Binary files differindex 1c9beff8849..590989c360e 100644 --- a/doc/user/project/repository/img/web_editor_new_directory_dialog.png +++ b/doc/user/project/repository/img/web_editor_new_directory_dialog.png diff --git a/doc/user/project/repository/img/web_editor_new_directory_dropdown.png b/doc/user/project/repository/img/web_editor_new_directory_dropdown.png Binary files differindex ede691f6f74..efa3087fc0c 100644 --- a/doc/user/project/repository/img/web_editor_new_directory_dropdown.png +++ b/doc/user/project/repository/img/web_editor_new_directory_dropdown.png diff --git a/doc/user/project/repository/img/web_editor_new_file_dropdown.png b/doc/user/project/repository/img/web_editor_new_file_dropdown.png Binary files differindex 13a4d721039..b40fb1ce58d 100644 --- a/doc/user/project/repository/img/web_editor_new_file_dropdown.png +++ b/doc/user/project/repository/img/web_editor_new_file_dropdown.png diff --git a/doc/user/project/repository/img/web_editor_new_push_widget.png b/doc/user/project/repository/img/web_editor_new_push_widget.png Binary files differindex 77756876d4f..8957b5d6a6b 100644 --- a/doc/user/project/repository/img/web_editor_new_push_widget.png +++ b/doc/user/project/repository/img/web_editor_new_push_widget.png diff --git a/doc/user/project/repository/img/web_editor_new_tag_dropdown.png b/doc/user/project/repository/img/web_editor_new_tag_dropdown.png Binary files differindex b52d5cabdf2..33e8ed891b5 100644 --- a/doc/user/project/repository/img/web_editor_new_tag_dropdown.png +++ b/doc/user/project/repository/img/web_editor_new_tag_dropdown.png diff --git a/doc/user/project/repository/img/web_editor_start_new_merge_request.png b/doc/user/project/repository/img/web_editor_start_new_merge_request.png Binary files differindex 384e8320f15..85f4769661a 100644 --- a/doc/user/project/repository/img/web_editor_start_new_merge_request.png +++ b/doc/user/project/repository/img/web_editor_start_new_merge_request.png diff --git a/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png b/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png Binary files differindex f21183125f6..4608843b1f4 100644 --- a/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png +++ b/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png diff --git a/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png b/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png Binary files differindex 7f31c2a8887..a4440ec3cc9 100644 --- a/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png +++ b/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png diff --git a/doc/user/project/repository/img/web_editor_upload_file_dialog.png b/doc/user/project/repository/img/web_editor_upload_file_dialog.png Binary files differindex 04e951406ad..c0e9a99aa61 100644 --- a/doc/user/project/repository/img/web_editor_upload_file_dialog.png +++ b/doc/user/project/repository/img/web_editor_upload_file_dialog.png diff --git a/doc/user/project/repository/img/web_editor_upload_file_dropdown.png b/doc/user/project/repository/img/web_editor_upload_file_dropdown.png Binary files differindex b8c766d4b99..c80a9ae4b3d 100644 --- a/doc/user/project/repository/img/web_editor_upload_file_dropdown.png +++ b/doc/user/project/repository/img/web_editor_upload_file_dropdown.png diff --git a/doc/user/project/settings/img/import_export_download_export.png b/doc/user/project/settings/img/import_export_download_export.png Binary files differindex 4945590e3e8..668254073e8 100644 --- a/doc/user/project/settings/img/import_export_download_export.png +++ b/doc/user/project/settings/img/import_export_download_export.png diff --git a/doc/user/project/settings/img/import_export_export_button.png b/doc/user/project/settings/img/import_export_export_button.png Binary files differindex eef79821f8b..7f21bb2335b 100644 --- a/doc/user/project/settings/img/import_export_export_button.png +++ b/doc/user/project/settings/img/import_export_export_button.png diff --git a/doc/user/project/settings/img/import_export_new_project.png b/doc/user/project/settings/img/import_export_new_project.png Binary files differindex 9dd509dc4a0..b335700c5be 100644 --- a/doc/user/project/settings/img/import_export_new_project.png +++ b/doc/user/project/settings/img/import_export_new_project.png diff --git a/doc/user/project/settings/img/import_export_select_file.png b/doc/user/project/settings/img/import_export_select_file.png Binary files differindex fb831dca32b..e1e5e031d81 100644 --- a/doc/user/project/settings/img/import_export_select_file.png +++ b/doc/user/project/settings/img/import_export_select_file.png diff --git a/doc/user/project/settings/img/settings_edit_button.png b/doc/user/project/settings/img/settings_edit_button.png Binary files differindex 9f3a8330e3a..32bcda03c7e 100644 --- a/doc/user/project/settings/img/settings_edit_button.png +++ b/doc/user/project/settings/img/settings_edit_button.png diff --git a/doc/user/project/settings/img/sharing_and_permissions_settings.png b/doc/user/project/settings/img/sharing_and_permissions_settings.png Binary files differindex 0f9cf9512af..f5e3e32f95c 100644 --- a/doc/user/project/settings/img/sharing_and_permissions_settings.png +++ b/doc/user/project/settings/img/sharing_and_permissions_settings.png diff --git a/doc/user/project/web_ide/img/open_web_ide.png b/doc/user/project/web_ide/img/open_web_ide.png Binary files differindex d1192daf506..02a5a564472 100644 --- a/doc/user/project/web_ide/img/open_web_ide.png +++ b/doc/user/project/web_ide/img/open_web_ide.png diff --git a/doc/user/project/wiki/img/wiki_create_home_page.png b/doc/user/project/wiki/img/wiki_create_home_page.png Binary files differindex f50f564034c..658af33d76e 100644 --- a/doc/user/project/wiki/img/wiki_create_home_page.png +++ b/doc/user/project/wiki/img/wiki_create_home_page.png diff --git a/doc/user/project/wiki/img/wiki_create_new_page.png b/doc/user/project/wiki/img/wiki_create_new_page.png Binary files differindex c19124a8923..8954ec0d3a8 100644 --- a/doc/user/project/wiki/img/wiki_create_new_page.png +++ b/doc/user/project/wiki/img/wiki_create_new_page.png diff --git a/doc/user/project/wiki/img/wiki_create_new_page_modal.png b/doc/user/project/wiki/img/wiki_create_new_page_modal.png Binary files differindex ece437967dc..b800508901b 100644 --- a/doc/user/project/wiki/img/wiki_create_new_page_modal.png +++ b/doc/user/project/wiki/img/wiki_create_new_page_modal.png diff --git a/doc/user/project/wiki/img/wiki_move_page_1.png b/doc/user/project/wiki/img/wiki_move_page_1.png Binary files differindex 0331c9d3a5c..189fcc9a845 100644 --- a/doc/user/project/wiki/img/wiki_move_page_1.png +++ b/doc/user/project/wiki/img/wiki_move_page_1.png diff --git a/doc/user/project/wiki/img/wiki_move_page_2.png b/doc/user/project/wiki/img/wiki_move_page_2.png Binary files differindex a8e0c055051..63e6ddb29c1 100644 --- a/doc/user/project/wiki/img/wiki_move_page_2.png +++ b/doc/user/project/wiki/img/wiki_move_page_2.png diff --git a/doc/user/project/wiki/img/wiki_page_history.png b/doc/user/project/wiki/img/wiki_page_history.png Binary files differindex 0e6af1b468d..5a1ae295ed2 100644 --- a/doc/user/project/wiki/img/wiki_page_history.png +++ b/doc/user/project/wiki/img/wiki_page_history.png diff --git a/doc/user/project/wiki/img/wiki_sidebar.png b/doc/user/project/wiki/img/wiki_sidebar.png Binary files differindex 59814e2a06e..ff39c861a73 100644 --- a/doc/user/project/wiki/img/wiki_sidebar.png +++ b/doc/user/project/wiki/img/wiki_sidebar.png diff --git a/doc/user/search/img/issue_search_by_term.png b/doc/user/search/img/issue_search_by_term.png Binary files differindex 3cefa3adb8b..64450c6a891 100644 --- a/doc/user/search/img/issue_search_by_term.png +++ b/doc/user/search/img/issue_search_by_term.png diff --git a/doc/user/search/img/issue_search_filter.png b/doc/user/search/img/issue_search_filter.png Binary files differindex f357abd6bac..d4de3ff7656 100644 --- a/doc/user/search/img/issue_search_filter.png +++ b/doc/user/search/img/issue_search_filter.png diff --git a/doc/user/search/img/issues_mrs_shortcut.png b/doc/user/search/img/issues_mrs_shortcut.png Binary files differindex cf43df98aa0..2fe1350c806 100644 --- a/doc/user/search/img/issues_mrs_shortcut.png +++ b/doc/user/search/img/issues_mrs_shortcut.png diff --git a/doc/user/search/img/project_search.png b/doc/user/search/img/project_search.png Binary files differindex 0b76d7d6038..b2525b2c771 100644 --- a/doc/user/search/img/project_search.png +++ b/doc/user/search/img/project_search.png diff --git a/doc/workflow/ci_mr.png b/doc/workflow/ci_mr.png Binary files differindex 77423c68190..85a609cb814 100644 --- a/doc/workflow/ci_mr.png +++ b/doc/workflow/ci_mr.png diff --git a/doc/workflow/environment_branches.png b/doc/workflow/environment_branches.png Binary files differindex 0941a4cad9c..0aff33c6bb8 100644 --- a/doc/workflow/environment_branches.png +++ b/doc/workflow/environment_branches.png diff --git a/doc/workflow/forking/branch_select.png b/doc/workflow/forking/branch_select.png Binary files differindex 3e82afca75b..77236137190 100644 --- a/doc/workflow/forking/branch_select.png +++ b/doc/workflow/forking/branch_select.png diff --git a/doc/workflow/forking/merge_request.png b/doc/workflow/forking/merge_request.png Binary files differindex 294775e1fdd..407ddfb4799 100644 --- a/doc/workflow/forking/merge_request.png +++ b/doc/workflow/forking/merge_request.png diff --git a/doc/workflow/git_pull.png b/doc/workflow/git_pull.png Binary files differindex 2dd06b56c56..0e56e59471c 100644 --- a/doc/workflow/git_pull.png +++ b/doc/workflow/git_pull.png diff --git a/doc/workflow/gitlab_flow.png b/doc/workflow/gitlab_flow.png Binary files differindex c3562cc69a8..a6f3c947843 100644 --- a/doc/workflow/gitlab_flow.png +++ b/doc/workflow/gitlab_flow.png diff --git a/doc/workflow/good_commit.png b/doc/workflow/good_commit.png Binary files differindex c3664aa97f2..ceb0d4b1691 100644 --- a/doc/workflow/good_commit.png +++ b/doc/workflow/good_commit.png diff --git a/doc/workflow/img/file_finder_find_button.png b/doc/workflow/img/file_finder_find_button.png Binary files differindex 23139cc00c5..0c2d7d7bc73 100644 --- a/doc/workflow/img/file_finder_find_button.png +++ b/doc/workflow/img/file_finder_find_button.png diff --git a/doc/workflow/img/forking_workflow_fork_button.png b/doc/workflow/img/forking_workflow_fork_button.png Binary files differindex 29854e6c516..941d5363c35 100644 --- a/doc/workflow/img/forking_workflow_fork_button.png +++ b/doc/workflow/img/forking_workflow_fork_button.png diff --git a/doc/workflow/img/forking_workflow_path_taken_error.png b/doc/workflow/img/forking_workflow_path_taken_error.png Binary files differindex 9365fd13200..df938da5677 100644 --- a/doc/workflow/img/forking_workflow_path_taken_error.png +++ b/doc/workflow/img/forking_workflow_path_taken_error.png diff --git a/doc/workflow/img/notification_group_settings.png b/doc/workflow/img/notification_group_settings.png Binary files differindex fc096f46901..ed5e9459216 100644 --- a/doc/workflow/img/notification_group_settings.png +++ b/doc/workflow/img/notification_group_settings.png diff --git a/doc/workflow/img/notification_project_settings.png b/doc/workflow/img/notification_project_settings.png Binary files differindex 006432f65c9..e2db2037d94 100644 --- a/doc/workflow/img/notification_project_settings.png +++ b/doc/workflow/img/notification_project_settings.png diff --git a/doc/workflow/img/todo_list_item.png b/doc/workflow/img/todo_list_item.png Binary files differindex 076069b651e..91bbf9e5373 100644 --- a/doc/workflow/img/todo_list_item.png +++ b/doc/workflow/img/todo_list_item.png diff --git a/doc/workflow/img/todos_add_todo_sidebar.png b/doc/workflow/img/todos_add_todo_sidebar.png Binary files differindex 3fa37067d1e..aefec7a2d9c 100644 --- a/doc/workflow/img/todos_add_todo_sidebar.png +++ b/doc/workflow/img/todos_add_todo_sidebar.png diff --git a/doc/workflow/img/todos_mark_done_sidebar.png b/doc/workflow/img/todos_mark_done_sidebar.png Binary files differindex a8e756a71db..2badd880b40 100644 --- a/doc/workflow/img/todos_mark_done_sidebar.png +++ b/doc/workflow/img/todos_mark_done_sidebar.png diff --git a/doc/workflow/merge_request.png b/doc/workflow/merge_request.png Binary files differindex 08dfc7f2468..010e95983fc 100644 --- a/doc/workflow/merge_request.png +++ b/doc/workflow/merge_request.png diff --git a/doc/workflow/messy_flow.png b/doc/workflow/messy_flow.png Binary files differindex 7e72e2a3be6..4fa22d2bb5d 100644 --- a/doc/workflow/messy_flow.png +++ b/doc/workflow/messy_flow.png diff --git a/doc/workflow/mr_inline_comments.png b/doc/workflow/mr_inline_comments.png Binary files differindex 6a2e66a01ba..a18801f56e4 100644 --- a/doc/workflow/mr_inline_comments.png +++ b/doc/workflow/mr_inline_comments.png diff --git a/doc/workflow/production_branch.png b/doc/workflow/production_branch.png Binary files differindex 648d5d5c92e..c132d51bfb6 100644 --- a/doc/workflow/production_branch.png +++ b/doc/workflow/production_branch.png diff --git a/doc/workflow/rebase.png b/doc/workflow/rebase.png Binary files differindex 8b9bb61a5cc..fe865177ba8 100644 --- a/doc/workflow/rebase.png +++ b/doc/workflow/rebase.png diff --git a/doc/workflow/release_branches.png b/doc/workflow/release_branches.png Binary files differindex 5194d75a667..0a7f61d0248 100644 --- a/doc/workflow/release_branches.png +++ b/doc/workflow/release_branches.png diff --git a/doc/workflow/releases/new_tag.png b/doc/workflow/releases/new_tag.png Binary files differindex 97519e5808f..6137ad2ee56 100644 --- a/doc/workflow/releases/new_tag.png +++ b/doc/workflow/releases/new_tag.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png b/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png Binary files differindex 333648942f8..2377a4a6516 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png b/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png Binary files differindex 038b05cb31d..786bd23eee6 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png Binary files differindex 99d429a1802..d8af5ce129e 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png Binary files differindex 0ab07afa3cc..a10102e97ac 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png Binary files differindex 5da5a7436bb..1f1b3e1d5fb 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png Binary files differindex 4b9085302a1..b8dfddb3d02 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png Binary files differindex 8c2efdafa43..8f1de1d3003 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png b/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png Binary files differindex 93f3a532a0e..930d10a0822 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png diff --git a/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png b/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png Binary files differindex 6997ad511d9..adc1eedac44 100644 --- a/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png +++ b/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png diff --git a/doc/workflow/time-tracking/time-tracking-example.png b/doc/workflow/time-tracking/time-tracking-example.png Binary files differindex bbcabb602d6..a96e4da7f74 100644 --- a/doc/workflow/time-tracking/time-tracking-example.png +++ b/doc/workflow/time-tracking/time-tracking-example.png diff --git a/doc/workflow/time-tracking/time-tracking-sidebar.png b/doc/workflow/time-tracking/time-tracking-sidebar.png Binary files differindex d1ff5571f95..22124afed6f 100644 --- a/doc/workflow/time-tracking/time-tracking-sidebar.png +++ b/doc/workflow/time-tracking/time-tracking-sidebar.png diff --git a/lib/api/api.rb b/lib/api/api.rb index e2ad3c5f4e3..c000666d992 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -99,12 +99,13 @@ module API mount ::API::Features mount ::API::Files mount ::API::GroupBoards - mount ::API::Groups mount ::API::GroupMilestones + mount ::API::Groups + mount ::API::GroupVariables mount ::API::Internal mount ::API::Issues - mount ::API::Jobs mount ::API::JobArtifacts + mount ::API::Jobs mount ::API::Keys mount ::API::Labels mount ::API::Lint @@ -122,11 +123,12 @@ module API mount ::API::ProjectExport mount ::API::ProjectImport mount ::API::ProjectHooks - mount ::API::Projects mount ::API::ProjectMilestones + mount ::API::Projects mount ::API::ProjectSnapshots mount ::API::ProjectSnippets mount ::API::ProtectedBranches + mount ::API::ProtectedTags mount ::API::Repositories mount ::API::Runner mount ::API::Runners @@ -143,7 +145,6 @@ module API mount ::API::Triggers mount ::API::Users mount ::API::Variables - mount ::API::GroupVariables mount ::API::Version mount ::API::Wikis diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index c3d93996816..bde4b3ff4f6 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -100,7 +100,7 @@ module API end def can_award_awardable? - awardable.user_can_award?(current_user, params[:name]) + awardable.user_can_award?(current_user) end def awardable diff --git a/lib/api/entities.rb b/lib/api/entities.rb index b6393fdef19..95b25d7351a 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -91,6 +91,7 @@ module API group_link.group.name end expose :group_access, as: :group_access_level + expose :expires_at end class ProjectIdentity < Grape::Entity @@ -428,6 +429,11 @@ module API expose :merge_access_levels, using: Entities::ProtectedRefAccess end + class ProtectedTag < Grape::Entity + expose :name + expose :create_access_levels, using: Entities::ProtectedRefAccess + end + class Milestone < Grape::Entity expose :id, :iid expose :project_id, if: -> (entity, options) { entity&.project_id } diff --git a/lib/api/files.rb b/lib/api/files.rb index 29d7489bd7c..ff4f75c12df 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -59,7 +59,7 @@ module API params :simple_file_params do requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb' requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.' - requires :commit_message, type: String, desc: 'Commit message' + requires :commit_message, type: String, allow_blank: false, desc: 'Commit message' optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from' optional :author_email, type: String, desc: 'The email of the author' optional :author_name, type: String, desc: 'The name of the author' diff --git a/lib/api/group_milestones.rb b/lib/api/group_milestones.rb index 93fa0b95857..4b4352c2b27 100644 --- a/lib/api/group_milestones.rb +++ b/lib/api/group_milestones.rb @@ -41,7 +41,7 @@ module API use :optional_params end post ":id/milestones" do - authorize! :admin_milestones, user_group + authorize! :admin_milestone, user_group create_milestone_for(user_group) end @@ -53,11 +53,21 @@ module API use :update_params end put ":id/milestones/:milestone_id" do - authorize! :admin_milestones, user_group + authorize! :admin_milestone, user_group update_milestone_for(user_group) end + desc 'Remove a project milestone' + delete ":id/milestones/:milestone_id" do + authorize! :admin_milestone, user_group + + milestone = user_group.milestones.find(params[:milestone_id]) + Milestones::DestroyService.new(user_group, current_user).execute(milestone) + + status(204) + end + desc 'Get all issues for a single group milestone' do success Entities::IssueBasic end diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb index e2984b08eca..7b1f5c2584b 100644 --- a/lib/api/helpers/notes_helpers.rb +++ b/lib/api/helpers/notes_helpers.rb @@ -92,10 +92,7 @@ module API parent = noteable_parent(noteable) - if opts[:created_at] - opts.delete(:created_at) unless - current_user.admin? || parent.owned_by?(current_user) - end + opts.delete(:created_at) unless current_user.can?(:set_note_created_at, policy_object) opts[:updated_at] = opts[:created_at] if opts[:created_at] diff --git a/lib/api/issues.rb b/lib/api/issues.rb index bda05d1795b..cedfd2fbaa0 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -172,11 +172,8 @@ module API authorize! :create_issue, user_project - # Setting created_at time or iid only allowed for admins and project owners - unless current_user.admin? || user_project.owner == current_user - params.delete(:created_at) - params.delete(:iid) - end + params.delete(:created_at) unless current_user.can?(:set_issue_created_at, user_project) + params.delete(:iid) unless current_user.can?(:set_issue_iid, user_project) issue_params = declared_params(include_missing: false) @@ -216,8 +213,8 @@ module API issue = user_project.issues.find_by!(iid: params.delete(:issue_iid)) authorize! :update_issue, issue - # Setting created_at time only allowed for admins and project owners - unless current_user.admin? || user_project.owner == current_user + # Setting created_at time only allowed for admins and project/group owners + unless current_user.admin? || user_project.owner == current_user || current_user.owned_groups.include?(user_project.owner) params.delete(:updated_at) end diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb index 306dc0e63d7..72cf32d7717 100644 --- a/lib/api/project_milestones.rb +++ b/lib/api/project_milestones.rb @@ -64,7 +64,8 @@ module API delete ":id/milestones/:milestone_id" do authorize! :admin_milestone, user_project - user_project.milestones.find(params[:milestone_id]).destroy + milestone = user_project.milestones.find(params[:milestone_id]) + Milestones::DestroyService.new(user_project, current_user).execute(milestone) status(204) end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index 1de5551fee9..0ada0ef4708 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -49,7 +49,7 @@ module API params do requires :title, type: String, desc: 'The title of the snippet' requires :file_name, type: String, desc: 'The file name of the snippet' - requires :code, type: String, desc: 'The content of the snippet' + requires :code, type: String, allow_blank: false, desc: 'The content of the snippet' optional :description, type: String, desc: 'The description of a snippet' requires :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, @@ -78,7 +78,7 @@ module API requires :snippet_id, type: Integer, desc: 'The ID of a project snippet' optional :title, type: String, desc: 'The title of the snippet' optional :file_name, type: String, desc: 'The file name of the snippet' - optional :code, type: String, desc: 'The content of the snippet' + optional :code, type: String, allow_blank: false, desc: 'The content of the snippet' optional :description, type: String, desc: 'The description of a snippet' optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 5738bf220c6..2801ae918c6 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -386,7 +386,7 @@ module API requires :forked_from_id, type: String, desc: 'The ID of the project it was forked from' end post ":id/fork/:forked_from_id" do - authenticated_as_admin! + authorize! :admin_project, user_project fork_from_project = find_project!(params[:forked_from_id]) diff --git a/lib/api/protected_tags.rb b/lib/api/protected_tags.rb new file mode 100644 index 00000000000..bf0a7184e1c --- /dev/null +++ b/lib/api/protected_tags.rb @@ -0,0 +1,79 @@ +module API + class ProtectedTags < Grape::API + include PaginationParams + + TAG_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX) + + before { authorize_admin_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + desc "Get a project's protected tags" do + detail 'This feature was introduced in GitLab 11.3.' + success Entities::ProtectedTag + end + params do + use :pagination + end + get ':id/protected_tags' do + protected_tags = user_project.protected_tags.preload(:create_access_levels) + + present paginate(protected_tags), with: Entities::ProtectedTag, project: user_project + end + + desc 'Get a single protected tag' do + detail 'This feature was introduced in GitLab 11.3.' + success Entities::ProtectedTag + end + params do + requires :name, type: String, desc: 'The name of the tag or wildcard' + end + get ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do + protected_tag = user_project.protected_tags.find_by!(name: params[:name]) + + present protected_tag, with: Entities::ProtectedTag, project: user_project + end + + desc 'Protect a single tag or wildcard' do + detail 'This feature was introduced in GitLab 11.3.' + success Entities::ProtectedTag + end + params do + requires :name, type: String, desc: 'The name of the protected tag' + optional :create_access_level, type: Integer, default: Gitlab::Access::MAINTAINER, + values: ProtectedRefAccess::ALLOWED_ACCESS_LEVELS, + desc: 'Access levels allowed to create (defaults: `40`, maintainer access level)' + end + post ':id/protected_tags' do + protected_tags_params = { + name: params[:name], + create_access_levels_attributes: [{ access_level: params[:create_access_level] }] + } + + protected_tag = ::ProtectedTags::CreateService.new(user_project, + current_user, + protected_tags_params).execute + + if protected_tag.persisted? + present protected_tag, with: Entities::ProtectedTag, project: user_project + else + render_api_error!(protected_tag.errors.full_messages, 422) + end + end + + desc 'Unprotect a single tag' do + detail 'This feature was introduced in GitLab 11.3.' + end + params do + requires :name, type: String, desc: 'The name of the protected tag' + end + delete ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do + protected_tag = user_project.protected_tags.find_by!(name: params[:name]) + + destroy_conditionally!(protected_tag) + end + end + end +end diff --git a/lib/banzai/reference_parser/merge_request_parser.rb b/lib/banzai/reference_parser/merge_request_parser.rb index a370ff5b5b3..9e5d55f72bc 100644 --- a/lib/banzai/reference_parser/merge_request_parser.rb +++ b/lib/banzai/reference_parser/merge_request_parser.rb @@ -14,11 +14,12 @@ module Banzai # Eager loading these ensures we don't end up running dozens of # queries in this process. target_project: [ - { namespace: :owner }, + { namespace: [:owner, :route] }, { group: [:owners, :group_members] }, :invited_groups, :project_members, - :project_feature + :project_feature, + :route ] }), self.class.data_attribute diff --git a/lib/feature.rb b/lib/feature.rb index 09c5ef3ad94..24dbcb32fc0 100644 --- a/lib/feature.rb +++ b/lib/feature.rb @@ -47,7 +47,8 @@ class Feature end def disabled?(key, thing = nil) - !enabled?(key, thing) + # we need to make different method calls to make it easy to mock / define expectations in test mode + thing.nil? ? !enabled?(key) : !enabled?(key, thing) end def enable(key, thing = true) diff --git a/lib/gitlab/auth/ldap/access.rb b/lib/gitlab/auth/ldap/access.rb index 865185eb5db..eeab7791643 100644 --- a/lib/gitlab/auth/ldap/access.rb +++ b/lib/gitlab/auth/ldap/access.rb @@ -19,8 +19,10 @@ module Gitlab # Whether user is allowed, or not, we should update # permissions to keep things clean if access.allowed? - access.update_user - Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute + unless Gitlab::Database.read_only? + access.update_user + Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute + end true else @@ -60,6 +62,12 @@ module Gitlab false end + def update_user + # no-op in CE + end + + private + def adapter @adapter ||= Gitlab::Auth::LDAP::Adapter.new(provider) end @@ -68,16 +76,16 @@ module Gitlab Gitlab::Auth::LDAP::Config.new(provider) end - def find_ldap_user - Gitlab::Auth::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter) - end - def ldap_user return unless provider @ldap_user ||= find_ldap_user end + def find_ldap_user + Gitlab::Auth::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter) + end + def block_user(user, reason) user.ldap_block @@ -102,10 +110,6 @@ module Gitlab "unblocking Gitlab user \"#{user.name}\" (#{user.email})" ) end - - def update_user - # no-op in CE - end end end end diff --git a/lib/gitlab/auth/o_auth/provider.rb b/lib/gitlab/auth/o_auth/provider.rb index e73743944a9..26da9d09ccc 100644 --- a/lib/gitlab/auth/o_auth/provider.rb +++ b/lib/gitlab/auth/o_auth/provider.rb @@ -29,6 +29,7 @@ module Gitlab def self.enabled?(name) return true if name == 'database' + return true if self.ldap_provider?(name) && providers.include?(name.to_sym) Gitlab::Auth.omniauth_enabled? && providers.include?(name.to_sym) end diff --git a/lib/gitlab/bitbucket_server_import/importer.rb b/lib/gitlab/bitbucket_server_import/importer.rb index 268d21a77d1..b591d94668f 100644 --- a/lib/gitlab/bitbucket_server_import/importer.rb +++ b/lib/gitlab/bitbucket_server_import/importer.rb @@ -1,7 +1,10 @@ +# frozen_string_literal: true + module Gitlab module BitbucketServerImport class Importer include Gitlab::ShellAdapter + attr_reader :recover_missing_commits attr_reader :project, :project_key, :repository_slug, :client, :errors, :users @@ -175,21 +178,18 @@ module Gitlab description = '' description += @formatter.author_line(pull_request.author) unless find_user_id(pull_request.author_email) description += pull_request.description if pull_request.description - - source_branch_sha = pull_request.source_branch_sha - target_branch_sha = pull_request.target_branch_sha author_id = gitlab_user_id(pull_request.author_email) attributes = { iid: pull_request.iid, title: pull_request.title, description: description, - source_project: project, + source_project_id: project.id, source_branch: Gitlab::Git.ref_name(pull_request.source_branch_name), - source_branch_sha: source_branch_sha, - target_project: project, + source_branch_sha: pull_request.source_branch_sha, + target_project_id: project.id, target_branch: Gitlab::Git.ref_name(pull_request.target_branch_name), - target_branch_sha: target_branch_sha, + target_branch_sha: pull_request.target_branch_sha, state: pull_request.state, author_id: author_id, assignee_id: nil, @@ -197,7 +197,9 @@ module Gitlab updated_at: pull_request.updated_at } - merge_request = project.merge_requests.create!(attributes) + creator = Gitlab::Import::MergeRequestCreator.new(project) + merge_request = creator.execute(attributes) + import_pull_request_comments(pull_request, merge_request) if merge_request.persisted? end diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb index 703f0b9217b..508b4814631 100644 --- a/lib/gitlab/ci/status/build/failed.rb +++ b/lib/gitlab/ci/status/build/failed.rb @@ -32,7 +32,7 @@ module Gitlab end def description - "<br> (#{failure_reason_message})" + "- (#{failure_reason_message})" end def failure_reason_message diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index 5c1baa19b66..1f012043e56 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -37,7 +37,7 @@ module Gitlab end end - diff_line.text = rich_line + diff_line.rich_text = rich_line diff_line end diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb index 1faf7770634..1ab6df0b6ae 100644 --- a/lib/gitlab/diff/line.rb +++ b/lib/gitlab/diff/line.rb @@ -1,16 +1,17 @@ module Gitlab module Diff class Line - SERIALIZE_KEYS = %i(line_code text type index old_pos new_pos).freeze + SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze attr_reader :line_code, :type, :index, :old_pos, :new_pos attr_writer :rich_text attr_accessor :text - def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil) + def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil) @text, @type, @index = text, type, index @old_pos, @new_pos = old_pos, new_pos @parent_file = parent_file + @rich_text = rich_text # When line code is not provided from cache store we build it # using the parent_file(Diff::File or Conflict::File). @@ -18,7 +19,7 @@ module Gitlab end def self.init_from_hash(hash) - new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code]) + new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code], rich_text: hash[:rich_text]) end def to_hash @@ -85,7 +86,7 @@ module Gitlab old_line: old_line, new_line: new_line, text: text, - rich_text: rich_text || text, + rich_text: rich_text || CGI.escapeHTML(text), meta_data: meta_positions } end diff --git a/lib/gitlab/github_import.rb b/lib/gitlab/github_import.rb index 65b5e30c70f..d40b06f969f 100644 --- a/lib/gitlab/github_import.rb +++ b/lib/gitlab/github_import.rb @@ -10,24 +10,6 @@ module Gitlab Client.new(token_to_use, parallel: parallel) end - # Inserts a raw row and returns the ID of the inserted row. - # - # attributes - The attributes/columns to set. - # relation - An ActiveRecord::Relation to use for finding the ID of the row - # when using MySQL. - def self.insert_and_return_id(attributes, relation) - # We use bulk_insert here so we can bypass any queries executed by - # callbacks or validation rules, as doing this wouldn't scale when - # importing very large projects. - result = Gitlab::Database - .bulk_insert(relation.table_name, [attributes], return_ids: true) - - # MySQL doesn't support returning the IDs of a bulk insert in a way that - # is not a pain, so in this case we'll issue an extra query instead. - result.first || - relation.where(iid: attributes[:iid]).limit(1).pluck(:id).first - end - # Returns the ID of the ghost user. def self.ghost_user_id key = 'github-import/ghost-user-id' diff --git a/lib/gitlab/github_import/importer/issue_importer.rb b/lib/gitlab/github_import/importer/issue_importer.rb index cb4d7a6a0b6..4226eee85cc 100644 --- a/lib/gitlab/github_import/importer/issue_importer.rb +++ b/lib/gitlab/github_import/importer/issue_importer.rb @@ -4,6 +4,8 @@ module Gitlab module GithubImport module Importer class IssueImporter + include Gitlab::Import::DatabaseHelpers + attr_reader :project, :issue, :client, :user_finder, :milestone_finder, :issuable_finder @@ -55,7 +57,7 @@ module Gitlab updated_at: issue.updated_at } - GithubImport.insert_and_return_id(attributes, project.issues).tap do |id| + insert_and_return_id(attributes, project.issues).tap do |id| # We use .insert_and_return_id which effectively disables all callbacks. # Trigger iid logic here to make sure we track internal id values consistently. project.issues.find(id).ensure_project_iid! diff --git a/lib/gitlab/github_import/importer/pull_request_importer.rb b/lib/gitlab/github_import/importer/pull_request_importer.rb index ed17aa54373..ae7c4cf1b38 100644 --- a/lib/gitlab/github_import/importer/pull_request_importer.rb +++ b/lib/gitlab/github_import/importer/pull_request_importer.rb @@ -4,6 +4,8 @@ module Gitlab module GithubImport module Importer class PullRequestImporter + include Gitlab::Import::MergeRequestHelpers + attr_reader :pull_request, :project, :client, :user_finder, :milestone_finder, :issuable_finder @@ -44,81 +46,27 @@ module Gitlab description = MarkdownText .format(pull_request.description, pull_request.author, author_found) - # This work must be wrapped in a transaction as otherwise we can leave - # behind incomplete data in the event of an error. This can then lead - # to duplicate key errors when jobs are retried. - MergeRequest.transaction do - attributes = { - iid: pull_request.iid, - title: pull_request.truncated_title, - description: description, - source_project_id: project.id, - target_project_id: project.id, - source_branch: pull_request.formatted_source_branch, - target_branch: pull_request.target_branch, - state: pull_request.state, - milestone_id: milestone_finder.id_for(pull_request), - author_id: author_id, - assignee_id: user_finder.assignee_id_for(pull_request), - created_at: pull_request.created_at, - updated_at: pull_request.updated_at - } - - # When creating merge requests there are a lot of hooks that may - # run, for many different reasons. Many of these hooks (e.g. the - # ones used for rendering Markdown) are completely unnecessary and - # may even lead to transaction timeouts. - # - # To ensure importing pull requests has a minimal impact and can - # complete in a reasonable time we bypass all the hooks by inserting - # the row and then retrieving it. We then only perform the - # additional work that is strictly necessary. - merge_request_id = GithubImport - .insert_and_return_id(attributes, project.merge_requests) - - merge_request = project.merge_requests.find(merge_request_id) - - # We use .insert_and_return_id which effectively disables all callbacks. - # Trigger iid logic here to make sure we track internal id values consistently. - merge_request.ensure_target_project_iid! + attributes = { + iid: pull_request.iid, + title: pull_request.truncated_title, + description: description, + source_project_id: project.id, + target_project_id: project.id, + source_branch: pull_request.formatted_source_branch, + target_branch: pull_request.target_branch, + state: pull_request.state, + milestone_id: milestone_finder.id_for(pull_request), + author_id: author_id, + assignee_id: user_finder.assignee_id_for(pull_request), + created_at: pull_request.created_at, + updated_at: pull_request.updated_at + } - [merge_request, false] - end - rescue ActiveRecord::InvalidForeignKey - # It's possible the project has been deleted since scheduling this - # job. In this case we'll just skip creating the merge request. - [] - rescue ActiveRecord::RecordNotUnique - # It's possible we previously created the MR, but failed when updating - # the Git data. In this case we'll just continue working on the - # existing row. - [project.merge_requests.find_by(iid: pull_request.iid), true] + create_merge_request_without_hooks(project, attributes, pull_request.iid) end - def insert_git_data(merge_request, already_exists = false) - # These fields are set so we can create the correct merge request - # diffs. - merge_request.source_branch_sha = pull_request.source_branch_sha - merge_request.target_branch_sha = pull_request.target_branch_sha - - merge_request.keep_around_commit - - # MR diffs normally use an "after_save" hook to pull data from Git. - # All of this happens in the transaction started by calling - # create/save/etc. This in turn can lead to these transactions being - # held open for much longer than necessary. To work around this we - # first save the diff, then populate it. - diff = - if already_exists - merge_request.merge_request_diffs.take || - merge_request.merge_request_diffs.build - else - merge_request.merge_request_diffs.build - end - - diff.importing = true - diff.save - diff.save_git_content + def insert_git_data(merge_request, already_exists) + insert_or_replace_git_data(merge_request, pull_request.source_branch_sha, pull_request.target_branch_sha, already_exists) end end end diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb index b8213929c6a..7346eab9e76 100644 --- a/lib/gitlab/i18n.rb +++ b/lib/gitlab/i18n.rb @@ -5,6 +5,7 @@ module Gitlab AVAILABLE_LANGUAGES = { 'en' => 'English', 'es' => 'Español', + 'gl_ES' => 'Galego', 'de' => 'Deutsch', 'fr' => 'Français', 'pt_BR' => 'Português (Brasil)', diff --git a/lib/gitlab/import/database_helpers.rb b/lib/gitlab/import/database_helpers.rb new file mode 100644 index 00000000000..80857061933 --- /dev/null +++ b/lib/gitlab/import/database_helpers.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Gitlab + module Import + module DatabaseHelpers + # Inserts a raw row and returns the ID of the inserted row. + # + # attributes - The attributes/columns to set. + # relation - An ActiveRecord::Relation to use for finding the ID of the row + # when using MySQL. + def insert_and_return_id(attributes, relation) + # We use bulk_insert here so we can bypass any queries executed by + # callbacks or validation rules, as doing this wouldn't scale when + # importing very large projects. + result = Gitlab::Database + .bulk_insert(relation.table_name, [attributes], return_ids: true) + + # MySQL doesn't support returning the IDs of a bulk insert in a way that + # is not a pain, so in this case we'll issue an extra query instead. + result.first || + relation.where(iid: attributes[:iid]).limit(1).pluck(:id).first + end + end + end +end diff --git a/lib/gitlab/import/merge_request_creator.rb b/lib/gitlab/import/merge_request_creator.rb new file mode 100644 index 00000000000..a01951b0762 --- /dev/null +++ b/lib/gitlab/import/merge_request_creator.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# This module is designed for importers that need to create many merge +# requests quickly. When creating merge requests there are a lot of hooks +# that may run, for many different reasons. Many of these hooks (e.g. the ones +# used for rendering Markdown) are completely unnecessary and may even lead to +# transaction timeouts. +# +# To ensure importing merge requests requests has a minimal impact and can +# complete in a reasonable time we bypass all the hooks by inserting the row +# and then retrieving it. We then only perform the additional work that is +# strictly necessary. +module Gitlab + module Import + class MergeRequestCreator + include ::Gitlab::Import::DatabaseHelpers + include ::Gitlab::Import::MergeRequestHelpers + + attr_accessor :project + + def initialize(project) + @project = project + end + + def execute(attributes) + source_branch_sha = attributes.delete(:source_branch_sha) + target_branch_sha = attributes.delete(:target_branch_sha) + iid = attributes[:iid] + + merge_request, already_exists = create_merge_request_without_hooks(project, attributes, iid) + + if merge_request + insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists) + end + + merge_request + end + end + end +end diff --git a/lib/gitlab/import/merge_request_helpers.rb b/lib/gitlab/import/merge_request_helpers.rb new file mode 100644 index 00000000000..8ba70700dc1 --- /dev/null +++ b/lib/gitlab/import/merge_request_helpers.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Gitlab + module Import + module MergeRequestHelpers + include DatabaseHelpers + + def create_merge_request_without_hooks(project, attributes, iid) + # This work must be wrapped in a transaction as otherwise we can leave + # behind incomplete data in the event of an error. This can then lead + # to duplicate key errors when jobs are retried. + MergeRequest.transaction do + # When creating merge requests there are a lot of hooks that may + # run, for many different reasons. Many of these hooks (e.g. the + # ones used for rendering Markdown) are completely unnecessary and + # may even lead to transaction timeouts. + # + # To ensure importing pull requests has a minimal impact and can + # complete in a reasonable time we bypass all the hooks by inserting + # the row and then retrieving it. We then only perform the + # additional work that is strictly necessary. + merge_request_id = insert_and_return_id(attributes, project.merge_requests) + + merge_request = project.merge_requests.find(merge_request_id) + + # We use .insert_and_return_id which effectively disables all callbacks. + # Trigger iid logic here to make sure we track internal id values consistently. + merge_request.ensure_target_project_iid! + + [merge_request, false] + end + rescue ActiveRecord::InvalidForeignKey + # It's possible the project has been deleted since scheduling this + # job. In this case we'll just skip creating the merge request. + [] + rescue ActiveRecord::RecordNotUnique + # It's possible we previously created the MR, but failed when updating + # the Git data. In this case we'll just continue working on the + # existing row. + [project.merge_requests.find_by(iid: iid), true] + end + + def insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists = false) + # These fields are set so we can create the correct merge request + # diffs. + merge_request.source_branch_sha = source_branch_sha + merge_request.target_branch_sha = target_branch_sha + + merge_request.keep_around_commit + + # MR diffs normally use an "after_save" hook to pull data from Git. + # All of this happens in the transaction started by calling + # create/save/etc. This in turn can lead to these transactions being + # held open for much longer than necessary. To work around this we + # first save the diff, then populate it. + diff = + if already_exists + merge_request.merge_request_diffs.take || + merge_request.merge_request_diffs.build + else + merge_request.merge_request_diffs.build + end + + diff.importing = true + diff.save + diff.save_git_content + end + end + end +end diff --git a/lib/gitlab/import_export/uploads_manager.rb b/lib/gitlab/import_export/uploads_manager.rb index 07875ebb56a..e0d4235e65b 100644 --- a/lib/gitlab/import_export/uploads_manager.rb +++ b/lib/gitlab/import_export/uploads_manager.rb @@ -13,13 +13,11 @@ module Gitlab end def save - copy_files(@from, uploads_export_path) if File.directory?(@from) - if File.file?(@from) && @relative_export_path == 'avatar' copy_files(@from, File.join(uploads_export_path, @project.avatar.filename)) end - copy_from_object_storage + copy_project_uploads true rescue => e @@ -48,14 +46,19 @@ module Gitlab UploadService.new(@project, File.open(upload, 'r'), FileUploader, uploader_context).execute end - def copy_from_object_storage - return unless Gitlab::ImportExport.object_storage? - + def copy_project_uploads each_uploader do |uploader| next unless uploader.file - next if uploader.upload.local? # Already copied, using the old method - download_and_copy(uploader) + if uploader.upload.local? + next unless uploader.upload.exist? + + copy_files(uploader.absolute_path, File.join(uploads_export_path, uploader.upload.path)) + else + next unless Gitlab::ImportExport.object_storage? + + download_and_copy(uploader) + end end end diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb index 18f91db98fc..3d588918adf 100644 --- a/lib/gitlab/middleware/multipart.rb +++ b/lib/gitlab/middleware/multipart.rb @@ -82,9 +82,13 @@ module Gitlab end def open_file(params, key) - ::UploadedFile.from_params( - params, key, - [FileUploader.root, Gitlab.config.uploads.storage_path]) + allowed_paths = [ + FileUploader.root, + Gitlab.config.uploads.storage_path, + File.join(Rails.root, 'public/uploads/tmp') + ] + + ::UploadedFile.from_params(params, key, allowed_paths) end end diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb index 61653044433..359dd2bcbc7 100644 --- a/lib/gitlab/path_regex.rb +++ b/lib/gitlab/path_regex.rb @@ -40,6 +40,7 @@ module Gitlab invites jwt koding + login notification_settings oauth profile diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb index 38be75b7482..3b483f27e70 100644 --- a/lib/gitlab/url_blocker.rb +++ b/lib/gitlab/url_blocker.rb @@ -31,6 +31,7 @@ module Gitlab validate_localhost!(addrs_info) unless allow_localhost validate_local_network!(addrs_info) unless allow_local_network + validate_link_local!(addrs_info) unless allow_local_network true end @@ -89,6 +90,13 @@ module Gitlab raise BlockedUrlError, "Requests to the local network are not allowed" end + def validate_link_local!(addrs_info) + netmask = IPAddr.new('169.254.0.0/16') + return unless addrs_info.any? { |addr| addr.ipv6_linklocal? || netmask.include?(addr.ip_address) } + + raise BlockedUrlError, "Requests to the link local network are not allowed" + end + def internal?(uri) internal_web?(uri) || internal_shell?(uri) end diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 22c9638ecc0..7797bd5fab2 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -34,6 +34,7 @@ module Gitlab def system_usage_data { counts: { + assignee_lists: List.assignee.count, boards: Board.count, ci_builds: ::Ci::Build.count, ci_internal_pipelines: ::Ci::Pipeline.internal.count, @@ -61,9 +62,11 @@ module Gitlab groups: Group.count, issues: Issue.count, keys: Key.count, + label_lists: List.label.count, labels: Label.count, lfs_objects: LfsObject.count, merge_requests: MergeRequest.count, + milestone_lists: List.milestone.count, milestones: Milestone.count, notes: Note.count, pages_domains: PagesDomain.count, diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake index f431352b61e..a497d26312e 100644 --- a/lib/tasks/gettext.rake +++ b/lib/tasks/gettext.rake @@ -82,7 +82,7 @@ namespace :gettext do # `gettext:find` writes touches to temp files to `stderr` which would cause # `static-analysis` to report failures. We can ignore these. - silence_stream($stderr) do + silence_sdterr do Rake::Task['gettext:find'].invoke end @@ -118,4 +118,15 @@ namespace :gettext do end end end + + def silence_sdterr(&block) + old_stderr = $stderr.dup + $stderr.reopen(File::NULL) + $stderr.sync = true + + yield + ensure + $stderr.reopen(old_stderr) + old_stderr.close + end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 73bff79aabe..ce5d82d479b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2391,6 +2391,18 @@ msgstr "" msgid "Enter in your Bitbucket Server URL and personal access token below" msgstr "" +msgid "Enter the issue description" +msgstr "" + +msgid "Enter the issue title" +msgstr "" + +msgid "Enter the merge request description" +msgstr "" + +msgid "Enter the merge request title" +msgstr "" + msgid "Environments" msgstr "" @@ -2508,6 +2520,12 @@ msgstr "" msgid "Error loading project data. Please try again." msgstr "" +msgid "Error loading template types." +msgstr "" + +msgid "Error loading template." +msgstr "" + msgid "Error occurred when toggling the notification subscription" msgstr "" @@ -3614,10 +3632,10 @@ msgstr "" msgid "Milestones" msgstr "" -msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} from this project and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered." +msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered." msgstr "" -msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} from this project. %{milestoneTitle} is not currently used in any issues or merge requests." +msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests." msgstr "" msgid "Milestones|Delete milestone" @@ -5044,6 +5062,9 @@ msgstr "" msgid "Settings" msgstr "" +msgid "Setup a %{type} Runner manually" +msgstr "" + msgid "Setup a specific Runner automatically" msgstr "" @@ -5471,6 +5492,9 @@ msgstr "" msgid "The collection of events added to the data gathered for that stage." msgstr "" +msgid "The deployment of this job to %{environmentLink} did not succeed." +msgstr "" + msgid "The fork relationship has been removed." msgstr "" @@ -5546,6 +5570,9 @@ msgstr "" msgid "The time taken by each data entry gathered by that stage." msgstr "" +msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination." +msgstr "" + msgid "The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side." msgstr "" @@ -5651,6 +5678,18 @@ msgstr "" msgid "This job has not started yet" msgstr "" +msgid "This job is an out-of-date deployment to %{environmentLink}." +msgstr "" + +msgid "This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}." +msgstr "" + +msgid "This job is creating a deployment to %{environmentLink} and will overwrite the last %{deploymentLink}." +msgstr "" + +msgid "This job is creating a deployment to %{environmentLink}." +msgstr "" + msgid "This job is in pending state and is waiting to be picked by a runner" msgstr "" @@ -5660,6 +5699,9 @@ msgstr "" msgid "This job is stuck, because you don't have any active runners that can run this job." msgstr "" +msgid "This job is the most recent deployment to %{link}." +msgstr "" + msgid "This job requires a manual action" msgstr "" @@ -6700,6 +6742,9 @@ msgstr "" msgid "mrWidget|The source branch has been removed" msgstr "" +msgid "mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch" +msgstr "" + msgid "mrWidget|The source branch is being removed" msgstr "" diff --git a/package.json b/package.json index f5fc759f76e..17ff85c9cd0 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js" }, "dependencies": { - "@gitlab-org/gitlab-svgs": "^1.27.0", + "@gitlab-org/gitlab-svgs": "^1.28.0", "@gitlab-org/gitlab-ui": "1.0.5", "autosize": "^4.0.0", "axios": "^0.17.1", @@ -83,6 +83,7 @@ module QA # Test scenario entrypoints. # module Test + autoload :Instance, 'qa/scenario/test/instance' module Instance autoload :All, 'qa/scenario/test/instance/all' autoload :Smoke, 'qa/scenario/test/instance/smoke' diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb index 36567927194..1a410a0f8a5 100644 --- a/qa/qa/page/project/import/github.rb +++ b/qa/qa/page/project/import/github.rb @@ -14,7 +14,7 @@ module QA element :project_import_row, 'data: { qa: { repo_path: repo.full_name } }' element :project_namespace_select element :project_namespace_field, 'select_tag :namespace_id' - element :project_path_field, 'text_field_tag :path, repo.name' + element :project_path_field, 'text_field_tag :path, sanitize_project_name(repo.name)' element :import_button, "_('Import')" end diff --git a/qa/qa/scenario/template.rb b/qa/qa/scenario/template.rb index 66eb86f25c8..a87d925ce32 100644 --- a/qa/qa/scenario/template.rb +++ b/qa/qa/scenario/template.rb @@ -21,14 +21,18 @@ module QA def perform(address, *rspec_options) Runtime::Scenario.define(:gitlab_address, address) + ## + # Perform before hooks, which are different for CE and EE + # + Runtime::Release.perform_before_hooks + Specs::Runner.perform do |specs| specs.tty = true - specs.tags = self.class.focus specs.options = if rspec_options.any? rspec_options else - ::File.expand_path('../specs/features', __dir__) + ['--tag', self.class.focus.join(','), '--', ::File.expand_path('../specs/features', __dir__)] end end end diff --git a/qa/qa/scenario/test/instance.rb b/qa/qa/scenario/test/instance.rb new file mode 100644 index 00000000000..a2d503cc015 --- /dev/null +++ b/qa/qa/scenario/test/instance.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module QA + module Scenario + module Test + # This class exists for back-compatibility so that gitlab-qa can continue + # to call Test::Instance instead of Test::Instance::All until at least + # the current latest GitLab version has the Test::Instance::All class. + # As of Aug, 22nd 2018. Only GitLab >= 11.3 has this class. + module Instance + include Bootable + + def self.perform(*args) + self.tap do |scenario| + yield scenario if block_given? + break scenario.do_perform(*args) + end + end + + def self.do_perform(address, *rspec_options) + Runtime::Scenario.define(:gitlab_address, address) + + ## + # Perform before hooks, which are different for CE and EE + # + Runtime::Release.perform_before_hooks + + Specs::Runner.perform do |specs| + specs.tty = true + specs.options = + if rspec_options.any? + rspec_options + else + ['--', ::File.expand_path('../../specs/features', __dir__)] + end + end + end + end + end + end +end diff --git a/qa/qa/scenario/test/integration/github.rb b/qa/qa/scenario/test/integration/github.rb index 1d22b532aa5..76c3923d68a 100644 --- a/qa/qa/scenario/test/integration/github.rb +++ b/qa/qa/scenario/test/integration/github.rb @@ -2,7 +2,7 @@ module QA module Scenario module Test module Integration - class Github < Test::Instance + class Github < Test::Instance::All tags :github def perform(address, *rspec_options) diff --git a/qa/qa/scenario/test/integration/kubernetes.rb b/qa/qa/scenario/test/integration/kubernetes.rb index 7479073e979..405962caeed 100644 --- a/qa/qa/scenario/test/integration/kubernetes.rb +++ b/qa/qa/scenario/test/integration/kubernetes.rb @@ -2,7 +2,7 @@ module QA module Scenario module Test module Integration - class Kubernetes < Test::Instance + class Kubernetes < Test::Instance::All tags :kubernetes end end diff --git a/qa/qa/scenario/test/integration/ldap.rb b/qa/qa/scenario/test/integration/ldap.rb index 257ed81d9e1..769fa389785 100644 --- a/qa/qa/scenario/test/integration/ldap.rb +++ b/qa/qa/scenario/test/integration/ldap.rb @@ -2,7 +2,7 @@ module QA module Scenario module Test module Integration - class LDAP < Test::Instance + class LDAP < Test::Instance::All tags :ldap end end diff --git a/qa/qa/scenario/test/integration/mattermost.rb b/qa/qa/scenario/test/integration/mattermost.rb index 13bfad28b0b..831c6a9fcff 100644 --- a/qa/qa/scenario/test/integration/mattermost.rb +++ b/qa/qa/scenario/test/integration/mattermost.rb @@ -6,7 +6,7 @@ module QA # Run test suite against any GitLab instance where mattermost is enabled, # including staging and on-premises installation. # - class Mattermost < Test::Instance + class Mattermost < Test::Instance::All tags :core, :mattermost def perform(address, mattermost, *rspec_options) diff --git a/qa/qa/specs/features/api/1_manage/.gitkeep b/qa/qa/specs/features/api/1_manage/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/1_manage/.gitkeep diff --git a/qa/qa/specs/features/api/users_spec.rb b/qa/qa/specs/features/api/1_manage/users_spec.rb index 3d25cca1e59..3e3c9e859aa 100644 --- a/qa/qa/specs/features/api/users_spec.rb +++ b/qa/qa/specs/features/api/1_manage/users_spec.rb @@ -1,19 +1,21 @@ +# frozen_string_literal: true + module QA - describe 'API users' do - before(:context) do - @api_client = Runtime::API::Client.new(:gitlab) - end + context :manage do + describe 'Users API' do + before(:context) do + @api_client = Runtime::API::Client.new(:gitlab) + end - context 'when authenticated' do let(:request) { Runtime::API::Request.new(@api_client, '/users') } - it 'get list of users' do + it 'GET /users' do get request.url expect_status(200) end - it 'submit request with a valid user name' do + it 'GET /users/:username with a valid username' do get request.url, { params: { username: Runtime::User.username } } expect_status(200) @@ -22,20 +24,12 @@ module QA ) end - it 'submit request with an invalid user name' do + it 'GET /users/:username with an invalid username' do get request.url, { params: { username: SecureRandom.hex(10) } } expect_status(200) expect(json_body).to eq([]) end end - - it 'submit request with an invalid token' do - request = Runtime::API::Request.new(@api_client, '/users', private_token: 'invalid') - - get request.url - - expect_status(401) - end end end diff --git a/qa/qa/specs/features/api/2_plan/.gitkeep b/qa/qa/specs/features/api/2_plan/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/2_plan/.gitkeep diff --git a/qa/qa/specs/features/api/basics_spec.rb b/qa/qa/specs/features/api/3_create/repository/files_spec.rb index bc0b5ebfe10..bc0b5ebfe10 100644 --- a/qa/qa/specs/features/api/basics_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/files_spec.rb diff --git a/qa/qa/specs/features/api/4_verify/.gitkeep b/qa/qa/specs/features/api/4_verify/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/4_verify/.gitkeep diff --git a/qa/qa/specs/features/api/5_package/.gitkeep b/qa/qa/specs/features/api/5_package/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/5_package/.gitkeep diff --git a/qa/qa/specs/features/api/6_release/.gitkeep b/qa/qa/specs/features/api/6_release/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/6_release/.gitkeep diff --git a/qa/qa/specs/features/api/7_configure/.gitkeep b/qa/qa/specs/features/api/7_configure/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/api/7_configure/.gitkeep diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb new file mode 100644 index 00000000000..1c7da930567 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb @@ -0,0 +1,17 @@ +module QA + context :manage, :smoke do + describe 'basic user login' do + it 'user logs in using basic credentials' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + # TODO, since `Signed in successfully` message was removed + # this is the only way to tell if user is signed in correctly. + # + Page::Menu::Main.perform do |menu| + expect(menu).to have_personal_area + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb new file mode 100644 index 00000000000..c9958917be9 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module QA + context :manage, :orchestrated, :ldap do + describe 'LDAP login' do + before do + Runtime::Env.user_type = 'ldap' + end + + it 'user logs into GitLab using LDAP credentials' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + # TODO, since `Signed in successfully` message was removed + # this is the only way to tell if user is signed in correctly. + # + Page::Menu::Main.perform do |menu| + expect(menu).to have_personal_area + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb new file mode 100644 index 00000000000..6eda2c750d4 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module QA + context :manage, :orchestrated, :mattermost do + describe 'Mattermost login' do + it 'user logs into Mattermost using GitLab OAuth' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) do + Page::Main::Login.act { sign_in_using_credentials } + + Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) do + Page::Mattermost::Login.act { sign_in_using_oauth } + + Page::Mattermost::Main.perform do |page| + expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/) + end + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb new file mode 100644 index 00000000000..bb1f3ab26d1 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module QA + context :manage, :smoke do + describe 'Project creation' do + it 'user creates a new project' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + created_project = Factory::Resource::Project.fabricate! do |project| + project.name = 'awesome-project' + project.description = 'create awesome project test' + end + + expect(created_project.name).to match /^awesome-project-\h{16}$/ + + expect(page).to have_content( + /Project \S?awesome-project\S+ was successfully created/ + ) + + expect(page).to have_content('create awesome project test') + expect(page).to have_content('The repository for this project is empty') + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb new file mode 100644 index 00000000000..2ef8de61441 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +module QA + context :manage, :orchestrated, :github do + describe 'Project import from GitHub' do + let(:imported_project) do + Factory::Resource::ProjectImportedFromGithub.fabricate! do |project| + project.name = 'imported-project' + project.personal_access_token = Runtime::Env.github_access_token + project.github_repository_path = 'gitlab-qa/test-project' + end + end + + after do + # We need to delete the imported project because it's impossible to import + # the same GitHub project twice for a given user. + api_client = Runtime::API::Client.new(:gitlab) + delete_project_request = Runtime::API::Request.new(api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{imported_project.name}")}") + delete delete_project_request.url + + expect_status(202) + end + + it 'user imports a GitHub repo' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + imported_project # import the project + + Page::Menu::Main.act { go_to_projects } + Page::Dashboard::Projects.perform do |dashboard| + dashboard.go_to_project(imported_project.name) + end + + Page::Project::Show.act { wait_for_import } + + verify_repository_import + verify_issues_import + verify_merge_requests_import + verify_labels_import + verify_milestones_import + verify_wiki_import + end + + def verify_repository_import + expect(page).to have_content('This test project is used for automated GitHub import by GitLab QA.') + expect(page).to have_content(imported_project.name) + end + + def verify_issues_import + Page::Menu::Side.act { click_issues } + expect(page).to have_content('This is a sample issue') + + click_link 'This is a sample issue' + + expect(page).to have_content('We should populate this project with issues, pull requests and wiki pages.') + + # Comments + expect(page).to have_content('This is a comment from @rymai.') + + Page::Issuable::Sidebar.perform do |issuable| + expect(issuable).to have_label('enhancement') + expect(issuable).to have_label('help wanted') + expect(issuable).to have_label('good first issue') + end + end + + def verify_merge_requests_import + Page::Menu::Side.act { click_merge_requests } + expect(page).to have_content('Improve README.md') + + click_link 'Improve README.md' + + expect(page).to have_content('This improves the README file a bit.') + + # Review comment are not supported yet + expect(page).not_to have_content('Really nice change.') + + # Comments + expect(page).to have_content('Nice work! This is a comment from @rymai.') + + # Diff comments + expect(page).to have_content('[Review comment] I like that!') + expect(page).to have_content('[Review comment] Nice blank line.') + expect(page).to have_content('[Single diff comment] Much better without this line!') + + Page::Issuable::Sidebar.perform do |issuable| + expect(issuable).to have_label('bug') + expect(issuable).to have_label('enhancement') + end + end + + def verify_labels_import + # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19228 + # to build upon it. + end + + def verify_milestones_import + # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18727 + # to build upon it. + end + + def verify_wiki_import + Page::Menu::Side.act { click_wiki } + + expect(page).to have_content('Welcome to the test-project wiki!') + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb new file mode 100644 index 00000000000..34bb6f1c197 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module QA + context :manage do + describe 'Project activity' do + it 'user creates an event in the activity page upon Git push' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + Factory::Repository::ProjectPush.fabricate! do |push| + push.file_name = 'README.md' + push.file_content = '# This is a test project' + push.commit_message = 'Add README.md' + end + + Page::Menu::Side.act { go_to_activity } + + Page::Project::Activity.act { go_to_push_events } + + expect(page).to have_content('pushed new branch master') + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb new file mode 100644 index 00000000000..1e110c331f7 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module QA + context :plan, :smoke do + describe 'Issue creation' do + let(:issue_title) { 'issue title' } + + def create_issue + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + Factory::Resource::Issue.fabricate! do |issue| + issue.title = issue_title + end + end + + it 'user creates an issue' do + create_issue + + Page::Menu::Side.act { click_issues } + + expect(page).to have_content(issue_title) + end + + context 'when using attachements in comments', :object_storage do + let(:file_to_attach) do + File.absolute_path(File.join('spec', 'fixtures', 'banana_sample.gif')) + end + + it 'user comments on an issue with an attachment' do + create_issue + + Page::Project::Issue::Show.perform do |show| + show.comment('See attached banana for scale', attachment: file_to_attach) + + show.refresh + + image_url = find('a[href$="banana_sample.gif"]')[:href] + + found = show.wait(reload: false) do + show.asset_exists?(image_url) + end + + expect(found).to be_truthy + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb new file mode 100644 index 00000000000..bcf55a02a61 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Merge request creation' do + it 'user creates a new merge request' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + current_project = Factory::Resource::Project.fabricate! do |project| + project.name = 'project-with-merge-request-and-milestone' + end + + current_milestone = Factory::Resource::ProjectMilestone.fabricate! do |milestone| + milestone.title = 'unique-milestone' + milestone.project = current_project + end + + Factory::Resource::MergeRequest.fabricate! do |merge_request| + merge_request.title = 'This is a merge request with a milestone' + merge_request.description = 'Great feature with milestone' + merge_request.project = current_project + merge_request.milestone = current_milestone + end + + expect(page).to have_content('This is a merge request with a milestone') + expect(page).to have_content('Great feature with milestone') + expect(page).to have_content(/Opened [\w\s]+ ago/) + + Page::Issuable::Sidebar.perform do |sidebar| + expect(sidebar).to have_milestone(current_milestone.title) + end + end + end + end + + describe 'creates a merge request', :smoke do + it 'user creates a new merge request' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + current_project = Factory::Resource::Project.fabricate! do |project| + project.name = 'project-with-merge-request' + end + + Factory::Resource::MergeRequest.fabricate! do |merge_request| + merge_request.title = 'This is a merge request' + merge_request.description = 'Great feature' + merge_request.project = current_project + end + + expect(page).to have_content('This is a merge request') + expect(page).to have_content('Great feature') + expect(page).to have_content(/Opened [\w\s]+ ago/) + end + end +end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb new file mode 100644 index 00000000000..407a15800ab --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Merge request creation from fork' do + it 'user forks a project, submits a merge request and maintainer merges it' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + merge_request = Factory::Resource::MergeRequestFromFork.fabricate! do |merge_request| + merge_request.fork_branch = 'feature-branch' + end + + Page::Menu::Main.perform { |main| main.sign_out } + Page::Main::Login.perform { |login| login.sign_in_using_credentials } + + merge_request.visit! + + Page::MergeRequest::Show.perform { |show| show.merge! } + + expect(page).to have_content('The changes were merged') + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb new file mode 100644 index 00000000000..ddcbc94b1b1 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Merge request rebasing' do + it 'user rebases source branch of merge request' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + project = Factory::Resource::Project.fabricate! do |project| + project.name = "only-fast-forward" + end + + Page::Menu::Side.act { go_to_settings } + Page::Project::Settings::MergeRequest.act { enable_ff_only } + + merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request| + merge_request.project = project + merge_request.title = 'Needs rebasing' + end + + Factory::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.file_name = "other.txt" + push.file_content = "New file added!" + push.branch_name = "master" + push.new_branch = false + end + + merge_request.visit! + + Page::MergeRequest::Show.perform do |merge_request| + expect(merge_request).to have_content('Needs rebasing') + expect(merge_request).not_to be_fast_forward_possible + expect(merge_request).not_to have_merge_button + + merge_request.rebase! + + expect(merge_request).to have_merge_button + expect(merge_request.fast_forward_possible?).to be_truthy + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb new file mode 100644 index 00000000000..b5b8855a35d --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Merge request squashing' do + it 'user squashes commits while merging' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + project = Factory::Resource::Project.fabricate! do |project| + project.name = "squash-before-merge" + end + + merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request| + merge_request.project = project + merge_request.title = 'Squashing commits' + end + + Factory::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.commit_message = 'to be squashed' + push.branch_name = merge_request.source_branch + push.new_branch = false + push.file_name = 'other.txt' + push.file_content = "Test with unicode characters ❤✓€❄" + end + + merge_request.visit! + + expect(page).to have_text('to be squashed') + + Page::MergeRequest::Show.perform do |merge_request_page| + merge_request_page.mark_to_squash + merge_request_page.merge! + + merge_request.project.visit! + + Git::Repository.perform do |repository| + repository.uri = Page::Project::Show.act do + choose_repository_clone_http + repository_location.uri + end + + repository.use_default_credentials + + repository.act { clone } + + expect(repository.commits.size).to eq 3 + end + end + end + end + end +end diff --git a/qa/qa/specs/features/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb index 8b0613c5f78..b19bdd950fa 100644 --- a/qa/qa/specs/features/repository/clone_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + module QA - describe 'clone code from the repository' do - context 'with regular account over http' do + context :create do + describe 'Git clone over HTTP' do let(:location) do Page::Project::Show.act do choose_repository_clone_http diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb new file mode 100644 index 00000000000..f18655442c1 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module QA + context :create, :core do + describe 'Files management' do + it 'user creates, edits and deletes a file via the Web' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + # Create + file_name = 'QA Test - File name' + file_content = 'QA Test - File content' + commit_message_for_create = 'QA Test - Create new file' + + Factory::Resource::File.fabricate! do |file| + file.name = file_name + file.content = file_content + file.commit_message = commit_message_for_create + end + + expect(page).to have_content('The file has been successfully created.') + expect(page).to have_content(file_name) + expect(page).to have_content(file_content) + expect(page).to have_content(commit_message_for_create) + + # Edit + updated_file_content = 'QA Test - Updated file content' + commit_message_for_update = 'QA Test - Update file' + + Page::File::Show.act { click_edit } + + Page::File::Form.act do + remove_content + add_content(updated_file_content) + add_commit_message(commit_message_for_update) + commit_changes + end + + expect(page).to have_content('Your changes have been successfully committed.') + expect(page).to have_content(updated_file_content) + expect(page).to have_content(commit_message_for_update) + + # Delete + commit_message_for_delete = 'QA Test - Delete file' + + Page::File::Show.act do + click_delete + add_commit_message(commit_message_for_delete) + click_delete_file + end + + expect(page).to have_content('The file has been successfully deleted.') + expect(page).to have_content(commit_message_for_delete) + expect(page).to have_no_content(file_name) + end + end + end +end diff --git a/qa/qa/specs/features/repository/push_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb index 1e89942e932..40dfd138a1b 100644 --- a/qa/qa/specs/features/repository/push_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + module QA - describe 'push code to repository' do - context 'with regular account over http' do + context :create do + describe 'Git push over HTTP' do it 'user pushes code to the repository' do Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.act { sign_in_using_credentials } diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb new file mode 100644 index 00000000000..1d9cc33080d --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Protected branch support' do + let(:branch_name) { 'protected-branch' } + let(:commit_message) { 'Protected push commit message' } + let(:project) do + Factory::Resource::Project.fabricate! do |resource| + resource.name = 'protected-branch-project' + end + end + + before do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + end + + after do + # We need to clear localStorage because we're using it for the dropdown, + # and capybara doesn't do this for us. + # https://github.com/teamcapybara/capybara/issues/1702 + Capybara.execute_script 'localStorage.clear()' + end + + context 'when developers and maintainers are allowed to push to a protected branch' do + it 'user with push rights successfully pushes to the protected branch' do + create_protected_branch(allow_to_push: true) + + push = push_new_file(branch_name) + + expect(push.output).to match(/remote: To create a merge request for protected-branch, visit/) + end + end + + context 'when developers and maintainers are not allowed to push to a protected branch' do + it 'user without push rights fails to push to the protected branch' do + create_protected_branch(allow_to_push: false) + + push = push_new_file(branch_name) + + expect(push.output) + .to match(/remote\: GitLab\: You are not allowed to push code to protected branches on this project/) + expect(push.output) + .to match(/\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/) + end + end + + def create_protected_branch(allow_to_push:) + Factory::Resource::Branch.fabricate! do |resource| + resource.branch_name = branch_name + resource.project = project + resource.allow_to_push = allow_to_push + resource.protected = true + end + end + + def push_new_file(branch) + Factory::Repository::ProjectPush.fabricate! do |resource| + resource.project = project + resource.file_name = 'new_file.md' + resource.file_content = '# This is a new file' + resource.commit_message = 'Add new_file.md' + resource.branch_name = branch_name + resource.new_branch = false + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb new file mode 100644 index 00000000000..8009b9e8609 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module QA + context :create do + describe 'Wiki management' do + def login + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + end + + def validate_content(content) + expect(page).to have_content('Wiki was successfully updated') + expect(page).to have_content(/#{content}/) + end + + before do + login + end + + it 'user creates, edits, clones, and pushes to the wiki' do + wiki = Factory::Resource::Wiki.fabricate! do |resource| + resource.title = 'Home' + resource.content = '# My First Wiki Content' + resource.message = 'Update home' + end + + validate_content('My First Wiki Content') + + Page::Project::Wiki::Edit.act { go_to_edit_page } + Page::Project::Wiki::New.perform do |page| + page.set_content("My Second Wiki Content") + page.save_changes + end + + validate_content('My Second Wiki Content') + + Factory::Repository::WikiPush.fabricate! do |push| + push.wiki = wiki + push.file_name = 'Home.md' + push.file_content = '# My Third Wiki Content' + push.commit_message = 'Update Home.md' + end + Page::Menu::Side.act { click_wiki } + + expect(page).to have_content('My Third Wiki Content') + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb new file mode 100644 index 00000000000..cdfe9b90e15 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module QA + context :verify, :orchestrated, :docker do + describe 'Pipeline creation and processing' do + let(:executor) { "qa-runner-#{Time.now.to_i}" } + + after do + Service::Runner.new(executor).remove! + end + + it 'users creates a pipeline which gets processed' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + project = Factory::Resource::Project.fabricate! do |project| + project.name = 'project-with-pipelines' + project.description = 'Project with CI/CD Pipelines.' + end + + Factory::Resource::Runner.fabricate! do |runner| + runner.project = project + runner.name = executor + runner.tags = %w[qa test] + end + + Factory::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.file_name = '.gitlab-ci.yml' + push.commit_message = 'Add .gitlab-ci.yml' + push.file_content = <<~EOF + test-success: + tags: + - qa + - test + script: echo 'OK' + + test-failure: + tags: + - qa + - test + script: + - echo 'FAILURE' + - exit 1 + + test-tags: + tags: + - qa + - docker + script: echo 'NOOP' + + test-artifacts: + tags: + - qa + - test + script: mkdir my-artifacts; echo "CONTENTS" > my-artifacts/artifact.txt + artifacts: + paths: + - my-artifacts/ + EOF + end + + Page::Project::Show.act { wait_for_push } + + expect(page).to have_content('Add .gitlab-ci.yml') + + Page::Menu::Side.act { click_ci_cd_pipelines } + + expect(page).to have_content('All 1') + expect(page).to have_content('Add .gitlab-ci.yml') + + puts 'Waiting for the runner to process the pipeline' + sleep 15 # Runner should process all jobs within 15 seconds. + + Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + + Page::Project::Pipeline::Show.perform do |pipeline| + expect(pipeline).to be_running + expect(pipeline).to have_build('test-success', status: :success) + expect(pipeline).to have_build('test-failure', status: :failed) + expect(pipeline).to have_build('test-tags', status: :pending) + expect(pipeline).to have_build('test-artifacts', status: :success) + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb new file mode 100644 index 00000000000..8d83a20f5bf --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module QA + context :verify, :docker do + describe 'Runner registration' do + let(:executor) { "qa-runner-#{Time.now.to_i}" } + + after do + Service::Runner.new(executor).remove! + end + + it 'user registers a new specific runner' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + Factory::Resource::Runner.fabricate! do |runner| + runner.name = executor + end + + Page::Project::Settings::CICD.perform do |settings| + sleep 5 # Runner should register within 5 seconds + settings.refresh + + settings.expand_runners_settings do |page| + expect(page).to have_content(executor) + expect(page).to have_online_runner + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb new file mode 100644 index 00000000000..08a87df5837 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module QA + context :verify do + describe 'Secret variable support' do + it 'user adds a secret variable' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + Factory::Resource::SecretVariable.fabricate! do |resource| + resource.key = 'VARIABLE_KEY' + resource.value = 'some secret variable' + end + + Page::Project::Settings::CICD.perform do |settings| + settings.expand_secret_variables do |page| + expect(page).to have_field(with: 'VARIABLE_KEY') + expect(page).not_to have_field(with: 'some secret variable') + + page.reveal_variables + + expect(page).to have_field(with: 'some secret variable') + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/.gitkeep b/qa/qa/specs/features/browser_ui/5_package/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/browser_ui/5_package/.gitkeep diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb new file mode 100644 index 00000000000..17dfa887434 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module QA + context :release do + describe 'Deploy key creation' do + it 'user adds a deploy key' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + key = Runtime::Key::RSA.new + deploy_key_title = 'deploy key title' + deploy_key_value = key.public_key + + deploy_key = Factory::Resource::DeployKey.fabricate! do |resource| + resource.title = deploy_key_title + resource.key = deploy_key_value + end + + expect(deploy_key.fingerprint).to eq(key.fingerprint) + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb new file mode 100644 index 00000000000..8352d13b06d --- /dev/null +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require 'digest/sha1' + +module QA + context :release, :docker do + describe 'Git clone using a deploy key' do + def login + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + end + + before(:all) do + login + + @runner_name = "qa-runner-#{Time.now.to_i}" + + @project = Factory::Resource::Project.fabricate! do |resource| + resource.name = 'deploy-key-clone-project' + end + + @repository_location = @project.repository_ssh_location + + Factory::Resource::Runner.fabricate! do |resource| + resource.project = @project + resource.name = @runner_name + resource.tags = %w[qa docker] + resource.image = 'gitlab/gitlab-runner:ubuntu' + end + + Page::Menu::Main.act { sign_out } + end + + after(:all) do + Service::Runner.new(@runner_name).remove! + end + + keys = [ + [Runtime::Key::RSA, 8192], + [Runtime::Key::ECDSA, 521], + [Runtime::Key::ED25519] + ] + + keys.each do |(key_class, bits)| + it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines" do + key = key_class.new(*bits) + + login + + Factory::Resource::DeployKey.fabricate! do |resource| + resource.project = @project + resource.title = "deploy key #{key.name}(#{key.bits})" + resource.key = key.public_key + end + + deploy_key_name = "DEPLOY_KEY_#{key.name}_#{key.bits}" + + Factory::Resource::SecretVariable.fabricate! do |resource| + resource.project = @project + resource.key = deploy_key_name + resource.value = key.private_key + end + + gitlab_ci = <<~YAML + cat-config: + script: + - mkdir -p ~/.ssh + - ssh-keyscan -p #{@repository_location.port} #{@repository_location.host} >> ~/.ssh/known_hosts + - eval $(ssh-agent -s) + - ssh-add -D + - echo "$#{deploy_key_name}" | ssh-add - + - git clone #{@repository_location.git_uri} + - cd #{@project.name} + - git checkout #{deploy_key_name} + - sha1sum .gitlab-ci.yml + tags: + - qa + - docker + YAML + + Factory::Repository::ProjectPush.fabricate! do |resource| + resource.project = @project + resource.file_name = '.gitlab-ci.yml' + resource.commit_message = 'Add .gitlab-ci.yml' + resource.file_content = gitlab_ci + resource.branch_name = deploy_key_name + resource.new_branch = true + end + + sha1sum = Digest::SHA1.hexdigest(gitlab_ci) + + Page::Project::Show.act { wait_for_push } + Page::Menu::Side.act { click_ci_cd_pipelines } + Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Pipeline::Show.act { go_to_first_job } + + Page::Project::Job::Show.perform do |job| + job.wait(reload: false) do + job.completed? && !job.trace_loading? + end + + expect(job.passed?).to be_truthy, "Job status did not become \"passed\"." + expect(job.output).to include(sha1sum) + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb new file mode 100644 index 00000000000..dd24e8ffba5 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'pathname' + +module QA + context :configure, :orchestrated, :kubernetes do + describe 'Auto DevOps support' do + after do + @cluster&.remove! + end + + it 'user creates a new project and runs auto devops' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + + project = Factory::Resource::Project.fabricate! do |p| + p.name = 'project-with-autodevops' + p.description = 'Project with Auto Devops' + end + + # Disable code_quality check in Auto DevOps pipeline as it takes + # too long and times out the test + Factory::Resource::SecretVariable.fabricate! do |resource| + resource.key = 'CODE_QUALITY_DISABLED' + resource.value = '1' + end + + # Create Auto Devops compatible repo + Factory::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.directory = Pathname + .new(__dir__) + .join('../../../fixtures/auto_devops_rack') + push.commit_message = 'Create Auto DevOps compatible rack application' + end + + Page::Project::Show.act { wait_for_push } + + # Create and connect K8s cluster + @cluster = Service::KubernetesCluster.new.create! + kubernetes_cluster = Factory::Resource::KubernetesCluster.fabricate! do |cluster| + cluster.project = project + cluster.cluster = @cluster + cluster.install_helm_tiller = true + cluster.install_ingress = true + cluster.install_prometheus = true + cluster.install_runner = true + end + + project.visit! + Page::Menu::Side.act { click_ci_cd_settings } + Page::Project::Settings::CICD.perform do |p| + p.enable_auto_devops_with_domain("#{kubernetes_cluster.ingress_ip}.nip.io") + end + + project.visit! + Page::Menu::Side.act { click_ci_cd_pipelines } + Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + + Page::Project::Pipeline::Show.perform do |pipeline| + expect(pipeline).to have_build('build', status: :success, wait: 600) + expect(pipeline).to have_build('test', status: :success, wait: 600) + expect(pipeline).to have_build('production', status: :success, wait: 1200) + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb new file mode 100644 index 00000000000..6ffdc55538a --- /dev/null +++ b/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module QA + context :configure, :orchestrated, :mattermost do + describe 'Mattermost support' do + it 'user creates a group with a mattermost team' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + Page::Menu::Main.act { go_to_groups } + + Page::Dashboard::Groups.perform do |page| + page.go_to_new_group + + expect(page).to have_content( + /Create a Mattermost team for this group/ + ) + end + end + end + end +end diff --git a/qa/qa/specs/features/login/basic_spec.rb b/qa/qa/specs/features/login/basic_spec.rb deleted file mode 100644 index f866466c7bf..00000000000 --- a/qa/qa/specs/features/login/basic_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -module QA - describe 'basic user login', :smoke do - it 'user logs in using basic credentials' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - # TODO, since `Signed in successfully` message was removed - # this is the only way to tell if user is signed in correctly. - # - Page::Menu::Main.perform do |menu| - expect(menu).to have_personal_area - end - end - end -end diff --git a/qa/qa/specs/features/login/ldap_spec.rb b/qa/qa/specs/features/login/ldap_spec.rb deleted file mode 100644 index de6111eea64..00000000000 --- a/qa/qa/specs/features/login/ldap_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -module QA - describe 'LDAP user login', :orchestrated, :ldap do - before do - Runtime::Env.user_type = 'ldap' - end - - it 'user logs in using LDAP credentials' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - # TODO, since `Signed in successfully` message was removed - # this is the only way to tell if user is signed in correctly. - # - Page::Menu::Main.perform do |menu| - expect(menu).to have_personal_area - end - end - end -end diff --git a/qa/qa/specs/features/mattermost/group_create_spec.rb b/qa/qa/specs/features/mattermost/group_create_spec.rb deleted file mode 100644 index 097e1713aef..00000000000 --- a/qa/qa/specs/features/mattermost/group_create_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -module QA - describe 'create a new group', :orchestrated, :mattermost do - it 'creating a group with a mattermost team' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - Page::Menu::Main.act { go_to_groups } - - Page::Dashboard::Groups.perform do |page| - page.go_to_new_group - - expect(page).to have_content( - /Create a Mattermost team for this group/ - ) - end - end - end -end diff --git a/qa/qa/specs/features/mattermost/login_spec.rb b/qa/qa/specs/features/mattermost/login_spec.rb deleted file mode 100644 index 27f7d4c245f..00000000000 --- a/qa/qa/specs/features/mattermost/login_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -module QA - describe 'logging in to Mattermost', :orchestrated, :mattermost do - it 'can use gitlab oauth' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) do - Page::Main::Login.act { sign_in_using_credentials } - - Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) do - Page::Mattermost::Login.act { sign_in_using_oauth } - - Page::Mattermost::Main.perform do |page| - expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/) - end - end - end - end - end -end diff --git a/qa/qa/specs/features/merge_request/create_spec.rb b/qa/qa/specs/features/merge_request/create_spec.rb deleted file mode 100644 index 71e79956b85..00000000000 --- a/qa/qa/specs/features/merge_request/create_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -module QA - describe 'creates a merge request with milestone' do - it 'user creates a new merge request' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - current_project = Factory::Resource::Project.fabricate! do |project| - project.name = 'project-with-merge-request-and-milestone' - end - - current_milestone = Factory::Resource::ProjectMilestone.fabricate! do |milestone| - milestone.title = 'unique-milestone' - milestone.project = current_project - end - - Factory::Resource::MergeRequest.fabricate! do |merge_request| - merge_request.title = 'This is a merge request with a milestone' - merge_request.description = 'Great feature with milestone' - merge_request.project = current_project - merge_request.milestone = current_milestone - end - - expect(page).to have_content('This is a merge request with a milestone') - expect(page).to have_content('Great feature with milestone') - expect(page).to have_content(/Opened [\w\s]+ ago/) - - Page::Issuable::Sidebar.perform do |sidebar| - expect(sidebar).to have_milestone(current_milestone.title) - end - end - end - - describe 'creates a merge request', :smoke do - it 'user creates a new merge request' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - current_project = Factory::Resource::Project.fabricate! do |project| - project.name = 'project-with-merge-request' - end - - Factory::Resource::MergeRequest.fabricate! do |merge_request| - merge_request.title = 'This is a merge request' - merge_request.description = 'Great feature' - merge_request.project = current_project - end - - expect(page).to have_content('This is a merge request') - expect(page).to have_content('Great feature') - expect(page).to have_content(/Opened [\w\s]+ ago/) - end - end -end diff --git a/qa/qa/specs/features/merge_request/rebase_spec.rb b/qa/qa/specs/features/merge_request/rebase_spec.rb deleted file mode 100644 index c36d28e4237..00000000000 --- a/qa/qa/specs/features/merge_request/rebase_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -module QA - describe 'merge request rebase' do - it 'rebases source branch of merge request' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - project = Factory::Resource::Project.fabricate! do |project| - project.name = "only-fast-forward" - end - - Page::Menu::Side.act { go_to_settings } - Page::Project::Settings::MergeRequest.act { enable_ff_only } - - merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request| - merge_request.project = project - merge_request.title = 'Needs rebasing' - end - - Factory::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.file_name = "other.txt" - push.file_content = "New file added!" - end - - merge_request.visit! - - Page::MergeRequest::Show.perform do |merge_request| - expect(merge_request).to have_content('Needs rebasing') - expect(merge_request).not_to be_fast_forward_possible - expect(merge_request).not_to have_merge_button - - merge_request.rebase! - - expect(merge_request).to have_merge_button - expect(merge_request.fast_forward_possible?).to be_truthy - end - end - end -end diff --git a/qa/qa/specs/features/merge_request/squash_spec.rb b/qa/qa/specs/features/merge_request/squash_spec.rb deleted file mode 100644 index 3ecc36a5ae1..00000000000 --- a/qa/qa/specs/features/merge_request/squash_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -module QA - describe 'merge request squash commits' do - it 'when squash commits is marked before merge' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - project = Factory::Resource::Project.fabricate! do |project| - project.name = "squash-before-merge" - end - - merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request| - merge_request.project = project - merge_request.title = 'Squashing commits' - end - - Factory::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.commit_message = 'to be squashed' - push.branch_name = merge_request.source_branch - push.new_branch = false - push.file_name = 'other.txt' - push.file_content = "Test with unicode characters ❤✓€❄" - end - - merge_request.visit! - - expect(page).to have_text('to be squashed') - - Page::MergeRequest::Show.perform do |merge_request_page| - merge_request_page.mark_to_squash - merge_request_page.merge! - - merge_request.project.visit! - - Git::Repository.perform do |repository| - repository.uri = Page::Project::Show.act do - choose_repository_clone_http - repository_location.uri - end - - repository.use_default_credentials - - repository.act { clone } - - expect(repository.commits.size).to eq 3 - end - end - end - end -end diff --git a/qa/qa/specs/features/project/activity_spec.rb b/qa/qa/specs/features/project/activity_spec.rb deleted file mode 100644 index c7ce8dfdcc6..00000000000 --- a/qa/qa/specs/features/project/activity_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -module QA - describe 'activity page' do - it 'push creates an event in the activity page' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - Factory::Repository::ProjectPush.fabricate! do |push| - push.file_name = 'README.md' - push.file_content = '# This is a test project' - push.commit_message = 'Add README.md' - end - - Page::Menu::Side.act { go_to_activity } - - Page::Project::Activity.act { go_to_push_events } - - expect(page).to have_content('pushed new branch master') - end - end -end diff --git a/qa/qa/specs/features/project/add_deploy_key_spec.rb b/qa/qa/specs/features/project/add_deploy_key_spec.rb deleted file mode 100644 index 24f9f4c77f8..00000000000 --- a/qa/qa/specs/features/project/add_deploy_key_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -module QA - describe 'deploy keys support' do - it 'user adds a deploy key' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - key = Runtime::Key::RSA.new - deploy_key_title = 'deploy key title' - deploy_key_value = key.public_key - - deploy_key = Factory::Resource::DeployKey.fabricate! do |resource| - resource.title = deploy_key_title - resource.key = deploy_key_value - end - - expect(deploy_key.fingerprint).to eq(key.fingerprint) - end - end -end diff --git a/qa/qa/specs/features/project/add_secret_variable_spec.rb b/qa/qa/specs/features/project/add_secret_variable_spec.rb deleted file mode 100644 index 04d9fe488e2..00000000000 --- a/qa/qa/specs/features/project/add_secret_variable_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -module QA - describe 'secret variables support' do - it 'user adds a secret variable' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - Factory::Resource::SecretVariable.fabricate! do |resource| - resource.key = 'VARIABLE_KEY' - resource.value = 'some secret variable' - end - - Page::Project::Settings::CICD.perform do |settings| - settings.expand_secret_variables do |page| - expect(page).to have_field(with: 'VARIABLE_KEY') - expect(page).not_to have_field(with: 'some secret variable') - - page.reveal_variables - - expect(page).to have_field(with: 'some secret variable') - end - end - end - end -end diff --git a/qa/qa/specs/features/project/auto_devops_spec.rb b/qa/qa/specs/features/project/auto_devops_spec.rb deleted file mode 100644 index 248669b6046..00000000000 --- a/qa/qa/specs/features/project/auto_devops_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'pathname' - -module QA - describe 'Auto Devops', :orchestrated, :kubernetes do - after do - @cluster&.remove! - end - - it 'user creates a new project and runs auto devops' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - project = Factory::Resource::Project.fabricate! do |p| - p.name = 'project-with-autodevops' - p.description = 'Project with Auto Devops' - end - - # Disable code_quality check in Auto DevOps pipeline as it takes - # too long and times out the test - Factory::Resource::SecretVariable.fabricate! do |resource| - resource.key = 'CODE_QUALITY_DISABLED' - resource.value = '1' - end - - # Create Auto Devops compatible repo - Factory::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.directory = Pathname - .new(__dir__) - .join('../../../fixtures/auto_devops_rack') - push.commit_message = 'Create Auto DevOps compatible rack application' - end - - Page::Project::Show.act { wait_for_push } - - # Create and connect K8s cluster - @cluster = Service::KubernetesCluster.new.create! - kubernetes_cluster = Factory::Resource::KubernetesCluster.fabricate! do |cluster| - cluster.project = project - cluster.cluster = @cluster - cluster.install_helm_tiller = true - cluster.install_ingress = true - cluster.install_prometheus = true - cluster.install_runner = true - end - - project.visit! - Page::Menu::Side.act { click_ci_cd_settings } - Page::Project::Settings::CICD.perform do |p| - p.enable_auto_devops_with_domain("#{kubernetes_cluster.ingress_ip}.nip.io") - end - - project.visit! - Page::Menu::Side.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } - - Page::Project::Pipeline::Show.perform do |pipeline| - expect(pipeline).to have_build('build', status: :success, wait: 600) - expect(pipeline).to have_build('test', status: :success, wait: 600) - expect(pipeline).to have_build('production', status: :success, wait: 1200) - end - end - end -end diff --git a/qa/qa/specs/features/project/create_issue_spec.rb b/qa/qa/specs/features/project/create_issue_spec.rb deleted file mode 100644 index bd3e8d2c666..00000000000 --- a/qa/qa/specs/features/project/create_issue_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -module QA - describe 'creates issue', :smoke do - let(:issue_title) { 'issue title' } - - def create_issue - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - Factory::Resource::Issue.fabricate! do |issue| - issue.title = issue_title - end - end - - it 'user creates issue' do - create_issue - - Page::Menu::Side.act { click_issues } - - expect(page).to have_content(issue_title) - end - - context 'when using attachements in comments', :object_storage do - let(:file_to_attach) do - File.absolute_path(File.join('spec', 'fixtures', 'banana_sample.gif')) - end - - it 'user comments on an issue with an attachment' do - create_issue - - Page::Project::Issue::Show.perform do |show| - show.comment('See attached banana for scale', attachment: file_to_attach) - - show.refresh - - image_url = find('a[href$="banana_sample.gif"]')[:href] - - found = show.wait(reload: false) do - show.asset_exists?(image_url) - end - - expect(found).to be_truthy - end - end - end - end -end diff --git a/qa/qa/specs/features/project/create_spec.rb b/qa/qa/specs/features/project/create_spec.rb deleted file mode 100644 index 5e19e490778..00000000000 --- a/qa/qa/specs/features/project/create_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -module QA - describe 'create a new project', :smoke do - it 'user creates a new project' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - created_project = Factory::Resource::Project.fabricate! do |project| - project.name = 'awesome-project' - project.description = 'create awesome project test' - end - - expect(created_project.name).to match /^awesome-project-\h{16}$/ - - expect(page).to have_content( - /Project \S?awesome-project\S+ was successfully created/ - ) - - expect(page).to have_content('create awesome project test') - expect(page).to have_content('The repository for this project is empty') - end - end -end diff --git a/qa/qa/specs/features/project/deploy_key_clone_spec.rb b/qa/qa/specs/features/project/deploy_key_clone_spec.rb deleted file mode 100644 index 1d099508c24..00000000000 --- a/qa/qa/specs/features/project/deploy_key_clone_spec.rb +++ /dev/null @@ -1,105 +0,0 @@ -require 'digest/sha1' - -module QA - describe 'cloning code using a deploy key', :docker do - def login - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - end - - before(:all) do - login - - @runner_name = "qa-runner-#{Time.now.to_i}" - - @project = Factory::Resource::Project.fabricate! do |resource| - resource.name = 'deploy-key-clone-project' - end - - @repository_location = @project.repository_ssh_location - - Factory::Resource::Runner.fabricate! do |resource| - resource.project = @project - resource.name = @runner_name - resource.tags = %w[qa docker] - resource.image = 'gitlab/gitlab-runner:ubuntu' - end - - Page::Menu::Main.act { sign_out } - end - - after(:all) do - Service::Runner.new(@runner_name).remove! - end - - keys = [ - [Runtime::Key::RSA, 8192], - [Runtime::Key::ECDSA, 521], - [Runtime::Key::ED25519] - ] - - keys.each do |(key_class, bits)| - it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines" do - key = key_class.new(*bits) - - login - - Factory::Resource::DeployKey.fabricate! do |resource| - resource.project = @project - resource.title = "deploy key #{key.name}(#{key.bits})" - resource.key = key.public_key - end - - deploy_key_name = "DEPLOY_KEY_#{key.name}_#{key.bits}" - - Factory::Resource::SecretVariable.fabricate! do |resource| - resource.project = @project - resource.key = deploy_key_name - resource.value = key.private_key - end - - gitlab_ci = <<~YAML - cat-config: - script: - - mkdir -p ~/.ssh - - ssh-keyscan -p #{@repository_location.port} #{@repository_location.host} >> ~/.ssh/known_hosts - - eval $(ssh-agent -s) - - ssh-add -D - - echo "$#{deploy_key_name}" | ssh-add - - - git clone #{@repository_location.git_uri} - - cd #{@project.name} - - git checkout #{deploy_key_name} - - sha1sum .gitlab-ci.yml - tags: - - qa - - docker - YAML - - Factory::Repository::ProjectPush.fabricate! do |resource| - resource.project = @project - resource.file_name = '.gitlab-ci.yml' - resource.commit_message = 'Add .gitlab-ci.yml' - resource.file_content = gitlab_ci - resource.branch_name = deploy_key_name - resource.new_branch = true - end - - sha1sum = Digest::SHA1.hexdigest(gitlab_ci) - - Page::Project::Show.act { wait_for_push } - Page::Menu::Side.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } - Page::Project::Pipeline::Show.act { go_to_first_job } - - Page::Project::Job::Show.perform do |job| - job.wait(reload: false) do - job.completed? && !job.trace_loading? - end - - expect(job.passed?).to be_truthy, "Job status did not become \"passed\"." - expect(job.output).to include(sha1sum) - end - end - end - end -end diff --git a/qa/qa/specs/features/project/file_spec.rb b/qa/qa/specs/features/project/file_spec.rb deleted file mode 100644 index 5659784cd5c..00000000000 --- a/qa/qa/specs/features/project/file_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -module QA - describe 'File Functionality', :core do - it 'lets a user create, edit and delete a file via WebUI' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - # Create - file_name = 'QA Test - File name' - file_content = 'QA Test - File content' - commit_message_for_create = 'QA Test - Create new file' - - Factory::Resource::File.fabricate! do |file| - file.name = file_name - file.content = file_content - file.commit_message = commit_message_for_create - end - - expect(page).to have_content('The file has been successfully created.') - expect(page).to have_content(file_name) - expect(page).to have_content(file_content) - expect(page).to have_content(commit_message_for_create) - - # Edit - updated_file_content = 'QA Test - Updated file content' - commit_message_for_update = 'QA Test - Update file' - - Page::File::Show.act { click_edit } - - Page::File::Form.act do - remove_content - add_content(updated_file_content) - add_commit_message(commit_message_for_update) - commit_changes - end - - expect(page).to have_content('Your changes have been successfully committed.') - expect(page).to have_content(updated_file_content) - expect(page).to have_content(commit_message_for_update) - - # Delete - commit_message_for_delete = 'QA Test - Delete file' - - Page::File::Show.act do - click_delete - add_commit_message(commit_message_for_delete) - click_delete_file - end - - expect(page).to have_content('The file has been successfully deleted.') - expect(page).to have_content(commit_message_for_delete) - expect(page).to have_no_content(file_name) - end - end -end diff --git a/qa/qa/specs/features/project/fork_project_spec.rb b/qa/qa/specs/features/project/fork_project_spec.rb deleted file mode 100644 index 280978bb950..00000000000 --- a/qa/qa/specs/features/project/fork_project_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -module QA - describe 'Project fork' do - it 'can submit merge requests to upstream master' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - merge_request = Factory::Resource::MergeRequestFromFork.fabricate! do |merge_request| - merge_request.fork_branch = 'feature-branch' - end - - Page::Menu::Main.perform { |main| main.sign_out } - Page::Main::Login.perform { |login| login.sign_in_using_credentials } - - merge_request.visit! - - Page::MergeRequest::Show.perform { |show| show.merge! } - - expect(page).to have_content('The changes were merged') - end - end -end diff --git a/qa/qa/specs/features/project/import_from_github_spec.rb b/qa/qa/specs/features/project/import_from_github_spec.rb deleted file mode 100644 index 57695d2c726..00000000000 --- a/qa/qa/specs/features/project/import_from_github_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -module QA - describe 'user imports a GitHub repo', :orchestrated, :github do - let(:imported_project) do - Factory::Resource::ProjectImportedFromGithub.fabricate! do |project| - project.name = 'imported-project' - project.personal_access_token = Runtime::Env.github_access_token - project.github_repository_path = 'gitlab-qa/test-project' - end - end - - after do - # We need to delete the imported project because it's impossible to import - # the same GitHub project twice for a given user. - api_client = Runtime::API::Client.new(:gitlab) - delete_project_request = Runtime::API::Request.new(api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{imported_project.name}")}") - delete delete_project_request.url - - expect_status(202) - end - - it 'user imports a GitHub repo' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - imported_project # import the project - - Page::Menu::Main.act { go_to_projects } - Page::Dashboard::Projects.perform do |dashboard| - dashboard.go_to_project(imported_project.name) - end - - Page::Project::Show.act { wait_for_import } - - verify_repository_import - verify_issues_import - verify_merge_requests_import - verify_labels_import - verify_milestones_import - verify_wiki_import - end - - def verify_repository_import - expect(page).to have_content('This test project is used for automated GitHub import by GitLab QA.') - expect(page).to have_content(imported_project.name) - end - - def verify_issues_import - Page::Menu::Side.act { click_issues } - expect(page).to have_content('This is a sample issue') - - click_link 'This is a sample issue' - - expect(page).to have_content('We should populate this project with issues, pull requests and wiki pages.') - - # Comments - expect(page).to have_content('This is a comment from @rymai.') - - Page::Issuable::Sidebar.perform do |issuable| - expect(issuable).to have_label('enhancement') - expect(issuable).to have_label('help wanted') - expect(issuable).to have_label('good first issue') - end - end - - def verify_merge_requests_import - Page::Menu::Side.act { click_merge_requests } - expect(page).to have_content('Improve README.md') - - click_link 'Improve README.md' - - expect(page).to have_content('This improves the README file a bit.') - - # Review comment are not supported yet - expect(page).not_to have_content('Really nice change.') - - # Comments - expect(page).to have_content('Nice work! This is a comment from @rymai.') - - # Diff comments - expect(page).to have_content('[Review comment] I like that!') - expect(page).to have_content('[Review comment] Nice blank line.') - expect(page).to have_content('[Single diff comment] Much better without this line!') - - Page::Issuable::Sidebar.perform do |issuable| - expect(issuable).to have_label('bug') - expect(issuable).to have_label('enhancement') - end - end - - def verify_labels_import - # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19228 - # to build upon it. - end - - def verify_milestones_import - # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18727 - # to build upon it. - end - - def verify_wiki_import - Page::Menu::Side.act { click_wiki } - - expect(page).to have_content('Welcome to the test-project wiki!') - end - end -end diff --git a/qa/qa/specs/features/project/pipelines_spec.rb b/qa/qa/specs/features/project/pipelines_spec.rb deleted file mode 100644 index 6c6b4e80626..00000000000 --- a/qa/qa/specs/features/project/pipelines_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -module QA - describe 'CI/CD Pipelines', :orchestrated, :docker do - let(:executor) { "qa-runner-#{Time.now.to_i}" } - - after do - Service::Runner.new(executor).remove! - end - - it 'user registers a new specific runner' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - Factory::Resource::Runner.fabricate! do |runner| - runner.name = executor - end - - Page::Project::Settings::CICD.perform do |settings| - sleep 5 # Runner should register within 5 seconds - settings.refresh - - settings.expand_runners_settings do |page| - expect(page).to have_content(executor) - expect(page).to have_online_runner - end - end - end - - it 'users creates a new pipeline' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - - project = Factory::Resource::Project.fabricate! do |project| - project.name = 'project-with-pipelines' - project.description = 'Project with CI/CD Pipelines.' - end - - Factory::Resource::Runner.fabricate! do |runner| - runner.project = project - runner.name = executor - runner.tags = %w[qa test] - end - - Factory::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.file_name = '.gitlab-ci.yml' - push.commit_message = 'Add .gitlab-ci.yml' - push.file_content = <<~EOF - test-success: - tags: - - qa - - test - script: echo 'OK' - - test-failure: - tags: - - qa - - test - script: - - echo 'FAILURE' - - exit 1 - - test-tags: - tags: - - qa - - docker - script: echo 'NOOP' - - test-artifacts: - tags: - - qa - - test - script: mkdir my-artifacts; echo "CONTENTS" > my-artifacts/artifact.txt - artifacts: - paths: - - my-artifacts/ - EOF - end - - Page::Project::Show.act { wait_for_push } - - expect(page).to have_content('Add .gitlab-ci.yml') - - Page::Menu::Side.act { click_ci_cd_pipelines } - - expect(page).to have_content('All 1') - expect(page).to have_content('Add .gitlab-ci.yml') - - puts 'Waiting for the runner to process the pipeline' - sleep 15 # Runner should process all jobs within 15 seconds. - - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } - - Page::Project::Pipeline::Show.perform do |pipeline| - expect(pipeline).to be_running - expect(pipeline).to have_build('test-success', status: :success) - expect(pipeline).to have_build('test-failure', status: :failed) - expect(pipeline).to have_build('test-tags', status: :pending) - expect(pipeline).to have_build('test-artifacts', status: :success) - end - end - end -end diff --git a/qa/qa/specs/features/project/wikis_spec.rb b/qa/qa/specs/features/project/wikis_spec.rb deleted file mode 100644 index 9af2dbd1264..00000000000 --- a/qa/qa/specs/features/project/wikis_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -module QA - describe 'Wiki Functionality' do - def login - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - end - - def validate_content(content) - expect(page).to have_content('Wiki was successfully updated') - expect(page).to have_content(/#{content}/) - end - - before do - login - end - - it 'User creates, edits, clones, and pushes to the wiki' do - wiki = Factory::Resource::Wiki.fabricate! do |resource| - resource.title = 'Home' - resource.content = '# My First Wiki Content' - resource.message = 'Update home' - end - - validate_content('My First Wiki Content') - - Page::Project::Wiki::Edit.act { go_to_edit_page } - Page::Project::Wiki::New.perform do |page| - page.set_content("My Second Wiki Content") - page.save_changes - end - - validate_content('My Second Wiki Content') - - Factory::Repository::WikiPush.fabricate! do |push| - push.wiki = wiki - push.file_name = 'Home.md' - push.file_content = '# My Third Wiki Content' - push.commit_message = 'Update Home.md' - end - Page::Menu::Side.act { click_wiki } - - expect(page).to have_content('My Third Wiki Content') - end - end -end diff --git a/qa/qa/specs/features/repository/protected_branches_spec.rb b/qa/qa/specs/features/repository/protected_branches_spec.rb deleted file mode 100644 index aa23145478d..00000000000 --- a/qa/qa/specs/features/repository/protected_branches_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -module QA - describe 'branch protection support' do - let(:branch_name) { 'protected-branch' } - let(:commit_message) { 'Protected push commit message' } - let(:project) do - Factory::Resource::Project.fabricate! do |resource| - resource.name = 'protected-branch-project' - end - end - - before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } - end - - after do - # We need to clear localStorage because we're using it for the dropdown, - # and capybara doesn't do this for us. - # https://github.com/teamcapybara/capybara/issues/1702 - Capybara.execute_script 'localStorage.clear()' - end - - context 'when developers and maintainers are allowed to push to a protected branch' do - it 'user with push rights successfully pushes to the protected branch' do - create_protected_branch(allow_to_push: true) - - push = push_new_file(branch_name) - - expect(push.output).to match(/remote: To create a merge request for protected-branch, visit/) - end - end - - context 'when developers and maintainers are not allowed to push to a protected branch' do - it 'user without push rights fails to push to the protected branch' do - create_protected_branch(allow_to_push: false) - - push = push_new_file(branch_name) - - expect(push.output) - .to match(/remote\: GitLab\: You are not allowed to push code to protected branches on this project/) - expect(push.output) - .to match(/\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/) - end - end - - def create_protected_branch(allow_to_push:) - Factory::Resource::Branch.fabricate! do |resource| - resource.branch_name = branch_name - resource.project = project - resource.allow_to_push = allow_to_push - resource.protected = true - end - end - - def push_new_file(branch) - Factory::Repository::ProjectPush.fabricate! do |resource| - resource.project = project - resource.file_name = 'new_file.md' - resource.file_content = '# This is a new file' - resource.commit_message = 'Add new_file.md' - resource.branch_name = branch_name - resource.new_branch = false - end - end - end -end diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb index ccc0b906845..5493a33cd2a 100644 --- a/qa/spec/runtime/env_spec.rb +++ b/qa/spec/runtime/env_spec.rb @@ -104,6 +104,8 @@ describe QA::Runtime::Env do describe '.github_access_token' do it 'returns "" if GITHUB_ACCESS_TOKEN is not defined' do + stub_env('GITHUB_ACCESS_TOKEN', nil) + expect(described_class.github_access_token).to eq('') end @@ -115,6 +117,8 @@ describe QA::Runtime::Env do describe '.require_github_access_token!' do it 'raises ArgumentError if GITHUB_ACCESS_TOKEN is not defined' do + stub_env('GITHUB_ACCESS_TOKEN', nil) + expect { described_class.require_github_access_token! }.to raise_error(ArgumentError) end diff --git a/qa/spec/scenario/test/instance/all_spec.rb b/qa/spec/scenario/test/instance/all_spec.rb index 423527e938e..1d96352550b 100644 --- a/qa/spec/scenario/test/instance/all_spec.rb +++ b/qa/spec/scenario/test/instance/all_spec.rb @@ -1,4 +1,10 @@ describe QA::Scenario::Test::Instance::All do + subject do + Class.new(described_class) do + tags :rspec, :foo + end + end + context '#perform' do let(:arguments) { spy('Runtime::Scenario') } let(:release) { spy('Runtime::Release') } @@ -24,7 +30,7 @@ describe QA::Scenario::Test::Instance::All do subject.perform("test") expect(runner).to have_received(:options=) - .with(::File.expand_path('../../../../qa/specs/features', __dir__)) + .with(['--tag', 'rspec,foo', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)]) end end diff --git a/qa/spec/scenario/test/instance/smoke_spec.rb b/qa/spec/scenario/test/instance/smoke_spec.rb index e79d19e8212..386eefae930 100644 --- a/qa/spec/scenario/test/instance/smoke_spec.rb +++ b/qa/spec/scenario/test/instance/smoke_spec.rb @@ -30,7 +30,7 @@ describe QA::Scenario::Test::Instance::Smoke do subject.perform("test") expect(runner).to have_received(:options=) - .with(::File.expand_path('../../../../qa/specs/features', __dir__)) + .with(['--tag', 'smoke', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)]) end end diff --git a/rubocop/cop/line_break_around_conditional_block.rb b/rubocop/cop/line_break_around_conditional_block.rb index 011f2bcf8bf..59fe6e5d98c 100644 --- a/rubocop/cop/line_break_around_conditional_block.rb +++ b/rubocop/cop/line_break_around_conditional_block.rb @@ -48,6 +48,8 @@ module RuboCop MSG = 'Add a line break around conditional blocks' def on_if(node) + # This cop causes errors in haml files, so let's skip those + return if in_haml?(node) return if node.single_line? return unless node.if? || node.unless? @@ -116,6 +118,10 @@ module RuboCop def end_line?(line) line =~ /^\s*(end|})/ end + + def in_haml?(node) + node.location.expression.source_buffer.name.end_with?('.haml.rb') + end end end end diff --git a/rubocop/cop/ruby_interpolation_in_translation.rb b/rubocop/cop/ruby_interpolation_in_translation.rb new file mode 100644 index 00000000000..b9411fcfd6c --- /dev/null +++ b/rubocop/cop/ruby_interpolation_in_translation.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + class RubyInterpolationInTranslation < RuboCop::Cop::Cop + MSG = "Don't use ruby interpolation \#{} inside translated strings, instead use \%{}" + + TRANSLATION_METHODS = ':_ :s_ :N_ :n_' + RUBY_INTERPOLATION_REGEX = /.*\#\{.*\}/ + + def_node_matcher :translation_method?, <<~PATTERN + (send nil? {#{TRANSLATION_METHODS}} $dstr ...) + PATTERN + + def_node_matcher :plural_translation_method?, <<~PATTERN + (send nil? :n_ str $dstr ...) + PATTERN + + def on_send(node) + interpolation = translation_method?(node) || plural_translation_method?(node) + return unless interpolation + + interpolation.descendants.each do |possible_violation| + add_offense(possible_violation, message: MSG) if possible_violation.type != :str + end + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index 88c9bbf24f4..eaf421a7235 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -28,3 +28,4 @@ require_relative 'cop/rspec/env_assignment' require_relative 'cop/rspec/factories_in_migration_specs' require_relative 'cop/sidekiq_options_queue' require_relative 'cop/destroy_all' +require_relative 'cop/ruby_interpolation_in_translation' diff --git a/scripts/frontend/extract_gettext_all.js b/scripts/frontend/extract_gettext_all.js index af8cc4c3341..725522a3540 100644 --- a/scripts/frontend/extract_gettext_all.js +++ b/scripts/frontend/extract_gettext_all.js @@ -7,7 +7,7 @@ const { } = require('gettext-extractor-vue'); const ensureSingleLine = require('../../app/assets/javascripts/locale/ensure_single_line.js'); -const arguments = argumentsParser +const args = argumentsParser .option('-f, --file <file>', 'Extract message from one single file') .option('-a, --all', 'Extract message from all js/vue files') .parse(process.argv); @@ -61,12 +61,12 @@ function printJson() { console.log(JSON.stringify(messages)); } -if (arguments.file) { - vueParser.parseFile(arguments.file).then(() => printJson()); -} else if (arguments.all) { +if (args.file) { + vueParser.parseFile(args.file).then(() => printJson()); +} else if (args.all) { vueParser.parseFilesGlob('{ee/app,app}/assets/javascripts/**/*.{js,vue}').then(() => printJson()); } else { console.warn('ERROR: Please use the script correctly:'); - arguments.outputHelp(); + args.outputHelp(); process.exit(1); } diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index f7068546093..465f3499703 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -141,6 +141,17 @@ describe Groups::MilestonesController do end end + describe "#destroy" do + let(:milestone) { create(:milestone, group: group) } + + it "removes milestone" do + delete :destroy, group_id: group.to_param, id: milestone.iid, format: :js + + expect(response).to be_success + expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound) + end + end + describe '#ensure_canonical_path' do before do sign_in(user) diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index 916a4be2567..9e149bc4c3c 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -230,7 +230,7 @@ describe Projects::CommitController do id: master_pickable_commit.id) expect(response).to redirect_to project_commits_path(project, 'master') - expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.') + expect(flash[:notice]).to eq('The commit has been successfully cherry-picked into master.') end end diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb index d8995f98575..f8c37c0a676 100644 --- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb @@ -29,6 +29,55 @@ describe Projects::MergeRequests::CreationsController do expect(response).to be_success end end + + context 'merge request with some commits' do + render_views + + let(:large_diff_params) do + { + namespace_id: fork_project.namespace.to_param, + project_id: fork_project, + merge_request: { + source_branch: 'master', + target_branch: 'fix' + } + } + end + + describe 'with artificial limits' do + before do + # Load MergeRequestdiff so stub_const won't override it with its own definition + # See https://github.com/rspec/rspec-mocks/issues/1079 + stub_const("#{MergeRequestDiff}::COMMITS_SAFE_SIZE", 2) + end + + it 'limits total commits' do + get :new, large_diff_params + + expect(response).to be_success + + total = assigns(:total_commit_count) + expect(assigns(:commits)).to be_an Array + expect(total).to be > 0 + expect(assigns(:hidden_commit_count)).to be > 0 + expect(response).to have_gitlab_http_status(200) + expect(response.body).to match %r(<span class="commits-count">2 commits</span>) + end + end + + it 'shows total commits' do + get :new, large_diff_params + + expect(response).to be_success + + total = assigns(:total_commit_count) + expect(assigns(:commits)).to be_an Array + expect(total).to be > 0 + expect(assigns(:hidden_commit_count)).to eq(0) + expect(response).to have_gitlab_http_status(200) + expect(response.body).to match %r(<span class="commits-count">#{total} commits</span>) + end + end end describe 'GET diffs' do diff --git a/spec/factories/milestones.rb b/spec/factories/milestones.rb index 019e4420212..027349b2f8e 100644 --- a/spec/factories/milestones.rb +++ b/spec/factories/milestones.rb @@ -34,7 +34,7 @@ FactoryBot.define do milestone.project_id = evaluator.project_id elsif evaluator.parent id = evaluator.parent.id - evaluator.parent.is_a?(Group) ? board.group_id = id : evaluator.project_id = id + evaluator.parent.is_a?(Group) ? evaluator.group_id = id : evaluator.project_id = id else milestone.project = create(:project) end diff --git a/spec/factories/project_group_links.rb b/spec/factories/project_group_links.rb index d5ace9425a0..59c77627ee5 100644 --- a/spec/factories/project_group_links.rb +++ b/spec/factories/project_group_links.rb @@ -2,5 +2,6 @@ FactoryBot.define do factory :project_group_link do project group + expires_at nil end end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 1db6c75b85b..b2eaeb1c487 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -134,6 +134,7 @@ describe "Admin::Users" do expect(page).to have_content(user.email) expect(page).to have_content(user.name) + expect(page).to have_content(user.id) expect(page).to have_link('Block user', href: block_admin_user_path(user)) expect(page).to have_button('Delete user') expect(page).to have_button('Delete user and contributions') diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb index 0db69432702..d9d67788b38 100644 --- a/spec/features/dashboard/milestones_spec.rb +++ b/spec/features/dashboard/milestones_spec.rb @@ -13,8 +13,10 @@ describe 'Dashboard > Milestones' do describe 'as logged-in user' do let(:user) { create(:user) } + let(:group) { create(:group) } let(:project) { create(:project, namespace: user.namespace) } let!(:milestone) { create(:milestone, project: project) } + let!(:milestone2) { create(:milestone, group: group) } before do project.add_maintainer(user) sign_in(user) @@ -24,6 +26,7 @@ describe 'Dashboard > Milestones' do it 'sees milestones' do expect(current_path).to eq dashboard_milestones_path expect(page).to have_content(milestone.title) + expect(page).to have_content(group.name) end end end diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb index d6e7ff33d5d..0c15febe8df 100644 --- a/spec/features/merge_request/user_sees_diff_spec.rb +++ b/spec/features/merge_request/user_sees_diff_spec.rb @@ -2,6 +2,7 @@ require 'rails_helper' describe 'Merge request > User sees diff', :js do include ProjectForksHelper + include RepoHelpers let(:project) { create(:project, :public, :repository) } let(:merge_request) { create(:merge_request, source_project: project) } @@ -81,5 +82,58 @@ describe 'Merge request > User sees diff', :js do expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1) end end + + context 'when file contains html' do + let(:current_user) { project.owner } + let(:branch_name) {"test_branch"} + + def create_file(branch_name, file_name, content) + Files::CreateService.new( + project, + current_user, + start_branch: branch_name, + branch_name: branch_name, + commit_message: "Create file", + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name) + end + + it 'escapes any HTML special characters in the diff chunk header' do + file_content = + <<~CONTENT + function foo<input> { + let a = 1; + let b = 2; + let c = 3; + let d = 3; + } + CONTENT + + new_file_content = + <<~CONTENT + function foo<input> { + let a = 1; + let b = 2; + let c = 3; + let x = 3; + } + CONTENT + + file_name = 'xss_file.txt' + + create_file('master', file_name, file_content) + merge_request = create(:merge_request, source_project: project) + create_file(merge_request.source_branch, file_name, new_file_content) + + project.commit(merge_request.source_branch) + + visit diffs_project_merge_request_path(project, merge_request) + + expect(page).to have_text("function foo<input> {") + end + end end end diff --git a/spec/features/milestones/user_deletes_milestone_spec.rb b/spec/features/milestones/user_deletes_milestone_spec.rb index 9d4a68239d3..a8c296b4cd2 100644 --- a/spec/features/milestones/user_deletes_milestone_spec.rb +++ b/spec/features/milestones/user_deletes_milestone_spec.rb @@ -1,26 +1,46 @@ require "rails_helper" describe "User deletes milestone", :js do - set(:user) { create(:user) } - set(:project) { create(:project) } - set(:milestone) { create(:milestone, project: project) } + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project) { create(:project, namespace: group) } before do - project.add_developer(user) sign_in(user) + end + + context "when milestone belongs to project" do + let!(:milestone) { create(:milestone, parent: project, title: "project milestone") } + + it "deletes milestone" do + project.add_developer(user) + visit(project_milestones_path(project)) + click_link(milestone.title) + click_button("Delete") + click_button("Delete milestone") + + expect(page).to have_content("No milestones to show") + + visit(activity_project_path(project)) - visit(project_milestones_path(project)) + expect(page).to have_content("#{user.name} destroyed milestone") + end end - it "deletes milestone" do - click_link(milestone.title) - click_button("Delete") - click_button("Delete milestone") + context "when milestone belongs to group" do + let!(:milestone_to_be_deleted) { create(:milestone, parent: group, title: "group milestone 1") } + let!(:milestone) { create(:milestone, parent: group, title: "group milestone 2") } - expect(page).to have_content("No milestones to show") + it "deletes milestone" do + group.add_developer(user) + visit(group_milestones_path(group)) - visit(activity_project_path(project)) + click_link(milestone_to_be_deleted.title) + click_button("Delete") + click_button("Delete milestone") - expect(page).to have_content("#{user.name} destroyed milestone") + expect(page).to have_content(milestone.title) + expect(page).not_to have_content(milestone_to_be_deleted) + end end end diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index 9e60b4995bd..206a3a4fe9a 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -130,5 +130,15 @@ describe 'User edit profile' do visit user_path(user) expect(page).not_to have_selector '.cover-status' end + + it 'displays a default emoji if only message is entered' do + message = 'a status without emoji' + visit(profile_path) + fill_in 'js-status-message-field', with: message + + within('.js-toggle-emoji-menu') do + expect(page).to have_emoji('speech_balloon') + end + end end end diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index bc3c00dafe2..a61b614dbc8 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -21,7 +21,7 @@ describe 'Cherry-pick Commits' do uncheck 'create_merge_request' click_button 'Cherry-pick' end - expect(page).to have_content('The commit has been successfully cherry-picked.') + expect(page).to have_content('The commit has been successfully cherry-picked into master.') end end @@ -32,7 +32,7 @@ describe 'Cherry-pick Commits' do uncheck 'create_merge_request' click_button 'Cherry-pick' end - expect(page).to have_content('The commit has been successfully cherry-picked.') + expect(page).to have_content('The commit has been successfully cherry-picked into master.') end end @@ -59,7 +59,7 @@ describe 'Cherry-pick Commits' do page.within('#modal-cherry-pick-commit') do click_button 'Cherry-pick' end - expect(page).to have_content('The commit has been successfully cherry-picked. You can now submit a merge request to get this change into the original branch.') + expect(page).to have_content("The commit has been successfully cherry-picked into cherry-pick-#{master_pickable_commit.short_id}. You can now submit a merge request to get this change into the original branch.") expect(page).to have_content("From cherry-pick-#{master_pickable_commit.short_id} into master") end end @@ -86,7 +86,7 @@ describe 'Cherry-pick Commits' do click_button 'Cherry-pick' end - expect(page).to have_content('The commit has been successfully cherry-picked.') + expect(page).to have_content('The commit has been successfully cherry-picked into feature.') end end diff --git a/spec/features/projects/issues/user_sorts_issues_spec.rb b/spec/features/projects/issues/user_sorts_issues_spec.rb index db5936a30cb..7d261ec7dae 100644 --- a/spec/features/projects/issues/user_sorts_issues_spec.rb +++ b/spec/features/projects/issues/user_sorts_issues_spec.rb @@ -1,7 +1,9 @@ require "spec_helper" describe "User sorts issues" do - set(:project) { create(:project_empty_repo, :public) } + set(:user) { create(:user) } + set(:group) { create(:group) } + set(:project) { create(:project_empty_repo, :public, group: group) } set(:issue1) { create(:issue, project: project) } set(:issue2) { create(:issue, project: project) } set(:issue3) { create(:issue, project: project) } @@ -12,7 +14,29 @@ describe "User sorts issues" do create(:award_emoji, :downvote, awardable: issue1) create(:award_emoji, :upvote, awardable: issue2) + sign_in(user) + + visit(project_issues_path(project)) + end + + it 'keeps the sort option' do + find('button.dropdown-toggle').click + + page.within('.content ul.dropdown-menu.dropdown-menu-right li') do + click_link('Milestone') + end + + visit(issues_dashboard_path(assignee_id: user.id)) + + expect(find('.issues-filters a.is-active')).to have_content('Milestone') + visit(project_issues_path(project)) + + expect(find('.issues-filters a.is-active')).to have_content('Milestone') + + visit(issues_group_path(group)) + + expect(find('.issues-filters a.is-active')).to have_content('Milestone') end it "sorts by popularity" do diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 50e957bf12b..2d791947ee9 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -40,7 +40,7 @@ describe 'User browses a job', :js do it 'displays the failure reason' do within('.builds-container') do build_link = first('.build-job > a') - expect(build_link['data-title']).to eq('test - failed <br> (unknown failure)') + expect(build_link['data-title']).to eq('test - failed - (unknown failure)') end end end @@ -51,7 +51,7 @@ describe 'User browses a job', :js do it 'displays the failure reason and retried label' do within('.builds-container') do build_link = first('.build-job > a') - expect(build_link['data-title']).to eq('test - failed <br> (unknown failure) (retried)') + expect(build_link['data-title']).to eq('test - failed - (unknown failure) (retried)') end end end diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb index 08786fe1630..ebc20d15d67 100644 --- a/spec/features/projects/jobs/user_browses_jobs_spec.rb +++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb @@ -36,7 +36,7 @@ describe 'User browses jobs' do it 'displays a tooltip with the failure reason' do page.within('.ci-table') do failed_job_link = page.find('.ci-failed') - expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)') + expect(failed_job_link[:title]).to eq('Failed - (unknown failure)') end end end diff --git a/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb index e401933aed2..82cfe600d52 100644 --- a/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb +++ b/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb @@ -1,15 +1,18 @@ require 'spec_helper' describe 'User sorts merge requests' do + include CookieHelper + let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let!(:merge_request2) do create(:merge_request_with_diffs, source_project: project, target_project: project, source_branch: 'merge-test') end - let(:project) { create(:project, :public, :repository) } - let(:user) { create(:user) } + set(:user) { create(:user) } + set(:group) { create(:group) } + set(:group_member) { create(:group_member, :maintainer, user: user, group: group) } + set(:project) { create(:project, :public, group: group) } before do - project.add_maintainer(user) sign_in(user) visit(project_merge_requests_path(project)) @@ -19,16 +22,42 @@ describe 'User sorts merge requests' do find('button.dropdown-toggle').click page.within('.content ul.dropdown-menu.dropdown-menu-right li') do - click_link('Last updated') + click_link('Milestone') end visit(merge_requests_dashboard_path(assignee_id: user.id)) - expect(find('.issues-filters')).to have_content('Last updated') + expect(find('.issues-filters a.is-active')).to have_content('Milestone') visit(project_merge_requests_path(project)) - expect(find('.issues-filters')).to have_content('Last updated') + expect(find('.issues-filters a.is-active')).to have_content('Milestone') + + visit(merge_requests_group_path(group)) + + expect(find('.issues-filters a.is-active')).to have_content('Milestone') + end + + it 'fallbacks to issuable_sort cookie key when remembering the sorting option' do + set_cookie('issuable_sort', 'milestone') + + visit(merge_requests_dashboard_path(assignee_id: user.id)) + + expect(find('.issues-filters a.is-active')).to have_content('Milestone') + end + + it 'separates remember sorting with issues' do + create(:issue, project: project) + + find('button.dropdown-toggle').click + + page.within('.content ul.dropdown-menu.dropdown-menu-right li') do + click_link('Milestone') + end + + visit(project_issues_path(project)) + + expect(find('.issues-filters a.is-active')).not_to have_content('Milestone') end context 'when merge requests have awards' do diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index a84492ea5f1..603503a531c 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -126,7 +126,7 @@ describe 'Pipeline', :js do it 'should include the failure reason' do page.within('#ci-badge-test') do build_link = page.find('.js-pipeline-graph-job-link') - expect(build_link['data-original-title']).to eq('test - failed <br> (unknown failure)') + expect(build_link['data-original-title']).to eq('test - failed - (unknown failure)') end end end @@ -319,7 +319,7 @@ describe 'Pipeline', :js do it 'displays a tooltip with the failure reason' do page.within('.ci-table') do failed_job_link = page.find('.ci-failed') - expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)') + expect(failed_job_link[:title]).to eq('Failed - (unknown failure)') end end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 4a83bcc3efb..26a92f14787 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -406,7 +406,7 @@ describe 'Pipelines', :js do within('.js-builds-dropdown-list') do build_element = page.find('.mini-pipeline-graph-dropdown-item') - expect(build_element['data-original-title']).to eq('build - failed <br> (unknown failure)') + expect(build_element['data-original-title']).to eq('build - failed - (unknown failure)') end end end diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb index 033155617c6..cb0ea4e26ba 100644 --- a/spec/helpers/import_helper_spec.rb +++ b/spec/helpers/import_helper_spec.rb @@ -1,6 +1,16 @@ require 'rails_helper' describe ImportHelper do + describe '#sanitize_project_name' do + it 'removes whitespace' do + expect(helper.sanitize_project_name('my test repo')).to eq('my-test-repo') + end + + it 'removes disallowed characters' do + expect(helper.sanitize_project_name('Test&me$over*h_ere')).to eq('Test-me-over-h_ere') + end + end + describe '#import_project_target' do let(:user) { create(:user) } diff --git a/spec/javascripts/badges/dummy_badge.js b/spec/javascripts/badges/dummy_badge.js index 6aaff21c503..f0cdaddbd33 100644 --- a/spec/javascripts/badges/dummy_badge.js +++ b/spec/javascripts/badges/dummy_badge.js @@ -1,8 +1,9 @@ +import _ from 'underscore'; import { PROJECT_BADGE } from '~/badges/constants'; import { DUMMY_IMAGE_URL, TEST_HOST } from 'spec/test_constants'; export const createDummyBadge = () => { - const id = Math.floor(1000 * Math.random()); + const id = _.uniqueId(); return { id, imageUrl: `${TEST_HOST}/badges/${id}/image/url`, diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js index 7198dbd4cf2..0a8e5a628c0 100644 --- a/spec/javascripts/flash_spec.js +++ b/spec/javascripts/flash_spec.js @@ -57,8 +57,11 @@ describe('Flash', () => { hideFlash(el); expect( - el.style.transition, - ).toBe('opacity 0.3s'); + el.style['transition-property'], + ).toBe('opacity'); + expect( + el.style['transition-duration'], + ).toBe('0.3s'); }); it('sets opacity style', () => { diff --git a/spec/javascripts/helpers/vue_mount_component_helper.js b/spec/javascripts/helpers/vue_mount_component_helper.js index 1057f0aca3e..6848c95d95d 100644 --- a/spec/javascripts/helpers/vue_mount_component_helper.js +++ b/spec/javascripts/helpers/vue_mount_component_helper.js @@ -1,3 +1,5 @@ +import Vue from 'vue'; + const mountComponent = (Component, props = {}, el = null) => new Component({ propsData: props, @@ -25,4 +27,12 @@ export const mountComponentWithSlots = (Component, { props, slots }) => { return component.$mount(); }; +/** + * Mount a component with the given render method. + * + * This helps with inserting slots that need to be compiled. + */ +export const mountComponentWithRender = (render, el = null) => + mountComponent(Vue.extend({ render }), {}, el); + export default mountComponent; diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js index 24a7d76f30b..06b8b452319 100644 --- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js +++ b/spec/javascripts/ide/stores/modules/commit/actions_spec.js @@ -184,7 +184,7 @@ describe('IDE commit module actions', () => { branch, }) .then(() => { - expect(f.lastCommit.message).toBe(data.message); + expect(f.lastCommitSha).toBe(data.id); }) .then(done) .catch(done.fail); @@ -266,19 +266,21 @@ describe('IDE commit module actions', () => { }); describe('success', () => { + const COMMIT_RESPONSE = { + id: '123456', + short_id: '123', + message: 'test message', + committed_date: 'date', + stats: { + additions: '1', + deletions: '2', + }, + }; + beforeEach(() => { spyOn(service, 'commit').and.returnValue( Promise.resolve({ - data: { - id: '123456', - short_id: '123', - message: 'test message', - committed_date: 'date', - stats: { - additions: '1', - deletions: '2', - }, - }, + data: COMMIT_RESPONSE, }), ); }); @@ -352,8 +354,8 @@ describe('IDE commit module actions', () => { store .dispatch('commit/commitChanges') .then(() => { - expect(store.state.entries[store.state.openFiles[0].path].lastCommit.message).toBe( - 'test message', + expect(store.state.entries[store.state.openFiles[0].path].lastCommitSha).toBe( + COMMIT_RESPONSE.id, ); done(); diff --git a/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js new file mode 100644 index 00000000000..f831a9f0a5d --- /dev/null +++ b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js @@ -0,0 +1,336 @@ +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import createState from '~/ide/stores/modules/file_templates/state'; +import * as actions from '~/ide/stores/modules/file_templates/actions'; +import * as types from '~/ide/stores/modules/file_templates/mutation_types'; +import testAction from 'spec/helpers/vuex_action_helper'; + +describe('IDE file templates actions', () => { + let state; + let mock; + + beforeEach(() => { + state = createState(); + + mock = new MockAdapter(axios); + }); + + afterEach(() => { + mock.restore(); + }); + + describe('requestTemplateTypes', () => { + it('commits REQUEST_TEMPLATE_TYPES', done => { + testAction( + actions.requestTemplateTypes, + null, + state, + [{ type: types.REQUEST_TEMPLATE_TYPES }], + [], + done, + ); + }); + }); + + describe('receiveTemplateTypesError', () => { + it('commits RECEIVE_TEMPLATE_TYPES_ERROR and dispatches setErrorMessage', done => { + testAction( + actions.receiveTemplateTypesError, + null, + state, + [{ type: types.RECEIVE_TEMPLATE_TYPES_ERROR }], + [ + { + type: 'setErrorMessage', + payload: { + action: jasmine.any(Function), + actionText: 'Please try again', + text: 'Error loading template types.', + }, + }, + ], + done, + ); + }); + }); + + describe('receiveTemplateTypesSuccess', () => { + it('commits RECEIVE_TEMPLATE_TYPES_SUCCESS', done => { + testAction( + actions.receiveTemplateTypesSuccess, + 'test', + state, + [{ type: types.RECEIVE_TEMPLATE_TYPES_SUCCESS, payload: 'test' }], + [], + done, + ); + }); + }); + + describe('fetchTemplateTypes', () => { + describe('success', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/templates\/licenses/).replyOnce(200, [ + { + name: 'MIT', + }, + ]); + }); + + it('rejects if selectedTemplateType is empty', done => { + const dispatch = jasmine.createSpy('dispatch'); + + actions + .fetchTemplateTypes({ dispatch, state }) + .then(done.fail) + .catch(() => { + expect(dispatch).not.toHaveBeenCalled(); + + done(); + }); + }); + + it('dispatches actions', done => { + state.selectedTemplateType = { + key: 'licenses', + }; + + testAction( + actions.fetchTemplateTypes, + null, + state, + [], + [ + { + type: 'requestTemplateTypes', + }, + { + type: 'receiveTemplateTypesSuccess', + payload: [ + { + name: 'MIT', + }, + ], + }, + ], + done, + ); + }); + }); + + describe('error', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/templates\/licenses/).replyOnce(500); + }); + + it('dispatches actions', done => { + state.selectedTemplateType = { + key: 'licenses', + }; + + testAction( + actions.fetchTemplateTypes, + null, + state, + [], + [ + { + type: 'requestTemplateTypes', + }, + { + type: 'receiveTemplateTypesError', + }, + ], + done, + ); + }); + }); + }); + + describe('setSelectedTemplateType', () => { + it('commits SET_SELECTED_TEMPLATE_TYPE', done => { + testAction( + actions.setSelectedTemplateType, + 'test', + state, + [{ type: types.SET_SELECTED_TEMPLATE_TYPE, payload: 'test' }], + [], + done, + ); + }); + }); + + describe('receiveTemplateError', () => { + it('dispatches setErrorMessage', done => { + testAction( + actions.receiveTemplateError, + 'test', + state, + [], + [ + { + type: 'setErrorMessage', + payload: { + action: jasmine.any(Function), + actionText: 'Please try again', + text: 'Error loading template.', + actionPayload: 'test', + }, + }, + ], + done, + ); + }); + }); + + describe('fetchTemplate', () => { + describe('success', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/templates\/licenses\/mit/).replyOnce(200, { + content: 'MIT content', + }); + mock.onGet(/api\/(.*)\/templates\/licenses\/testing/).replyOnce(200, { + content: 'testing content', + }); + }); + + it('dispatches setFileTemplate if template already has content', done => { + const template = { + content: 'already has content', + }; + + testAction( + actions.fetchTemplate, + template, + state, + [], + [{ type: 'setFileTemplate', payload: template }], + done, + ); + }); + + it('dispatches success', done => { + const template = { + key: 'mit', + }; + + state.selectedTemplateType = { + key: 'licenses', + }; + + testAction( + actions.fetchTemplate, + template, + state, + [], + [{ type: 'setFileTemplate', payload: { content: 'MIT content' } }], + done, + ); + }); + + it('dispatches success and uses name key for API call', done => { + const template = { + name: 'testing', + }; + + state.selectedTemplateType = { + key: 'licenses', + }; + + testAction( + actions.fetchTemplate, + template, + state, + [], + [{ type: 'setFileTemplate', payload: { content: 'testing content' } }], + done, + ); + }); + }); + + describe('error', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/templates\/licenses\/mit/).replyOnce(500); + }); + + it('dispatches error', done => { + const template = { + name: 'testing', + }; + + state.selectedTemplateType = { + key: 'licenses', + }; + + testAction( + actions.fetchTemplate, + template, + state, + [], + [{ type: 'receiveTemplateError', payload: template }], + done, + ); + }); + }); + }); + + describe('setFileTemplate', () => { + it('dispatches changeFileContent', () => { + const dispatch = jasmine.createSpy('dispatch'); + const commit = jasmine.createSpy('commit'); + const rootGetters = { + activeFile: { path: 'test' }, + }; + + actions.setFileTemplate({ dispatch, commit, rootGetters }, { content: 'content' }); + + expect(dispatch).toHaveBeenCalledWith( + 'changeFileContent', + { path: 'test', content: 'content' }, + { root: true }, + ); + }); + + it('commits SET_UPDATE_SUCCESS', () => { + const dispatch = jasmine.createSpy('dispatch'); + const commit = jasmine.createSpy('commit'); + const rootGetters = { + activeFile: { path: 'test' }, + }; + + actions.setFileTemplate({ dispatch, commit, rootGetters }, { content: 'content' }); + + expect(commit).toHaveBeenCalledWith('SET_UPDATE_SUCCESS', true); + }); + }); + + describe('undoFileTemplate', () => { + it('dispatches changeFileContent', () => { + const dispatch = jasmine.createSpy('dispatch'); + const commit = jasmine.createSpy('commit'); + const rootGetters = { + activeFile: { path: 'test', raw: 'raw content' }, + }; + + actions.undoFileTemplate({ dispatch, commit, rootGetters }); + + expect(dispatch).toHaveBeenCalledWith( + 'changeFileContent', + { path: 'test', content: 'raw content' }, + { root: true }, + ); + }); + + it('commits SET_UPDATE_SUCCESS', () => { + const dispatch = jasmine.createSpy('dispatch'); + const commit = jasmine.createSpy('commit'); + const rootGetters = { + activeFile: { path: 'test', raw: 'raw content' }, + }; + + actions.undoFileTemplate({ dispatch, commit, rootGetters }); + + expect(commit).toHaveBeenCalledWith('SET_UPDATE_SUCCESS', false); + }); + }); +}); diff --git a/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js b/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js new file mode 100644 index 00000000000..e337c3f331b --- /dev/null +++ b/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js @@ -0,0 +1,30 @@ +import * as getters from '~/ide/stores/modules/file_templates/getters'; + +describe('IDE file templates getters', () => { + describe('templateTypes', () => { + it('returns list of template types', () => { + expect(getters.templateTypes().length).toBe(4); + }); + }); + + describe('showFileTemplatesBar', () => { + it('finds template type by name', () => { + expect( + getters.showFileTemplatesBar(null, { + templateTypes: getters.templateTypes(), + })('LICENSE'), + ).toEqual({ + name: 'LICENSE', + key: 'licenses', + }); + }); + + it('returns undefined if not found', () => { + expect( + getters.showFileTemplatesBar(null, { + templateTypes: getters.templateTypes(), + })('test'), + ).toBe(undefined); + }); + }); +}); diff --git a/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js new file mode 100644 index 00000000000..a51527d699f --- /dev/null +++ b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js @@ -0,0 +1,61 @@ +import createState from '~/ide/stores/modules/file_templates/state'; +import * as types from '~/ide/stores/modules/file_templates/mutation_types'; +import mutations from '~/ide/stores/modules/file_templates/mutations'; + +describe('IDE file templates mutations', () => { + let state; + + beforeEach(() => { + state = createState(); + }); + + describe(types.REQUEST_TEMPLATE_TYPES, () => { + it('sets isLoading', () => { + mutations[types.REQUEST_TEMPLATE_TYPES](state); + + expect(state.isLoading).toBe(true); + }); + }); + + describe(types.RECEIVE_TEMPLATE_TYPES_ERROR, () => { + it('sets isLoading', () => { + state.isLoading = true; + + mutations[types.RECEIVE_TEMPLATE_TYPES_ERROR](state); + + expect(state.isLoading).toBe(false); + }); + }); + + describe(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, () => { + it('sets isLoading to false', () => { + state.isLoading = true; + + mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, []); + + expect(state.isLoading).toBe(false); + }); + + it('sets templates', () => { + mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, ['test']); + + expect(state.templates).toEqual(['test']); + }); + }); + + describe(types.SET_SELECTED_TEMPLATE_TYPE, () => { + it('sets selectedTemplateType', () => { + mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, 'type'); + + expect(state.selectedTemplateType).toBe('type'); + }); + }); + + describe(types.SET_UPDATE_SUCCESS, () => { + it('sets updateSuccess', () => { + mutations[types.SET_UPDATE_SUCCESS](state, true); + + expect(state.updateSuccess).toBe(true); + }); + }); +}); diff --git a/spec/javascripts/jobs/artifacts_block_spec.js b/spec/javascripts/jobs/components/artifacts_block_spec.js index c544c6f3e89..a06d287b3fa 100644 --- a/spec/javascripts/jobs/artifacts_block_spec.js +++ b/spec/javascripts/jobs/components/artifacts_block_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import { getTimeago } from '~/lib/utils/datetime_utility'; import component from '~/jobs/components/artifacts_block.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Artifacts block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js index f755a5042b5..e21fa9c2874 100644 --- a/spec/javascripts/jobs/commit_block_spec.js +++ b/spec/javascripts/jobs/components/commit_block_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/commit_block.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Commit block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js index f8feb069fe0..dcc2b3d8a20 100644 --- a/spec/javascripts/jobs/empty_state_spec.js +++ b/spec/javascripts/jobs/components/empty_state_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/empty_state.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Empty State', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/components/environments_block_spec.js b/spec/javascripts/jobs/components/environments_block_spec.js new file mode 100644 index 00000000000..015c26be9fc --- /dev/null +++ b/spec/javascripts/jobs/components/environments_block_spec.js @@ -0,0 +1,137 @@ +import Vue from 'vue'; +import component from '~/jobs/components/environments_block.vue'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +describe('Environments block', () => { + const Component = Vue.extend(component); + let vm; + const icon = { + group: 'success', + icon: 'status_success', + label: 'passed', + text: 'passed', + tooltip: 'passed', + }; + const deployment = { + path: 'deployment', + name: 'deployment name', + }; + const environment = { + path: '/environment', + name: 'environment', + }; + + afterEach(() => { + vm.$destroy(); + }); + + describe('with latest deployment', () => { + it('renders info for most recent deployment', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'latest', + icon, + deployment, + environment, + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'This job is the most recent deployment to environment.', + ); + }); + }); + + describe('with out of date deployment', () => { + describe('with last deployment', () => { + it('renders info for out date and most recent', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'out_of_date', + icon, + deployment, + environment: Object.assign({}, environment, { + last_deployment: { name: 'deployment', path: 'last_deployment' }, + }), + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'This job is an out-of-date deployment to environment. View the most recent deployment deployment.', + ); + }); + }); + + describe('without last deployment', () => { + it('renders info about out of date deployment', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'out_of_date', + icon, + deployment: null, + environment, + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'This job is an out-of-date deployment to environment.', + ); + }); + }); + }); + + describe('with failed deployment', () => { + it('renders info about failed deployment', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'failed', + icon, + deployment: null, + environment, + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'The deployment of this job to environment did not succeed.', + ); + }); + }); + + describe('creating deployment', () => { + describe('with last deployment', () => { + it('renders info about creating deployment and overriding lastest deployment', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'creating', + icon, + deployment, + environment: Object.assign({}, environment, { + last_deployment: { name: 'deployment', path: 'last_deployment' }, + }), + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'This job is creating a deployment to environment and will overwrite the last deployment.', + ); + }); + }); + + describe('without last deployment', () => { + it('renders info about failed deployment', () => { + vm = mountComponent(Component, { + deploymentStatus: { + status: 'creating', + icon, + deployment: null, + environment, + }, + }); + + expect(vm.$el.textContent.trim()).toEqual( + 'This job is creating a deployment to environment.', + ); + }); + }); + }); +}); diff --git a/spec/javascripts/jobs/erased_block_spec.js b/spec/javascripts/jobs/components/erased_block_spec.js index 7cf32e984a2..a4ae0c7c81e 100644 --- a/spec/javascripts/jobs/erased_block_spec.js +++ b/spec/javascripts/jobs/components/erased_block_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import { getTimeago } from '~/lib/utils/datetime_utility'; import component from '~/jobs/components/erased_block.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Erased block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/header_spec.js b/spec/javascripts/jobs/components/header_spec.js index e21e2c6d6e3..e21e2c6d6e3 100644 --- a/spec/javascripts/jobs/header_spec.js +++ b/spec/javascripts/jobs/components/header_spec.js diff --git a/spec/javascripts/jobs/job_details_mediator_spec.js b/spec/javascripts/jobs/components/job_details_mediator_spec.js index ca5c9cf87e4..3e2fb7bfbbb 100644 --- a/spec/javascripts/jobs/job_details_mediator_spec.js +++ b/spec/javascripts/jobs/components/job_details_mediator_spec.js @@ -1,7 +1,7 @@ import MockAdapter from 'axios-mock-adapter'; import axios from '~/lib/utils/axios_utils'; import JobMediator from '~/jobs/job_details_mediator'; -import job from './mock_data'; +import job from '../mock_data'; describe('JobMediator', () => { let mediator; diff --git a/spec/javascripts/jobs/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js index 406f1c4ccc5..6a5b375a26c 100644 --- a/spec/javascripts/jobs/job_log_spec.js +++ b/spec/javascripts/jobs/components/job_log_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/job_log.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Job Log', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/job_store_spec.js b/spec/javascripts/jobs/components/job_store_spec.js index d00faf29d1e..0dad5111b32 100644 --- a/spec/javascripts/jobs/job_store_spec.js +++ b/spec/javascripts/jobs/components/job_store_spec.js @@ -1,5 +1,5 @@ import JobStore from '~/jobs/stores/job_store'; -import job from './mock_data'; +import job from '../mock_data'; describe('Job Store', () => { let store; diff --git a/spec/javascripts/jobs/jobs_container_spec.js b/spec/javascripts/jobs/components/jobs_container_spec.js index bf52e65cbc8..f3f8ff0d031 100644 --- a/spec/javascripts/jobs/jobs_container_spec.js +++ b/spec/javascripts/jobs/components/jobs_container_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/jobs_container.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Artifacts block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/sidebar_detail_row_spec.js b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js index e6bfb0c4adc..e6bfb0c4adc 100644 --- a/spec/javascripts/jobs/sidebar_detail_row_spec.js +++ b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js diff --git a/spec/javascripts/jobs/sidebar_details_block_spec.js b/spec/javascripts/jobs/components/sidebar_details_block_spec.js index 21ef5650b80..ba19534dac2 100644 --- a/spec/javascripts/jobs/sidebar_details_block_spec.js +++ b/spec/javascripts/jobs/components/sidebar_details_block_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import sidebarDetailsBlock from '~/jobs/components/sidebar_details_block.vue'; -import job from './mock_data'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import job from '../mock_data'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Sidebar details block', () => { let SidebarComponent; diff --git a/spec/javascripts/jobs/stages_dropdown_spec.js b/spec/javascripts/jobs/components/stages_dropdown_spec.js index d3a5d48f56c..402289345aa 100644 --- a/spec/javascripts/jobs/stages_dropdown_spec.js +++ b/spec/javascripts/jobs/components/stages_dropdown_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/stages_dropdown.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Artifacts block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/stuck_block_spec.js b/spec/javascripts/jobs/components/stuck_block_spec.js index 4e2108dfdfb..c320793b2be 100644 --- a/spec/javascripts/jobs/stuck_block_spec.js +++ b/spec/javascripts/jobs/components/stuck_block_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/stuck_block.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Stuck Block Job component', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/jobs/trigger_value_spec.js b/spec/javascripts/jobs/components/trigger_value_spec.js index acf91510ed2..3d41a3cfac1 100644 --- a/spec/javascripts/jobs/trigger_value_spec.js +++ b/spec/javascripts/jobs/components/trigger_value_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import component from '~/jobs/components/trigger_block.vue'; -import mountComponent from '../helpers/vue_mount_component_helper'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('Trigger block', () => { const Component = Vue.extend(component); diff --git a/spec/javascripts/performance_bar/services/performance_bar_service_spec.js b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js new file mode 100644 index 00000000000..bc6947dbe81 --- /dev/null +++ b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js @@ -0,0 +1,63 @@ +import PerformanceBarService from '~/performance_bar/services/performance_bar_service'; + +describe('PerformanceBarService', () => { + describe('callbackParams', () => { + describe('fireCallback', () => { + function fireCallback(response, peekUrl) { + return PerformanceBarService.callbackParams(response, peekUrl)[0]; + } + + it('returns false when the request URL is the peek URL', () => { + expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/peek' }, '/peek')) + .toBeFalsy(); + }); + + it('returns false when there is no request ID', () => { + expect(fireCallback({ headers: {}, url: '/request' }, '/peek')) + .toBeFalsy(); + }); + + it('returns false when the request is an API request', () => { + expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/api/' }, '/peek')) + .toBeFalsy(); + }); + + it('returns false when the response is from the cache', () => { + expect(fireCallback({ headers: { 'x-request-id': '123', 'x-gitlab-from-cache': 'true' }, url: '/request' }, '/peek')) + .toBeFalsy(); + }); + + it('returns true when all conditions are met', () => { + expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/request' }, '/peek')) + .toBeTruthy(); + }); + }); + + describe('requestId', () => { + function requestId(response, peekUrl) { + return PerformanceBarService.callbackParams(response, peekUrl)[1]; + } + + it('gets the request ID from the headers', () => { + expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek')) + .toEqual('123'); + }); + }); + + describe('requestUrl', () => { + function requestUrl(response, peekUrl) { + return PerformanceBarService.callbackParams(response, peekUrl)[2]; + } + + it('gets the request URL from the response object', () => { + expect(requestUrl({ headers: {}, url: '/request' }, '/peek')) + .toEqual('/request'); + }); + + it('gets the request URL from response.config if present', () => { + expect(requestUrl({ headers: {}, config: { url: '/config-url' }, url: '/request' }, '/peek')) + .toEqual('/config-url'); + }); + }); + }); +}); diff --git a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js index ff584396d61..2b47ca236b2 100644 --- a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js +++ b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js @@ -82,12 +82,4 @@ describe('dropdown job component', () => { it('renders dropdown with jobs', () => { expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(mock.jobs.length); }); - - it('escapes tooltip title', () => { - expect( - vm.$el.querySelector('.js-pipeline-graph-job-link').getAttribute('data-original-title'), - ).toEqual( - '<img src=x onerror=alert(document.domain)> - passed', - ); - }); }); diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_component_spec.js index 215ce1e81b5..0ae448f2ea8 100644 --- a/spec/javascripts/pipelines/graph/job_component_spec.js +++ b/spec/javascripts/pipelines/graph/job_component_spec.js @@ -161,24 +161,4 @@ describe('pipeline graph job component', () => { expect(component.$el.querySelector(tooltipBoundary)).toBeNull(); }); }); - - describe('tooltipText', () => { - it('escapes job name', () => { - component = mountComponent(JobComponent, { - job: { - id: 4259, - name: '<img src=x onerror=alert(document.domain)>', - status: { - icon: 'status_success', - label: 'success', - tooltip: 'failed', - }, - }, - }); - - expect( - component.$el.querySelector('.js-job-component-tooltip').getAttribute('data-original-title'), - ).toEqual('<img src=x onerror=alert(document.domain)> - failed'); - }); - }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js index 8ac2f26979b..0e42537faed 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js @@ -45,7 +45,7 @@ describe('MRWidgetHeader', () => { }); }); - describe('commitsText', () => { + describe('commitsBehindText', () => { it('returns singular when there is one commit', () => { vm = mountComponent(Component, { mr: { @@ -53,11 +53,12 @@ describe('MRWidgetHeader', () => { sourceBranch: 'mr-widget-refactor', sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>', targetBranch: 'master', + targetBranchPath: '/foo/bar/master', statusPath: 'abc', }, }); - expect(vm.commitsText).toEqual('1 commit behind'); + expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch'); }); it('returns plural when there is more than one commit', () => { @@ -67,11 +68,12 @@ describe('MRWidgetHeader', () => { sourceBranch: 'mr-widget-refactor', sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>', targetBranch: 'master', + targetBranchPath: '/foo/bar/master', statusPath: 'abc', }, }); - expect(vm.commitsText).toEqual('2 commits behind'); + expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch'); }); }); }); @@ -280,9 +282,9 @@ describe('MRWidgetHeader', () => { }); it('renders diverged commits info', () => { - expect(vm.$el.querySelector('.diverged-commits-count').textContent).toMatch( - /(mr-widget-refactor[\s\S]+?is 12 commits behind[\s\S]+?master)/, - ); + expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual('The source branch is 12 commits behind the target branch'); + expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual('12 commits behind'); + expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr('href', vm.mr.targetBranchPath); }); }); }); diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js index 076d940961d..f1fe2e996fc 100644 --- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js +++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js @@ -44,7 +44,11 @@ describe('StackedProgressBarComponent', () => { }); it('returns percentage with decimal place from provided count based on `totalCount`', () => { - expect(vm.getPercent(10)).toBe(0.2); + expect(vm.getPercent(67)).toBe(1.3); + }); + + it('returns percentage as `< 1` from provided count based on `totalCount` when evaluated value is less than 1', () => { + expect(vm.getPercent(10)).toBe('< 1'); }); }); diff --git a/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js new file mode 100644 index 00000000000..8465757deb6 --- /dev/null +++ b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js @@ -0,0 +1,162 @@ +import { mountComponentWithRender } from 'spec/helpers/vue_mount_component_helper'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; + +const TEST_TITLE = 'lorem-ipsum-dolar-sit-amit-consectur-adipiscing-elit-sed-do'; +const CLASS_SHOW_TOOLTIP = 'js-show-tooltip'; +const STYLE_TRUNCATED = { + display: 'inline-block', + 'max-width': '20px', +}; +const STYLE_NORMAL = { + display: 'inline-block', + 'max-width': '1000px', +}; + +function mountTooltipOnTruncate(options, createChildren) { + return mountComponentWithRender(h => h(TooltipOnTruncate, options, createChildren(h)), '#app'); +} + +describe('TooltipOnTruncate component', () => { + let vm; + + beforeEach(() => { + const el = document.createElement('div'); + el.id = 'app'; + document.body.appendChild(el); + }); + + afterEach(() => { + vm.$destroy(); + }); + + describe('with default target', () => { + it('renders tooltip if truncated', done => { + const options = { + style: STYLE_TRUNCATED, + props: { + title: TEST_TITLE, + }, + }; + + vm = mountTooltipOnTruncate(options, () => [TEST_TITLE]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP); + expect(vm.$el).toHaveData('original-title', TEST_TITLE); + expect(vm.$el).toHaveData('placement', 'top'); + }) + .then(done) + .catch(done.fail); + }); + + it('does not render tooltip if normal', done => { + const options = { + style: STYLE_NORMAL, + props: { + title: TEST_TITLE, + }, + }; + + vm = mountTooltipOnTruncate(options, () => [TEST_TITLE]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).not.toHaveClass(CLASS_SHOW_TOOLTIP); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('with child target', () => { + it('renders tooltip if truncated', done => { + const options = { + style: STYLE_NORMAL, + props: { + title: TEST_TITLE, + truncateTarget: 'child', + }, + }; + + vm = mountTooltipOnTruncate(options, (h) => [ + h('a', { style: STYLE_TRUNCATED }, TEST_TITLE), + ]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP); + }) + .then(done) + .catch(done.fail); + }); + + it('does not render tooltip if normal', done => { + const options = { + props: { + title: TEST_TITLE, + truncateTarget: 'child', + }, + }; + + vm = mountTooltipOnTruncate(options, (h) => [ + h('a', { style: STYLE_NORMAL }, TEST_TITLE), + ]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).not.toHaveClass(CLASS_SHOW_TOOLTIP); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('with fn target', () => { + it('renders tooltip if truncated', done => { + const options = { + style: STYLE_NORMAL, + props: { + title: TEST_TITLE, + truncateTarget: (el) => el.childNodes[1], + }, + }; + + vm = mountTooltipOnTruncate(options, (h) => [ + h('a', { style: STYLE_NORMAL }, TEST_TITLE), + h('span', { style: STYLE_TRUNCATED }, TEST_TITLE), + ]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('placement', () => { + it('sets data-placement when tooltip is rendered', done => { + const options = { + props: { + title: TEST_TITLE, + truncateTarget: 'child', + placement: 'bottom', + }, + }; + + vm = mountTooltipOnTruncate(options, (h) => [ + h('a', { style: STYLE_TRUNCATED }, TEST_TITLE), + ]); + + vm.$nextTick() + .then(() => { + expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP); + expect(vm.$el).toHaveData('placement', options.props.placement); + }) + .then(done) + .catch(done.fail); + }); + }); +}); diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb index f313e675654..8bb5a843484 100644 --- a/spec/lib/feature_spec.rb +++ b/spec/lib/feature_spec.rb @@ -1,6 +1,13 @@ require 'spec_helper' describe Feature do + before do + # We mock all calls to .enabled? to return true in order to force all + # specs to run the feature flag gated behavior, but here we need a clean + # behavior from the class + allow(described_class).to receive(:enabled?).and_call_original + end + describe '.get' do let(:feature) { double(:feature) } let(:key) { 'my_feature' } @@ -106,4 +113,63 @@ describe Feature do it_behaves_like 'a memoized Flipper instance' end end + + describe '.enabled?' do + it 'returns false for undefined feature' do + expect(described_class.enabled?(:some_random_feature_flag)).to be_falsey + end + + it 'returns false for existing disabled feature in the database' do + described_class.disable(:disabled_feature_flag) + + expect(described_class.enabled?(:disabled_feature_flag)).to be_falsey + end + + it 'returns true for existing enabled feature in the database' do + described_class.enable(:enabled_feature_flag) + + expect(described_class.enabled?(:enabled_feature_flag)).to be_truthy + end + + context 'with an individual actor' do + CustomActor = Struct.new(:flipper_id) + + let(:actor) { CustomActor.new(flipper_id: 'CustomActor:5') } + let(:another_actor) { CustomActor.new(flipper_id: 'CustomActor:10') } + + before do + described_class.enable(:enabled_feature_flag, actor) + end + + it 'returns true when same actor is informed' do + expect(described_class.enabled?(:enabled_feature_flag, actor)).to be_truthy + end + + it 'returns false when different actor is informed' do + expect(described_class.enabled?(:enabled_feature_flag, another_actor)).to be_falsey + end + + it 'returns false when no actor is informed' do + expect(described_class.enabled?(:enabled_feature_flag)).to be_falsey + end + end + end + + describe '.disable?' do + it 'returns true for undefined feature' do + expect(described_class.disabled?(:some_random_feature_flag)).to be_truthy + end + + it 'returns true for existing disabled feature in the database' do + described_class.disable(:disabled_feature_flag) + + expect(described_class.disabled?(:disabled_feature_flag)).to be_truthy + end + + it 'returns false for existing enabled feature in the database' do + described_class.enable(:enabled_feature_flag) + + expect(described_class.disabled?(:enabled_feature_flag)).to be_falsey + end + end end diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb index eff21985108..7800c543cdb 100644 --- a/spec/lib/gitlab/auth/ldap/access_spec.rb +++ b/spec/lib/gitlab/auth/ldap/access_spec.rb @@ -3,51 +3,61 @@ require 'spec_helper' describe Gitlab::Auth::LDAP::Access do include LdapHelpers - let(:access) { described_class.new user } let(:user) { create(:omniauth_user) } + subject(:access) { described_class.new(user) } + describe '.allowed?' do - it 'updates the users `last_credential_check_at' do + before do allow(access).to receive(:update_user) - expect(access).to receive(:allowed?) { true } - expect(described_class).to receive(:open).and_yield(access) + allow(access).to receive(:allowed?).and_return(true) + allow(described_class).to receive(:open).and_yield(access) + end + it "updates the user's `last_credential_check_at`" do expect { described_class.allowed?(user) } .to change { user.last_credential_check_at } end - end - describe '#find_ldap_user' do - it 'finds a user by dn first' do - expect(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(:ldap_user) + it "does not update user's `last_credential_check_at` when in a read-only GitLab instance" do + allow(Gitlab::Database).to receive(:read_only?).and_return(true) - access.find_ldap_user + expect { described_class.allowed?(user) } + .not_to change { user.last_credential_check_at } end end describe '#allowed?' do - subject { access.allowed? } - context 'when the user cannot be found' do before do - allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(nil) - allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_email).and_return(nil) + stub_ldap_person_find_by_dn(nil) + stub_ldap_person_find_by_email(user.email, nil) end - it { is_expected.to be_falsey } + it 'returns false' do + expect(access.allowed?).to be_falsey + end it 'blocks user in GitLab' do - expect(access).to receive(:block_user).with(user, 'does not exist anymore') + access.allowed? + + expect(user).to be_blocked + expect(user).to be_ldap_blocked + end + + it 'logs the reason' do + expect(Gitlab::AppLogger).to receive(:info).with( + "LDAP account \"123456\" does not exist anymore, " \ + "blocking Gitlab user \"#{user.name}\" (#{user.email})" + ) access.allowed? end end context 'when the user is found' do - let(:ldap_user) { Gitlab::Auth::LDAP::Person.new(Net::LDAP::Entry.new, 'ldapmain') } - before do - allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user) + stub_ldap_person_find_by_dn(Net::LDAP::Entry.new) end context 'and the user is disabled via active directory' do @@ -55,10 +65,22 @@ describe Gitlab::Auth::LDAP::Access do allow(Gitlab::Auth::LDAP::Person).to receive(:disabled_via_active_directory?).and_return(true) end - it { is_expected.to be_falsey } + it 'returns false' do + expect(access.allowed?).to be_falsey + end it 'blocks user in GitLab' do - expect(access).to receive(:block_user).with(user, 'is disabled in Active Directory') + access.allowed? + + expect(user).to be_blocked + expect(user).to be_ldap_blocked + end + + it 'logs the reason' do + expect(Gitlab::AppLogger).to receive(:info).with( + "LDAP account \"123456\" is disabled in Active Directory, " \ + "blocking Gitlab user \"#{user.name}\" (#{user.email})" + ) access.allowed? end @@ -92,7 +114,17 @@ describe Gitlab::Auth::LDAP::Access do end it 'unblocks user in GitLab' do - expect(access).to receive(:unblock_user).with(user, 'is not disabled anymore') + access.allowed? + + expect(user).not_to be_blocked + expect(user).not_to be_ldap_blocked + end + + it 'logs the reason' do + expect(Gitlab::AppLogger).to receive(:info).with( + "LDAP account \"123456\" is not disabled anymore, " \ + "unblocking Gitlab user \"#{user.name}\" (#{user.email})" + ) access.allowed? end @@ -105,18 +137,32 @@ describe Gitlab::Auth::LDAP::Access do allow_any_instance_of(Gitlab::Auth::LDAP::Config).to receive(:active_directory).and_return(false) end - it { is_expected.to be_truthy } + it 'returns true' do + expect(access.allowed?).to be_truthy + end context 'when user cannot be found' do before do - allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(nil) - allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_email).and_return(nil) + stub_ldap_person_find_by_dn(nil) + stub_ldap_person_find_by_email(user.email, nil) end - it { is_expected.to be_falsey } + it 'returns false' do + expect(access.allowed?).to be_falsey + end it 'blocks user in GitLab' do - expect(access).to receive(:block_user).with(user, 'does not exist anymore') + access.allowed? + + expect(user).to be_blocked + expect(user).to be_ldap_blocked + end + + it 'logs the reason' do + expect(Gitlab::AppLogger).to receive(:info).with( + "LDAP account \"123456\" does not exist anymore, " \ + "blocking Gitlab user \"#{user.name}\" (#{user.email})" + ) access.allowed? end @@ -128,7 +174,17 @@ describe Gitlab::Auth::LDAP::Access do end it 'unblocks the user if it exists' do - expect(access).to receive(:unblock_user).with(user, 'is available again') + access.allowed? + + expect(user).not_to be_blocked + expect(user).not_to be_ldap_blocked + end + + it 'logs the reason' do + expect(Gitlab::AppLogger).to receive(:info).with( + "LDAP account \"123456\" is available again, " \ + "unblocking Gitlab user \"#{user.name}\" (#{user.email})" + ) access.allowed? end @@ -152,46 +208,4 @@ describe Gitlab::Auth::LDAP::Access do end end end - - describe '#block_user' do - before do - user.activate - allow(Gitlab::AppLogger).to receive(:info) - - access.block_user user, 'reason' - end - - it 'blocks the user' do - expect(user).to be_blocked - expect(user).to be_ldap_blocked - end - - it 'logs the reason' do - expect(Gitlab::AppLogger).to have_received(:info).with( - "LDAP account \"123456\" reason, " \ - "blocking Gitlab user \"#{user.name}\" (#{user.email})" - ) - end - end - - describe '#unblock_user' do - before do - user.ldap_block - allow(Gitlab::AppLogger).to receive(:info) - - access.unblock_user user, 'reason' - end - - it 'activates the user' do - expect(user).not_to be_blocked - expect(user).not_to be_ldap_blocked - end - - it 'logs the reason' do - Gitlab::AppLogger.info( - "LDAP account \"123456\" reason, " \ - "unblocking Gitlab user \"#{user.name}\" (#{user.email})" - ) - end - end end diff --git a/spec/lib/gitlab/auth/o_auth/provider_spec.rb b/spec/lib/gitlab/auth/o_auth/provider_spec.rb index fc35d430917..80d702cf9dc 100644 --- a/spec/lib/gitlab/auth/o_auth/provider_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/provider_spec.rb @@ -1,6 +1,48 @@ require 'spec_helper' describe Gitlab::Auth::OAuth::Provider do + describe '.enabled?' do + before do + allow(described_class).to receive(:providers).and_return([:ldapmain, :google_oauth2]) + end + + context 'when OmniAuth is disabled' do + before do + allow(Gitlab::Auth).to receive(:omniauth_enabled?).and_return(false) + end + + it 'allows database auth' do + expect(described_class.enabled?('database')).to be_truthy + end + + it 'allows LDAP auth' do + expect(described_class.enabled?('ldapmain')).to be_truthy + end + + it 'does not allow other OmniAuth providers' do + expect(described_class.enabled?('google_oauth2')).to be_falsey + end + end + + context 'when OmniAuth is enabled' do + before do + allow(Gitlab::Auth).to receive(:omniauth_enabled?).and_return(true) + end + + it 'allows database auth' do + expect(described_class.enabled?('database')).to be_truthy + end + + it 'allows LDAP auth' do + expect(described_class.enabled?('ldapmain')).to be_truthy + end + + it 'allows other OmniAuth providers' do + expect(described_class.enabled?('google_oauth2')).to be_truthy + end + end + end + describe '#config_for' do context 'for an LDAP provider' do context 'when the provider exists' do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index d53a7d468e3..8b92088902b 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -88,7 +88,7 @@ describe Gitlab::Ci::Status::Build::Factory do expect(status.icon).to eq 'status_failed' expect(status.favicon).to eq 'favicon_status_failed' expect(status.label).to eq 'failed' - expect(status.status_tooltip).to eq 'failed <br> (unknown failure)' + expect(status.status_tooltip).to eq 'failed - (unknown failure)' expect(status).to have_details expect(status).to have_action end diff --git a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb index bfaa508785e..af03d5a1308 100644 --- a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb +++ b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb @@ -76,7 +76,7 @@ describe Gitlab::Ci::Status::Build::FailedAllowed do let(:status) { described_class.new(build_status) } it 'does override badge_tooltip' do - expect(status.badge_tooltip).to eq('failed <br> (unknown failure)') + expect(status.badge_tooltip).to eq('failed - (unknown failure)') end end @@ -87,7 +87,7 @@ describe Gitlab::Ci::Status::Build::FailedAllowed do let(:status) { described_class.new(build_status) } it 'does override status_tooltip' do - expect(status.status_tooltip).to eq 'failed <br> (unknown failure) (allowed to fail)' + expect(status.status_tooltip).to eq 'failed - (unknown failure) (allowed to fail)' end end diff --git a/spec/lib/gitlab/ci/status/build/failed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_spec.rb index b6676b40fd3..e424270f7c5 100644 --- a/spec/lib/gitlab/ci/status/build/failed_spec.rb +++ b/spec/lib/gitlab/ci/status/build/failed_spec.rb @@ -52,7 +52,7 @@ describe Gitlab::Ci::Status::Build::Failed do let(:status) { Gitlab::Ci::Status::Failed.new(build, user) } it 'does override badge_tooltip' do - expect(subject.badge_tooltip).to eq 'failed <br> (script failure)' + expect(subject.badge_tooltip).to eq 'failed - (script failure)' end end @@ -61,7 +61,7 @@ describe Gitlab::Ci::Status::Build::Failed do let(:status) { Gitlab::Ci::Status::Failed.new(build, user) } it 'does override status_tooltip' do - expect(subject.status_tooltip).to eq 'failed <br> (script failure)' + expect(subject.status_tooltip).to eq 'failed - (script failure)' end end diff --git a/spec/lib/gitlab/ci/status/build/retried_spec.rb b/spec/lib/gitlab/ci/status/build/retried_spec.rb index ee9acaf1c21..76c2fb01e3f 100644 --- a/spec/lib/gitlab/ci/status/build/retried_spec.rb +++ b/spec/lib/gitlab/ci/status/build/retried_spec.rb @@ -66,7 +66,7 @@ describe Gitlab::Ci::Status::Build::Retried do let(:status) { Gitlab::Ci::Status::Build::Failed.new(failed_status) } it 'does override status_tooltip' do - expect(subject.status_tooltip).to eq 'failed <br> (unknown failure) (retried)' + expect(subject.status_tooltip).to eq 'failed - (unknown failure) (retried)' end end diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index 5b343920429..9095ffbfd52 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -69,10 +69,6 @@ describe Gitlab::Conflict::File do CGI.unescapeHTML(ActionView::Base.full_sanitizer.sanitize(html)).delete("\n") end - it 'modifies the existing lines' do - expect { conflict_file.highlight_lines! }.to change { conflict_file.lines.map(&:instance_variables) } - end - it 'is called implicitly when rich_text is accessed on a line' do expect(conflict_file).to receive(:highlight_lines!).once.and_call_original diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb index 7c9e8c8d04e..3c8cf9c56cc 100644 --- a/spec/lib/gitlab/diff/highlight_spec.rb +++ b/spec/lib/gitlab/diff/highlight_spec.rb @@ -24,19 +24,19 @@ describe Gitlab::Diff::Highlight do it 'highlights and marks unchanged lines' do code = %Q{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n} - expect(subject[2].text).to eq(code) + expect(subject[2].rich_text).to eq(code) end it 'highlights and marks removed lines' do code = %Q{-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n} - expect(subject[4].text).to eq(code) + expect(subject[4].rich_text).to eq(code) end it 'highlights and marks added lines' do code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n} - expect(subject[5].text).to eq(code) + expect(subject[5].rich_text).to eq(code) end end @@ -69,8 +69,8 @@ describe Gitlab::Diff::Highlight do it 'marks added lines' do code = %q{+ raise <span class="idiff left right">RuntimeError, </span>"System commands must be given as an array of strings"} - expect(subject[5].text).to eq(code) - expect(subject[5].text).to be_html_safe + expect(subject[5].rich_text).to eq(code) + expect(subject[5].rich_text).to be_html_safe end context 'when the inline diff marker has an invalid range' do diff --git a/spec/lib/gitlab/diff/line_spec.rb b/spec/lib/gitlab/diff/line_spec.rb new file mode 100644 index 00000000000..76d411973c7 --- /dev/null +++ b/spec/lib/gitlab/diff/line_spec.rb @@ -0,0 +1,22 @@ +describe Gitlab::Diff::Line do + describe '.init_from_hash' do + it 'round-trips correctly with to_hash' do + line = described_class.new('<input>', 'match', 0, 0, 1, + parent_file: double(:file), + line_code: double(:line_code), + rich_text: '<input>') + + expect(described_class.init_from_hash(line.to_hash).to_hash) + .to eq(line.to_hash) + end + end + + context "when setting rich text" do + it 'escapes any HTML special characters in the diff chunk header' do + subject = described_class.new("<input>", "", 0, 0, 0) + line = subject.as_json + + expect(line[:rich_text]).to eq("<input>") + end + end +end diff --git a/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb b/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb index 3f7a12144d5..65a2e1cb5cb 100644 --- a/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb @@ -92,7 +92,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach .with(issue) .and_return([user.id, true]) - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .with( { @@ -121,7 +121,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach .with(issue) .and_return([project.creator_id, false]) - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .with( { @@ -150,7 +150,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach .with(issue) .and_return([user.id, true]) - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key') @@ -185,7 +185,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach .and_return([user.id, true]) issue = build_stubbed(:issue, project: project) - allow(Gitlab::GithubImport) + allow(importer) .to receive(:insert_and_return_id) .and_return(issue.id) allow(project.issues).to receive(:find).with(issue.id).and_return(issue) diff --git a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb index 44c920043b4..25684ea9e2c 100644 --- a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb @@ -80,7 +80,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi end it 'imports the pull request with the pull request author as the merge request author' do - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .with( { @@ -114,7 +114,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi it 'triggers internal_id functionality to track greatest iids' do mr = build_stubbed(:merge_request, source_project: project, target_project: project) - allow(Gitlab::GithubImport).to receive(:insert_and_return_id).and_return(mr.id) + allow(importer).to receive(:insert_and_return_id).and_return(mr.id) allow(project.merge_requests).to receive(:find).with(mr.id).and_return(mr) expect(mr).to receive(:ensure_target_project_iid!) @@ -135,7 +135,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi .with(pull_request) .and_return(user.id) - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .with( { @@ -181,7 +181,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi .to receive(:source_branch) .and_return('master') - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .with( { @@ -219,7 +219,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi .with(pull_request) .and_return(user.id) - expect(Gitlab::GithubImport) + expect(importer) .to receive(:insert_and_return_id) .and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key') diff --git a/spec/lib/gitlab/github_import_spec.rb b/spec/lib/gitlab/github_import_spec.rb index 51414800e8c..496244c91bf 100644 --- a/spec/lib/gitlab/github_import_spec.rb +++ b/spec/lib/gitlab/github_import_spec.rb @@ -27,39 +27,6 @@ describe Gitlab::GithubImport do end end - describe '.insert_and_return_id' do - let(:attributes) { { iid: 1, title: 'foo' } } - let(:project) { create(:project) } - - context 'on PostgreSQL' do - it 'returns the ID returned by the query' do - expect(Gitlab::Database) - .to receive(:bulk_insert) - .with(Issue.table_name, [attributes], return_ids: true) - .and_return([10]) - - id = described_class.insert_and_return_id(attributes, project.issues) - - expect(id).to eq(10) - end - end - - context 'on MySQL' do - it 'uses a separate query to retrieve the ID' do - issue = create(:issue, project: project, iid: attributes[:iid]) - - expect(Gitlab::Database) - .to receive(:bulk_insert) - .with(Issue.table_name, [attributes], return_ids: true) - .and_return([]) - - id = described_class.insert_and_return_id(attributes, project.issues) - - expect(id).to eq(issue.id) - end - end - end - describe '.ghost_user_id', :clean_gitlab_redis_cache do it 'returns the ID of the ghost user' do expect(described_class.ghost_user_id).to eq(User.ghost.id) diff --git a/spec/lib/gitlab/import/database_helpers_spec.rb b/spec/lib/gitlab/import/database_helpers_spec.rb new file mode 100644 index 00000000000..e716155b7d5 --- /dev/null +++ b/spec/lib/gitlab/import/database_helpers_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Import::DatabaseHelpers do + let(:database_helper) do + Class.new do + include Gitlab::Import::DatabaseHelpers + end + end + + subject { database_helper.new } + + describe '.insert_and_return_id' do + let(:attributes) { { iid: 1, title: 'foo' } } + let(:project) { create(:project) } + + context 'on PostgreSQL' do + it 'returns the ID returned by the query' do + expect(Gitlab::Database) + .to receive(:bulk_insert) + .with(Issue.table_name, [attributes], return_ids: true) + .and_return([10]) + + id = subject.insert_and_return_id(attributes, project.issues) + + expect(id).to eq(10) + end + end + + context 'on MySQL' do + it 'uses a separate query to retrieve the ID' do + issue = create(:issue, project: project, iid: attributes[:iid]) + + expect(Gitlab::Database) + .to receive(:bulk_insert) + .with(Issue.table_name, [attributes], return_ids: true) + .and_return([]) + + id = subject.insert_and_return_id(attributes, project.issues) + + expect(id).to eq(issue.id) + end + end + end +end diff --git a/spec/lib/gitlab/import/merge_request_creator_spec.rb b/spec/lib/gitlab/import/merge_request_creator_spec.rb new file mode 100644 index 00000000000..7c73e9b39f7 --- /dev/null +++ b/spec/lib/gitlab/import/merge_request_creator_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Import::MergeRequestCreator do + let(:project) { create(:project, :repository) } + + subject { described_class.new(project) } + + describe '#execute' do + context 'merge request already exists' do + let(:merge_request) { create(:merge_request, target_project: project, source_project: project) } + let(:commits) { merge_request.merge_request_diffs.first.commits } + let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes.except("merge_params")) } + + it 'updates the data' do + commits_count = commits.count + merge_request.merge_request_diffs.destroy_all # rubocop: disable DestroyAll + + expect(merge_request.merge_request_diffs.count).to eq(0) + + subject.execute(attributes) + + expect(merge_request.reload.merge_request_diffs.count).to eq(1) + expect(merge_request.reload.merge_request_diffs.first.commits.count).to eq(commits_count) + end + end + + context 'new merge request' do + let(:merge_request) { build(:merge_request, target_project: project, source_project: project) } + let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes.except("merge_params")) } + + it 'creates a new merge request' do + attributes.delete(:id) + + expect { subject.execute(attributes) }.to change { MergeRequest.count }.by(1) + + new_mr = MergeRequest.last + expect(new_mr.merge_request_diffs.count).to eq(1) + end + end + end +end diff --git a/spec/lib/gitlab/import_export/uploads_manager_spec.rb b/spec/lib/gitlab/import_export/uploads_manager_spec.rb index 9c3870a0af8..f799de18cd0 100644 --- a/spec/lib/gitlab/import_export/uploads_manager_spec.rb +++ b/spec/lib/gitlab/import_export/uploads_manager_spec.rb @@ -36,6 +36,38 @@ describe Gitlab::ImportExport::UploadsManager do expect(File).to exist(exported_file_path) end + + context 'with orphaned project upload files' do + let(:orphan_path) { File.join(FileUploader.absolute_base_dir(project), 'f93f088ddf492ffd950cf059002cbbb6', 'orphan.jpg') } + let(:exported_orphan_path) { "#{shared.export_path}/uploads/f93f088ddf492ffd950cf059002cbbb6/orphan.jpg" } + + before do + FileUtils.mkdir_p(File.dirname(orphan_path)) + FileUtils.touch(orphan_path) + end + + after do + File.delete(orphan_path) if File.exist?(orphan_path) + end + + it 'excludes orphaned upload files' do + manager.save + + expect(File).not_to exist(exported_orphan_path) + end + end + + context 'with an upload missing its file' do + before do + File.delete(upload.absolute_path) + end + + it 'does not cause errors' do + manager.save + + expect(shared.errors).to be_empty + end + end end context 'using object storage' do diff --git a/spec/lib/gitlab/middleware/multipart_spec.rb b/spec/lib/gitlab/middleware/multipart_spec.rb index f788f8ee276..daf454665b0 100644 --- a/spec/lib/gitlab/middleware/multipart_spec.rb +++ b/spec/lib/gitlab/middleware/multipart_spec.rb @@ -75,6 +75,26 @@ describe Gitlab::Middleware::Multipart do it_behaves_like 'multipart upload files' end + it 'allows files in uploads/tmp directory' do + Dir.mktmpdir do |dir| + uploads_dir = File.join(dir, 'public/uploads/tmp') + FileUtils.mkdir_p(uploads_dir) + + allow(Rails).to receive(:root).and_return(dir) + allow(Dir).to receive(:tmpdir).and_return(File.join(Dir.tmpdir, 'tmpsubdir')) + + Tempfile.open('top-level', uploads_dir) do |tempfile| + env = post_env({ 'file' => tempfile.path }, { 'file.name' => original_filename, 'file.path' => tempfile.path }, Gitlab::Workhorse.secret, 'gitlab-workhorse') + + expect(app).to receive(:call) do |env| + expect(Rack::Request.new(env).params['file']).to be_a(::UploadedFile) + end + + middleware.call(env) + end + end + end + it 'allows symlinks for uploads dir' do Tempfile.open('two-levels') do |tempfile| symlinked_dir = '/some/dir/uploads' diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb index 6f5f9938eca..624e2add860 100644 --- a/spec/lib/gitlab/url_blocker_spec.rb +++ b/spec/lib/gitlab/url_blocker_spec.rb @@ -1,3 +1,4 @@ +# coding: utf-8 require 'spec_helper' describe Gitlab::UrlBlocker do @@ -82,6 +83,17 @@ describe Gitlab::UrlBlocker do expect(described_class).not_to be_blocked_url("http://#{ip}") end end + + it 'allows IPv4 link-local endpoints' do + expect(described_class).not_to be_blocked_url('http://169.254.169.254') + expect(described_class).not_to be_blocked_url('http://169.254.168.100') + end + + # This is blocked due to the hostname check: https://gitlab.com/gitlab-org/gitlab-ce/issues/50227 + it 'blocks IPv6 link-local endpoints' do + expect(described_class).to be_blocked_url('http://[::ffff:169.254.169.254]') + expect(described_class).to be_blocked_url('http://[::ffff:169.254.168.100]') + end end context 'false' do @@ -96,10 +108,21 @@ describe Gitlab::UrlBlocker do expect(described_class).to be_blocked_url("http://#{ip}", allow_local_network: false) end end + + it 'blocks IPv4 link-local endpoints' do + expect(described_class).to be_blocked_url('http://169.254.169.254', allow_local_network: false) + expect(described_class).to be_blocked_url('http://169.254.168.100', allow_local_network: false) + end + + it 'blocks IPv6 link-local endpoints' do + expect(described_class).to be_blocked_url('http://[::ffff:169.254.169.254]', allow_local_network: false) + expect(described_class).to be_blocked_url('http://[::ffff:169.254.168.100]', allow_local_network: false) + expect(described_class).to be_blocked_url('http://[FE80::C800:EFF:FE74:8]', allow_local_network: false) + end end def stub_domain_resolv(domain, ip) - allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true)]) + allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false)]) end def unstub_domain_resolv diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index a19b3c0ba66..de6dd2a9fea 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -56,6 +56,7 @@ describe Gitlab::UsageData do expect(count_data[:projects]).to eq(3) expect(count_data.keys).to match_array(%i( + assignee_lists boards ci_builds ci_internal_pipelines @@ -83,9 +84,11 @@ describe Gitlab::UsageData do groups issues keys + label_lists labels lfs_objects merge_requests + milestone_lists milestones notes projects diff --git a/spec/migrations/drop_duplicate_protected_tags_spec.rb b/spec/migrations/drop_duplicate_protected_tags_spec.rb new file mode 100644 index 00000000000..acfb6850722 --- /dev/null +++ b/spec/migrations/drop_duplicate_protected_tags_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20180711103851_drop_duplicate_protected_tags.rb') + +describe DropDuplicateProtectedTags, :migration do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:protected_tags) { table(:protected_tags) } + + before do + stub_const("#{described_class}::BATCH_SIZE", 2) + + namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org') + projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', path: 'gitlab1') + projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', path: 'gitlab2') + end + + it 'removes duplicated protected tags' do + protected_tags.create!(id: 1, project_id: 1, name: 'foo') + tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo1') + protected_tags.create!(id: 3, project_id: 1, name: 'foo') + tag4 = protected_tags.create!(id: 4, project_id: 1, name: 'foo') + tag5 = protected_tags.create!(id: 5, project_id: 2, name: 'foo') + + migrate! + + expect(protected_tags.all.count).to eq 3 + expect(protected_tags.all.pluck(:id)).to contain_exactly(tag2.id, tag4.id, tag5.id) + end + + it 'does not remove unique protected tags' do + tag1 = protected_tags.create!(id: 1, project_id: 1, name: 'foo1') + tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo2') + tag3 = protected_tags.create!(id: 3, project_id: 1, name: 'foo3') + + migrate! + + expect(protected_tags.all.count).to eq 3 + expect(protected_tags.all.pluck(:id)).to contain_exactly(tag1.id, tag2.id, tag3.id) + end +end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 5157d8fc645..d5f88e930d4 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -225,6 +225,12 @@ eos end describe 'description' do + it 'returns no_commit_message when safe_message is blank' do + allow(commit).to receive(:safe_message).and_return(nil) + + expect(commit.description).to eq('--no commit message') + end + it 'returns description of commit message if title less than 100 characters' do message = <<eos Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit. diff --git a/spec/models/concerns/awardable_spec.rb b/spec/models/concerns/awardable_spec.rb index a980cff28fb..69083bdc125 100644 --- a/spec/models/concerns/awardable_spec.rb +++ b/spec/models/concerns/awardable_spec.rb @@ -53,21 +53,14 @@ describe Awardable do issue.project.add_guest(user) end - it 'does not allow upvoting or downvoting your own issue' do - issue.update!(author: user) - - expect(issue.user_can_award?(user, AwardEmoji::DOWNVOTE_NAME)).to be_falsy - expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy - end - it 'is truthy when the user is allowed to award emoji' do - expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_truthy + expect(issue.user_can_award?(user)).to be_truthy end it 'is falsy when the project is archived' do issue.project.update!(archived: true) - expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy + expect(issue.user_can_award?(user)).to be_falsy end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 84edfc3ff00..c21d85fb2a4 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -188,98 +188,6 @@ describe Issue do end end - describe '#closed_by_merge_requests' do - let(:project) { create(:project, :repository) } - let(:issue) { create(:issue, project: project)} - let(:closed_issue) { build(:issue, :closed, project: project)} - - let(:mr) do - opts = { - title: 'Awesome merge_request', - description: "Fixes #{issue.to_reference}", - source_branch: 'feature', - target_branch: 'master' - } - MergeRequests::CreateService.new(project, project.owner, opts).execute - end - - let(:closed_mr) do - opts = { - title: 'Awesome merge_request 2', - description: "Fixes #{issue.to_reference}", - source_branch: 'feature', - target_branch: 'master', - state: 'closed' - } - MergeRequests::CreateService.new(project, project.owner, opts).execute - end - - it 'returns the merge request to close this issue' do - expect(issue.closed_by_merge_requests(mr.author)).to eq([mr]) - end - - it "returns an empty array when the merge request is closed already" do - expect(issue.closed_by_merge_requests(closed_mr.author)).to eq([]) - end - - it "returns an empty array when the current issue is closed already" do - expect(closed_issue.closed_by_merge_requests(closed_issue.author)).to eq([]) - end - end - - describe '#referenced_merge_requests' do - let(:project) { create(:project, :public) } - let(:issue) do - create(:issue, description: merge_request.to_reference, project: project) - end - let!(:merge_request) do - create(:merge_request, - source_project: project, - source_branch: 'master', - target_branch: 'feature') - end - - it 'returns the referenced merge requests' do - mr2 = create(:merge_request, - source_project: project, - source_branch: 'feature', - target_branch: 'master') - - create(:note_on_issue, - noteable: issue, - note: mr2.to_reference, - project_id: project.id) - - expect(issue.referenced_merge_requests).to eq([merge_request, mr2]) - end - - it 'returns cross project referenced merge requests' do - other_project = create(:project, :public) - cross_project_merge_request = create(:merge_request, source_project: other_project) - create(:note_on_issue, - noteable: issue, - note: cross_project_merge_request.to_reference(issue.project), - project_id: issue.project.id) - - expect(issue.referenced_merge_requests).to eq([merge_request, cross_project_merge_request]) - end - - it 'excludes cross project references if the user cannot read cross project' do - user = create(:user) - allow(Ability).to receive(:allowed?).and_call_original - expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false } - - other_project = create(:project, :public) - cross_project_merge_request = create(:merge_request, source_project: other_project) - create(:note_on_issue, - noteable: issue, - note: cross_project_merge_request.to_reference(issue.project), - project_id: issue.project.id) - - expect(issue.referenced_merge_requests(user)).to eq([merge_request]) - end - end - describe '#can_move?' do let(:user) { create(:user) } let(:issue) { create(:issue) } @@ -365,7 +273,12 @@ describe Issue do source_project: subject.project, source_branch: "#{subject.iid}-branch" }) merge_request.create_cross_references!(user) - expect(subject.referenced_merge_requests(user)).not_to be_empty + + referenced_merge_requests = Issues::ReferencedMergeRequestsService + .new(subject.project, user) + .referenced_merge_requests(subject) + + expect(referenced_merge_requests).not_to be_empty expect(subject.related_branches(user)).to eq([subject.to_branch_name]) end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 8cb706b54b0..7cfffbde42f 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2989,6 +2989,7 @@ describe Project do # call. This makes testing a bit easier. allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) allow(project).to receive(:previous_changes).and_return('path' => ['foo']) + stub_feature_flags(skip_hashed_storage_upgrade: false) end it 'renames a repository' do @@ -3160,6 +3161,7 @@ describe Project do # call. This makes testing a bit easier. allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) allow(project).to receive(:previous_changes).and_return('path' => ['foo']) + stub_feature_flags(skip_hashed_storage_upgrade: false) end context 'migration to hashed storage' do diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb index c2ef0435c8e..269d5deca20 100644 --- a/spec/models/remote_mirror_spec.rb +++ b/spec/models/remote_mirror_spec.rb @@ -220,6 +220,18 @@ describe RemoteMirror do end end + context '#ensure_remote!' do + let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first } + + it 'adds a remote multiple times with no errors' do + expect(remote_mirror.project.repository).to receive(:add_remote).with(remote_mirror.remote_name, remote_mirror.url).twice.and_call_original + + 2.times do + remote_mirror.ensure_remote! + end + end + end + context '#updated_since?' do let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first } let(:timestamp) { Time.now - 5.minutes } diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 2859d5149ec..93898012d34 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2005,6 +2005,24 @@ describe Repository do File.delete(path) end + + context 'for multiple SHAs' do + it 'skips non-existent SHAs' do + repository.keep_around('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', sample_commit.id) + + expect(repository.kept_around?(sample_commit.id)).to be_truthy + end + + it 'skips already-kept-around SHAs' do + repository.keep_around(sample_commit.id) + + expect(repository.raw_repository).to receive(:write_ref).exactly(1).and_call_original + + repository.keep_around(sample_commit.id, another_sample_commit.id) + + expect(repository.kept_around?(another_sample_commit.id)).to be_truthy + end + end end describe '#update_ref' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9763477a711..fd99acb3bb2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -315,6 +315,14 @@ describe User do expect(users_with_two_factor).to eq([user_with_2fa.id]) expect(users_with_two_factor).not_to include(user_without_2fa.id) end + + it 'works with ORDER BY' do + user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_u2f) + + expect(described_class + .with_two_factor + .reorder_by_name).to eq([user_with_2fa]) + end end describe ".without_two_factor" do diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 615fea11f26..5e583be457e 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -17,7 +17,7 @@ describe GroupPolicy do let(:reporter_permissions) { [:admin_label] } - let(:developer_permissions) { [:admin_milestones] } + let(:developer_permissions) { [:admin_milestone] } let(:maintainer_permissions) do [ @@ -31,6 +31,7 @@ describe GroupPolicy do :admin_namespace, :admin_group_member, :change_visibility_level, + :set_note_created_at, (Gitlab::Database.postgresql? ? :create_subgroup : nil) ].compact end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index dd3fa4e6a51..b7ec35d6ec5 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -64,6 +64,7 @@ describe ProjectPolicy do %i[ change_namespace change_visibility_level rename_project remove_project archive_project remove_fork_project destroy_merge_request destroy_issue + set_issue_iid set_issue_created_at set_note_created_at ] end diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index 6dfaa3b72f7..547d95e0908 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -78,7 +78,7 @@ describe Ci::BuildPresenter do it 'returns the reason of failure' do status_title = presenter.status_title - expect(status_title).to eq('Failed <br> (unknown failure)') + expect(status_title).to eq('Failed - (unknown failure)') end end @@ -89,7 +89,7 @@ describe Ci::BuildPresenter do status_title = presenter.status_title expect(status_title).not_to include('(retried)') - expect(status_title).to eq('Failed <br> (unknown failure)') + expect(status_title).to eq('Failed - (unknown failure)') end end @@ -99,7 +99,7 @@ describe Ci::BuildPresenter do it 'returns the reason of failure' do status_title = presenter.status_title - expect(status_title).to eq('Failed <br> (unknown failure)') + expect(status_title).to eq('Failed - (unknown failure)') end end @@ -173,7 +173,7 @@ describe Ci::BuildPresenter do it 'returns the reason of failure' do tooltip = subject.tooltip_message - expect(tooltip).to eq("#{build.name} - failed <br> (script failure)") + expect(tooltip).to eq("#{build.name} - failed - (script failure)") end end @@ -183,7 +183,7 @@ describe Ci::BuildPresenter do it 'should include the reason of failure and the retried title' do tooltip = subject.tooltip_message - expect(tooltip).to eq("#{build.name} - failed <br> (script failure) (retried)") + expect(tooltip).to eq("#{build.name} - failed - (script failure) (retried)") end end @@ -193,7 +193,7 @@ describe Ci::BuildPresenter do it 'should include the reason of failure' do tooltip = subject.tooltip_message - expect(tooltip).to eq("#{build.name} - failed <br> (script failure) (allowed to fail)") + expect(tooltip).to eq("#{build.name} - failed - (script failure) (allowed to fail)") end end diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index 0921fecb933..7f3f3ab0977 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -167,12 +167,6 @@ describe API::AwardEmoji do expect(response).to have_gitlab_http_status(401) end - it "returns a 404 error if the user authored issue" do - post api("/projects/#{project.id}/issues/#{issue2.id}/award_emoji", user), name: 'thumbsup' - - expect(response).to have_gitlab_http_status(404) - end - it "normalizes +1 as thumbsup award" do post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: '+1' @@ -215,12 +209,6 @@ describe API::AwardEmoji do expect(json_response['user']['username']).to eq(user.username) end - it "it returns 404 error when user authored note" do - post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note2.id}/award_emoji", user), name: 'thumbsup' - - expect(response).to have_gitlab_http_status(404) - end - it "normalizes +1 as thumbsup award" do post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: '+1' diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index 0aec186f738..a2b41d56b8b 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -313,7 +313,7 @@ describe API::Files do describe "POST /projects/:id/repository/files/:file_path" do let!(:file_path) { "new_subfolder%2Fnewfile%2Erb" } - let(:valid_params) do + let(:params) do { branch: "master", content: "puts 8", @@ -322,7 +322,7 @@ describe API::Files do end it "creates a new file in project repo" do - post api(route(file_path), user), valid_params + post api(route(file_path), user), params expect(response).to have_gitlab_http_status(201) expect(json_response["file_path"]).to eq(CGI.unescape(file_path)) @@ -337,20 +337,28 @@ describe API::Files do expect(response).to have_gitlab_http_status(400) end + it 'returns a 400 bad request if the commit message is empty' do + params[:commit_message] = '' + + post api(route(file_path), user), params + + expect(response).to have_gitlab_http_status(400) + end + it "returns a 400 if editor fails to create file" do allow_any_instance_of(Repository).to receive(:create_file) .and_raise(Gitlab::Git::CommitError, 'Cannot create file') - post api(route("any%2Etxt"), user), valid_params + post api(route("any%2Etxt"), user), params expect(response).to have_gitlab_http_status(400) end context "when specifying an author" do it "creates a new file with the specified author" do - valid_params.merge!(author_email: author_email, author_name: author_name) + params.merge!(author_email: author_email, author_name: author_name) - post api(route("new_file_with_author%2Etxt"), user), valid_params + post api(route("new_file_with_author%2Etxt"), user), params expect(response).to have_gitlab_http_status(201) expect(response.content_type).to eq('application/json') @@ -364,7 +372,7 @@ describe API::Files do let!(:project) { create(:project_empty_repo, namespace: user.namespace ) } it "creates a new file in project repo" do - post api(route("newfile%2Erb"), user), valid_params + post api(route("newfile%2Erb"), user), params expect(response).to have_gitlab_http_status(201) expect(json_response['file_path']).to eq('newfile.rb') @@ -376,7 +384,7 @@ describe API::Files do end describe "PUT /projects/:id/repository/files" do - let(:valid_params) do + let(:params) do { branch: 'master', content: 'puts 8', @@ -385,7 +393,7 @@ describe API::Files do end it "updates existing file in project repo" do - put api(route(file_path), user), valid_params + put api(route(file_path), user), params expect(response).to have_gitlab_http_status(200) expect(json_response['file_path']).to eq(CGI.unescape(file_path)) @@ -394,8 +402,16 @@ describe API::Files do expect(last_commit.author_name).to eq(user.name) end + it 'returns a 400 bad request if the commit message is empty' do + params[:commit_message] = '' + + put api(route(file_path), user), params + + expect(response).to have_gitlab_http_status(400) + end + it "returns a 400 bad request if update existing file with stale last commit id" do - params_with_stale_id = valid_params.merge(last_commit_id: 'stale') + params_with_stale_id = params.merge(last_commit_id: 'stale') put api(route(file_path), user), params_with_stale_id @@ -406,7 +422,7 @@ describe API::Files do it "updates existing file in project repo with accepts correct last commit id" do last_commit = Gitlab::Git::Commit .last_for_path(project.repository, 'master', URI.unescape(file_path)) - params_with_correct_id = valid_params.merge(last_commit_id: last_commit.id) + params_with_correct_id = params.merge(last_commit_id: last_commit.id) put api(route(file_path), user), params_with_correct_id @@ -421,9 +437,9 @@ describe API::Files do context "when specifying an author" do it "updates a file with the specified author" do - valid_params.merge!(author_email: author_email, author_name: author_name, content: "New content") + params.merge!(author_email: author_email, author_name: author_name, content: "New content") - put api(route(file_path), user), valid_params + put api(route(file_path), user), params expect(response).to have_gitlab_http_status(200) last_commit = project.repository.commit.raw @@ -434,7 +450,7 @@ describe API::Files do end describe "DELETE /projects/:id/repository/files" do - let(:valid_params) do + let(:params) do { branch: 'master', commit_message: 'Changed file' @@ -442,7 +458,7 @@ describe API::Files do end it "deletes existing file in project repo" do - delete api(route(file_path), user), valid_params + delete api(route(file_path), user), params expect(response).to have_gitlab_http_status(204) end @@ -453,19 +469,27 @@ describe API::Files do expect(response).to have_gitlab_http_status(400) end + it 'returns a 400 bad request if the commit message is empty' do + params[:commit_message] = '' + + delete api(route(file_path), user), params + + expect(response).to have_gitlab_http_status(400) + end + it "returns a 400 if fails to delete file" do allow_any_instance_of(Repository).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file') - delete api(route(file_path), user), valid_params + delete api(route(file_path), user), params expect(response).to have_gitlab_http_status(400) end context "when specifying an author" do it "removes a file with the specified author" do - valid_params.merge!(author_email: author_email, author_name: author_name) + params.merge!(author_email: author_email, author_name: author_name) - delete api(route(file_path), user), valid_params + delete api(route(file_path), user), params expect(response).to have_gitlab_http_status(204) end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 28ba00c7293..f64815feffa 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -1023,6 +1023,20 @@ describe API::Issues do end end + context 'by a group owner' do + let(:group) { create(:group) } + let(:group_project) { create(:project, :public, namespace: group) } + + it 'sets the internal ID on the new issue' do + group.add_owner(user2) + post api("/projects/#{group_project.id}/issues", user2), + title: 'new issue', iid: 9001 + + expect(response).to have_gitlab_http_status(201) + expect(json_response['iid']).to eq 9001 + end + end + context 'by another user' do it 'ignores the given internal ID' do post api("/projects/#{project.id}/issues", user2), @@ -1154,14 +1168,47 @@ describe API::Issues do end end - context 'when an admin or owner makes the request' do - it 'accepts the creation date to be set' do - creation_time = 2.weeks.ago - post api("/projects/#{project.id}/issues", user), - title: 'new issue', labels: 'label, label2', created_at: creation_time + context 'setting created_at' do + let(:creation_time) { 2.weeks.ago } + let(:params) { { title: 'new issue', labels: 'label, label2', created_at: creation_time } } - expect(response).to have_gitlab_http_status(201) - expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + context 'by an admin' do + it 'sets the creation time on the new issue' do + post api("/projects/#{project.id}/issues", admin), params + + expect(response).to have_gitlab_http_status(201) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + end + end + + context 'by a project owner' do + it 'sets the creation time on the new issue' do + post api("/projects/#{project.id}/issues", user), params + + expect(response).to have_gitlab_http_status(201) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + end + end + + context 'by a group owner' do + it 'sets the creation time on the new issue' do + group = create(:group) + group_project = create(:project, :public, namespace: group) + group.add_owner(user2) + post api("/projects/#{group_project.id}/issues", user2), params + + expect(response).to have_gitlab_http_status(201) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + end + end + + context 'by another user' do + it 'ignores the given creation time' do + post api("/projects/#{project.id}/issues", user2), params + + expect(response).to have_gitlab_http_status(201) + expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time) + end end end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index a4220f5b2be..b8a4a04a7e4 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -306,16 +306,16 @@ describe API::Labels do end it 'returns 400 for too long color code' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', + put api("/projects/#{project.id}/labels", user), + name: 'label1', color: '#FFAAFFFF' expect(response).to have_gitlab_http_status(400) expect(json_response['message']['color']).to eq(['must be a valid color code']) end it 'returns 400 for invalid priority' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', + put api("/projects/#{project.id}/labels", user), + name: 'label1', priority: 'foo' expect(response).to have_gitlab_http_status(400) diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb index 6c05c166bd6..62613aa5938 100644 --- a/spec/requests/api/project_milestones_spec.rb +++ b/spec/requests/api/project_milestones_spec.rb @@ -39,19 +39,6 @@ describe API::ProjectMilestones do expect(response).to have_gitlab_http_status(404) end - - it "rejects a member with reporter access from deleting a milestone" do - delete api("/projects/#{project.id}/milestones/#{milestone.id}", reporter) - - expect(response).to have_gitlab_http_status(403) - end - - it 'deletes the milestone when the user has developer access to the project' do - delete api("/projects/#{project.id}/milestones/#{milestone.id}", user) - - expect(project.milestones.find_by_id(milestone.id)).to be_nil - expect(response).to have_gitlab_http_status(204) - end end describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index a3b5e8c6223..5dec0bc778c 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -116,6 +116,14 @@ describe API::ProjectSnippets do expect(response).to have_gitlab_http_status(400) end + it 'returns 400 for empty code field' do + params[:code] = '' + + post api("/projects/#{project.id}/snippets/", admin), params + + expect(response).to have_gitlab_http_status(400) + end + context 'when the snippet is spam' do def create_snippet(project, snippet_params = {}) project.add_developer(user) @@ -180,6 +188,14 @@ describe API::ProjectSnippets do expect(response).to have_gitlab_http_status(400) end + it 'returns 400 for empty code field' do + new_content = '' + + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content + + expect(response).to have_gitlab_http_status(400) + end + context 'when the snippet is spam' do def update_snippet(snippet_params = {}) put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index c249c881db5..b6f92042ecc 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -402,7 +402,7 @@ describe API::Projects do context 'and with min_access_level' do before do - project2.add_master(user2) + project2.add_maintainer(user2) project3.add_developer(user2) project4.add_reporter(user2) end @@ -913,12 +913,28 @@ describe API::Projects do expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id) expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name) expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access) + expect(json_response['shared_with_groups'][0]['expires_at']).to be_nil expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds) expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved) expect(json_response['merge_method']).to eq(project.merge_method.to_s) expect(json_response['readme_url']).to eq(project.readme_url) end + it 'returns a group link with expiration date' do + group = create(:group) + expires_at = 5.days.from_now.to_date + link = create(:project_group_link, project: project, group: group, expires_at: expires_at) + + get api("/projects/#{project.id}", user) + + expect(json_response['shared_with_groups']).to be_an Array + expect(json_response['shared_with_groups'].length).to eq(1) + expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id) + expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name) + expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access) + expect(json_response['shared_with_groups'][0]['expires_at']).to eq(expires_at.to_s) + end + it 'returns a project by path name' do get api("/projects/#{project.id}", user) expect(response).to have_gitlab_http_status(200) @@ -1121,47 +1137,87 @@ describe API::Projects do describe 'fork management' do let(:project_fork_target) { create(:project) } let(:project_fork_source) { create(:project, :public) } + let(:private_project_fork_source) { create(:project, :private) } describe 'POST /projects/:id/fork/:forked_from_id' do - let(:new_project_fork_source) { create(:project, :public) } + context 'user is a developer' do + before do + project_fork_target.add_developer(user) + end - it "is not available for non admin users" do - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user) - expect(response).to have_gitlab_http_status(403) - end + it 'denies project to be forked from an existing project' do + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user) - it 'allows project to be forked from an existing project' do - expect(project_fork_target.forked?).not_to be_truthy - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) - expect(response).to have_gitlab_http_status(201) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - expect(project_fork_target.forked_project_link).not_to be_nil - expect(project_fork_target.forked?).to be_truthy + expect(response).to have_gitlab_http_status(403) + end end it 'refreshes the forks count cache' do expect(project_fork_source.forks_count).to be_zero + end - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) + context 'user is maintainer' do + before do + project_fork_target.add_maintainer(user) + end - expect(project_fork_source.forks_count).to eq(1) - end + it 'allows project to be forked from an existing project' do + expect(project_fork_target).not_to be_forked - it 'fails if forked_from project which does not exist' do - post api("/projects/#{project_fork_target.id}/fork/9999", admin) - expect(response).to have_gitlab_http_status(404) + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user) + project_fork_target.reload + + expect(response).to have_gitlab_http_status(201) + expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) + expect(project_fork_target.forked_project_link).to be_present + expect(project_fork_target).to be_forked + end + + it 'denies project to be forked from a private project' do + post api("/projects/#{project_fork_target.id}/fork/#{private_project_fork_source.id}", user) + + expect(response).to have_gitlab_http_status(404) + end end - it 'fails with 409 if already forked' do - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin) - expect(response).to have_gitlab_http_status(409) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - expect(project_fork_target.forked?).to be_truthy + context 'user is admin' do + it 'allows project to be forked from an existing project' do + expect(project_fork_target).not_to be_forked + + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) + + expect(response).to have_gitlab_http_status(201) + end + + it 'allows project to be forked from a private project' do + post api("/projects/#{project_fork_target.id}/fork/#{private_project_fork_source.id}", admin) + + expect(response).to have_gitlab_http_status(201) + end + + it 'refreshes the forks count cachce' do + expect do + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) + end.to change(project_fork_source, :forks_count).by(1) + end + + it 'fails if forked_from project which does not exist' do + post api("/projects/#{project_fork_target.id}/fork/9999", admin) + expect(response).to have_gitlab_http_status(404) + end + + it 'fails with 409 if already forked' do + other_project_fork_source = create(:project, :public) + + Projects::ForkService.new(project_fork_source, admin).execute(project_fork_target) + + post api("/projects/#{project_fork_target.id}/fork/#{other_project_fork_source.id}", admin) + project_fork_target.reload + + expect(response).to have_gitlab_http_status(409) + expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) + expect(project_fork_target).to be_forked + end end end @@ -1183,8 +1239,8 @@ describe API::Projects do before do post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) project_fork_target.reload - expect(project_fork_target.forked_from_project).not_to be_nil - expect(project_fork_target.forked?).to be_truthy + expect(project_fork_target.forked_from_project).to be_present + expect(project_fork_target).to be_forked end it 'makes forked project unforked' do @@ -1193,7 +1249,7 @@ describe API::Projects do expect(response).to have_gitlab_http_status(204) project_fork_target.reload expect(project_fork_target.forked_from_project).to be_nil - expect(project_fork_target.forked?).not_to be_truthy + expect(project_fork_target).not_to be_forked end it_behaves_like '412 response' do @@ -1228,8 +1284,8 @@ describe API::Projects do before do post api("/projects/#{private_fork.id}/fork/#{project_fork_source.id}", admin) private_fork.reload - expect(private_fork.forked_from_project).not_to be_nil - expect(private_fork.forked?).to be_truthy + expect(private_fork.forked_from_project).to be_present + expect(private_fork).to be_forked project_fork_source.reload expect(project_fork_source.forks.length).to eq(1) expect(project_fork_source.forks).to include(private_fork) diff --git a/spec/requests/api/protected_tags_spec.rb b/spec/requests/api/protected_tags_spec.rb new file mode 100644 index 00000000000..f4f3ef31bc3 --- /dev/null +++ b/spec/requests/api/protected_tags_spec.rb @@ -0,0 +1,202 @@ +require 'spec_helper' + +describe API::ProtectedTags do + let(:user) { create(:user) } + let!(:project) { create(:project, :repository) } + let(:project2) { create(:project, path: 'project2', namespace: user.namespace) } + let(:protected_name) { 'feature' } + let(:tag_name) { protected_name } + let!(:protected_tag) do + create(:protected_tag, project: project, name: protected_name) + end + + describe 'GET /projects/:id/protected_tags' do + let(:route) { "/projects/#{project.id}/protected_tags" } + + shared_examples_for 'protected tags' do + it 'returns the protected tags' do + get api(route, user), per_page: 100 + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + + protected_tag_names = json_response.map { |x| x['name'] } + expected_tags_names = project.protected_tags.map { |x| x['name'] } + expect(protected_tag_names).to match_array(expected_tags_names) + end + end + + context 'when authenticated as a maintainer' do + before do + project.add_maintainer(user) + end + + it_behaves_like 'protected tags' + end + + context 'when authenticated as a guest' do + before do + project.add_guest(user) + end + + it_behaves_like '403 response' do + let(:request) { get api(route, user) } + end + end + end + + describe 'GET /projects/:id/protected_tags/:tag' do + let(:route) { "/projects/#{project.id}/protected_tags/#{tag_name}" } + + shared_examples_for 'protected tag' do + it 'returns the protected tag' do + get api(route, user) + + expect(response).to have_gitlab_http_status(200) + expect(json_response['name']).to eq(tag_name) + expect(json_response['create_access_levels'][0]['access_level']).to eq(::Gitlab::Access::MAINTAINER) + end + + context 'when protected tag does not exist' do + let(:tag_name) { 'unknown' } + + it_behaves_like '404 response' do + let(:request) { get api(route, user) } + let(:message) { '404 Not found' } + end + end + end + + context 'when authenticated as a maintainer' do + before do + project.add_maintainer(user) + end + + it_behaves_like 'protected tag' + + context 'when protected tag contains a wildcard' do + let(:protected_name) { 'feature*' } + + it_behaves_like 'protected tag' + end + end + + context 'when authenticated as a guest' do + before do + project.add_guest(user) + end + + it_behaves_like '403 response' do + let(:request) { get api(route, user) } + end + end + end + + describe 'POST /projects/:id/protected_tags' do + let(:tag_name) { 'new_tag' } + + context 'when authenticated as a maintainer' do + before do + project.add_maintainer(user) + end + + it 'protects a single tag with maintainers can create tags' do + post api("/projects/#{project.id}/protected_tags", user), name: tag_name + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(tag_name) + expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::MAINTAINER) + end + + it 'protects a single tag with developers can create tags' do + post api("/projects/#{project.id}/protected_tags", user), + name: tag_name, create_access_level: 30 + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(tag_name) + expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER) + end + + it 'protects a single tag with no one can create tags' do + post api("/projects/#{project.id}/protected_tags", user), + name: tag_name, create_access_level: 0 + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(tag_name) + expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS) + end + + it 'returns a 422 error if the same tag is protected twice' do + post api("/projects/#{project.id}/protected_tags", user), name: protected_name + + expect(response).to have_gitlab_http_status(422) + expect(json_response['message'][0]).to eq('Name has already been taken') + end + + it 'returns 201 if the same tag is proteted on different projects' do + post api("/projects/#{project.id}/protected_tags", user), name: protected_name + post api("/projects/#{project2.id}/protected_tags", user), name: protected_name + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(protected_name) + end + + context 'when tag has a wildcard in its name' do + let(:tag_name) { 'feature/*' } + + it 'protects multiple tags with a wildcard in the name' do + post api("/projects/#{project.id}/protected_tags", user), name: tag_name + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(tag_name) + expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::MAINTAINER) + end + end + end + + context 'when authenticated as a guest' do + before do + project.add_guest(user) + end + + it 'returns a 403 error if guest' do + post api("/projects/#{project.id}/protected_tags/", user), name: tag_name + + expect(response).to have_gitlab_http_status(403) + end + end + end + + describe 'DELETE /projects/:id/protected_tags/unprotect/:tag' do + before do + project.add_maintainer(user) + end + + it 'unprotects a single tag' do + delete api("/projects/#{project.id}/protected_tags/#{tag_name}", user) + + expect(response).to have_gitlab_http_status(204) + end + + it_behaves_like '412 response' do + let(:request) { api("/projects/#{project.id}/protected_tags/#{tag_name}", user) } + end + + it "returns 404 if tag does not exist" do + delete api("/projects/#{project.id}/protected_tags/barfoo", user) + + expect(response).to have_gitlab_http_status(404) + end + + context 'when tag has a wildcard in its name' do + let(:protected_name) { 'feature*' } + + it 'unprotects a wildcard tag' do + delete api("/projects/#{project.id}/protected_tags/#{tag_name}", user) + + expect(response).to have_gitlab_http_status(204) + end + end + end +end diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb index 98df5f787f7..77baaef7afd 100644 --- a/spec/routing/admin_routing_spec.rb +++ b/spec/routing/admin_routing_spec.rb @@ -103,11 +103,11 @@ describe Admin::HooksController, "routing" do end end -# admin_hook_hook_log_retry GET /admin/hooks/:hook_id/hook_logs/:id/retry(.:format) admin/hook_logs#retry +# admin_hook_hook_log_retry POST /admin/hooks/:hook_id/hook_logs/:id/retry(.:format) admin/hook_logs#retry # admin_hook_hook_log GET /admin/hooks/:hook_id/hook_logs/:id(.:format) admin/hook_logs#show describe Admin::HookLogsController, 'routing' do it 'to #retry' do - expect(get('/admin/hooks/1/hook_logs/1/retry')).to route_to('admin/hook_logs#retry', hook_id: '1', id: '1') + expect(post('/admin/hooks/1/hook_logs/1/retry')).to route_to('admin/hook_logs#retry', hook_id: '1', id: '1') end it 'to #show' do diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 70a7707826e..5abc6d81958 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -381,7 +381,7 @@ describe 'project routing' do end end - # test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test + # test_project_hook POST /:project_id/hooks/:id/test(.:format) hooks#test # project_hooks GET /:project_id/hooks(.:format) hooks#index # POST /:project_id/hooks(.:format) hooks#create # edit_project_hook GET /:project_id/hooks/:id/edit(.:format) hooks#edit @@ -398,11 +398,11 @@ describe 'project routing' do end end - # retry_namespace_project_hook_hook_log GET /:project_id/hooks/:hook_id/hook_logs/:id/retry(.:format) projects/hook_logs#retry + # retry_namespace_project_hook_hook_log POST /:project_id/hooks/:hook_id/hook_logs/:id/retry(.:format) projects/hook_logs#retry # namespace_project_hook_hook_log GET /:project_id/hooks/:hook_id/hook_logs/:id(.:format) projects/hook_logs#show describe Projects::HookLogsController, 'routing' do it 'to #retry' do - expect(get('/gitlab/gitlabhq/hooks/1/hook_logs/1/retry')).to route_to('projects/hook_logs#retry', namespace_id: 'gitlab', project_id: 'gitlabhq', hook_id: '1', id: '1') + expect(post('/gitlab/gitlabhq/hooks/1/hook_logs/1/retry')).to route_to('projects/hook_logs#retry', namespace_id: 'gitlab', project_id: 'gitlabhq', hook_id: '1', id: '1') end it 'to #show' do diff --git a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb new file mode 100644 index 00000000000..7bd50866577 --- /dev/null +++ b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require 'rubocop' +require 'rubocop/rspec/support' + +require_relative '../../../rubocop/cop/ruby_interpolation_in_translation' + +# Disabling interpolation check as we deliberately want to have #{} in strings. +# rubocop:disable Lint/InterpolationCheck +describe RuboCop::Cop::RubyInterpolationInTranslation do + subject(:cop) { described_class.new } + + it 'does not add an offence for a regular messages' do + inspect_source('_("Hello world")') + + expect(cop.offenses).to be_empty + end + + it 'adds the correct offence when using interpolation in a string' do + inspect_source('_("Hello #{world}")') + + offense = cop.offenses.first + + expect(offense.location.source).to eq('#{world}') + expect(offense.message).to eq('Don\'t use ruby interpolation #{} inside translated strings, instead use %{}') + end + + it 'detects when using a ruby interpolation in the first argument of a pluralized string' do + inspect_source('n_("Hello #{world}", "Hello world")') + + expect(cop.offenses).not_to be_empty + end + + it 'detects when using a ruby interpolation in the second argument of a pluralized string' do + inspect_source('n_("Hello world", "Hello #{world}")') + + expect(cop.offenses).not_to be_empty + end + + it 'detects when using interpolation in a namespaced translation' do + inspect_source('s_("Hello|#{world}")') + + expect(cop.offenses).not_to be_empty + end + + it 'does not add an offence for messages defined over multiple lines' do + source = <<~SRC + _("Hello "\ + "world ") + SRC + + inspect_source(source) + expect(cop.offenses).to be_empty + end + + it 'adds an offence for violations in a message defined over multiple lines' do + source = <<~SRC + _("Hello "\ + "\#{world} ") + SRC + + inspect_source(source) + expect(cop.offenses).not_to be_empty + end +end +# rubocop:enable Lint/InterpolationCheck diff --git a/spec/serializers/build_serializer_spec.rb b/spec/serializers/build_serializer_spec.rb index 52459cd369d..302ef147eb2 100644 --- a/spec/serializers/build_serializer_spec.rb +++ b/spec/serializers/build_serializer_spec.rb @@ -37,7 +37,7 @@ describe BuildSerializer do it 'serializes only status' do expect(subject[:text]).to eq(status.text) expect(subject[:label]).to eq('failed') - expect(subject[:tooltip]).to eq('failed <br> (unknown failure)') + expect(subject[:tooltip]).to eq('failed - (unknown failure)') expect(subject[:icon]).to eq(status.icon) expect(subject[:favicon]).to match_asset_path("/assets/ci_favicons/#{status.favicon}.png") end diff --git a/spec/serializers/job_entity_spec.rb b/spec/serializers/job_entity_spec.rb index a5581a34517..8e1ca3f308d 100644 --- a/spec/serializers/job_entity_spec.rb +++ b/spec/serializers/job_entity_spec.rb @@ -142,7 +142,7 @@ describe JobEntity do end it 'should indicate the failure reason on tooltip' do - expect(subject[:status][:tooltip]).to eq('failed <br> (API failure)') + expect(subject[:status][:tooltip]).to eq('failed - (API failure)') end it 'should include a callout message with a verbose output' do @@ -166,7 +166,7 @@ describe JobEntity do end it 'should indicate the failure reason on tooltip' do - expect(subject[:status][:tooltip]).to eq('failed <br> (API failure) (allowed to fail)') + expect(subject[:status][:tooltip]).to eq('failed - (API failure) (allowed to fail)') end it 'should include a callout message with a verbose output' do diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index a3c9a660c2f..d4528256640 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -204,16 +204,37 @@ describe GitPushService, services: true do end describe "Push Event" do - let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) } - let(:event) { Event.find_by_action(Event::PUSHED) } + context "with an existing branch" do + let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) } + let(:event) { Event.find_by_action(Event::PUSHED) } - it { expect(event).to be_an_instance_of(PushEvent) } - it { expect(event.project).to eq(project) } - it { expect(event.action).to eq(Event::PUSHED) } - it { expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) } - it { expect(event.push_event_payload.commit_from).to eq(oldrev) } - it { expect(event.push_event_payload.commit_to).to eq(newrev) } - it { expect(event.push_event_payload.ref).to eq('master') } + it 'generates a push event with one commit' do + expect(event).to be_an_instance_of(PushEvent) + expect(event.project).to eq(project) + expect(event.action).to eq(Event::PUSHED) + expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) + expect(event.push_event_payload.commit_from).to eq(oldrev) + expect(event.push_event_payload.commit_to).to eq(newrev) + expect(event.push_event_payload.ref).to eq('master') + expect(event.push_event_payload.commit_count).to eq(1) + end + end + + context "with a new branch" do + let!(:new_branch_data) { push_data_from_service(project, user, Gitlab::Git::BLANK_SHA, newrev, ref) } + let(:event) { Event.find_by_action(Event::PUSHED) } + + it 'generates a push event with more than one commit' do + expect(event).to be_an_instance_of(PushEvent) + expect(event.project).to eq(project) + expect(event.action).to eq(Event::PUSHED) + expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) + expect(event.push_event_payload.commit_from).to be_nil + expect(event.push_event_payload.commit_to).to eq(newrev) + expect(event.push_event_payload.ref).to eq('master') + expect(event.push_event_payload.commit_count).to be > 1 + end + end context "Updates merge requests" do it "when pushing a new branch for the first time" do @@ -223,9 +244,14 @@ describe GitPushService, services: true do end end - context "Sends System Push data" do - it "when pushing on a branch" do - expect(SystemHookPushWorker).to receive(:perform_async).with(push_data, :push_hooks) + describe 'system hooks' do + let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) } + let(:system_hooks_service) { SystemHooksService.new } + + it "sends a system hook after pushing a branch" do + expect(SystemHooksService).to receive(:new).and_return(system_hooks_service) + expect(system_hooks_service).to receive(:execute_hooks).with(push_data, :push_hooks) + execute_service(project, user, oldrev, newrev, ref) end end diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb index d80d0f5a8a8..97a88b5d697 100644 --- a/spec/services/groups/destroy_service_spec.rb +++ b/spec/services/groups/destroy_service_spec.rb @@ -35,6 +35,14 @@ describe Groups::DestroyService do it { expect(NotificationSetting.unscoped.all).not_to include(notification_setting) } end + context 'site statistics' do + it 'doesnt trigger project deletion hooks twice' do + expect_any_instance_of(Project).to receive(:untrack_site_statistics).once + + destroy_group(group, user, async) + end + end + context 'mattermost team' do let!(:chat_team) { create(:chat_team, namespace: group) } diff --git a/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb b/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb deleted file mode 100644 index 4e58179f45f..00000000000 --- a/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper.rb' - -describe Issues::FetchReferencedMergeRequestsService do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:other_project) { create(:project) } - - let(:mr) { create(:merge_request, source_project: project, target_project: project, id: 2)} - let(:other_mr) { create(:merge_request, source_project: other_project, target_project: other_project, id: 1)} - - let(:user) { create(:user) } - let(:service) { described_class.new(project, user) } - - context 'with mentioned merge requests' do - it 'returns a list of sorted merge requests' do - allow(issue).to receive(:referenced_merge_requests).with(user).and_return([other_mr, mr]) - - mrs, closed_by_mrs = service.execute(issue) - - expect(mrs).to match_array([mr, other_mr]) - expect(closed_by_mrs).to match_array([]) - end - end - - context 'with closed-by merge requests' do - it 'returns a list of sorted merge requests' do - allow(issue).to receive(:closed_by_merge_requests).with(user).and_return([other_mr, mr]) - - mrs, closed_by_mrs = service.execute(issue) - - expect(mrs).to match_array([]) - expect(closed_by_mrs).to match_array([mr, other_mr]) - end - end -end diff --git a/spec/services/issues/referenced_merge_requests_service_spec.rb b/spec/services/issues/referenced_merge_requests_service_spec.rb new file mode 100644 index 00000000000..61d1612829f --- /dev/null +++ b/spec/services/issues/referenced_merge_requests_service_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require 'spec_helper.rb' + +describe Issues::ReferencedMergeRequestsService do + def create_referencing_mr(attributes = {}) + create(:merge_request, attributes).tap do |merge_request| + create(:note, :system, project: project, noteable: issue, author: user, note: merge_request.to_reference(full: true)) + end + end + + def create_closing_mr(attributes = {}) + create_referencing_mr(attributes).tap do |merge_request| + create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request) + end + end + + set(:user) { create(:user) } + set(:project) { create(:project, :public, :repository) } + set(:other_project) { create(:project, :public, :repository) } + set(:issue) { create(:issue, author: user, project: project) } + + set(:closing_mr) { create_closing_mr(source_project: project) } + set(:closing_mr_other_project) { create_closing_mr(source_project: other_project) } + + set(:referencing_mr) { create_referencing_mr(source_project: project, source_branch: 'csv') } + set(:referencing_mr_other_project) { create_referencing_mr(source_project: other_project, source_branch: 'csv') } + + let(:service) { described_class.new(project, user) } + + describe '#execute' do + it 'returns a list of sorted merge requests' do + mrs, closed_by_mrs = service.execute(issue) + + expect(mrs).to eq([closing_mr, referencing_mr, closing_mr_other_project, referencing_mr_other_project]) + expect(closed_by_mrs).to eq([closing_mr, closing_mr_other_project]) + end + + context 'performance' do + it 'does not run extra queries when extra namespaces are included', :use_clean_rails_memory_store_caching do + service.execute(issue) # warm cache + control_count = ActiveRecord::QueryRecorder.new { service.execute(issue) }.count + + third_project = create(:project, :public) + create_closing_mr(source_project: third_project) + service.execute(issue) # warm cache + + expect { service.execute(issue) }.not_to exceed_query_limit(control_count) + end + + it 'preloads the head pipeline for each merge request, and its routes' do + # Hack to ensure no data is preserved on issue before starting the spec, + # to avoid false negatives + reloaded_issue = Issue.find(issue.id) + + pipeline_routes = lambda do |merge_requests| + merge_requests.map { |mr| mr.head_pipeline&.project&.full_path } + end + + closing_mr_other_project.update!(head_pipeline: create(:ci_pipeline)) + control_count = ActiveRecord::QueryRecorder.new { service.execute(reloaded_issue).each(&pipeline_routes) } + + closing_mr.update!(head_pipeline: create(:ci_pipeline)) + + expect { service.execute(issue).each(&pipeline_routes) } + .not_to exceed_query_limit(control_count) + end + + it 'only loads issue notes once' do + expect(issue).to receive(:notes).once.and_call_original + + service.execute(issue) + end + end + end + + describe '#referenced_merge_requests' do + it 'returns the referenced merge requests' do + expect(service.referenced_merge_requests(issue)).to match_array([ + closing_mr, + closing_mr_other_project, + referencing_mr, + referencing_mr_other_project + ]) + end + + it 'excludes cross project references if the user cannot read cross project' do + allow(Ability).to receive(:allowed?).and_call_original + expect(Ability).to receive(:allowed?).with(user, :read_cross_project).at_least(:once).and_return(false) + + expect(service.referenced_merge_requests(issue)).not_to include(closing_mr_other_project) + expect(service.referenced_merge_requests(issue)).not_to include(referencing_mr_other_project) + end + + context 'performance' do + it 'does not run a query for each note author', :use_clean_rails_memory_store_caching do + service.referenced_merge_requests(issue) # warm cache + control_count = ActiveRecord::QueryRecorder.new { service.referenced_merge_requests(issue) }.count + + create(:note, project: project, noteable: issue, author: create(:user)) + service.referenced_merge_requests(issue) # warm cache + + expect { service.referenced_merge_requests(issue) }.not_to exceed_query_limit(control_count) + end + end + end + + describe '#closed_by_merge_requests' do + let(:closed_issue) { build(:issue, :closed, project: project)} + + it 'returns the open merge requests that close this issue' do + create_closing_mr(source_project: project, state: 'closed') + + expect(service.closed_by_merge_requests(issue)).to match_array([closing_mr, closing_mr_other_project]) + end + + it 'returns an empty array when the current issue is closed already' do + expect(service.closed_by_merge_requests(closed_issue)).to eq([]) + end + + context 'performance' do + it 'does not run a query for each note author', :use_clean_rails_memory_store_caching do + service.closed_by_merge_requests(issue) # warm cache + control_count = ActiveRecord::QueryRecorder.new { service.closed_by_merge_requests(issue) }.count + + create(:note, :system, project: project, noteable: issue, author: create(:user)) + service.closed_by_merge_requests(issue) # warm cache + + expect { service.closed_by_merge_requests(issue) }.not_to exceed_query_limit(control_count) + end + end + end +end diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index 6aed481939e..0ced5d1b6d6 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -169,6 +169,10 @@ describe MergeRequests::BuildService do end end + it 'uses the title of the commit as the title of the merge request' do + expect(merge_request.title).to eq('Initial commit') + end + it 'appends the closing description' do expected_description = [commit_description, closing_message].compact.join("\n\n") diff --git a/spec/services/milestones/destroy_service_spec.rb b/spec/services/milestones/destroy_service_spec.rb index 6f3612501f4..8680e428517 100644 --- a/spec/services/milestones/destroy_service_spec.rb +++ b/spec/services/milestones/destroy_service_spec.rb @@ -4,8 +4,6 @@ describe Milestones::DestroyService do let(:user) { create(:user) } let(:project) { create(:project) } let(:milestone) { create(:milestone, title: 'Milestone v1.0', project: project) } - let!(:issue) { create(:issue, project: project, milestone: milestone) } - let!(:merge_request) { create(:merge_request, source_project: project, milestone: milestone) } before do project.add_maintainer(user) @@ -23,12 +21,23 @@ describe Milestones::DestroyService do end it 'deletes milestone id from issuables' do + issue = create(:issue, project: project, milestone: milestone) + merge_request = create(:merge_request, source_project: project, milestone: milestone) + service.execute(milestone) expect(issue.reload.milestone).to be_nil expect(merge_request.reload.milestone).to be_nil end + it 'logs destroy event' do + service.execute(milestone) + + event = Event.where(project_id: milestone.project_id, target_type: 'Milestone') + + expect(event.count).to eq(1) + end + context 'group milestones' do let(:group) { create(:group) } let(:group_milestone) { create(:milestone, group: group) } @@ -38,13 +47,20 @@ describe Milestones::DestroyService do group.add_developer(user) end - it { expect(service.execute(group_milestone)).to be_nil } + it { expect(service.execute(group_milestone)).to eq(group_milestone) } - it 'does not update milestone issuables' do - expect(MergeRequests::UpdateService).not_to receive(:new) - expect(Issues::UpdateService).not_to receive(:new) + it 'deletes milestone id from issuables' do + issue = create(:issue, project: project, milestone: group_milestone) + merge_request = create(:merge_request, source_project: project, milestone: group_milestone) service.execute(group_milestone) + + expect(issue.reload.milestone).to be_nil + expect(merge_request.reload.milestone).to be_nil + end + + it 'does not log destroy event' do + expect { service.execute(group_milestone) }.not_to change { Event.count } end end end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index f89f9b54f53..947cb61038d 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -264,6 +264,14 @@ describe Projects::ForkService do expect(fork_from_project.forks_count).to eq(1) end + + it 'leaves no LFS objects dangling' do + create(:lfs_objects_project, project: fork_to_project) + + expect { subject.execute(fork_to_project) } + .to change { fork_to_project.lfs_objects_projects.count } + .to(0) + end end end end diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb index 5c2e79ff9af..96e8a80b334 100644 --- a/spec/services/projects/update_remote_mirror_service_spec.rb +++ b/spec/services/projects/update_remote_mirror_service_spec.rb @@ -18,6 +18,7 @@ describe Projects::UpdateRemoteMirrorService do end it "fetches the remote repository" do + expect(remote_mirror).to receive(:ensure_remote!).and_call_original expect(repository).to receive(:fetch_remote).with(remote_mirror.remote_name, no_tags: true) do sync_remote(repository, remote_mirror.remote_name, local_branch_names) end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index 9572b4110d5..695b9980548 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -249,9 +249,20 @@ describe Projects::UpdateService do expect(project.errors.messages[:base]).to include('There is already a repository with that name on disk') end - context 'when hashed storage enabled' do + it 'renames the project without upgrading it' do + result = update_project(project, admin, path: 'new-path') + + expect(result).not_to include(status: :error) + expect(project).to be_valid + expect(project.errors).to be_empty + expect(project.disk_path).to include('new-path') + expect(project.reload.hashed_storage?(:repository)).to be_falsey + end + + context 'when hashed storage is enabled' do before do stub_application_setting(hashed_storage_enabled: true) + stub_feature_flags(skip_hashed_storage_upgrade: false) end it 'migrates project to a hashed storage instead of renaming the repo to another legacy name' do @@ -262,6 +273,22 @@ describe Projects::UpdateService do expect(project.errors).to be_empty expect(project.reload.hashed_storage?(:repository)).to be_truthy end + + context 'when skip_hashed_storage_upgrade feature flag is enabled' do + before do + stub_feature_flags(skip_hashed_storage_upgrade: true) + end + + it 'renames the project without upgrading it' do + result = update_project(project, admin, path: 'new-path') + + expect(result).not_to include(status: :error) + expect(project).to be_valid + expect(project.errors).to be_empty + expect(project.disk_path).to include('new-path') + expect(project.reload.hashed_storage?(:repository)).to be_falsey + end + end end end diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb index afd6448aa26..3bebb7aae90 100644 --- a/spec/support/api/milestones_shared_examples.rb +++ b/spec/support/api/milestones_shared_examples.rb @@ -196,6 +196,24 @@ shared_examples_for 'group and project milestones' do |route_definition| end end + describe "DELETE #{route_definition}/:milestone_id" do + it "rejects a member with reporter access from deleting a milestone" do + reporter = create(:user) + milestone.parent.add_reporter(reporter) + + delete api(resource_route, reporter) + + expect(response).to have_gitlab_http_status(403) + end + + it 'deletes the milestone when the user has developer access to the project' do + delete api(resource_route, user) + + expect(project.milestones.find_by_id(milestone.id)).to be_nil + expect(response).to have_gitlab_http_status(204) + end + end + describe "GET #{route_definition}/:milestone_id/issues" do let(:issues_route) { "#{route}/#{milestone.id}/issues" } diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb index c228bd2393b..e0fceae88de 100644 --- a/spec/support/helpers/cycle_analytics_helpers.rb +++ b/spec/support/helpers/cycle_analytics_helpers.rb @@ -65,7 +65,9 @@ module CycleAnalyticsHelpers end def merge_merge_requests_closing_issue(user, project, issue) - merge_requests = issue.closed_by_merge_requests(user) + merge_requests = Issues::ReferencedMergeRequestsService + .new(project, user) + .closed_by_merge_requests(issue) merge_requests.each { |merge_request| MergeRequests::MergeService.new(project, user).execute(merge_request) } end diff --git a/spec/support/helpers/ldap_helpers.rb b/spec/support/helpers/ldap_helpers.rb index b90bbc4b106..66ca5d7f0a3 100644 --- a/spec/support/helpers/ldap_helpers.rb +++ b/spec/support/helpers/ldap_helpers.rb @@ -37,6 +37,23 @@ module LdapHelpers .to receive(:find_by_uid).with(uid, any_args).and_return(return_value) end + def stub_ldap_person_find_by_dn(entry, provider = 'ldapmain') + person = ::Gitlab::Auth::LDAP::Person.new(entry, provider) if entry.present? + + allow(::Gitlab::Auth::LDAP::Person) + .to receive(:find_by_dn) + .and_return(person) + end + + def stub_ldap_person_find_by_email(email, entry, provider = 'ldapmain') + person = ::Gitlab::Auth::LDAP::Person.new(entry, provider) if entry.present? + + allow(::Gitlab::Auth::LDAP::Person) + .to receive(:find_by_email) + .with(email, anything) + .and_return(person) + end + # Create a simple LDAP user entry. def ldap_user_entry(uid) entry = Net::LDAP::Entry.new diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb index 1823099dd9c..8475f91799b 100644 --- a/spec/support/helpers/stub_configuration.rb +++ b/spec/support/helpers/stub_configuration.rb @@ -68,6 +68,10 @@ module StubConfiguration allow(Gitlab.config.repositories).to receive(:storages).and_return(Settingslogic.new(messages)) end + def stub_kerberos_setting(messages) + allow(Gitlab.config.kerberos).to receive_messages(to_settings(messages)) + end + private # Modifies stubbed messages to also stub possible predicate versions diff --git a/spec/support/helpers/stub_feature_flags.rb b/spec/support/helpers/stub_feature_flags.rb index b96338bf548..c54a871b157 100644 --- a/spec/support/helpers/stub_feature_flags.rb +++ b/spec/support/helpers/stub_feature_flags.rb @@ -1,4 +1,7 @@ module StubFeatureFlags + # Stub Feature flags with `flag_name: true/false` + # + # @param [Hash] features where key is feature name and value is boolean whether enabled or not def stub_feature_flags(features) features.each do |feature_name, enabled| allow(Feature).to receive(:enabled?).with(feature_name) { enabled } diff --git a/spec/support/shared_examples/requests/api/notes.rb b/spec/support/shared_examples/requests/api/notes.rb index 1b563021244..0e20dfe0725 100644 --- a/spec/support/shared_examples/requests/api/notes.rb +++ b/spec/support/shared_examples/requests/api/notes.rb @@ -111,17 +111,79 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name| post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!' end - context 'when an admin or owner makes the request' do - it 'accepts the creation date to be set' do - creation_time = 2.weeks.ago - post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), - body: 'hi!', created_at: creation_time + context 'setting created_at' do + let(:creation_time) { 2.weeks.ago } + let(:params) { { body: 'hi!', created_at: creation_time } } + + context 'by an admin' do + it 'sets the creation time on the new note' do + admin = create(:admin) + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(admin.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time) + end + end - expect(response).to have_gitlab_http_status(201) - expect(json_response['body']).to eq('hi!') - expect(json_response['author']['username']).to eq(user.username) - expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) - expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time) + if parent_type == 'projects' + context 'by a project owner' do + it 'sets the creation time on the new note' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time) + end + end + + context 'by a group owner' do + it 'sets the creation time on the new note' do + user2 = create(:user) + group = create(:group) + group.add_owner(user2) + parent.update!(namespace: group) + user2.refresh_authorized_projects + + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user2.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time) + end + end + elsif parent_type == 'groups' + context 'by a group owner' do + it 'sets the creation time on the new note' do + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time) + end + end + end + + context 'by another user' do + it 'ignores the given creation time' do + user2 = create(:user) + parent.add_developer(user2) + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user2.username) + expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time) + expect(Time.parse(json_response['updated_at'])).not_to be_like_time(creation_time) + end end end diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb index b1c6565c08a..a7628548de6 100644 --- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb @@ -20,6 +20,7 @@ describe 'projects/merge_requests/_commits.html.haml' do assign(:merge_request, merge_request) assign(:commits, merge_request.commits) + assign(:hidden_commit_count, 0) end it 'shows commits from source project' do @@ -30,4 +31,16 @@ describe 'projects/merge_requests/_commits.html.haml' do expect(rendered).to have_link(href: href) end + + context 'when there are hidden commits' do + before do + assign(:hidden_commit_count, 1) + end + + it 'shows notice about omitted commits' do + render + + expect(rendered).to match(/1 additional commit has been omitted to prevent performance issues/) + end + end end diff --git a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb index 9ab105c3238..8befae39d3a 100644 --- a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb @@ -9,6 +9,8 @@ describe 'projects/merge_requests/creations/_new_submit.html.haml' do assign(:merge_request, merge_request) assign(:commits, merge_request.commits) + assign(:hidden_commit_count, 0) + assign(:total_commit_count, merge_request.commits.count) assign(:project, merge_request.target_project) allow(view).to receive(:can?).and_return(true) @@ -29,4 +31,17 @@ describe 'projects/merge_requests/creations/_new_submit.html.haml' do expect(rendered).not_to have_text('Builds') end end + + context 'when there are hidden commits' do + before do + assign(:pipelines, Ci::Pipeline.none) + assign(:hidden_commit_count, 2) + end + + it 'shows notice about omitted commits' do + render + + expect(rendered).to match(/2 additional commits have been omitted to prevent performance issues/) + end + end end diff --git a/yarn.lock b/yarn.lock index 4326245d2ac..db3b0bbe573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,10 +78,14 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.27.0": +"@gitlab-org/gitlab-svgs@^1.23.0": version "1.27.0" resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.27.0.tgz#638e70399ebd59e503732177316bb9a18bf7a13f" +"@gitlab-org/gitlab-svgs@^1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.28.0.tgz#f689dfd46504df0a75027d6dd4ea01a71cd46f88" + "@gitlab-org/gitlab-ui@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.0.5.tgz#a64b402650494115c8b494a44b72c2d6fbf33fff" |