diff options
1092 files changed, 8733 insertions, 6059 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml index ebf8048f19c..a954bb4ff37 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -56,6 +56,10 @@ rules: component: always svg: always math: always + camelcase: + - error + - properties: never + ignoreDestructuring: true ## Conflicting rules with prettier: space-before-function-paren: off curly: off @@ -63,7 +67,7 @@ rules: function-paren-newline: off object-curly-newline: off padded-blocks: off - # Disabled for now, to make the eslint 3 -> eslint 4 update smoother + # Disabled for now, to make the eslint 3 -> eslint 5 update smoother ## Indent rule. We are using the old for now: https://eslint.org/docs/user-guide/migrating-to-4.0.0#indent-rewrite indent: off indent-legacy: @@ -78,3 +82,18 @@ rules: FunctionExpression: parameters: 1 body: 1 + # Disabled for now, to make the airbnb-base 12.1.0 -> 13.1.0 update smoother + operator-linebreak: off + implicit-arrow-linebreak: off + no-else-return: + - error + - allowElseIf: true + import/no-useless-path-segments: off + lines-between-class-members: off + # Disabled for now, to make the plugin-vue 4.5 -> 5.0 update smoother + vue/html-closing-bracket-newline: off + vue/html-closing-bracket-spacing: off + vue/no-confusing-v-for-v-if: error + vue/no-unused-components: off + vue/no-use-v-if-with-v-for: off + vue/no-v-html: off diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cc27ac3677b..058cacb0774 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -130,7 +130,6 @@ stages: .single-script-job: &single-script-job image: ruby:2.4-alpine - before_script: [] stage: test cache: {} dependencies: [] @@ -259,6 +258,7 @@ package-and-qa: SCRIPT_NAME: trigger-build retry: 0 script: + - gem install gitlab --no-document - ./$SCRIPT_NAME omnibus when: manual only: @@ -285,7 +285,7 @@ review-docs-deploy-manual: <<: *review-docs stage: build script: - - gem install gitlab --no-ri --no-rdoc + - gem install gitlab --no-document - ./$SCRIPT_NAME deploy when: manual only: @@ -299,7 +299,7 @@ review-docs-deploy: <<: *review-docs stage: post-test script: - - gem install gitlab --no-ri --no-rdoc + - gem install gitlab --no-document - ./$SCRIPT_NAME deploy only: - /(^docs[\/-].*|.*-docs$)/@gitlab-org/gitlab-ce @@ -314,7 +314,7 @@ review-docs-cleanup: name: review-docs/$CI_COMMIT_REF_SLUG action: stop script: - - gem install gitlab --no-ri --no-rdoc + - gem install gitlab --no-document - ./$SCRIPT_NAME cleanup when: manual only: @@ -327,14 +327,14 @@ review-docs-cleanup: cloud-native-image: image: ruby:2.4-alpine before_script: [] - stage: build + stage: test allow_failure: true variables: GIT_DEPTH: "1" cache: {} script: - - gem install gitlab --no-ri --no-rdoc - - BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN scripts/trigger-build cng + - gem install gitlab --no-document + - CNG_PROJECT_PATH="gitlab-org/build/CNG" BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN ./scripts/trigger-build cng only: - tags@gitlab-org/gitlab-ce - tags@gitlab-org/gitlab-ee @@ -366,7 +366,7 @@ update-tests-metadata: - rspec_flaky/ policy: push script: - - retry gem install fog-aws mime-types activesupport --no-ri --no-rdoc + - retry gem install fog-aws mime-types activesupport --no-document - scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json - scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json - FLAKY_RSPEC_GENERATE_REPORT=1 scripts/prune-old-flaky-specs ${FLAKY_RSPEC_SUITE_REPORT_PATH} @@ -729,6 +729,9 @@ karma: dependencies: - compile-assets - setup-test-env + variables: + # we override the max_old_space_size to prevent OOM errors + NODE_OPTIONS: --max_old_space_size=3584 script: - export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log - date diff --git a/.rubocop.yml b/.rubocop.yml index 9858bbe0ddd..ce7be208186 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -111,7 +111,7 @@ Naming/FileName: - XSRF - XSS -# Gitlab ################################################################### +# GitLab ################################################################### Gitlab/ModuleWithInstanceVariables: Enable: true diff --git a/CHANGELOG.md b/CHANGELOG.md index c1d5a638cd0..e514a42108c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,253 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 11.3.0 (2018-09-22) + +### Security (5 changes, 1 of them is from the community) + +- Disable the Sidekiq Admin Rack session. !21441 +- Set issuable_sort, diff_view, and perf_bar_enabled cookies to secure when possible. !21442 +- Update rubyzip to 1.2.2 (CVE-2018-1000544). !21460 (Takuya Noguchi) +- Fixed persistent XSS rendering/escaping of diff location lines. +- Block link-local addresses in URLBlocker. + +### Removed (1 change) + +- Remove Gemnasium service. !21185 + +### Fixed (83 changes, 24 of them are from the community) + +- Hide PAT creation advice for HTTP clone if PAT exists. !18208 (George Thomas @thegeorgeous) +- Allow spaces in wiki markdown links when using CommonMark. !20417 +- disable_statement_timeout no longer leak to other migrations. !20503 +- Events API now requires the read_user or api scope. !20627 (Warren Parad) +- Fix If-Check the result that a function was executed several times. !20640 (Max Dicker) +- Add migration to cleanup internal_ids inconsistency. !20926 +- Fix fallback logic for automatic MR title assignment. !20930 (Franz Liedke) +- Fixed bug when the project logo file is stored in LFS. !20948 +- Fix buttons on the new file page wrapping outside of the container. !21015 +- Solve tooltip appears under modal. !21017 +- Fix Bitbucket Cloud importer omitting replies. !21076 +- Fix pipeline fixture seeder. !21088 +- Fix blocked user card style. !21095 +- Fix empty merge requests not opening in the Web IDE. !21102 +- Fix label list item container height when there is no label description. !21106 +- Fixes input alignment in user admin form with errors. !21108 (Jacopo Beschi @jacopo-beschi) +- Rails5 fix specs duplicate key value violates unique constraint 'index_gpg_signatures_on_commit_sha'. !21119 (Jasper Maes) +- Add gitlab theme to spam logs pagination. !21145 +- Split remembering sorting for issues and merge requests. !21153 (Jacopo Beschi @jacopo-beschi) +- Fix git submodule link for subgroup projects with relative path. !21154 +- Fix: Project deletion may not log audit events during group deletion. !21162 +- Fix 1px cutoff of emojis. !21180 (gfyoung) +- Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28. !21191 (sgerrand) +- Show google icon in audit log. !21207 (Jan Beckmann) +- Fix bin/secpick error and security branch prefixing. !21210 +- Importing a project no longer fails when visibility level holds a string value type. !21242 +- Fix attachments not displaying inline with Google Cloud Storage. !21265 +- Fix IDE issues with persistent banners. !21283 +- Fix "Confidential comments" button not saving in project hooks. !21289 +- Bump fog-google to 1.7.0 and google-api-client to 0.23.0. !21295 +- Don't use arguments keyword in gettext script. !21296 (gfyoung) +- Fix breadcrumb link to issues on new issue page. !21305 (J.D. Bean) +- Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress Bar. !21306 +- API: Catch empty commit messages. !21322 (Robert Schilling) +- Fix SQL error when sorting 2FA-enabled users by name in admin area. !21324 +- API: Catch empty code content for project snippets. !21325 (Robert Schilling) +- Avoid nil safe message. !21326 (Yi Siliang) +- Allow date parameters on Issues, Notes, and Discussions API for group owners. !21342 (Florent Dubois) +- Fix remote mirrors failing if Git remotes have not been added. !21351 +- Removing a group no longer triggers hooks for project deletion twice. !21366 +- Use slugs for default project path and sanitize names before import. !21367 +- Vertically centres landscape avatars. !21371 (Vicary Archangel) +- Fix Web IDE unable to commit to same file twice. !21372 +- Fix project transfer name validation issues causing a redirect loop. !21408 +- Fix Error 500s due to encoding issues when Wiki hooks fire. !21414 +- Rails 5: include opclasses in rails 5 schema dump. !21416 (Jasper Maes) +- Bump GitLab Pages to v1.1.0. !21419 +- Fix links in RSS feed elements. !21424 (Marc Schwede) +- Allow gaps in multiseries metrics charts. !21427 +- Auto-DevOps.gitlab-ci.yml: fix redeploying deleted app gives helm error. !21429 +- Use sample data for push event when no commits created. !21440 (Takuya Noguchi) +- Fix importers not assigning a new default group. !21456 +- Fix edge cases of JUnitParser. !21469 +- Fix breadcrumb link to merge requests on new merge request page. !21502 (J.D. Bean) +- Handle database statement timeouts in usage ping. !21523 +- Handles exception during file upload - replaces the stack trace with a small error message. !21528 +- Fix closing issue default pattern. !21531 (Samuele Kaplun) +- Fix outdated discussions being shown on Merge Request Changes tab. !21543 +- Remove orphaned label links. !21552 +- Delete a container registry asynchronously. !21553 +- Make MR diff file filter input Clear button functional. !21556 +- Replace white spaces in wiki attachments file names. !21569 +- API: Use find_branch! in all places. !21614 (Robert Schilling) +- Fixes double +/- on inline diff view. !21634 +- Fix broken exports when they include a projet avatar. !21649 +- Fix workhorse temp path for namespace uploads. !21650 +- Fixed resolved discussions not toggling expanded state on changes tab. !21676 +- Update GitLab Shell to v8.3.2. !21701 +- Fix absent Click to Expand link on diffs not rendered on first load of Merge Requests Changes tab. !21716 +- Update GitLab Shell to v8.3.3. !21750 +- Fix import error when archive does not have the correct extension. !21765 +- Fixed IDE deleting new files creating wrong state. +- Does not collapse runners section when using pagination. +- Fix Emojis cutting in the right way. (Alexander Popov) +- Fix NamespaceUploader.base_dir for remote uploads. +- Increase width of checkout branch modal box. +- Fixes SVGs for empty states in job page overflowing on mobile. +- Fix checkboxes on runner admin settings - The labels are now clickable. +- Fixed IDE file row scrolling into view when hovering. +- Accept upload files in public/uplaods/tmp when using accelerated uploads. +- Include correct CSS file for xterm in environments page. +- Increase padding in code blocks. +- Fix: Project deletion may not log audit events during user deletion. + +### Changed (32 changes, 5 of them are from the community) + +- Add default avatar to group. !17271 (George Tsiolis) +- Allow project owners to set up forking relation through API. !18104 +- Limit navbar search for current project or group for small viewports. !18634 (George Tsiolis) +- Add Noto Color Emoji font support. !19036 (Alexander Popov) +- Update design of project overview page. !20536 +- Improve visuals of language bar on projects. !21006 +- Migrate NULL wiki_access_level to correct number so we count active wikis correctly. !21030 +- Support a custom action, such as proxying to another server, after /api/v4/internal/allowed check succeeds. !21034 +- Remove storage path dependency of gitaly install task. !21101 +- Support Kubernetes RBAC for GitLab Managed Apps when adding a existing cluster. !21127 +- Change 'Backlog' list title to 'Open' in Issue Boards. !21131 +- Enable Auto DevOps Instance Wide Default. !21157 +- Allow author to vote on their own issue and MRs. !21203 +- Truncate branch names and update "commits behind" text in MR page. !21206 +- Adds count for different board list types (label lists, assignee lists, and milestone lists) to usage statistics. !21208 +- Render files (`.md`) and wikis using CommonMark. !21228 +- Show deprecation message on project milestone page for category tabs. !21236 +- Remove redundant header from metrics page. !21282 +- Add default parameter to branches API. !21294 (Riccardo Padovani) +- Restrict reopening locked issues for non authorized issue authors. !21299 +- Send back required object storage PUT headers in /uploads/authorize API. !21319 +- Display default status emoji if only message is entered. !21330 +- Move badge settings to general settings. !21333 +- Move project settings for default branch under "Repository". !21380 +- Import all common metrics into database. !21459 +- Improved commit panel in Web IDE. !21471 +- Administrative cleanup rake tasks now leverage Gitaly. !21588 +- Remove health check feature flag in BackgroundMigrationWorker. +- Expose user's id in /admin/users/ show page. (Eva Kadlecova) +- Improved styling of top bar in IDE job trace pane. +- Make terminal button more visible. +- Shows download artifacts button for pipelines on small screens. + +### Performance (13 changes, 2 of them are from the community) + +- Enable frozen string in rest of app/models/**/*.rb. +- Add background migrations for legacy artifacts. !18615 +- Optimize querying User#manageable_groups. !21050 +- Incremental rendering with Vue on merge request page. !21063 +- Remove redundant ci_builds (status) index. !21070 +- Enable frozen in app/mailers/**/*.rb. !21147 (gfyoung) +- Improve performance when fetching related merge requests for an issue. !21237 +- Speed up diff comparisons by limiting number of commit messages rendered. !21335 +- Write diff highlighting cache upon MR creation (refactors caching). !21489 +- Bulk-render commit titles in the tree view to improve performance. !21500 +- Enable frozen string in vestigial app files. (gfyoung) +- Disable project avatar validation if avatar has not changed. +- Bitbucket Server importer: Eliminate most idle-in-transaction issues. + +### Added (41 changes, 17 of them are from the community) + +- API: Protected tags. !14986 (Robert Schilling) +- Include private contributions to contributions calendar. !17296 (George Tsiolis) +- Add an option to whitelist users based on email address as internal when the "New user set to external" setting is enabled. !17711 (Roger Rüttimann) +- Overhaul listing of projects in the group overview page. !20262 +- Add the ability to reference projects in comments and other markdown text. !20285 (Reuben Pereira) +- Add branch filter to project webhooks. !20338 (Duana Saskia) +- Allows to cancel a Created job. !20635 (Jacopo Beschi @jacopo-beschi) +- First Improvements made to the contributor on-boarding experience. !20682 (Eddie Stubbington) +- `/tag` quick action on Commit comments. !20694 (Peter Leitzen) +- Allow admins to configure the maximum Git push size. !20758 +- Expose all artifacts sizes in jobs api. !20821 (Peter Marko) +- Get the merge base of two refs through the API. !20929 +- Add ability to suppress the global "You won't be able to use SSH" message. !21027 (Ævar Arnfjörð Bjarmason) +- API: Add expiration date for shared projects to the project entity. !21104 (Robert Schilling) +- Added tooltips to tree list header. !21138 +- #47845 Add failure_reason to job webhook. !21143 (matemaciek) +- Vendor Auto-DevOps.gitlab-ci.yml with new proxy env vars passed through to docker. !21159 (kinolaev) +- Disable Auto DevOps for project upon first pipeline failure. !21172 +- Add rake command to migrate archived traces from local storage to object storage. !21193 +- Add Czech as an available language. !21201 +- Add Galician as an available language. !21202 +- Add support for extendable CI/CD config with. !21243 +- Disable Web IDE button if user is not allowed to push the source branch. !21288 +- Feature flag to disable Hashed Storage migration when renaming a repository. !21291 +- Store wiki uploads inside git repository. !21362 +- Adds Rubocop rule to enforce class_methods over module ClassMethods. !21379 (Jacopo Beschi @jacopo-beschi) +- Merge request copies all associated issue labels and milestone on creation. !21383 +- Add group name badge under group milestone. !21384 +- Adds diverged_commits_count field to GET api/v4/projects/:project_id/merge_requests/:merge_request_iid. !21405 (Jacopo Beschi @jacopo-beschi) +- Update Import/Export to only use new storage uploaders logic. !21409 +- Ask user explicitly about usage stats agreement on single user deployments. !21423 +- Added atom feed for tags. !21428 +- Add search to a group labels page. !21480 +- Display banner on project page if AutoDevOps is implicitly enabled. !21503 +- Recognize 'UNLICENSE' license files. !21508 (J.D. Bean) +- Add git_v2 feature flag. !21520 +- Added file templates to the Web IDE. +- Enabled multiple file uploads in the Web IDE. +- Allow to delete group milestones. +- Use separate model for tracking resource label changes and render label system notes based on data from this model. +- Add system note when due date is changed. (Eva Kadlecova) + +### Other (48 changes, 16 of them are from the community) + +- Remove extra spaces from MR discussion notes. !18946 (Takuya Noguchi) +- Add an example of the configuration of archive trace cron worker in gitlab.yml.example. !20583 +- Add target branch name to cherrypick confirmation message. !20846 (George Andrinopoulos) +- CE Port of Protected Environments backend. !20859 +- Added missing i18n strings to issue boards lables dropdown. !21081 +- Combines emoji award spec files into single user_interacts_with_awards_in_issue_spec.rb file. !21126 (Nate Geslin) +- Clarify current runners online text. !21151 (Ben Bodenmiller) +- Rails5: Enable verbose query logs. !21231 (Jasper Maes) +- Update presentation for SSO providers on log in page. !21233 +- Make margin of user status emoji consistent. !21268 +- Move usage ping payload from User Cohorts page to admin application settings. !21343 +- Add JSON logging for Bitbucket Server importer. !21378 +- Re-add project name field on "Create new project" page. !21386 +- Rails 5: replace removed silence_stream. !21387 (Jasper Maes) +- Rails5 update Gemfile.rails5.lock. !21388 (Jasper Maes) +- Rails5: fix can't quote ActiveSupport::HashWithIndifferentAccess. !21397 (Jasper Maes) +- Don't show flash messages for performance bar errors. !21411 +- Backport schema_changed.sh from EE which prints the diff if the schema is different. !21422 (Jasper Maes) +- Remove unused CSS part in mobile framework. !21439 (Takuya Noguchi) +- Bump unauthenticated session time from 1 hour to 2 hours. !21453 +- Run review-docs-cleanup job for gitlab-org repos only. !21463 (Takuya Noguchi) +- Rails 5: support schema t.index for mysql. !21485 (Jasper Maes) +- Add route information to lograge structured logging for API logs. !21487 +- Add gitaly_calls attribute to API logs. !21496 +- Ignore irrelevant sql commands in metrics. !21498 +- Rails 5: fix hashed_path? method that looks up file_location that doesn't exist when running certain migration specs. !21510 (Jasper Maes) +- Explicit hashed path check for trace, prevents background migration from accessing file_location column that doesn't exist. !21533 (Jasper Maes) +- Add terminal_path to job API response. !21537 +- Add User-Agent to production_json.log. !21546 +- Make cluster page settings easier to read. !21550 +- Remove striped table styling of Find files and Admin Area Applications views. !21560 (Andreas Kämmerle) +- Update ffi to 1.9.25. !21561 (Takuya Noguchi) +- Send max_patch_bytes to Gitaly via Gitaly::CommitDiffRequest. !21575 +- Add margin between username and subsequent text in issuable header. !21697 +- Send artifact information in job API. !50460 +- Reduce differences between CE and EE code base in reports components. +- Move project services log to a separate file. +- Creates vue component for job log top bar with controllers. +- Creates Vue component for trigger variables block in job log page. +- Creates Vvue component for warning block about stuck runners. +- Creates vue component for job log trace. +- Creates vue component for erased block on job view. +- Creates vue component for environments information in job log view. +- Upgrade Monaco editor. +- Creates empty state vue component for job view. +- Creates vue component for commit block in job log page. +- Creates vue components for stage dropdowns and job list container for job log view. +- Creates Vue component for artifacts block on job page. + + ## 11.2.3 (2018-08-28) ### Fixed (1 change) @@ -879,7 +1126,7 @@ entry. - Use the default strings of timeago.js for timeago. !19350 (Takuya Noguchi) - Update selenium-webdriver to 3.12.0. !19351 (Takuya Noguchi) - Include username in output when testing SSH to GitLab. !19358 -- Update screenshot in Gitlab.com integration documentation. !19433 (Tuğçe Nur Taş) +- Update screenshot in GitLab.com integration documentation. !19433 (Tuğçe Nur Taş) - Users can accept terms during registration. !19583 - Fix issue count on sidebar. - Add merge requests list endpoint for groups. @@ -1009,7 +1256,7 @@ entry. - Make toggle markdown preview shortcut only toggle selected field. - Verifiy if pipeline has commit idetails and render information in MR widget when branch is deleted. - Fixed inconsistent protected branch pill baseline. -- Fix setting Gitlab metrics content types. +- Fix setting GitLab metrics content types. - Display only generic message on merge error to avoid exposing any potentially sensitive or user unfriendly backend messages. - Fix label links update on project transfer. - Breaks commit not found message in pipelines table. @@ -1379,7 +1626,7 @@ entry. - Add 'Assigned Issues' and 'Assigned Merge Requests' as dashboard view choices for users. !17860 (Elias Werberich) - Extend API for importing a project export with overwrite support. !17883 - Create Deploy Tokens to allow permanent access to repository and registry. !17894 -- Detect commit message trailers and link users properly to their accounts on Gitlab. !17919 (cousine) +- Detect commit message trailers and link users properly to their accounts on GitLab. !17919 (cousine) - Adds cancel btn to new pages domain page. !18026 (Jacopo Beschi @jacopo-beschi) - API: Add parameter merge_method to projects. !18031 (Jan Beckmann) - Introduce simpler env vars for auto devops REPLICAS and CANARY_REPLICAS #41436. !18036 @@ -2827,7 +3074,7 @@ entry. - [FIXED] Fix broken wiki pages that link to a wiki file. !15019 - [FIXED] Don't rename paths that were freed up when upgrading. !15029 - [FIXED] Fix bitbucket login. !15051 -- [FIXED] Update gitaly in Gitlab 10.1 to 0.43.1 for temp file cleanup. !15055 +- [FIXED] Update gitaly in GitLab 10.1 to 0.43.1 for temp file cleanup. !15055 - [FIXED] Use the correct visibility attribute for projects in system hooks. !15065 - [FIXED] Normalize LDAP DN when looking up identity. - [FIXED] Adds callback functions for initial request in clusters page. @@ -4537,7 +4784,7 @@ entry. - Make user mentions case-insensitive. !10285 (blackst0ne) - Update rugged to 0.25.1.1. !10286 (Elan Ruusamäe) - Handle parsing OpenBSD ps output properly to display sidekiq infos on admin->monitoring->background. !10303 (Sebastian Reitenbach) -- Log errors during generating of Gitlab Pages to debug log. !10335 (Danilo Bargen) +- Log errors during generating of GitLab Pages to debug log. !10335 (Danilo Bargen) - Update issue board cards design. !10353 - Tags can be protected, restricting creation of matching tags by user role. !10356 - Set GIT_TERMINAL_PROMPT env variable in initializer. !10372 @@ -4950,7 +5197,7 @@ entry. - Restore keyboard shortcuts for "Activity" and "Charts". !9680 - Added commit array to Syshook json. !9685 (Gabriele Pongelli) - Document ability to list issues with no labels using API. !9697 (Vignesh Ravichandran) -- Fix typo in Gitlab config file. !9702 (medied) +- Fix typo in GitLab config file. !9702 (medied) - Fix json response in branches controller. !9710 (George Andrinopoulos) - Refactor dropdown_assignee_spec. !9711 (George Andrinopoulos) - Delete artifacts for pages unless expiry date is specified. !9716 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8596037afa3..81fc46c2b6f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,11 +72,13 @@ For a first-time step-by-step guide to the contribution process, please see Looking for something to work on? Look for issues in the [Backlog (Accepting merge requests) milestone](#i-want-to-contribute). -GitLab comes into two flavors, GitLab Community Edition (CE) our free and open +GitLab comes in two flavors, GitLab Community Edition (CE) our free and open source edition, and GitLab Enterprise Edition (EE) which is our commercial edition. Throughout this guide you will see references to CE and EE for abbreviation. +To get an overview of GitLab community membership including those that would be reviewing or merging your contributions, please visit [the community roles page](doc/development/contributing/community_roles.md). + If you want to know how the GitLab [core team] operates please see [the GitLab contributing process](PROCESS.md). diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 61825a7bf03..ee1e4d2aee5 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.121.0 +0.122.0 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index dfda3e0b4f0..f3b5af39e43 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -6.1.0 +6.1.1 @@ -89,7 +89,7 @@ gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false gem 'github-linguist', '~> 5.3.3', require: 'linguist' # API -gem 'grape', '~> 1.0' +gem 'grape', '~> 1.1' gem 'grape-entity', '~> 0.7.1' gem 'rack-cors', '~> 1.0.0', require: 'rack/cors' @@ -173,7 +173,6 @@ gem 'acts-as-taggable-on', '~> 5.0' gem 'sidekiq', '~> 5.2.1' gem 'sidekiq-cron', '~> 0.6.0' gem 'redis-namespace', '~> 1.6.0' -gem 'sidekiq-limit_fetch', '~> 3.4', require: false # Cron Parser gem 'rufus-scheduler', '~> 3.4' diff --git a/Gemfile.lock b/Gemfile.lock index 328cc55cb8c..d8eaaac99b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -343,7 +343,7 @@ GEM signet (~> 0.7) gpgme (2.0.13) mini_portile2 (~> 2.1) - grape (1.0.3) + grape (1.1.0) activesupport builder mustermann-grape (~> 1.0.0) @@ -501,7 +501,7 @@ GEM multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) - mustermann (1.0.2) + mustermann (1.0.3) mustermann-grape (1.0.0) mustermann (~> 1.0.0) mysql2 (0.4.10) @@ -846,8 +846,6 @@ GEM sidekiq-cron (0.6.0) rufus-scheduler (>= 3.3.0) sidekiq (>= 4.2.1) - sidekiq-limit_fetch (3.4.0) - sidekiq (>= 4) signet (0.8.1) addressable (~> 2.3) faraday (~> 0.9) @@ -1045,7 +1043,7 @@ DEPENDENCIES google-api-client (~> 0.23) google-protobuf (= 3.5.1) gpgme - grape (~> 1.0) + grape (~> 1.1) grape-entity (~> 0.7.1) grape-path-helpers (~> 1.0) grape_logging (~> 1.7) @@ -1162,7 +1160,6 @@ DEPENDENCIES shoulda-matchers (~> 3.1.2) sidekiq (~> 5.2.1) sidekiq-cron (~> 0.6.0) - sidekiq-limit_fetch (~> 3.4) simple_po_parser (~> 1.1.2) simplecov (~> 0.14.0) slack-notifier (~> 1.5.1) diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock index aa6a32fa84e..ab35a4a399f 100644 --- a/Gemfile.rails5.lock +++ b/Gemfile.rails5.lock @@ -346,7 +346,7 @@ GEM signet (~> 0.7) gpgme (2.0.13) mini_portile2 (~> 2.1) - grape (1.0.3) + grape (1.1.0) activesupport builder mustermann-grape (~> 1.0.0) @@ -504,7 +504,7 @@ GEM multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) - mustermann (1.0.2) + mustermann (1.0.3) mustermann-grape (1.0.0) mustermann (~> 1.0.0) mysql2 (0.4.10) @@ -854,8 +854,6 @@ GEM sidekiq-cron (0.6.0) rufus-scheduler (>= 3.3.0) sidekiq (>= 4.2.1) - sidekiq-limit_fetch (3.4.0) - sidekiq (>= 4) signet (0.8.1) addressable (~> 2.3) faraday (~> 0.9) @@ -1054,7 +1052,7 @@ DEPENDENCIES google-api-client (~> 0.23) google-protobuf (= 3.5.1) gpgme - grape (~> 1.0) + grape (~> 1.1) grape-entity (~> 0.7.1) grape-path-helpers (~> 1.0) grape_logging (~> 1.7) @@ -1172,7 +1170,6 @@ DEPENDENCIES shoulda-matchers (~> 3.1.2) sidekiq (~> 5.2.1) sidekiq-cron (~> 0.6.0) - sidekiq-limit_fetch (~> 3.4) simple_po_parser (~> 1.1.2) simplecov (~> 0.14.0) slack-notifier (~> 1.5.1) @@ -1 +1 @@ -11.3.0-pre +11.4.0-pre diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue index b08dc454d12..97232d7f783 100644 --- a/app/assets/javascripts/badges/components/badge.vue +++ b/app/assets/javascripts/badges/components/badge.vue @@ -103,8 +103,8 @@ export default { </div> <button - v-tooltip v-show="hasError" + v-tooltip :title="s__('Badges|Reload badge image')" class="btn btn-transparent btn-sm text-primary" type="button" diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js index dbff2bd4b10..429455f97ec 100644 --- a/app/assets/javascripts/behaviors/markdown/render_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js @@ -3,7 +3,7 @@ import syntaxHighlight from '~/syntax_highlight'; import renderMath from './render_math'; import renderMermaid from './render_mermaid'; -// Render Gitlab flavoured Markdown +// Render GitLab flavoured Markdown // // Delegates to syntax highlight and render math & mermaid diagrams. // diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue index 606c9e81db4..7ddb22ad824 100644 --- a/app/assets/javascripts/boards/components/board_list.vue +++ b/app/assets/javascripts/boards/components/board_list.vue @@ -231,14 +231,14 @@ export default { <board-card v-for="(issue, index) in issues" ref="issue" + :key="issue.id" :index="index" :list="list" :issue="issue" :issue-link-base="issueLinkBase" :group-id="groupId" :root-path="rootPath" - :disabled="disabled" - :key="issue.id" /> + :disabled="disabled" /> <li v-if="showCount" class="board-list-count text-center" diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue index 1e3cd43d1f0..f248f53fa51 100644 --- a/app/assets/javascripts/boards/components/board_new_issue.vue +++ b/app/assets/javascripts/boards/components/board_new_issue.vue @@ -110,9 +110,9 @@ export default { Title </label> <input + :id="list.id + '-title'" ref="input" v-model="title" - :id="list.id + '-title'" class="form-control" type="text" name="issue_title" diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue index d50641dc3a9..d3666cf3980 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.vue +++ b/app/assets/javascripts/boards/components/issue_card_inner.vue @@ -152,7 +152,7 @@ class="js-no-trigger">{{ issue.title }}</a> <span v-if="issueId" - class="board-card-number" + class="board-card-number append-right-5" > {{ issue.referencePath }} </span> @@ -170,8 +170,8 @@ tooltip-placement="bottom" /> <span - v-tooltip v-if="shouldRenderCounter" + v-tooltip :title="assigneeCounterTooltip" class="avatar-counter" > @@ -184,10 +184,10 @@ class="board-card-footer" > <button - v-tooltip v-for="label in issue.labels" v-if="showLabel(label)" :key="label.id" + v-tooltip :style="labelStyle(label)" :title="label.description" class="badge color-label" diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.vue b/app/assets/javascripts/boards/components/modal/lists_dropdown.vue index 6a5a39099bd..4f23e5db35c 100644 --- a/app/assets/javascripts/boards/components/modal/lists_dropdown.vue +++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.vue @@ -1,7 +1,11 @@ <script> +import { Link } from '@gitlab-org/gitlab-ui'; import ModalStore from '../../stores/modal_store'; export default { + components: { + 'gl-link': Link, + }, data() { return { modal: ModalStore.store, @@ -38,7 +42,7 @@ export default { v-for="(list, i) in state.lists" v-if="list.type == 'label'" :key="i"> - <a + <gl-link :class="{ 'is-active': list.id == selected.id }" href="#" role="button" @@ -48,7 +52,7 @@ export default { class="dropdown-label-box"> </span> {{ list.title }} - </a> + </gl-link> </li> </ul> </div> diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 8be99566f09..662363a6f26 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -9,7 +9,7 @@ import '~/vue_shared/models/assignee'; import FilteredSearchBoards from './filtered_search_boards'; import eventHub from './eventhub'; -import sidebarEventHub from '~/sidebar/event_hub'; // eslint-disable-line import/first +import sidebarEventHub from '~/sidebar/event_hub'; import './models/issue'; import './models/list'; import './models/milestone'; @@ -24,7 +24,7 @@ import './components/board'; import './components/board_sidebar'; import './components/new_list_dropdown'; import BoardAddIssuesModal from './components/modal/index.vue'; -import '~/vue_shared/vue_resource_interceptor'; // eslint-disable-line import/first +import '~/vue_shared/vue_resource_interceptor'; export default () => { const $boardApp = document.getElementById('board-app'); diff --git a/app/assets/javascripts/build_variables.js b/app/assets/javascripts/build_variables.js deleted file mode 100644 index d398e4a4c83..00000000000 --- a/app/assets/javascripts/build_variables.js +++ /dev/null @@ -1,10 +0,0 @@ -import $ from 'jquery'; - -export default function handleRevealVariables() { - $('.js-reveal-variables') - .off('click') - .on('click', function click() { - $('.js-build-variables').toggle(); - $(this).hide(); - }); -} diff --git a/app/assets/javascripts/commons/gitlab_ui.js b/app/assets/javascripts/commons/gitlab_ui.js index aed26adfa5c..1411f7ffd5e 100644 --- a/app/assets/javascripts/commons/gitlab_ui.js +++ b/app/assets/javascripts/commons/gitlab_ui.js @@ -1,16 +1,17 @@ import Vue from 'vue'; -import Pagination from '@gitlab-org/gitlab-ui/dist/components/base/pagination'; -import progressBar from '@gitlab-org/gitlab-ui/dist/components/base/progress_bar'; -import modal from '@gitlab-org/gitlab-ui/dist/components/base/modal'; -import loadingIcon from '@gitlab-org/gitlab-ui/dist/components/base/loading_icon'; - -import dModal from '@gitlab-org/gitlab-ui/dist/directives/modal'; -import dTooltip from '@gitlab-org/gitlab-ui/dist/directives/tooltip'; +import { + Pagination, + ProgressBar, + Modal, + LoadingIcon, + ModalDirective, + TooltipDirective, +} from '@gitlab-org/gitlab-ui'; Vue.component('gl-pagination', Pagination); -Vue.component('gl-progress-bar', progressBar); -Vue.component('gl-ui-modal', modal); -Vue.component('gl-loading-icon', loadingIcon); +Vue.component('gl-progress-bar', ProgressBar); +Vue.component('gl-ui-modal', Modal); +Vue.component('gl-loading-icon', LoadingIcon); -Vue.directive('gl-modal', dModal); -Vue.directive('gl-tooltip', dTooltip); +Vue.directive('gl-modal', ModalDirective); +Vue.directive('gl-tooltip', TooltipDirective); diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue index f66ca070445..c05b9b1de79 100644 --- a/app/assets/javascripts/deploy_keys/components/key.vue +++ b/app/assets/javascripts/deploy_keys/components/key.vue @@ -145,8 +145,8 @@ export default { <icon :name="firstProject.can_push ? 'lock-open' : 'lock'"/> </a> <a - v-tooltip v-if="isExpandable" + v-tooltip :title="restProjectsTooltip" class="label deploy-project-label" @click="toggleExpanded" @@ -154,10 +154,10 @@ export default { <span>{{ restProjectsLabel }}</span> </a> <a - v-tooltip v-for="deployKeysProject in restProjects" v-else-if="isExpanded" :key="deployKeysProject.project.full_path" + v-tooltip :href="deployKeysProject.project.full_path" :title="projectTooltipTitle(deployKeysProject)" class="label deploy-project-label" @@ -198,8 +198,8 @@ export default { {{ __('Enable') }} </action-btn> <a - v-tooltip v-if="deployKey.can_edit" + v-tooltip :href="editDeployKeyPath" :title="__('Edit')" class="btn btn-default text-secondary" @@ -208,8 +208,8 @@ export default { <icon name="pencil"/> </a> <action-btn - v-tooltip v-if="isRemovable" + v-tooltip :deploy-key="deployKey" :title="__('Remove')" btn-css-class="btn-danger" @@ -219,8 +219,8 @@ export default { <icon name="remove"/> </action-btn> <action-btn - v-tooltip v-else-if="isEnabled" + v-tooltip :deploy-key="deployKey" :title="__('Disable')" btn-css-class="btn-warning" diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index bfb992340bc..fc41ee4b777 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -9,6 +9,7 @@ import ChangedFiles from './changed_files.vue'; import DiffFile from './diff_file.vue'; import NoChanges from './no_changes.vue'; import HiddenFilesWarning from './hidden_files_warning.vue'; +import CommitWidget from './commit_widget.vue'; export default { name: 'DiffsApp', @@ -19,6 +20,7 @@ export default { DiffFile, NoChanges, HiddenFilesWarning, + CommitWidget, }, props: { endpoint: { @@ -208,6 +210,11 @@ export default { </div> </div> + <commit-widget + v-if="commit" + :commit="commit" + /> + <changed-files :diff-files="diffFiles" /> diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue new file mode 100644 index 00000000000..5758588e82e --- /dev/null +++ b/app/assets/javascripts/diffs/components/commit_item.vue @@ -0,0 +1,119 @@ +<script> +import tooltip from '~/vue_shared/directives/tooltip'; +import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; +import Icon from '~/vue_shared/components/icon.vue'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import CIIcon from '~/vue_shared/components/ci_icon.vue'; +import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; + +/** + * CommitItem + * + * ----------------------------------------------------------------- + * WARNING: Please keep changes up-to-date with the following files: + * - `views/projects/commits/_commit.html.haml` + * ----------------------------------------------------------------- + * + * This Component was cloned from a HAML view. For the time being they + * coexist, but there is an issue to remove the duplication. + * https://gitlab.com/gitlab-org/gitlab-ce/issues/51613 + * + */ +export default { + directives: { + tooltip, + }, + components: { + UserAvatarLink, + Icon, + ClipboardButton, + CIIcon, + TimeAgoTooltip, + }, + props: { + commit: { + type: Object, + required: true, + }, + }, + computed: { + authorName() { + return (this.commit.author && this.commit.author.name) || this.commit.authorName; + }, + authorUrl() { + return (this.commit.author && this.commit.author.webUrl) || `mailto:${this.commit.authorEmail}`; + }, + authorAvatar() { + return (this.commit.author && this.commit.author.avatarUrl) || this.commit.authorGravatarUrl; + }, + }, +}; +</script> + +<template> + <li class="commit flex-row js-toggle-container"> + <user-avatar-link + :link-href="authorUrl" + :img-src="authorAvatar" + :img-alt="authorName" + :img-size="36" + class="avatar-cell d-none d-sm-block" + /> + <div class="commit-detail flex-list"> + <div class="commit-content qa-commit-content"> + <a + :href="commit.commitUrl" + class="commit-row-message item-title" + v-html="commit.titleHtml" + ></a> + + <span class="commit-row-message d-block d-sm-none"> + · + {{ commit.shortId }} + </span> + + <button + v-if="commit.descriptionHtml" + class="text-expander js-toggle-button" + type="button" + :aria-label="__('Toggle commit description')" + > + <icon + :size="12" + name="ellipsis_h" + /> + </button> + + <div class="commiter"> + <a + :href="authorUrl" + v-text="authorName" + ></a> + {{ s__('CommitWidget|authored') }} + <time-ago-tooltip + :time="commit.authoredDate" + /> + </div> + + <pre + v-if="commit.descriptionHtml" + class="commit-row-description js-toggle-content append-bottom-8" + v-html="commit.descriptionHtml" + ></pre> + </div> + <div class="commit-actions flex-row d-none d-sm-flex"> + <div class="commit-sha-group"> + <div + class="label label-monospace" + v-text="commit.shortId" + ></div> + <clipboard-button + :text="commit.id" + :title="__('Copy commit SHA to clipboard')" + class="btn btn-default" + /> + </div> + </div> + </div> + </li> +</template> diff --git a/app/assets/javascripts/diffs/components/commit_widget.vue b/app/assets/javascripts/diffs/components/commit_widget.vue new file mode 100644 index 00000000000..cc8e72eb1c8 --- /dev/null +++ b/app/assets/javascripts/diffs/components/commit_widget.vue @@ -0,0 +1,40 @@ +<script> +import CommitItem from './commit_item.vue'; + +/** + * CommitWidget + * + * ----------------------------------------------------------------- + * WARNING: Please keep changes up-to-date with the following files: + * - `views/projects/merge_requests/diffs/_commit_widget.html.haml` + * ----------------------------------------------------------------- + * + * This Component was cloned from a HAML view. For the time being, + * they coexist, but there is an issue to remove the duplication. + * https://gitlab.com/gitlab-org/gitlab-ce/issues/51613 + * + */ +export default { + components: { + CommitItem, + }, + props: { + commit: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <div class="info-well prepend-top-default"> + <div class="well-segment"> + <ul class="blob-commit-info"> + <commit-item + :commit="commit" + /> + </ul> + </div> + </div> +</template> diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue index d3ffbe0415a..517fbf400e8 100644 --- a/app/assets/javascripts/diffs/components/diff_file_header.vue +++ b/app/assets/javascripts/diffs/components/diff_file_header.vue @@ -181,8 +181,8 @@ export default { </span> <strong - v-tooltip v-else + v-tooltip :title="filePath" class="file-title-name" data-container="body" @@ -255,8 +255,8 @@ export default { </a> <a - v-tooltip v-if="diffFile.externalUrl" + v-tooltip :href="diffFile.externalUrl" :title="`View on ${diffFile.formattedExternalUrl}`" target="_blank" diff --git a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue index a02c41f39ab..1b59777f901 100644 --- a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue +++ b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue @@ -87,8 +87,8 @@ export default { @click.native="toggleDiscussions" /> <span - v-gl-tooltip v-if="moreText" + v-gl-tooltip :title="moreText" class="diff-comments-more-count js-diff-comment-avatar js-diff-comment-plus" data-container="body" diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index 0fa14615532..bb9bb821de3 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -1,12 +1,9 @@ <script> import { mapState, mapGetters, mapActions } from 'vuex'; -import createFlash from '~/flash'; import { s__ } from '~/locale'; import noteForm from '../../notes/components/note_form.vue'; -import { getNoteFormData } from '../store/utils'; import autosave from '../../notes/mixins/autosave'; import { DIFF_NOTE_TYPE } from '../constants'; -import { reduceDiscussionsToLineCodes } from '../../notes/stores/utils'; export default { components: { @@ -39,6 +36,16 @@ export default { }), ...mapGetters('diffs', ['getDiffFileByHash']), ...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']), + formData() { + return { + noteableData: this.noteableData, + noteableType: this.noteableType, + noteTargetLine: this.noteTargetLine, + diffViewType: this.diffViewType, + diffFile: this.getDiffFileByHash(this.diffFileHash), + linePosition: this.linePosition, + }; + }, }, mounted() { if (this.isLoggedIn) { @@ -53,8 +60,7 @@ export default { } }, methods: { - ...mapActions('diffs', ['cancelCommentForm', 'assignDiscussionsToDiff']), - ...mapActions(['saveNote', 'refetchDiscussionById']), + ...mapActions('diffs', ['cancelCommentForm', 'assignDiscussionsToDiff', 'saveDiffDiscussion']), handleCancelCommentForm(shouldConfirm, isDirty) { if (shouldConfirm && isDirty) { const msg = s__('Notes|Are you sure you want to cancel creating this comment?'); @@ -73,35 +79,9 @@ export default { }); }, handleSaveNote(note) { - const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash); - const postData = getNoteFormData({ - note, - noteableData: this.noteableData, - noteableType: this.noteableType, - noteTargetLine: this.noteTargetLine, - diffViewType: this.diffViewType, - diffFile: selectedDiffFile, - linePosition: this.linePosition, - }); - - this.saveNote(postData) - .then(result => { - const endpoint = this.getNotesDataByProp('discussionsPath'); - - this.refetchDiscussionById({ path: endpoint, discussionId: result.discussion_id }) - .then(selectedDiscussion => { - const lineCodeDiscussions = reduceDiscussionsToLineCodes([selectedDiscussion]); - this.assignDiscussionsToDiff(lineCodeDiscussions); - - this.handleCancelCommentForm(); - }) - .catch(() => { - createFlash(s__('MergeRequests|Updating discussions failed')); - }); - }) - .catch(() => { - createFlash(s__('MergeRequests|Saving the comment failed')); - }); + return this.saveDiffDiscussion({ note, formData: this.formData }).then(() => + this.handleCancelCommentForm(), + ); }, }, }; diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue index 947e7c98fae..fbf9e77ac07 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_view.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue @@ -43,18 +43,18 @@ export default { v-for="(line, index) in diffLines" > <inline-diff-table-row + :key="line.lineCode" :file-hash="diffFile.fileHash" :context-lines-path="diffFile.contextLinesPath" :line="line" :is-bottom="index + 1 === diffLinesLength" - :key="line.lineCode" /> <inline-diff-comment-row v-if="shouldRenderInlineCommentRow(line)" + :key="index" :diff-file-hash="diffFile.fileHash" :line="line" :line-index="index" - :key="index" /> </template> </tbody> diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue index 501bd4450d8..3452f0d2b00 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue @@ -45,11 +45,11 @@ export default { v-for="(line, index) in diffLines" > <parallel-diff-table-row + :key="index" :file-hash="diffFile.fileHash" :context-lines-path="diffFile.contextLinesPath" :line="line" :is-bottom="index + 1 === diffLinesLength" - :key="index" /> <parallel-diff-comment-row v-if="shouldRenderParallelCommentRow(line)" diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index e60bb9dd7e3..98d8d5943f9 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -1,9 +1,12 @@ import Vue from 'vue'; import axios from '~/lib/utils/axios_utils'; import Cookies from 'js-cookie'; +import createFlash from '~/flash'; +import { s__ } from '~/locale'; import { handleLocationHash, historyPushState } from '~/lib/utils/common_utils'; import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility'; -import { getDiffPositionByLineCode } from './utils'; +import { reduceDiscussionsToLineCodes } from '../../notes/stores/utils'; +import { getDiffPositionByLineCode, getNoteFormData } from './utils'; import * as types from './mutation_types'; import { PARALLEL_DIFF_VIEW_TYPE, @@ -178,5 +181,19 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => { }); }; +export const saveDiffDiscussion = ({ dispatch }, { note, formData }) => { + const postData = getNoteFormData({ + note, + ...formData, + }); + + return dispatch('saveNote', postData, { root: true }) + .then(result => dispatch('updateDiscussion', result.discussion, { root: true })) + .then(discussion => + dispatch('assignDiscussionsToDiff', reduceDiscussionsToLineCodes([discussion])), + ) + .catch(() => createFlash(s__('MergeRequests|Saving the comment failed'))); +}; + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 834a94ea42a..631e3de311e 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -55,6 +55,7 @@ export function getNoteFormData(params) { note_project_id: '', target_type: noteableData.targetType, target_id: noteableData.id, + return_discussion: true, note: { note, position, diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue index a9d9d768c06..16abafebbc0 100644 --- a/app/assets/javascripts/environments/components/environments_table.vue +++ b/app/assets/javascripts/environments/components/environments_table.vue @@ -83,10 +83,10 @@ export default { :model="model"> <div is="environment-item" + :key="`environment-item-${i}`" :model="model" :can-create-deployment="canCreateDeployment" :can-read-environment="canReadEnvironment" - :key="`environment-item-${i}`" /> <template @@ -102,10 +102,10 @@ export default { <div is="environment-item" v-for="(children, index) in model.children" + :key="`env-item-${i}-${index}`" :model="children" :can-create-deployment="canCreateDeployment" :can-read-environment="canReadEnvironment" - :key="`env-item-${i}-${index}`" /> <div :key="`sub-div-${i}`"> diff --git a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js index b4588cc1318..d7aa4ce597f 100644 --- a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js +++ b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js @@ -7,6 +7,13 @@ const tokenKeys = [{ symbol: '', icon: 'messages', tag: 'status', +}, { + key: 'type', + type: 'string', + param: 'type', + symbol: '', + icon: 'cube', + tag: 'type', }]; const AdminRunnersFilteredSearchTokenKeys = new FilteredSearchTokenKeys(tokenKeys); diff --git a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue index a8eb8d94be3..21b5ccdb613 100644 --- a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue +++ b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue @@ -72,8 +72,8 @@ export default { @click="onItemActivated(item.text)"> <span> <span - v-for="(token, index) in item.tokens" - :key="`dropdown-token-${index}`" + v-for="(token, tokenIndex) in item.tokens" + :key="`dropdown-token-${tokenIndex}`" class="filtered-search-history-dropdown-token" > <span class="name">{{ token.prefix }}</span> diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index a750647f8be..207616b9de2 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -96,6 +96,11 @@ export default class FilteredSearchDropdownManager { gl: NullDropdown, element: this.container.querySelector('#js-dropdown-admin-runner-status'), }, + type: { + reference: null, + gl: NullDropdown, + element: this.container.querySelector('#js-dropdown-admin-runner-type'), + }, }; supportedTokens.forEach((type) => { diff --git a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue index 1f1665ff7fe..2399ee15332 100644 --- a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue +++ b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue @@ -1,5 +1,5 @@ <script> -/* eslint-disable vue/require-default-prop, vue/require-prop-types */ +/* eslint-disable vue/require-default-prop */ import Identicon from '../../vue_shared/components/identicon.vue'; export default { diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue index 6e700b8bf8a..c1783d5ce25 100644 --- a/app/assets/javascripts/groups/components/item_actions.vue +++ b/app/assets/javascripts/groups/components/item_actions.vue @@ -46,8 +46,8 @@ export default { <template> <div class="controls"> <a - v-tooltip v-if="group.canEdit" + v-tooltip :href="group.editPath" :title="editBtnTitle" :aria-label="editBtnTitle" @@ -57,8 +57,8 @@ export default { <icon name="settings"/> </a> <a - v-tooltip v-if="group.canLeave" + v-tooltip :href="group.leavePath" :title="leaveBtnTitle" :aria-label="leaveBtnTitle" diff --git a/app/assets/javascripts/ide/components/branches/search_list.vue b/app/assets/javascripts/ide/components/branches/search_list.vue index bf0ff6e35ec..52ccc537c9d 100644 --- a/app/assets/javascripts/ide/components/branches/search_list.vue +++ b/app/assets/javascripts/ide/components/branches/search_list.vue @@ -60,8 +60,8 @@ export default { <div class="position-relative"> <input ref="searchInput" - :placeholder="__('Search branches')" v-model="search" + :placeholder="__('Search branches')" type="search" class="form-control dropdown-input-field" @input="searchBranches" diff --git a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue index c3ca147e850..3aca38399fb 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue @@ -52,6 +52,7 @@ export default { </strong> <changed-file-icon :file="activeFile" + class="ml-0" /> <div class="ml-auto"> <button diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index 3fdd35ad228..3e3539e364b 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -113,8 +113,8 @@ export default { </strong> <div class="d-flex ml-auto"> <button - v-tooltip ref="actionBtn" + v-tooltip :title="actionBtnText" :aria-label="actionBtnText" :disabled="!filesLength" @@ -135,8 +135,8 @@ export default { /> </button> <button - v-tooltip v-if="!stagedList" + v-tooltip :title="__('Discard all changes')" :aria-label="__('Discard all changes')" :disabled="!filesLength" diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue index 10c78a80302..ee0e72cd05f 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -120,10 +120,6 @@ export default { :css-classes="iconClass" /> </div> - <component - :is="actionComponent" - :path="file.path" - /> </div> </div> </div> diff --git a/app/assets/javascripts/ide/components/file_finder/index.vue b/app/assets/javascripts/ide/components/file_finder/index.vue index 0ba33053717..760ed8654ee 100644 --- a/app/assets/javascripts/ide/components/file_finder/index.vue +++ b/app/assets/javascripts/ide/components/file_finder/index.vue @@ -174,8 +174,8 @@ export default { <div class="dropdown-input"> <input ref="searchInput" - :placeholder="__('Search files')" v-model="searchText" + :placeholder="__('Search files')" type="search" class="dropdown-input-field" autocomplete="off" diff --git a/app/assets/javascripts/ide/components/file_finder/item.vue b/app/assets/javascripts/ide/components/file_finder/item.vue index f5252ce7706..a612739d641 100644 --- a/app/assets/javascripts/ide/components/file_finder/item.vue +++ b/app/assets/javascripts/ide/components/file_finder/item.vue @@ -78,10 +78,10 @@ export default { class="diff-changed-file-name" > <span - v-for="(char, index) in file.name.split('')" - :key="index + char" + v-for="(char, charIndex) in file.name.split('')" + :key="charIndex + char" :class="{ - highlighted: nameSearchTextOccurences.indexOf(index) >= 0, + highlighted: nameSearchTextOccurences.indexOf(charIndex) >= 0, }" v-text="char" > @@ -91,10 +91,10 @@ export default { class="diff-changed-file-path prepend-top-5" > <span - v-for="(char, index) in pathWithEllipsis.split('')" - :key="index + char" + v-for="(char, charIndex) in pathWithEllipsis.split('')" + :key="charIndex + char" :class="{ - highlighted: pathSearchTextOccurences.indexOf(index) >= 0, + highlighted: pathSearchTextOccurences.indexOf(charIndex) >= 0, }" v-text="char" > diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index a3add3b778f..ad6151e3bf6 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -1,4 +1,5 @@ <script> +import Vue from 'vue'; import Mousetrap from 'mousetrap'; import { mapActions, mapState, mapGetters } from 'vuex'; import { __ } from '~/locale'; @@ -22,10 +23,16 @@ export default { IdeStatusBar, RepoEditor, FindFile, - RightPane, ErrorMessage, CommitEditorHeader, }, + props: { + rightPaneComponent: { + type: Vue.Component, + required: false, + default: () => RightPane, + }, + }, computed: { ...mapState([ 'openFiles', @@ -143,7 +150,8 @@ export default { </div> </template> </div> - <right-pane + <component + :is="rightPaneComponent" v-if="currentProjectId" /> </div> diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue index 4771c58a11d..f99ff6d6da8 100644 --- a/app/assets/javascripts/ide/components/ide_side_bar.vue +++ b/app/assets/javascripts/ide/components/ide_side_bar.vue @@ -1,6 +1,6 @@ <script> import { mapState, mapGetters } from 'vuex'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; import IdeTree from './ide_tree.vue'; import ResizablePanel from './resizable_panel.vue'; import ActivityBar from './activity_bar.vue'; @@ -13,7 +13,7 @@ import { activityBarViews } from '../constants'; export default { components: { - SkeletonLoadingContainer, + SkeletonLoading, ResizablePanel, ActivityBar, CommitSection, @@ -56,7 +56,7 @@ export default { :key="n" class="multi-file-loading-container" > - <skeleton-loading-container /> + <skeleton-loading /> </div> </div> </template> diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue index e658d1bf956..cfe25084b42 100644 --- a/app/assets/javascripts/ide/components/ide_tree_list.vue +++ b/app/assets/javascripts/ide/components/ide_tree_list.vue @@ -1,7 +1,7 @@ <script> import { mapActions, mapGetters, mapState } from 'vuex'; import Icon from '~/vue_shared/components/icon.vue'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; import FileRow from '~/vue_shared/components/file_row.vue'; import NavDropdown from './nav_dropdown.vue'; import FileRowExtra from './file_row_extra.vue'; @@ -9,7 +9,7 @@ import FileRowExtra from './file_row_extra.vue'; export default { components: { Icon, - SkeletonLoadingContainer, + SkeletonLoading, NavDropdown, FileRow, }, @@ -51,7 +51,7 @@ export default { :key="n" class="multi-file-loading-container" > - <skeleton-loading-container /> + <skeleton-loading /> </div> </template> <template v-else> diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue index 1c474acb4b2..ec168d36b9e 100644 --- a/app/assets/javascripts/ide/components/jobs/stage.vue +++ b/app/assets/javascripts/ide/components/jobs/stage.vue @@ -69,8 +69,8 @@ export default { :size="24" /> <strong - v-tooltip="showTooltip" ref="stageTitle" + v-tooltip="showTooltip" :title="showTooltip ? stage.name : null" data-container="body" class="prepend-left-8 ide-stage-title" diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue index 79df225c432..75a9a9e9b8f 100644 --- a/app/assets/javascripts/ide/components/panes/right.vue +++ b/app/assets/javascripts/ide/components/panes/right.vue @@ -1,5 +1,6 @@ <script> import { mapActions, mapState, mapGetters } from 'vuex'; +import { __ } from '~/locale'; import tooltip from '../../../vue_shared/directives/tooltip'; import Icon from '../../../vue_shared/components/icon.vue'; import { rightSidebarViews } from '../../constants'; @@ -21,6 +22,13 @@ export default { MergeRequestInfo, Clientside, }, + props: { + extensionTabs: { + type: Array, + required: false, + default: () => [], + }, + }, computed: { ...mapState(['rightPane', 'currentMergeRequestId', 'clientsidePreviewEnabled']), ...mapGetters(['packageJson']), @@ -33,6 +41,36 @@ export default { showLivePreview() { return this.packageJson && this.clientsidePreviewEnabled; }, + defaultTabs() { + return [ + { + show: this.currentMergeRequestId, + title: __('Merge Request'), + isActive: this.rightPane === rightSidebarViews.mergeRequestInfo, + view: rightSidebarViews.mergeRequestInfo, + icon: 'text-description', + }, + { + show: true, + title: __('Pipelines'), + isActive: this.pipelinesActive, + view: rightSidebarViews.pipelines, + icon: 'rocket', + }, + { + show: this.showLivePreview, + title: __('Live preview'), + isActive: this.rightPane === rightSidebarViews.clientSidePreview, + view: rightSidebarViews.clientSidePreview, + icon: 'live-preview', + }, + ]; + }, + tabs() { + return this.defaultTabs + .concat(this.extensionTabs) + .filter(tab => tab.show); + }, }, methods: { ...mapActions(['setRightPane']), @@ -42,7 +80,6 @@ export default { this.setRightPane(view); }, }, - rightSidebarViews, }; </script> @@ -64,64 +101,25 @@ export default { <nav class="ide-activity-bar"> <ul class="list-unstyled"> <li - v-if="currentMergeRequestId" + v-for="tab of tabs" + :key="tab.title" > <button v-tooltip - :title="__('Merge Request')" - :aria-label="__('Merge Request')" - :class="{ - active: rightPane === $options.rightSidebarViews.mergeRequestInfo - }" - data-container="body" - data-placement="left" - class="ide-sidebar-link is-right" - type="button" - @click="clickTab($event, $options.rightSidebarViews.mergeRequestInfo)" - > - <icon - :size="16" - name="text-description" - /> - </button> - </li> - <li> - <button - v-tooltip - :title="__('Pipelines')" - :aria-label="__('Pipelines')" - :class="{ - active: pipelinesActive - }" - data-container="body" - data-placement="left" - class="ide-sidebar-link is-right" - type="button" - @click="clickTab($event, $options.rightSidebarViews.pipelines)" - > - <icon - :size="16" - name="rocket" - /> - </button> - </li> - <li v-if="showLivePreview"> - <button - v-tooltip - :title="__('Live preview')" - :aria-label="__('Live preview')" + :title="tab.title" + :aria-label="tab.title" :class="{ - active: rightPane === $options.rightSidebarViews.clientSidePreview + active: tab.isActive }" data-container="body" data-placement="left" class="ide-sidebar-link is-right" type="button" - @click="clickTab($event, $options.rightSidebarViews.clientSidePreview)" + @click="clickTab($event, tab.view)" > <icon :size="16" - name="live-preview" + :name="tab.icon" /> </button> </li> diff --git a/app/assets/javascripts/ide/components/repo_file_status_icon.vue b/app/assets/javascripts/ide/components/repo_file_status_icon.vue index 76a3333be50..97589e116c5 100644 --- a/app/assets/javascripts/ide/components/repo_file_status_icon.vue +++ b/app/assets/javascripts/ide/components/repo_file_status_icon.vue @@ -26,8 +26,8 @@ export default { <template> <span - v-tooltip v-if="file.file_lock" + v-tooltip :title="lockTooltip" data-container="body" > diff --git a/app/assets/javascripts/ide/components/repo_loading_file.vue b/app/assets/javascripts/ide/components/repo_loading_file.vue deleted file mode 100644 index 7a5ede82253..00000000000 --- a/app/assets/javascripts/ide/components/repo_loading_file.vue +++ /dev/null @@ -1,42 +0,0 @@ -<script> - import { mapState } from 'vuex'; - import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; - - export default { - components: { - skeletonLoadingContainer, - }, - computed: { - ...mapState([ - 'leftPanelCollapsed', - ]), - }, - }; -</script> - -<template> - <tr - class="loading-file" - aria-label="Loading files" - > - <td class="multi-file-table-col-name"> - <skeleton-loading-container - :small="true" - /> - </td> - <template v-if="!leftPanelCollapsed"> - <td class="d-none d-sm-none d-md-block"> - <skeleton-loading-container - :small="true" - /> - </td> - - <td class="d-none d-sm-block"> - <skeleton-loading-container - :small="true" - class="animation-container-right" - /> - </td> - </template> - </tr> -</template> diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js index 79e38ae911e..c0550116633 100644 --- a/app/assets/javascripts/ide/index.js +++ b/app/assets/javascripts/ide/index.js @@ -8,16 +8,28 @@ import { convertPermissionToBoolean } from '../lib/utils/common_utils'; Vue.use(Translate); -export function initIde(el) { +/** + * Initialize the IDE on the given element. + * + * @param {Element} el - The element that will contain the IDE. + * @param {Object} options - Extra options for the IDE (Used by EE). + * @param {(e:Element) => Object} options.extraInitialData - + * Function that returns extra properties to seed initial data. + * @param {Component} options.rootComponent - + * Component that overrides the root component. + */ +export function initIde(el, options = {}) { if (!el) return null; + const { + extraInitialData = () => ({}), + rootComponent = ide, + } = options; + return new Vue({ el, store, router, - components: { - ide, - }, created() { this.setEmptyStateSvgs({ emptyStateSvgPath: el.dataset.emptyStateSvgPath, @@ -32,13 +44,14 @@ export function initIde(el) { }); this.setInitialData({ clientsidePreviewEnabled: convertPermissionToBoolean(el.dataset.clientsidePreviewEnabled), + ...extraInitialData(el), }); }, methods: { ...mapActions(['setEmptyStateSvgs', 'setLinks', 'setInitialData']), }, render(createElement) { - return createElement('ide'); + return createElement(rootComponent); }, }); } @@ -52,3 +65,18 @@ export function resetServiceWorkersPublicPath() { const webpackAssetPath = `${relativeRootPath}/assets/webpack/`; __webpack_public_path__ = webpackAssetPath; // eslint-disable-line camelcase } + +/** + * Start the IDE. + * + * @param {Objects} options - Extra options for the IDE (Used by EE). + */ +export function startIde(options) { + document.addEventListener('DOMContentLoaded', () => { + const ideElement = document.getElementById('ide'); + if (ideElement) { + resetServiceWorkersPublicPath(); + initIde(ideElement, options); + } + }); +} diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js index 35eaf21a836..9e848699163 100644 --- a/app/assets/javascripts/issuable_bulk_update_actions.js +++ b/app/assets/javascripts/issuable_bulk_update_actions.js @@ -36,7 +36,7 @@ export default { }, getSelectedIssues() { - return this.issues.has('.selected_issue:checked'); + return this.issues.has('.selected-issuable:checked'); }, getLabelsFromSelection() { @@ -110,7 +110,7 @@ export default { getOriginalCommonIds() { const labelIds = []; - this.getElement('.selected_issue:checked').each((i, el) => { + this.getElement('.selected-issuable:checked').each((i, el) => { labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels')); }); return _.intersection.apply(this, labelIds); @@ -119,7 +119,7 @@ export default { // From issuable's initial bulk selection getOriginalMarkedIds() { const labelIds = []; - this.getElement('.selected_issue:checked').each((i, el) => { + this.getElement('.selected-issuable:checked').each((i, el) => { labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels')); }); return _.intersection.apply(this, labelIds); @@ -132,7 +132,7 @@ export default { let issuableLabels = []; // Collect unique label IDs for all checked issues - this.getElement('.selected_issue:checked').each((i, el) => { + this.getElement('.selected-issuable:checked').each((i, el) => { issuableLabels = this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels'); issuableLabels.forEach((labelId) => { // Store unique IDs diff --git a/app/assets/javascripts/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable_bulk_update_sidebar.js index 2307c8e0d85..74150ce3a8b 100644 --- a/app/assets/javascripts/issuable_bulk_update_sidebar.js +++ b/app/assets/javascripts/issuable_bulk_update_sidebar.js @@ -30,7 +30,7 @@ export default class IssuableBulkUpdateSidebar { this.$otherFilters = $('.issues-other-filters'); this.$checkAllContainer = $('.check-all-holder'); this.$issueChecks = $('.issue-check'); - this.$issuesList = $('.selected_issue'); + this.$issuesList = $('.selected-issuable'); this.$issuableIdsInput = $('#update_issuable_ids'); } @@ -55,7 +55,7 @@ export default class IssuableBulkUpdateSidebar { } updateFormState() { - const noCheckedIssues = !$('.selected_issue:checked').length; + const noCheckedIssues = !$('.selected-issuable:checked').length; this.toggleSubmitButtonDisabled(noCheckedIssues); this.updateSelectedIssuableIds(); @@ -123,7 +123,7 @@ export default class IssuableBulkUpdateSidebar { } static getCheckedIssueIds() { - const $checkedIssues = $('.selected_issue:checked'); + const $checkedIssues = $('.selected-issuable:checked'); if ($checkedIssues.length > 0) { return $.map($checkedIssues, value => $(value).data('id')); diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index ad928484952..c6ad3aa3e0d 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -293,6 +293,7 @@ :show-delete-button="showDeleteButton" :can-attach-file="canAttachFile" :enable-autocomplete="enableAutocomplete" + :issuable-type="issuableType" /> <recaptcha-modal diff --git a/app/assets/javascripts/issue_show/components/edit_actions.vue b/app/assets/javascripts/issue_show/components/edit_actions.vue index 7fd3ea61aa7..bcf8686afcc 100644 --- a/app/assets/javascripts/issue_show/components/edit_actions.vue +++ b/app/assets/javascripts/issue_show/components/edit_actions.vue @@ -1,7 +1,13 @@ <script> + import { __, sprintf } from '~/locale'; import updateMixin from '../mixins/update'; import eventHub from '../event_hub'; + const issuableTypes = { + issue: __('Issue'), + epic: __('Epic'), + }; + export default { mixins: [updateMixin], props: { @@ -18,6 +24,10 @@ required: false, default: true, }, + issuableType: { + type: String, + required: true, + }, }, data() { return { @@ -37,8 +47,11 @@ eventHub.$emit('close.form'); }, deleteIssuable() { + const confirmMessage = sprintf(__('%{issuableType} will be removed! Are you sure?'), { + issuableType: issuableTypes[this.issuableType], + }); // eslint-disable-next-line no-alert - if (window.confirm('Issue will be removed! Are you sure?')) { + if (window.confirm(confirmMessage)) { this.deleteLoading = true; eventHub.$emit('delete.issuable'); diff --git a/app/assets/javascripts/issue_show/components/form.vue b/app/assets/javascripts/issue_show/components/form.vue index e509bb52f7d..03d8d0ec67c 100644 --- a/app/assets/javascripts/issue_show/components/form.vue +++ b/app/assets/javascripts/issue_show/components/form.vue @@ -27,6 +27,10 @@ required: false, default: () => [], }, + issuableType: { + type: String, + required: true, + }, markdownPreviewPath: { type: String, required: true, @@ -110,6 +114,7 @@ :form-state="formState" :can-destroy="canDestroy" :show-delete-button="showDeleteButton" + :issuable-type="issuableType" /> </form> </template> diff --git a/app/assets/javascripts/issue_show/components/title.vue b/app/assets/javascripts/issue_show/components/title.vue index b5e8e0ea44b..cf99e9a9cd8 100644 --- a/app/assets/javascripts/issue_show/components/title.vue +++ b/app/assets/javascripts/issue_show/components/title.vue @@ -76,8 +76,8 @@ export default { > </h2> <button - v-tooltip v-if="showInlineEditButton && canUpdate" + v-tooltip type="button" class="btn btn-default btn-edit btn-svg js-issuable-edit" title="Edit title and description" diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js index d4f2a3ef7d3..0e71e705c13 100644 --- a/app/assets/javascripts/job.js +++ b/app/assets/javascripts/job.js @@ -6,7 +6,7 @@ import { visitUrl } from './lib/utils/url_utility'; import bp from './breakpoints'; import { numberToHumanSize } from './lib/utils/number_utils'; import { setCiStatusFavicon } from './lib/utils/common_utils'; -import { isScrolledToBottom, scrollDown } from './lib/utils/scroll_utils'; +import { isScrolledToBottom, scrollDown, scrollUp } from './lib/utils/scroll_utils'; import LogOutputBehaviours from './lib/utils/logoutput_behaviours'; export default class Job extends LogOutputBehaviours { @@ -80,7 +80,7 @@ export default class Job extends LogOutputBehaviours { } scrollToTop() { - $(document).scrollTop(0); + scrollUp(); this.hasBeenScrolled = true; this.toggleScroll(); } diff --git a/app/assets/javascripts/jobs/components/artifacts_block.vue b/app/assets/javascripts/jobs/components/artifacts_block.vue index 525c5eec91a..d5866f9b9f1 100644 --- a/app/assets/javascripts/jobs/components/artifacts_block.vue +++ b/app/assets/javascripts/jobs/components/artifacts_block.vue @@ -1,40 +1,27 @@ <script> - import TimeagoTooltiop from '~/vue_shared/components/time_ago_tooltip.vue'; + import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; + import timeagoMixin from '~/vue_shared/mixins/timeago'; export default { components: { - TimeagoTooltiop, + TimeagoTooltip, }, + mixins: [ + timeagoMixin, + ], props: { - // @build.artifacts_expired? - haveArtifactsExpired: { - type: Boolean, + artifact: { + type: Object, required: true, }, - // @build.has_expiring_artifacts? - willArtifactsExpire: { - type: Boolean, - required: true, - }, - expireAt: { - type: String, - required: false, - default: null, - }, - keepArtifactsPath: { - type: String, - required: false, - default: null, - }, - downloadArtifactsPath: { - type: String, - required: false, - default: null, + }, + computed: { + isExpired() { + return this.artifact.expired; }, - browseArtifactsPath: { - type: String, - required: false, - default: null, + // Only when the key is `false` we can render this block + willExpire() { + return this.artifact.expired === false; }, }, }; @@ -46,21 +33,22 @@ </div> <p - v-if="haveArtifactsExpired" + v-if="isExpired" class="js-artifacts-removed build-detail-row" > {{ s__('Job|The artifacts were removed') }} </p> + <p - v-else-if="willArtifactsExpire" + v-else-if="willExpire" class="js-artifacts-will-be-removed build-detail-row" > - {{ s__('Job|The artifacts will be removed') }} + {{ s__('Job|The artifacts will be removed in') }} </p> - <timeago-tooltiop - v-if="expireAt" - :time="expireAt" + <timeago-tooltip + v-if="artifact.expire_at" + :time="artifact.expire_at" /> <div @@ -68,8 +56,8 @@ role="group" > <a - v-if="keepArtifactsPath" - :href="keepArtifactsPath" + v-if="artifact.keep_path" + :href="artifact.keep_path" class="js-keep-artifacts btn btn-sm btn-default" data-method="post" > @@ -77,8 +65,8 @@ </a> <a - v-if="downloadArtifactsPath" - :href="downloadArtifactsPath" + v-if="artifact.download_path" + :href="artifact.download_path" class="js-download-artifacts btn btn-sm btn-default" download rel="nofollow" @@ -87,8 +75,8 @@ </a> <a - v-if="browseArtifactsPath" - :href="browseArtifactsPath" + v-if="artifact.browse_path" + :href="artifact.browse_path" class="js-browse-artifacts btn btn-sm btn-default" > {{ s__('Job|Browse') }} diff --git a/app/assets/javascripts/jobs/components/commit_block.vue b/app/assets/javascripts/jobs/components/commit_block.vue index 7f485295513..39a4ff159e2 100644 --- a/app/assets/javascripts/jobs/components/commit_block.vue +++ b/app/assets/javascripts/jobs/components/commit_block.vue @@ -1,64 +1,56 @@ <script> -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; + import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; -export default { - components: { - ClipboardButton, - }, - props: { - pipelineShortSha: { - type: String, - required: true, + export default { + components: { + ClipboardButton, }, - pipelineShaPath: { - type: String, - required: true, + props: { + commit: { + type: Object, + required: true, + }, + mergeRequest: { + type: Object, + required: false, + default: null, + }, + isLastBlock: { + type: Boolean, + required: true, + }, }, - mergeRequestReference: { - type: String, - required: false, - default: null, - }, - mergeRequestPath: { - type: String, - required: false, - default: null, - }, - gitCommitTitlte: { - type: String, - required: true, - }, - }, -}; + }; </script> <template> - <div class="block"> + <div + :class="{ + 'block-last': isLastBlock, + block: !isLastBlock + }"> <p> {{ __('Commit') }} <a - :href="pipelineShaPath" + :href="commit.commit_path" class="js-commit-sha commit-sha link-commit" - > - {{ pipelineShortSha }} - </a> + >{{ commit.short_id }}</a> <clipboard-button - :text="pipelineShortSha" + :text="commit.short_id" :title="__('Copy commit SHA to clipboard')" + css-class="btn btn-clipboard btn-transparent" /> <a - v-if="mergeRequestPath && mergeRequestReference" - :href="mergeRequestPath" + v-if="mergeRequest" + :href="mergeRequest.path" class="js-link-commit link-commit" - > - {{ mergeRequestReference }} - </a> + >{{ mergeRequest.iid }}</a> </p> <p class="build-light-text append-bottom-0"> - {{ gitCommitTitlte }} + {{ commit.title }} </p> </div> </template> diff --git a/app/assets/javascripts/jobs/components/empty_state.vue b/app/assets/javascripts/jobs/components/empty_state.vue index 4faf08387fb..ff45a5b05f8 100644 --- a/app/assets/javascripts/jobs/components/empty_state.vue +++ b/app/assets/javascripts/jobs/components/empty_state.vue @@ -25,7 +25,7 @@ validator(value) { return ( value === null || - (Object.prototype.hasOwnProperty.call(value, 'link') && + (Object.prototype.hasOwnProperty.call(value, 'path') && Object.prototype.hasOwnProperty.call(value, 'method') && Object.prototype.hasOwnProperty.call(value, 'title')) ); @@ -63,7 +63,7 @@ class="text-center" > <a - :href="action.link" + :href="action.path" :data-method="action.method" class="js-job-empty-state-action btn btn-primary" > diff --git a/app/assets/javascripts/jobs/components/erased_block.vue b/app/assets/javascripts/jobs/components/erased_block.vue index d688eebfa95..3d6d9ba4387 100644 --- a/app/assets/javascripts/jobs/components/erased_block.vue +++ b/app/assets/javascripts/jobs/components/erased_block.vue @@ -1,39 +1,36 @@ <script> -import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; + import _ from 'underscore'; + import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; -export default { - components: { - TimeagoTooltip, - }, - props: { - erasedByUser: { - type: Boolean, - required: true, + export default { + components: { + TimeagoTooltip, }, - username: { - type: String, - required: false, - default: null, + props: { + user: { + type: Object, + required: false, + default: () => ({}), + }, + erasedAt: { + type: String, + required: true, + }, }, - linkToUser: { - type: String, - required: false, - default: null, + computed: { + isErasedByUser() { + return !_.isEmpty(this.user); + }, }, - erasedAt: { - type: String, - required: true, - }, - }, -}; + }; </script> <template> <div class="prepend-top-default js-build-erased"> <div class="erased alert alert-warning"> - <template v-if="erasedByUser"> + <template v-if="isErasedByUser"> {{ s__("Job|Job has been erased by") }} - <a :href="linkToUser"> - {{ username }} + <a :href="user.web_url"> + {{ user.username }} </a> </template> <template v-else> diff --git a/app/assets/javascripts/jobs/components/job_log.vue b/app/assets/javascripts/jobs/components/job_log.vue index 3c4749d996b..b12e963b60c 100644 --- a/app/assets/javascripts/jobs/components/job_log.vue +++ b/app/assets/javascripts/jobs/components/job_log.vue @@ -6,7 +6,7 @@ type: String, required: true, }, - isReceivingBuildTrace: { + isComplete: { type: Boolean, required: true, }, @@ -22,7 +22,7 @@ </code> <div - v-if="isReceivingBuildTrace" + v-if="isComplete" class="js-log-animation build-loader-animation" > <div class="dot"></div> diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue index 513851e376f..3e62ababea3 100644 --- a/app/assets/javascripts/jobs/components/job_log_controllers.vue +++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue @@ -1,8 +1,9 @@ <script> + import { polyfillSticky } from '~/lib/utils/sticky'; import Icon from '~/vue_shared/components/icon.vue'; import tooltip from '~/vue_shared/directives/tooltip'; import { numberToHumanSize } from '~/lib/utils/number_utils'; - import { s__, sprintf } from '~/locale'; + import { sprintf } from '~/locale'; export default { components: { @@ -12,44 +13,48 @@ tooltip, }, props: { - canEraseJob: { - type: Boolean, - required: true, + erasePath: { + type: String, + required: false, + default: null, }, size: { type: Number, required: true, }, - rawTracePath: { + rawPath: { type: String, required: false, default: null, }, - canScrollToTop: { + isScrollTopDisabled: { + type: Boolean, + required: true, + }, + isScrollBottomDisabled: { + type: Boolean, + required: true, + }, + isScrollingDown: { type: Boolean, required: true, }, - canScrollToBottom: { + isTraceSizeVisible: { type: Boolean, required: true, }, }, computed: { jobLogSize() { - return sprintf('Showing last %{startSpanTag} %{size} %{endSpanTag} of log -', { - startSpanTag: '<span class="s-truncated-info-size truncated-info-size">', - endSpanTag: '</span>', + return sprintf('Showing last %{size} of log -', { size: numberToHumanSize(this.size), }); }, }, + mounted() { + polyfillSticky(this.$el); + }, methods: { - handleEraseJobClick() { - // eslint-disable-next-line no-alert - if (window.confirm(s__('Job|Are you sure you want to erase this job?'))) { - this.$emit('eraseJob'); - } - }, handleScrollToTop() { this.$emit('scrollJobLogTop'); }, @@ -57,48 +62,52 @@ this.$emit('scrollJobLogBottom'); }, }, + }; </script> <template> <div class="top-bar"> <!-- truncate information --> <div class="js-truncated-info truncated-info d-none d-sm-block float-left"> - <p v-html="jobLogSize"></p> + <template v-if="isTraceSizeVisible"> + {{ jobLogSize }} - <a - v-if="rawTracePath" - :href="rawTracePath" - class="js-raw-link raw-link" - > - {{ s__("Job|Complete Raw") }} - </a> + <a + v-if="rawPath" + :href="rawPath" + class="js-raw-link raw-link" + > + {{ s__("Job|Complete Raw") }} + </a> + </template> </div> <!-- eo truncate information --> <div class="controllers float-right"> <!-- links --> <a + v-if="rawPath" v-tooltip - v-if="rawTracePath" :title="s__('Job|Show complete raw')" - :href="rawTracePath" + :href="rawPath" class="js-raw-link-controller controllers-buttons" data-container="body" > <icon name="doc-text" /> </a> - <button + <a + v-if="erasePath" v-tooltip - v-if="canEraseJob" :title="s__('Job|Erase job log')" - type="button" + :href="erasePath" + data-confirm="__('Are you sure you want to erase this build?')" class="js-erase-link controllers-buttons" data-container="body" - @click="handleEraseJobClick" + data-method="post" > <icon name="remove" /> - </button> + </a> <!-- eo links --> <!-- scroll buttons --> @@ -109,7 +118,7 @@ data-container="body" > <button - :disabled="!canScrollToTop" + :disabled="isScrollTopDisabled" type="button" class="js-scroll-top btn-scroll btn-transparent btn-blank" @click="handleScrollToTop" @@ -125,9 +134,10 @@ data-container="body" > <button - :disabled="!canScrollToBottom" + :disabled="isScrollBottomDisabled" type="button" class="js-scroll-bottom btn-scroll btn-transparent btn-blank" + :class="{ animate: isScrollingDown }" @click="handleScrollToBottom" > <icon name="scroll_down"/> diff --git a/app/assets/javascripts/jobs/components/jobs_container.vue b/app/assets/javascripts/jobs/components/jobs_container.vue index b81109bdd06..93e2292ff84 100644 --- a/app/assets/javascripts/jobs/components/jobs_container.vue +++ b/app/assets/javascripts/jobs/components/jobs_container.vue @@ -25,9 +25,9 @@ class="build-job" > <a - v-tooltip v-for="job in jobs" :key="job.id" + v-tooltip :href="job.path" :title="job.tooltip" :class="{ active: job.active, retried: job.retried }" diff --git a/app/assets/javascripts/jobs/components/sidebar_details_block.vue b/app/assets/javascripts/jobs/components/sidebar_details_block.vue index 80c2a5fb48b..a591fcfb482 100644 --- a/app/assets/javascripts/jobs/components/sidebar_details_block.vue +++ b/app/assets/javascripts/jobs/components/sidebar_details_block.vue @@ -1,89 +1,113 @@ <script> -import timeagoMixin from '~/vue_shared/mixins/timeago'; -import { timeIntervalInWords } from '~/lib/utils/datetime_utility'; -import Icon from '~/vue_shared/components/icon.vue'; -import DetailRow from './sidebar_detail_row.vue'; + import _ from 'underscore'; + import timeagoMixin from '~/vue_shared/mixins/timeago'; + import { timeIntervalInWords } from '~/lib/utils/datetime_utility'; + import Icon from '~/vue_shared/components/icon.vue'; + import DetailRow from './sidebar_detail_row.vue'; + import ArtifactsBlock from './artifacts_block.vue'; + import TriggerBlock from './trigger_block.vue'; + import CommitBlock from './commit_block.vue'; -export default { - name: 'SidebarDetailsBlock', - components: { - DetailRow, - Icon, - }, - mixins: [timeagoMixin], - props: { - job: { - type: Object, - required: true, + export default { + name: 'SidebarDetailsBlock', + components: { + ArtifactsBlock, + CommitBlock, + DetailRow, + Icon, + TriggerBlock, }, - isLoading: { - type: Boolean, - required: true, + mixins: [timeagoMixin], + props: { + job: { + type: Object, + required: true, + }, + isLoading: { + type: Boolean, + required: true, + }, + runnerHelpUrl: { + type: String, + required: false, + default: '', + }, + terminalPath: { + type: String, + required: false, + default: null, + }, }, - runnerHelpUrl: { - type: String, - required: false, - default: '', - }, - terminalPath: { - type: String, - required: false, - default: null, - }, - }, - computed: { - shouldRenderContent() { - return !this.isLoading && Object.keys(this.job).length > 0; - }, - coverage() { - return `${this.job.coverage}%`; - }, - duration() { - return timeIntervalInWords(this.job.duration); - }, - queued() { - return timeIntervalInWords(this.job.queued); - }, - runnerId() { - return `${this.job.runner.description} (#${this.job.runner.id})`; - }, - retryButtonClass() { - let className = - 'js-retry-button float-right btn btn-retry d-none d-md-block d-lg-block d-xl-block'; - className += - this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary'; - return className; - }, - hasTimeout() { - return this.job.metadata != null && this.job.metadata.timeout_human_readable !== null; - }, - timeout() { - if (this.job.metadata == null) { - return ''; - } + computed: { + shouldRenderContent() { + return !this.isLoading && Object.keys(this.job).length > 0; + }, + coverage() { + return `${this.job.coverage}%`; + }, + duration() { + return timeIntervalInWords(this.job.duration); + }, + queued() { + return timeIntervalInWords(this.job.queued); + }, + runnerId() { + return `${this.job.runner.description} (#${this.job.runner.id})`; + }, + retryButtonClass() { + let className = + 'js-retry-button float-right btn btn-retry d-none d-md-block d-lg-block d-xl-block'; + className += + this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary'; + return className; + }, + hasTimeout() { + return this.job.metadata != null && this.job.metadata.timeout_human_readable !== null; + }, + timeout() { + if (this.job.metadata == null) { + return ''; + } - let t = this.job.metadata.timeout_human_readable; - if (this.job.metadata.timeout_source !== '') { - t += ` (from ${this.job.metadata.timeout_source})`; - } + let t = this.job.metadata.timeout_human_readable; + if (this.job.metadata.timeout_source !== '') { + t += ` (from ${this.job.metadata.timeout_source})`; + } - return t; - }, - renderBlock() { - return ( - this.job.merge_request || - this.job.duration || - this.job.finished_data || - this.job.erased_at || - this.job.queued || - this.job.runner || - this.job.coverage || - this.job.tags.length || - this.job.cancel_path - ); + return t; + }, + renderBlock() { + return ( + this.job.merge_request || + this.job.duration || + this.job.finished_data || + this.job.erased_at || + this.job.queued || + this.job.runner || + this.job.coverage || + this.job.tags.length || + this.job.cancel_path + ); + }, + hasArtifact() { + return !_.isEmpty(this.job.artifact); + }, + hasTriggers() { + return !_.isEmpty(this.job.trigger); + }, + hasStages() { + return ( + this.job && + this.job.pipeline && + this.job.pipeline.stages && + this.job.pipeline.stages.length > 0 + ) || false; + }, + commit() { + return this.job.pipeline.commit || {}; + }, }, - }, -}; + }; </script> <template> <div> @@ -229,6 +253,19 @@ export default { </a> </div> </div> + <artifacts-block + v-if="hasArtifact" + :artifact="job.artifact" + /> + <trigger-block + v-if="hasTriggers" + :trigger="job.trigger" + /> + <commit-block + :is-last-block="hasStages" + :commit="commit" + :merge-request="job.merge_request" + /> </template> <gl-loading-icon v-if="isLoading" diff --git a/app/assets/javascripts/jobs/components/stuck_block.vue b/app/assets/javascripts/jobs/components/stuck_block.vue index 18883fea950..a60643b2c65 100644 --- a/app/assets/javascripts/jobs/components/stuck_block.vue +++ b/app/assets/javascripts/jobs/components/stuck_block.vue @@ -24,14 +24,14 @@ export default { <div class="bs-callout bs-callout-warning"> <p v-if="hasNoRunnersForProject" - class="js-stuck-no-runners" + class="js-stuck-no-runners append-bottom-0" > {{ s__(`Job|This job is stuck, because the project doesn't have any runners online assigned to it.`) }} </p> <p v-else-if="tags.length" - class="js-stuck-with-tags" + class="js-stuck-with-tags append-bottom-0" > {{ s__(`This job is stuck, because you don't have any active runners online with any of these tags assigned to them:`) }} @@ -45,7 +45,7 @@ export default { </p> <p v-else - class="js-stuck-no-active-runner" + class="js-stuck-no-active-runner append-bottom-0" > {{ s__(`This job is stuck, because you don't have any active runners that can run this job.`) }} diff --git a/app/assets/javascripts/jobs/components/trigger_block.vue b/app/assets/javascripts/jobs/components/trigger_block.vue index 8a88e5da6aa..d7b3c4fcb5b 100644 --- a/app/assets/javascripts/jobs/components/trigger_block.vue +++ b/app/assets/javascripts/jobs/components/trigger_block.vue @@ -1,16 +1,9 @@ <script> export default { props: { - shortToken: { - type: String, - required: false, - default: null, - }, - - variables: { + trigger: { type: Object, - required: false, - default: () => ({}), + required: true, }, }, data() { @@ -20,7 +13,7 @@ }, computed: { hasVariables() { - return Object.keys(this.variables).length > 0; + return this.trigger.variables && this.trigger.variables.length > 0; }, }, methods: { @@ -38,17 +31,18 @@ </h4> <p - v-if="shortToken" + v-if="trigger.short_token" class="js-short-token" > <span class="build-light-text"> {{ __('Token') }} </span> - {{ shortToken }} + {{ trigger.short_token }} </p> <p v-if="hasVariables"> <button + v-if="!areVariablesVisible" type="button" class="btn btn-default group js-reveal-variables" @click="revealVariables" @@ -63,20 +57,20 @@ class="js-build-variables trigger-build-variables" > <template - v-for="(value, key) in variables" + v-for="variable in trigger.variables" > <dt - :key="`${key}-variable`" + :key="`${variable.key}-variable`" class="js-build-variable trigger-build-variable" > - {{ key }} + {{ variable.key }} </dt> <dd - :key="`${key}-value`" + :key="`${variable.key}-value`" class="js-build-value trigger-build-value" > - {{ value }} + {{ variable.value }} </dd> </template> </dl> diff --git a/app/assets/javascripts/jobs/job_details_bundle.js b/app/assets/javascripts/jobs/job_details_bundle.js index a84324f14b2..0136ec4d194 100644 --- a/app/assets/javascripts/jobs/job_details_bundle.js +++ b/app/assets/javascripts/jobs/job_details_bundle.js @@ -1,34 +1,36 @@ +import { mapState } from 'vuex'; import Vue from 'vue'; -import JobMediator from './job_details_mediator'; -import jobHeader from './components/header.vue'; -import detailsBlock from './components/sidebar_details_block.vue'; +import Job from '../job'; +import JobHeader from './components/header.vue'; +import DetailsBlock from './components/sidebar_details_block.vue'; +import createStore from './store'; export default () => { const { dataset } = document.getElementById('js-job-details-vue'); - const mediator = new JobMediator({ endpoint: dataset.endpoint }); - mediator.fetchJob(); + // eslint-disable-next-line no-new + new Job(); + + const store = createStore(); + store.dispatch('setJobEndpoint', dataset.endpoint); + store.dispatch('fetchJob'); // Header // eslint-disable-next-line no-new new Vue({ el: '#js-build-header-vue', components: { - jobHeader, - }, - data() { - return { - mediator, - }; + JobHeader, }, - mounted() { - this.mediator.initBuildClass(); + store, + computed: { + ...mapState(['job', 'isLoading']), }, render(createElement) { return createElement('job-header', { props: { - isLoading: this.mediator.state.isLoading, - job: this.mediator.store.state.job, + isLoading: this.isLoading, + job: this.job, }, }); }, @@ -41,18 +43,17 @@ export default () => { new Vue({ el: detailsBlockElement, components: { - detailsBlock, + DetailsBlock, }, - data() { - return { - mediator, - }; + store, + computed: { + ...mapState(['job', 'isLoading']), }, render(createElement) { return createElement('details-block', { props: { - isLoading: this.mediator.state.isLoading, - job: this.mediator.store.state.job, + isLoading: this.isLoading, + job: this.job, runnerHelpUrl: dataset.runnerHelpUrl, terminalPath: detailsBlockDataset.terminalPath, }, diff --git a/app/assets/javascripts/jobs/job_details_mediator.js b/app/assets/javascripts/jobs/job_details_mediator.js deleted file mode 100644 index 89019da9d1e..00000000000 --- a/app/assets/javascripts/jobs/job_details_mediator.js +++ /dev/null @@ -1,67 +0,0 @@ -import Visibility from 'visibilityjs'; -import Flash from '../flash'; -import Poll from '../lib/utils/poll'; -import JobStore from './stores/job_store'; -import JobService from './services/job_service'; -import Job from '../job'; -import handleRevealVariables from '../build_variables'; - -export default class JobMediator { - constructor(options = {}) { - this.options = options; - - this.store = new JobStore(); - this.service = new JobService(options.endpoint); - - this.state = { - isLoading: false, - }; - } - - initBuildClass() { - this.build = new Job(); - handleRevealVariables(); - } - - fetchJob() { - this.poll = new Poll({ - resource: this.service, - method: 'getJob', - successCallback: response => this.successCallback(response), - errorCallback: () => this.errorCallback(), - }); - - if (!Visibility.hidden()) { - this.state.isLoading = true; - this.poll.makeRequest(); - } else { - this.getJob(); - } - - Visibility.change(() => { - if (!Visibility.hidden()) { - this.poll.restart(); - } else { - this.poll.stop(); - } - }); - } - - getJob() { - return this.service - .getJob() - .then(response => this.successCallback(response)) - .catch(() => this.errorCallback()); - } - - successCallback(response) { - this.state.isLoading = false; - return this.store.storeJob(response.data); - } - - errorCallback() { - this.state.isLoading = false; - - return new Flash('An error occurred while fetching the job.'); - } -} diff --git a/app/assets/javascripts/jobs/services/job_service.js b/app/assets/javascripts/jobs/services/job_service.js deleted file mode 100644 index b746489c45c..00000000000 --- a/app/assets/javascripts/jobs/services/job_service.js +++ /dev/null @@ -1,11 +0,0 @@ -import axios from '../../lib/utils/axios_utils'; - -export default class JobService { - constructor(endpoint) { - this.job = endpoint; - } - - getJob() { - return axios.get(this.job); - } -} diff --git a/app/assets/javascripts/jobs/store/mutations.js b/app/assets/javascripts/jobs/store/mutations.js index cd12ef87d40..c3f2359fa4d 100644 --- a/app/assets/javascripts/jobs/store/mutations.js +++ b/app/assets/javascripts/jobs/store/mutations.js @@ -1,6 +1,9 @@ import * as types from './mutation_types'; export default { + [types.SET_JOB_ENDPOINT](state, endpoint) { + state.jobEndpoint = endpoint; + }, [types.REQUEST_STATUS_FAVICON](state) { state.fetchingStatusFavicon = true; }, diff --git a/app/assets/javascripts/jobs/stores/job_store.js b/app/assets/javascripts/jobs/stores/job_store.js deleted file mode 100644 index 766194b8387..00000000000 --- a/app/assets/javascripts/jobs/stores/job_store.js +++ /dev/null @@ -1,11 +0,0 @@ -export default class JobStore { - constructor() { - this.state = { - job: {}, - }; - } - - storeJob(job = {}) { - this.state.job = job; - } -} diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index 6499b919787..1c7bca78df3 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -449,11 +449,11 @@ export default class LabelsSelect { } bindEvents() { - return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue); + return $('body').on('change', '.selected-issuable', this.onSelectCheckboxIssue); } // eslint-disable-next-line class-methods-use-this onSelectCheckboxIssue() { - if ($('.selected_issue:checked').length) { + if ($('.selected-issuable:checked').length) { return; } return $('.issues-bulk-update .labels-filter .dropdown-toggle-text').text('Label'); diff --git a/app/assets/javascripts/lib/utils/logoutput_behaviours.js b/app/assets/javascripts/lib/utils/logoutput_behaviours.js index 1bf99d935ef..41b57025cc9 100644 --- a/app/assets/javascripts/lib/utils/logoutput_behaviours.js +++ b/app/assets/javascripts/lib/utils/logoutput_behaviours.js @@ -1,5 +1,11 @@ import $ from 'jquery'; -import { canScroll, isScrolledToBottom, toggleDisableButton } from './scroll_utils'; +import { + canScroll, + isScrolledToBottom, + isScrolledToTop, + isScrolledToMiddle, + toggleDisableButton, +} from './scroll_utils'; export default class LogOutputBehaviours { constructor() { @@ -12,18 +18,13 @@ export default class LogOutputBehaviours { } toggleScroll() { - const $document = $(document); - const currentPosition = $document.scrollTop(); - const scrollHeight = $document.height(); - - const windowHeight = $(window).height(); if (canScroll()) { - if (currentPosition > 0 && scrollHeight - currentPosition !== windowHeight) { + if (isScrolledToMiddle()) { // User is in the middle of the log toggleDisableButton(this.$scrollTopBtn, false); toggleDisableButton(this.$scrollBottomBtn, false); - } else if (currentPosition === 0) { + } else if (isScrolledToTop()) { // User is at Top of Log toggleDisableButton(this.$scrollTopBtn, true); diff --git a/app/assets/javascripts/lib/utils/scroll_utils.js b/app/assets/javascripts/lib/utils/scroll_utils.js index 9313b570863..b4da1e16f08 100644 --- a/app/assets/javascripts/lib/utils/scroll_utils.js +++ b/app/assets/javascripts/lib/utils/scroll_utils.js @@ -4,6 +4,7 @@ export const canScroll = () => $(document).height() > $(window).height(); /** * Checks if the entire page is scrolled down all the way to the bottom + * @returns {Boolean} */ export const isScrolledToBottom = () => { const $document = $(document); @@ -16,11 +17,34 @@ export const isScrolledToBottom = () => { return scrollHeight - currentPosition === windowHeight; }; +/** + * Checks if page is scrolled to the top + * @returns {Boolean} + */ +export const isScrolledToTop = () => $(document).scrollTop() === 0; + export const scrollDown = () => { const $document = $(document); $document.scrollTop($document.height()); }; +export const scrollUp = () => { + $(document).scrollTop(0); +}; + +/** + * Checks if scroll position is in the middle of the page + * @returns {Boolean} + */ +export const isScrolledToMiddle = () => { + const $document = $(document); + const currentPosition = $document.scrollTop(); + const scrollHeight = $document.height(); + const windowHeight = $(window).height(); + + return currentPosition > 0 && scrollHeight - currentPosition !== windowHeight; +}; + export const toggleDisableButton = ($button, disable) => { if (disable && $button.prop('disabled')) return; $button.prop('disabled', disable); diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 53d7504de35..763429d7242 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -115,8 +115,9 @@ export default class MergeRequestTabs { this.mergeRequestTabs && this.mergeRequestTabs.querySelector(`a[data-action='${action}']`) && this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click - ) + ) { this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click(); + } this.initAffix(); } diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index ae96ac3b80c..67338aa96c3 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -97,33 +97,45 @@ export default { store: new MonitoringStore(), state: 'gettingStarted', showEmptyState: true, - updateAspectRatio: false, - updatedAspectRatios: 0, hoverData: {}, - resizeThrottled: {}, + elWidth: 0, }; }, + computed: { + forceRedraw() { + return this.elWidth; + }, + }, created() { this.service = new MonitoringService({ metricsEndpoint: this.metricsEndpoint, deploymentEndpoint: this.deploymentEndpoint, environmentsEndpoint: this.environmentsEndpoint, }); - eventHub.$on('toggleAspectRatio', this.toggleAspectRatio); + this.mutationObserverConfig = { + attributes: true, + childList: false, + subtree: false, + }; eventHub.$on('hoverChanged', this.hoverChanged); }, beforeDestroy() { - eventHub.$off('toggleAspectRatio', this.toggleAspectRatio); eventHub.$off('hoverChanged', this.hoverChanged); window.removeEventListener('resize', this.resizeThrottled, false); + this.sidebarMutationObserver.disconnect(); }, mounted() { - this.resizeThrottled = _.throttle(this.resize, 600); + this.resizeThrottled = _.debounce(this.resize, 100); if (!this.hasMetrics) { this.state = 'gettingStarted'; } else { this.getGraphsData(); window.addEventListener('resize', this.resizeThrottled, false); + + const sidebarEl = document.querySelector('.nav-sidebar'); + // The sidebar listener + this.sidebarMutationObserver = new MutationObserver(this.resizeThrottled); + this.sidebarMutationObserver.observe(sidebarEl, this.mutationObserverConfig); } }, methods: { @@ -153,14 +165,7 @@ export default { }); }, resize() { - this.updateAspectRatio = true; - }, - toggleAspectRatio() { - this.updatedAspectRatios += 1; - if (this.store.getMetricsCount() === this.updatedAspectRatios) { - this.updateAspectRatio = !this.updateAspectRatio; - this.updatedAspectRatios = 0; - } + this.elWidth = this.$el.clientWidth; }, hoverChanged(data) { this.hoverData = data; @@ -172,6 +177,7 @@ export default { <template> <div v-if="!showEmptyState" + :key="forceRedraw" class="prometheus-graphs prepend-top-default" > <div class="environments d-flex align-items-center"> @@ -214,11 +220,10 @@ export default { :show-panels="showPanels" > <graph - v-for="(graphData, index) in groupData.metrics" - :key="index" + v-for="(graphData, graphIndex) in groupData.metrics" + :key="graphIndex" :graph-data="graphData" :hover-data="hoverData" - :update-aspect-ratio="updateAspectRatio" :deployment-data="store.deploymentData" :project-path="projectPath" :tags-path="tagsPath" diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index a13f30e6079..ff44f51b8f8 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -32,10 +32,6 @@ export default { type: Object, required: true, }, - updateAspectRatio: { - type: Boolean, - required: true, - }, deploymentData: { type: Array, required: true, @@ -110,15 +106,6 @@ export default { }, }, watch: { - updateAspectRatio() { - if (this.updateAspectRatio) { - this.graphHeight = 450; - this.graphWidth = 600; - this.measurements = measurements.large; - this.draw(); - eventHub.$emit('toggleAspectRatio'); - } - }, hoverData() { this.positionFlag(); }, diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue index 3276f3a1ceb..ef18ae5c2c8 100644 --- a/app/assets/javascripts/monitoring/components/graph/legend.vue +++ b/app/assets/javascripts/monitoring/components/graph/legend.vue @@ -58,8 +58,8 @@ export default { </td> <template v-for="(track, trackIndex) in series.tracksLegend"> <track-line - :track="track" - :key="`track-line-${trackIndex}`"/> + :key="`track-line-${trackIndex}`" + :track="track"/> <td :key="`track-info-${trackIndex}`"> <track-info :track="track" diff --git a/app/assets/javascripts/notebook/index.vue b/app/assets/javascripts/notebook/index.vue index e2e3b08c77f..f241df9620d 100644 --- a/app/assets/javascripts/notebook/index.vue +++ b/app/assets/javascripts/notebook/index.vue @@ -51,10 +51,10 @@ <template> <div v-if="hasNotebook"> <component - v-for="(cell, index) in cells" :is="cellType(cell.cell_type)" - :cell="cell" + v-for="(cell, index) in cells" :key="index" + :cell="cell" :code-css-class="codeCssClass" /> </div> </template> diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 0c966e0808a..f301f093ef4 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -16,7 +16,7 @@ import 'vendor/jquery.atwho'; import AjaxCache from '~/lib/utils/ajax_cache'; import Vue from 'vue'; import syntaxHighlight from '~/syntax_highlight'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; import axios from './lib/utils/axios_utils'; import { getLocationHash } from './lib/utils/url_utility'; import Flash from './flash'; @@ -1293,10 +1293,10 @@ export default class Notes { new Vue({ el, components: { - SkeletonLoadingContainer, + SkeletonLoading, }, render(createElement) { - return createElement('skeleton-loading-container'); + return createElement('skeleton-loading'); }, }); } diff --git a/app/assets/javascripts/notes/components/diff_file_header.vue b/app/assets/javascripts/notes/components/diff_file_header.vue index fc7b52be241..4fd93304a03 100644 --- a/app/assets/javascripts/notes/components/diff_file_header.vue +++ b/app/assets/javascripts/notes/components/diff_file_header.vue @@ -41,8 +41,8 @@ export default { </div> <template v-else> <component - ref="titleWrapper" :is="titleTag" + ref="titleWrapper" :href="diffFile.discussionPath" > <span v-html="diffFile.blobIcon"></span> diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue index 802be022ba6..353aa790743 100644 --- a/app/assets/javascripts/notes/components/diff_with_note.vue +++ b/app/assets/javascripts/notes/components/diff_with_note.vue @@ -3,13 +3,13 @@ import { mapState, mapActions } from 'vuex'; import imageDiffHelper from '~/image_diff/helpers/index'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; import { trimFirstCharOfLineContent } from '~/diffs/store/utils'; export default { components: { DiffFileHeader, - SkeletonLoadingContainer, + SkeletonLoading, }, props: { discussion: { @@ -142,7 +142,7 @@ export default { class="line_content js-success-lazy-load" > <span></span> - <skeleton-loading-container /> + <skeleton-loading /> <span></span> </td> </tr> diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue index 051b17e9aa9..c68860d98ae 100644 --- a/app/assets/javascripts/notes/components/note_awards_list.vue +++ b/app/assets/javascripts/notes/components/note_awards_list.vue @@ -182,9 +182,9 @@ export default { <div class="note-awards"> <div class="awards js-awards-block"> <button - v-tooltip v-for="(awardList, awardName, index) in groupedAwards" :key="index" + v-tooltip :class="getAwardClassBindings(awardList)" :title="awardTitle(awardList)" class="btn award-control" diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue index 29595a2ba73..2d47d55f33c 100644 --- a/app/assets/javascripts/notes/components/note_form.vue +++ b/app/assets/javascripts/notes/components/note_form.vue @@ -171,8 +171,8 @@ export default { id="note_note" ref="textarea" slot="textarea" - :data-supports-quick-actions="!isEditing" v-model="updatedNoteBody" + :data-supports-quick-actions="!isEditing" name="note[note]" class="note-textarea js-gfm-input js-note-text js-autosize markdown-area js-vue-issue-note-form js-vue-textarea" diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index afe86911230..6ede7562edf 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -348,10 +348,10 @@ Please check your network connection and try again.`; <div class="discussion-notes"> <ul class="notes"> <component - v-for="note in discussion.notes" :is="componentName(note)" - :note="componentData(note)" + v-for="note in discussion.notes" :key="note.id" + :note="componentData(note)" @handleDeleteNote="deleteNoteHandler" /> </ul> diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue index 42c87fdf54a..d8e8efb982a 100644 --- a/app/assets/javascripts/notes/components/notes_app.vue +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -187,10 +187,10 @@ export default { class="notes main-notes-list timeline" > <component - v-for="discussion in allDiscussions" :is="getComponentName(discussion)" - v-bind="getComponentData(discussion)" + v-for="discussion in allDiscussions" :key="discussion.id" + v-bind="getComponentData(discussion)" /> </ul> diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js index 68df63b8539..320dfa47d5a 100644 --- a/app/assets/javascripts/notes/stores/actions.js +++ b/app/assets/javascripts/notes/stores/actions.js @@ -44,23 +44,11 @@ export const fetchDiscussions = ({ commit }, path) => commit(types.SET_INITIAL_DISCUSSIONS, discussions); }); -export const refetchDiscussionById = ({ commit, state }, { path, discussionId }) => - new Promise(resolve => { - service - .fetchDiscussions(path) - .then(res => res.json()) - .then(discussions => { - const selectedDiscussion = discussions.find(discussion => discussion.id === discussionId); - if (selectedDiscussion) { - commit(types.UPDATE_DISCUSSION, selectedDiscussion); - // We need to refetch as it is now the transformed one in state - const discussion = utils.findNoteObjectById(state.discussions, discussionId); - - resolve(discussion); - } - }) - .catch(() => {}); - }); +export const updateDiscussion = ({ commit, state }, discussion) => { + commit(types.UPDATE_DISCUSSION, discussion); + + return utils.findNoteObjectById(state.discussions, discussion.id); +}; export const deleteNote = ({ commit, dispatch }, note) => service.deleteNote(note.path).then(() => { diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js index 16bb54be126..73e55705f39 100644 --- a/app/assets/javascripts/notes/stores/mutations.js +++ b/app/assets/javascripts/notes/stores/mutations.js @@ -4,7 +4,8 @@ import * as constants from '../constants'; import { isInMRPage } from '../../lib/utils/common_utils'; export default { - [types.ADD_NEW_NOTE](state, note) { + [types.ADD_NEW_NOTE](state, data) { + const note = data.discussion ? data.discussion.notes[0] : data; const { discussion_id, type } = note; const [exists] = state.discussions.filter(n => n.id === note.discussion_id); const isDiscussion = type === constants.DISCUSSION_NOTE || type === constants.DIFF_NOTE; @@ -100,7 +101,10 @@ export default { discussionsData.forEach(discussion => { if (discussion.diff_file) { - Object.assign(discussion, { fileHash: discussion.diff_file.file_hash }); + Object.assign(discussion, { + fileHash: discussion.diff_file.file_hash, + truncated_diff_lines: discussion.truncated_diff_lines || [], + }); } // To support legacy notes, should be very rare case. diff --git a/app/assets/javascripts/pages/admin/application_settings/index.js b/app/assets/javascripts/pages/admin/application_settings/index.js index 069f8ce55d0..47bd70537f1 100644 --- a/app/assets/javascripts/pages/admin/application_settings/index.js +++ b/app/assets/javascripts/pages/admin/application_settings/index.js @@ -1,13 +1,8 @@ import initSettingsPanels from '~/settings_panels'; import projectSelect from '~/project_select'; -import UsagePingPayload from './usage_ping_payload'; document.addEventListener('DOMContentLoaded', () => { // Initialize expandable settings panels initSettingsPanels(); projectSelect(); - new UsagePingPayload( - document.querySelector('.js-usage-ping-payload-trigger'), - document.querySelector('.js-usage-ping-payload'), - ).init(); }); diff --git a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js new file mode 100644 index 00000000000..c40503603be --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js @@ -0,0 +1,8 @@ +import UsagePingPayload from './../usage_ping_payload'; + +document.addEventListener('DOMContentLoaded', () => { + new UsagePingPayload( + document.querySelector('.js-usage-ping-payload-trigger'), + document.querySelector('.js-usage-ping-payload'), + ).init(); +}); diff --git a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue index d6aa4bb95d2..8d5efcdcd96 100644 --- a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue +++ b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue @@ -155,10 +155,7 @@ /> </form> </template> - <template - slot="secondary-button" - slot-scope="props" - > + <template slot="secondary-button"> <button :disabled="!canSubmit" type="button" diff --git a/app/assets/javascripts/pages/ide/index.js b/app/assets/javascripts/pages/ide/index.js index efadf6967aa..d192df3561e 100644 --- a/app/assets/javascripts/pages/ide/index.js +++ b/app/assets/javascripts/pages/ide/index.js @@ -1,9 +1,3 @@ -import { initIde, resetServiceWorkersPublicPath } from '~/ide/index'; +import { startIde } from '~/ide/index'; -document.addEventListener('DOMContentLoaded', () => { - const ideElement = document.getElementById('ide'); - if (ideElement) { - resetServiceWorkersPublicPath(); - initIde(ideElement); - } -}); +startIde(); diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue index 0d05668b285..ef53d67e7cb 100644 --- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue @@ -147,8 +147,8 @@ <div class="cron-interval-input-wrapper"> <input id="schedule_cron" - :placeholder="__('Define a custom pattern with cron syntax')" v-model="cronInterval" + :placeholder="__('Define a custom pattern with cron syntax')" :name="inputNameAttribute" :disabled="!isEditable" class="form-control inline cron-interval-input" diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index ae88b765abf..875f6928bed 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -240,8 +240,8 @@ help-text="Lightweight issue tracking system for this project" > <project-feature-setting - :options="featureAccessLevelOptions" v-model="issuesAccessLevel" + :options="featureAccessLevelOptions" name="project[project_feature_attributes][issues_access_level]" /> </project-setting-row> @@ -250,8 +250,8 @@ help-text="View and edit files in this project" > <project-feature-setting - :options="featureAccessLevelOptions" v-model="repositoryAccessLevel" + :options="featureAccessLevelOptions" name="project[project_feature_attributes][repository_access_level]" /> </project-setting-row> @@ -261,8 +261,8 @@ help-text="Submit changes to be merged upstream" > <project-feature-setting - :options="repoFeatureAccessLevelOptions" v-model="mergeRequestsAccessLevel" + :options="repoFeatureAccessLevelOptions" :disabled-input="!repositoryEnabled" name="project[project_feature_attributes][merge_requests_access_level]" /> @@ -272,8 +272,8 @@ help-text="Build, test, and deploy your changes" > <project-feature-setting - :options="repoFeatureAccessLevelOptions" v-model="buildsAccessLevel" + :options="repoFeatureAccessLevelOptions" :disabled-input="!repositoryEnabled" name="project[project_feature_attributes][builds_access_level]" /> @@ -308,8 +308,8 @@ help-text="Pages for project documentation" > <project-feature-setting - :options="featureAccessLevelOptions" v-model="wikiAccessLevel" + :options="featureAccessLevelOptions" name="project[project_feature_attributes][wiki_access_level]" /> </project-setting-row> @@ -318,8 +318,8 @@ help-text="Share code pastes with others out of Git repository" > <project-feature-setting - :options="featureAccessLevelOptions" v-model="snippetsAccessLevel" + :options="featureAccessLevelOptions" name="project[project_feature_attributes][snippets_access_level]" /> </project-setting-row> diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue index 0fdb0a080cf..1522e2227e4 100644 --- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue +++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue @@ -42,7 +42,7 @@ export default { keys: ['feature', 'request'], }, ], - simpleMetrics: ['redis', 'sidekiq'], + simpleMetrics: ['redis'], data() { return { currentRequestId: '' }; }, @@ -130,8 +130,8 @@ export default { </div> <simple-metric v-for="metric in $options.simpleMetrics" - :current-request="currentRequest" :key="metric" + :current-request="currentRequest" :metric="metric" /> <div diff --git a/app/assets/javascripts/performance_bar/components/simple_metric.vue b/app/assets/javascripts/performance_bar/components/simple_metric.vue index b654bc66249..760ea8fe1e6 100644 --- a/app/assets/javascripts/performance_bar/components/simple_metric.vue +++ b/app/assets/javascripts/performance_bar/components/simple_metric.vue @@ -1,16 +1,29 @@ <script> -export default { - props: { - currentRequest: { - type: Object, - required: true, + export default { + props: { + currentRequest: { + type: Object, + required: true, + }, + metric: { + type: String, + required: true, + }, }, - metric: { - type: String, - required: true, + computed: { + duration() { + return ( + this.currentRequest.details[this.metric] && + this.currentRequest.details[this.metric].duration + ); + }, + calls() { + return ( + this.currentRequest.details[this.metric] && this.currentRequest.details[this.metric].calls + ); + }, }, - }, -}; + }; </script> <template> <div @@ -21,9 +34,9 @@ export default { v-if="currentRequest.details" class="bold" > - {{ currentRequest.details[metric].duration }} + {{ duration }} / - {{ currentRequest.details[metric].calls }} + {{ calls }} </span> {{ metric }} </div> diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index e27f195c9b0..9b4ba0c1a9a 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -68,9 +68,9 @@ export default { class="stage-column-list"> <stage-column-component v-for="(stage, index) in graph" + :key="stage.name" :title="capitalizeStageName(stage.name)" :jobs="stage.groups" - :key="stage.name" :stage-connector-class="stageConnectorClass(index, stage)" :is-first-column="isFirstColumn(index)" @refreshPipelineGraph="refreshPipelineGraph" diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index 9ac16b7e541..a1504592bbc 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -98,8 +98,8 @@ export default { <template> <div class="ci-job-component"> <a - v-tooltip v-if="status.has_details" + v-tooltip :href="status.details_path" :title="tooltipText" :class="cssClassJobName" @@ -115,8 +115,8 @@ export default { </a> <div - v-tooltip v-else + v-tooltip :title="tooltipText" :class="cssClassJobName" class="js-job-component-tooltip non-details-job-component" diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue index e7b2de52f76..567ea119343 100644 --- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue @@ -62,9 +62,9 @@ export default { <ul> <li v-for="(job, index) in jobs" + :id="jobId(job)" :key="job.id" :class="buildConnnectorClass(index)" - :id="jobId(job)" class="build" > diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 75db1e9ae7c..40df07650c9 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -67,29 +67,29 @@ export default { </span> <div class="label-container"> <span - v-tooltip v-if="pipeline.flags.latest" + v-tooltip class="js-pipeline-url-latest badge badge-success" title="Latest pipeline for this branch"> latest </span> <span - v-tooltip v-if="pipeline.flags.yaml_errors" + v-tooltip :title="pipeline.yaml_errors" class="js-pipeline-url-yaml badge badge-danger"> yaml invalid </span> <span - v-tooltip v-if="pipeline.flags.failure_reason" + v-tooltip :title="pipeline.failure_reason" class="js-pipeline-url-failure badge badge-danger"> error </span> <a - v-popover="popoverOptions" v-if="pipeline.flags.auto_devops" + v-popover="popoverOptions" tabindex="0" class="js-pipeline-url-autodevops badge badge-info autodevops-badge" role="button"> diff --git a/app/assets/javascripts/pipelines/components/stage.vue b/app/assets/javascripts/pipelines/components/stage.vue index 3e13bad9a0b..47c15b1a9c4 100644 --- a/app/assets/javascripts/pipelines/components/stage.vue +++ b/app/assets/javascripts/pipelines/components/stage.vue @@ -155,9 +155,9 @@ export default { <template> <div class="dropdown"> <button - v-tooltip id="stageDropdown" ref="dropdown" + v-tooltip :class="triggerButtonClass" :title="stage.title" class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button" diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue index d4c4d779d44..d9bf41924d1 100644 --- a/app/assets/javascripts/registry/components/collapsible_container.vue +++ b/app/assets/javascripts/registry/components/collapsible_container.vue @@ -88,8 +88,8 @@ <div class="controls d-none d-sm-block float-right"> <button - v-tooltip v-if="repo.canDelete" + v-tooltip :title="s__('ContainerRegistry|Remove repository')" :aria-label="s__('ContainerRegistry|Remove repository')" type="button" diff --git a/app/assets/javascripts/registry/components/table_registry.vue b/app/assets/javascripts/registry/components/table_registry.vue index 9f4973c3490..fafb35bd69a 100644 --- a/app/assets/javascripts/registry/components/table_registry.vue +++ b/app/assets/javascripts/registry/components/table_registry.vue @@ -118,8 +118,8 @@ <td class="content"> <button - v-tooltip v-if="item.canDelete" + v-tooltip :title="s__('ContainerRegistry|Remove tag')" :aria-label="s__('ContainerRegistry|Remove tag')" type="button" diff --git a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue index 7b37f4e9a97..fb8c6402d02 100644 --- a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue +++ b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue @@ -92,16 +92,16 @@ v-for="(report, i) in reports" > <summary-row + :key="`summary-row-${i}`" :summary="reportText(report)" :status-icon="getReportIcon(report)" - :key="`summary-row-${i}`" /> <issues-list v-if="shouldRenderIssuesList(report)" + :key="`issues-list-${i}`" :unresolved-issues="report.existing_failures" :new-issues="report.new_failures" :resolved-issues="report.resolved_failures" - :key="`issues-list-${i}`" :component="$options.componentNames.TestIssueBody" class="report-block-group-list" /> diff --git a/app/assets/javascripts/reports/components/report_issues.vue b/app/assets/javascripts/reports/components/report_issues.vue index c553a374f66..a2a03945ae3 100644 --- a/app/assets/javascripts/reports/components/report_issues.vue +++ b/app/assets/javascripts/reports/components/report_issues.vue @@ -37,8 +37,8 @@ export default { <ul class="report-block-list"> <li v-for="(issue, index) in issues" - :class="{ 'is-dismissed': issue.isDismissed }" :key="index" + :class="{ 'is-dismissed': issue.isDismissed }" class="report-block-list-issue" > <issue-status-icon @@ -47,8 +47,8 @@ export default { /> <component - v-if="component" :is="component" + v-if="component" :issue="issue" :status="issue.status || status" :is-new="isNew" diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue index ca3b9338c29..2ee3e1f322e 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue @@ -19,19 +19,23 @@ export default { TimeTrackingHelpState, }, props: { + // eslint-disable-next-line vue/prop-name-casing time_estimate: { type: Number, required: true, }, + // eslint-disable-next-line vue/prop-name-casing time_spent: { type: Number, required: true, }, + // eslint-disable-next-line vue/prop-name-casing human_time_estimate: { type: String, required: false, default: '', }, + // eslint-disable-next-line vue/prop-name-casing human_time_spent: { type: String, required: false, 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 d530ab2767b..70518ad73e8 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue @@ -106,8 +106,8 @@ export default { </tooltip-on-truncate> </template> <span - v-tooltip v-if="hasDeploymentTime" + v-tooltip :title="deployment.deployed_at_formatted" class="js-deploy-time" > 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 4c3f8dff3c4..acfdab3a015 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 @@ -28,11 +28,17 @@ export default { return this.mr.divergedCommitsCount > 0; }, 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); + 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 @@ -45,17 +51,24 @@ export default { }, webIdePath() { if (this.mr.canPushToSourceBranch) { - return mergeUrlParams({ - target_project: this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath ? - this.mr.targetProjectFullPath : '', - }, webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`)); + return mergeUrlParams( + { + target_project: + this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath + ? this.mr.targetProjectFullPath + : '', + }, + webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`), + ); } return null; }, ideButtonTitle() { return !this.mr.canPushToSourceBranch - ? s__('mrWidget|You are not allowed to edit this project directly. Please fork to make changes.') + ? s__( + 'mrWidget|You are not allowed to edit this project directly. Please fork to make changes.', + ) : ''; }, }, @@ -104,37 +117,34 @@ export default { <div v-if="mr.isOpen" - class="branch-actions" + class="branch-actions d-flex" > - <span + <a + v-if="!mr.sourceBranchRemoved" v-tooltip + :href="webIdePath" :title="ideButtonTitle" + :class="{ disabled: !mr.canPushToSourceBranch }" + class="btn btn-default js-web-ide d-none d-md-inline-block append-right-8" data-placement="bottom" tabindex="0" + role="button" > - <a - v-if="!mr.sourceBranchRemoved" - :href="webIdePath" - :class="{ disabled: !mr.canPushToSourceBranch }" - class="btn btn-default inline js-web-ide d-none d-md-inline-block" - role="button" - > - {{ s__("mrWidget|Open in Web IDE") }} - </a> - </span> + {{ s__("mrWidget|Open in Web IDE") }} + </a> <button :disabled="mr.sourceBranchRemoved" data-target="#modal_merge_info" data-toggle="modal" - class="btn btn-default inline js-check-out-branch" + class="btn btn-default js-check-out-branch append-right-default" type="button" > {{ s__("mrWidget|Check out branch") }} </button> - <span class="dropdown prepend-left-10"> + <span class="dropdown"> <button type="button" - class="btn inline dropdown-toggle" + class="btn dropdown-toggle" data-toggle="dropdown" aria-label="Download as" aria-haspopup="true" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue index 2f2394371ef..8184ef33022 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue @@ -114,8 +114,8 @@ :date-readable="mr.metrics.readableMergedAt" /> <a - v-tooltip v-if="mr.canRevertInCurrentMR" + v-tooltip :title="revertTitle" class="btn btn-close btn-sm" href="#modal-revert-commit" @@ -125,8 +125,8 @@ {{ revertLabel }} </a> <a - v-tooltip v-else-if="mr.revertInForkPath" + v-tooltip :href="mr.revertInForkPath" :title="revertTitle" class="btn btn-close btn-sm" @@ -135,8 +135,8 @@ {{ revertLabel }} </a> <a - v-tooltip v-if="mr.canCherryPickInCurrentMR" + v-tooltip :title="cherryPickTitle" class="btn btn-default btn-sm" href="#modal-cherry-pick-commit" @@ -146,8 +146,8 @@ {{ cherryPickLabel }} </a> <a - v-tooltip v-else-if="mr.cherryPickInForkPath" + v-tooltip :href="mr.cherryPickInForkPath" :title="cherryPickTitle" class="btn btn-default btn-sm" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js deleted file mode 100644 index bf8628d18a6..00000000000 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js +++ /dev/null @@ -1,15 +0,0 @@ -/* -The squash-before-merge button is EE only, but it's located right in the middle -of the readyToMerge state component template. - -If we didn't declare this component in CE, we'd need to maintain a separate copy -of the readyToMergeState template in EE, which is pretty big and likely to change. - -Instead, in CE, we declare the component, but it's hidden and is configured to do nothing. -In EE, the configuration extends this object to add a functioning squash-before-merge -button. -*/ - -export default { - template: '', -}; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index a5ca7b719a1..c8ad2aa30a6 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -6,7 +6,7 @@ import MergeRequest from '../../../merge_request'; import Flash from '../../../flash'; import statusIcon from '../mr_widget_status_icon.vue'; import eventHub from '../../event_hub'; -import SquashBeforeMerge from './mr_widget_squash_before_merge.vue'; +import SquashBeforeMerge from './squash_before_merge.vue'; export default { name: 'ReadyToMerge', @@ -255,7 +255,7 @@ export default { data-toggle="dropdown" aria-label="Select merge moment"> <i - class="fa fa-chevron-down" + class="fa fa-chevron-down qa-merge-moment-dropdown" aria-hidden="true" ></i> </button> @@ -265,7 +265,7 @@ export default { role="menu"> <li> <a - class="merge_when_pipeline_succeeds" + class="merge_when_pipeline_succeeds qa-merge-when-pipeline-succeeds-option" href="#" @click.prevent="handleMergeButtonClick(true)"> <span class="media"> @@ -279,7 +279,7 @@ export default { </li> <li> <a - class="accept-merge-request" + class="accept-merge-request qa-merge-immediately-option" href="#" @click.prevent="handleMergeButtonClick(false, true)"> <span class="media"> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue index 25c1044fe2b..25ad329e196 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue @@ -37,8 +37,8 @@ export default { <div class="accept-control inline"> <label class="merge-param-checkbox"> <input - :disabled="isMergeButtonDisabled" v-model="squashBeforeMerge" + :disabled="isMergeButtonDisabled" type="checkbox" name="squash" class="qa-squash-checkbox" diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js index 15097fa2a3f..a23496c6bf5 100644 --- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js +++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js @@ -40,7 +40,7 @@ export { default as MRWidgetService } from './services/mr_widget_service'; export { default as eventHub } from './event_hub'; export { default as getStateKey } from './stores/get_state_key'; export { default as stateMaps } from './stores/state_maps'; -export { default as SquashBeforeMerge } from './components/states/mr_widget_squash_before_merge.vue'; +export { default as SquashBeforeMerge } from './components/states/squash_before_merge.vue'; export { default as notify } from '../lib/utils/notify'; export { default as SourceBranchRemovalStatus } from './components/source_branch_removal_status.vue'; 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 b5eaaf054e7..0e445a29de4 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 @@ -114,6 +114,8 @@ export default { }, beforeDestroy() { eventHub.$off('mr.discussion.updated', this.checkStatus); + this.pollingInterval.destroy(); + this.deploymentsInterval.destroy(); }, methods: { createService(store) { diff --git a/app/assets/javascripts/vue_shared/components/bar_chart.vue b/app/assets/javascripts/vue_shared/components/bar_chart.vue index 3ced4eb691a..33af7a7f1df 100644 --- a/app/assets/javascripts/vue_shared/components/bar_chart.vue +++ b/app/assets/javascripts/vue_shared/components/bar_chart.vue @@ -291,8 +291,8 @@ export default { <template v-for="(data, index) in graphData"> <rect - v-tooltip :key="index" + v-tooltip :width="xScale.bandwidth()" :x="xScale(data.name)" :y="yScale(data.value)" diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue index a10deb93f0f..807e049caf6 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue @@ -2,14 +2,14 @@ import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; import $ from 'jquery'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; const { CancelToken } = axios; let axiosSource; export default { components: { - SkeletonLoadingContainer, + SkeletonLoading, }, props: { content: { @@ -81,7 +81,7 @@ export default { <div ref="markdown-preview" class="md md-previewer"> - <skeleton-loading-container v-if="isLoading" /> + <skeleton-loading v-if="isLoading" /> <div v-else v-html="previewContent"> diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 6f7bdbc2c4d..c797ad62a5d 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -135,8 +135,8 @@ export default { {{ file.name }} </span> <component - v-if="extraComponent" :is="extraComponent" + v-if="extraComponent" :file="file" :mouse-over="mouseOver" /> diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue index 18f5ce53bb1..b371b6adf7e 100644 --- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue +++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue @@ -126,18 +126,18 @@ export default { > <a v-if="action.type === 'link'" + :key="i" :href="action.path" :class="action.cssClass" - :key="i" > {{ action.label }} </a> <a v-else-if="action.type === 'ujs-link'" + :key="i" :href="action.path" :class="action.cssClass" - :key="i" data-method="post" rel="nofollow" > @@ -146,9 +146,9 @@ export default { <button v-else-if="action.type === 'button'" + :key="i" :disabled="action.isLoading" :class="action.cssClass" - :key="i" type="button" @click="onClickAction(action)" > diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue index d63318f3da6..c45dafa9807 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue @@ -1,5 +1,10 @@ <script> + import { Link } from '@gitlab-org/gitlab-ui'; + export default { + components: { + 'gl-link': Link, + }, props: { markdownDocsPath: { type: String, @@ -28,30 +33,30 @@ <div class="comment-toolbar clearfix"> <div class="toolbar-text"> <template v-if="!hasQuickActionsDocsPath && markdownDocsPath"> - <a + <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1" > Markdown is supported - </a> + </gl-link> </template> <template v-if="hasQuickActionsDocsPath && markdownDocsPath"> - <a + <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1" > Markdown - </a> + </gl-link> and - <a + <gl-link :href="quickActionsDocsPath" target="_blank" tabindex="-1" > quick actions - </a> + </gl-link> are supported </template> </div> diff --git a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue index 2eb6c20b2c0..1d9c9220469 100644 --- a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue +++ b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue @@ -1,3 +1,14 @@ +<script> +import { SkeletonLoading } from '@gitlab-org/gitlab-ui'; + +export default { + name: 'SkeletonNote', + components: { + SkeletonLoading, + }, +}; +</script> + <template> <li class="timeline-entry note"> <div class="timeline-entry-inner"> @@ -6,20 +17,9 @@ <div class="timeline-content"> <div class="note-header"></div> <div class="note-body"> - <skeleton-loading-container /> + <skeleton-loading /> </div> </div> </div> </li> </template> - -<script> -import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; - -export default { - name: 'SkeletonNote', - components: { - skeletonLoadingContainer, - }, -}; -</script> diff --git a/app/assets/javascripts/vue_shared/components/skeleton_loading_container.vue b/app/assets/javascripts/vue_shared/components/skeleton_loading_container.vue deleted file mode 100644 index 4a5ffbe5d5a..00000000000 --- a/app/assets/javascripts/vue_shared/components/skeleton_loading_container.vue +++ /dev/null @@ -1,37 +0,0 @@ -<script> - export default { - props: { - small: { - type: Boolean, - required: false, - default: false, - }, - lines: { - type: Number, - required: false, - default: 3, - }, - }, - computed: { - lineClasses() { - return new Array(this.lines).fill().map((_, i) => `skeleton-line-${i + 1}`); - }, - }, - }; -</script> - -<template> - <div - :class="{ - 'animation-container-small': small, - }" - class="animation-container" - > - <div - v-for="(css, index) in lineClasses" - :key="index" - :class="css" - > - </div> - </div> -</template> 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 78fde463507..cd3ee544344 100644 --- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue +++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue @@ -99,8 +99,8 @@ export default { {{ __("Not available") }} </span> <span - v-tooltip v-if="successPercent" + v-tooltip :title="successTooltip" :style="successBarStyle" class="status-green" @@ -109,8 +109,8 @@ export default { {{ successPercent }}% </span> <span - v-tooltip v-if="neutralPercent" + v-tooltip :title="neutralTooltip" :style="neutralBarStyle" class="status-neutral" @@ -119,8 +119,8 @@ export default { {{ neutralPercent }}% </span> <span - v-tooltip v-if="failurePercent" + v-tooltip :title="failureTooltip" :style="failureBarStyle" class="status-red" diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue index 125826da6c3..d5b58574123 100644 --- a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue +++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue @@ -51,8 +51,8 @@ export default { <template> <span - v-tooltip v-if="showTooltip" + v-tooltip :title="title" :data-placement="placement" class="js-show-tooltip" diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue index 01c36fec41a..08e102e57c3 100644 --- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue +++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue @@ -94,8 +94,8 @@ export default { :tooltip-text="avatarTooltipText" :tooltip-placement="tooltipPlacement" /><span - v-tooltip v-if="shouldShowUsername" + v-tooltip :title="tooltipText" :tooltip-placement="tooltipPlacement" >{{ username }}</span> diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index c91f5e279ea..af73954bd2e 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -93,7 +93,6 @@ hr { } .form-group.row .col-form-label { - padding-top: 0; // Bootstrap 4 aligns labels to the left // for horizontal forms @include media-breakpoint-up(md) { diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index fdc0454d837..d9d4a210f5f 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -111,6 +111,7 @@ ul.content-list { border-color: $white-normal; font-size: $gl-font-size; color: $gl-text-color; + word-break: break-word; &.no-description { .title { diff --git a/app/assets/stylesheets/framework/responsive_tables.scss b/app/assets/stylesheets/framework/responsive_tables.scss index 764bebd82c6..29a9c076cdf 100644 --- a/app/assets/stylesheets/framework/responsive_tables.scss +++ b/app/assets/stylesheets/framework/responsive_tables.scss @@ -39,7 +39,7 @@ .table-section { white-space: nowrap; - $section-widths: 10 15 20 25 30 40 50 100; + $section-widths: 5 10 15 20 25 30 40 50 60 100; @each $width in $section-widths { &.section-#{$width} { flex: 0 0 #{$width + '%'}; diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 0c1b8b92de3..6d891e21556 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -286,7 +286,7 @@ body { } .page-title { - margin-top: $gl-padding; + margin: #{2 * $grid-size} 0; line-height: 1.3; font-size: 1.25em; font-weight: $gl-font-weight-bold; diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index f66782ab882..837016db67b 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -55,7 +55,7 @@ $blue-50: #f6fafe; $blue-100: #e4f0fb; $blue-200: #b8d6f4; $blue-300: #73afea; -$blue-400: #2e87e0; +$blue-400: #418cd8; $blue-500: #1f78d1; $blue-600: #1b69b6; $blue-700: #17599c; @@ -67,7 +67,7 @@ $orange-50: #fffaf4; $orange-100: #fff1de; $orange-200: #fed69f; $orange-300: #fdbc60; -$orange-400: #fca121; +$orange-400: #fca429; $orange-500: #fc9403; $orange-600: #de7e00; $orange-700: #c26700; @@ -78,7 +78,7 @@ $orange-950: #592800; $red-50: #fef6f5; $red-100: #fbe5e1; $red-200: #f2b4a9; -$red-300: #e67664; +$red-300: #ea8271; $red-400: #e05842; $red-500: #db3b21; $red-600: #c0341d; diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index 69d7de886b4..b3c5c693824 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -136,15 +136,23 @@ right: 0; bottom: 0; left: 0; + + button { + display: none; + } } .board-title { padding: 0; border-bottom: 0; + justify-content: center; > span { + width: 100%; + margin-top: -12px; display: block; - transform: rotate(90deg) translate(35px, 10px); + transform: rotate(90deg) translate(35px, 0); + overflow: initial; } } @@ -265,7 +273,7 @@ margin-bottom: 0; padding: 5px; list-style: none; - overflow-y: scroll; + overflow-y: auto; overflow-x: hidden; } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 57539212e0c..62a9f97caa9 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -726,13 +726,13 @@ display: flex; } - .issue-info-container { + .issuable-info-container { -webkit-flex: 1; flex: 1; display: flex; padding-right: $gl-padding; - .issue-main-info { + .issuable-main-info { flex: 1 auto; margin-right: 10px; } @@ -768,7 +768,7 @@ margin-bottom: 10px; min-width: 15px; - .selected_issue { + .selected-issuable { vertical-align: text-top; } } @@ -800,7 +800,7 @@ } .issuable-list li, -.issue-info-container .controls { +.issuable-info-container .controls { .avatar-counter { display: inline-block; vertical-align: middle; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 9d46c2cf4fa..97b131687d3 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -460,7 +460,7 @@ display: -webkit-flex; display: flex; - .issue-info-container { + .issuable-info-container { -webkit-flex: 1; flex: 1; } diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb index 51547ed7eaf..68e14f0c2e5 100644 --- a/app/controllers/abuse_reports_controller.rb +++ b/app/controllers/abuse_reports_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AbuseReportsController < ApplicationController before_action :set_user, only: [:new] diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb index 68a49f0749f..d5537023b26 100644 --- a/app/controllers/admin/abuse_reports_controller.rb +++ b/app/controllers/admin/abuse_reports_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::AbuseReportsController < Admin::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/appearances_controller.rb b/app/controllers/admin/appearances_controller.rb index 9aaec905734..fdd3b4126ff 100644 --- a/app/controllers/admin/appearances_controller.rb +++ b/app/controllers/admin/appearances_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::AppearancesController < Admin::ApplicationController before_action :set_appearance, except: :create diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index a4648b33cfa..ef182b981f1 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Provides a base class for Admin controllers to subclass # # Automatically sets the layout and ensures an administrator is logged in diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 869213d61f1..b7c758a42ed 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -1,9 +1,39 @@ +# frozen_string_literal: true + class Admin::ApplicationSettingsController < Admin::ApplicationController + include InternalRedirect before_action :set_application_setting def show end + def integrations + end + + def repository + end + + def templates + end + + def ci_cd + end + + def reporting + end + + def metrics_and_profiling + end + + def network + end + + def geo + end + + def preferences + end + def update successful = ApplicationSettings::UpdateService .new(@application_setting, current_user, application_setting_params) @@ -13,10 +43,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent? end + redirect_path = referer_path(request) || admin_application_settings_path + respond_to do |format| if successful format.json { head :ok } - format.html { redirect_to admin_application_settings_path, notice: 'Application settings saved successfully' } + format.html { redirect_to redirect_path, notice: 'Application settings saved successfully' } else format.json { head :bad_request } format.html { render :show } @@ -96,8 +128,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController disabled_oauth_sign_in_sources: [], import_sources: [], repository_storages: [], - restricted_visibility_levels: [], - sidekiq_throttling_queues: [] + restricted_visibility_levels: [] ] end end diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb index daa21d1be93..00d2cc01192 100644 --- a/app/controllers/admin/applications_controller.rb +++ b/app/controllers/admin/applications_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::ApplicationsController < Admin::ApplicationController include OauthApplications diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb index 5f90ad7137d..7701f2e645b 100644 --- a/app/controllers/admin/background_jobs_controller.rb +++ b/app/controllers/admin/background_jobs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::BackgroundJobsController < Admin::ApplicationController def show ps_output, _ = Gitlab::Popen.popen(%W(ps ww -U #{Gitlab.config.gitlab.user} -o pid,pcpu,pmem,stat,start,command)) diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index b2fbbfc3e64..a91d9a534cd 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::BroadcastMessagesController < Admin::ApplicationController include BroadcastMessagesHelper diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 5dc3e6c2990..b5fb5511638 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::DashboardController < Admin::ApplicationController include CountHelper diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb index 5c2025c1988..49ce275ad14 100644 --- a/app/controllers/admin/deploy_keys_controller.rb +++ b/app/controllers/admin/deploy_keys_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::DeployKeysController < Admin::ApplicationController before_action :deploy_keys, only: [:index] before_action :deploy_key, only: [:destroy, :edit, :update] diff --git a/app/controllers/admin/gitaly_servers_controller.rb b/app/controllers/admin/gitaly_servers_controller.rb index 11c4dfe3d8d..0a5566bfe70 100644 --- a/app/controllers/admin/gitaly_servers_controller.rb +++ b/app/controllers/admin/gitaly_servers_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::GitalyServersController < Admin::ApplicationController def index @gitaly_servers = Gitaly::Server.all diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 2a47f01c6ad..46e85e1424f 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::GroupsController < Admin::ApplicationController include MembersPresentation diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb index 61247b280b3..44864f9c7d0 100644 --- a/app/controllers/admin/health_check_controller.rb +++ b/app/controllers/admin/health_check_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::HealthCheckController < Admin::ApplicationController def show @errors = HealthCheck::Utils.process_checks(['standard']) diff --git a/app/controllers/admin/hook_logs_controller.rb b/app/controllers/admin/hook_logs_controller.rb index 3017f96c26f..8301b3aa880 100644 --- a/app/controllers/admin/hook_logs_controller.rb +++ b/app/controllers/admin/hook_logs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::HookLogsController < Admin::ApplicationController include HooksExecution diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb index a98c355c7ba..d0abdec50ae 100644 --- a/app/controllers/admin/hooks_controller.rb +++ b/app/controllers/admin/hooks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::HooksController < Admin::ApplicationController include HooksExecution diff --git a/app/controllers/admin/identities_controller.rb b/app/controllers/admin/identities_controller.rb index 57ad7389a23..b51c2f678ca 100644 --- a/app/controllers/admin/identities_controller.rb +++ b/app/controllers/admin/identities_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::IdentitiesController < Admin::ApplicationController before_action :user before_action :identity, except: [:index, :new, :create] diff --git a/app/controllers/admin/impersonation_tokens_controller.rb b/app/controllers/admin/impersonation_tokens_controller.rb index 9ebba88ef16..f5825ecb19a 100644 --- a/app/controllers/admin/impersonation_tokens_controller.rb +++ b/app/controllers/admin/impersonation_tokens_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::ImpersonationTokensController < Admin::ApplicationController before_action :user diff --git a/app/controllers/admin/impersonations_controller.rb b/app/controllers/admin/impersonations_controller.rb index d2f947d2c66..08d7e3b4fa2 100644 --- a/app/controllers/admin/impersonations_controller.rb +++ b/app/controllers/admin/impersonations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::ImpersonationsController < Admin::ApplicationController skip_before_action :authenticate_admin! before_action :authenticate_impersonator! diff --git a/app/controllers/admin/jobs_controller.rb b/app/controllers/admin/jobs_controller.rb index 788693c62c4..0c1afdc3d3b 100644 --- a/app/controllers/admin/jobs_controller.rb +++ b/app/controllers/admin/jobs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::JobsController < Admin::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/keys_controller.rb b/app/controllers/admin/keys_controller.rb index 0400a3b2f3b..4e9262ccc96 100644 --- a/app/controllers/admin/keys_controller.rb +++ b/app/controllers/admin/keys_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::KeysController < Admin::ApplicationController before_action :user, only: [:show, :destroy] diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb index 7eb8f758807..aa5eae7a474 100644 --- a/app/controllers/admin/labels_controller.rb +++ b/app/controllers/admin/labels_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::LabelsController < Admin::ApplicationController before_action :set_label, only: [:show, :edit, :update, :destroy] diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb index 7248edb64e1..06b0e6a15a3 100644 --- a/app/controllers/admin/logs_controller.rb +++ b/app/controllers/admin/logs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::LogsController < Admin::ApplicationController before_action :loggers diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 5cb08c9787b..550f29a58d2 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::ProjectsController < Admin::ApplicationController include MembersPresentation diff --git a/app/controllers/admin/requests_profiles_controller.rb b/app/controllers/admin/requests_profiles_controller.rb index a478176e138..64d74ae4231 100644 --- a/app/controllers/admin/requests_profiles_controller.rb +++ b/app/controllers/admin/requests_profiles_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::RequestsProfilesController < Admin::ApplicationController def index @profile_token = Gitlab::RequestProfiler.profile_token diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb index 51d5799cd89..774ce04d079 100644 --- a/app/controllers/admin/runner_projects_controller.rb +++ b/app/controllers/admin/runner_projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::RunnerProjectsController < Admin::ApplicationController before_action :project, only: [:create] diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 911603bac17..0b6ff491c66 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::RunnersController < Admin::ApplicationController before_action :runner, except: :index diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb index 8df35d25303..18d22c95b61 100644 --- a/app/controllers/admin/spam_logs_controller.rb +++ b/app/controllers/admin/spam_logs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::SpamLogsController < Admin::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb index 99039724521..244fc2b31bb 100644 --- a/app/controllers/admin/system_info_controller.rb +++ b/app/controllers/admin/system_info_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::SystemInfoController < Admin::ApplicationController EXCLUDED_MOUNT_OPTIONS = [ 'nobrowse', diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 85bdc85c55b..b783c0e2a6f 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Admin::UsersController < Admin::ApplicationController before_action :user, except: [:index, :new, :create] diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7e2b2cf3ad3..b87034d10b6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'gon' require 'fogbugz' @@ -10,6 +12,7 @@ class ApplicationController < ActionController::Base include WorkhorseHelper include EnforcesTwoFactorAuthentication include WithPerformanceBar + include InvalidUTF8ErrorHandler before_action :authenticate_sessionless_user! before_action :authenticate_user! @@ -270,9 +273,10 @@ class ApplicationController < ActionController::Base end def event_filter - # Split using comma to maintain backward compatibility Ex/ "filter1,filter2" - filters = cookies['event_filter'].split(',')[0] if cookies['event_filter'].present? - @event_filter ||= EventFilter.new(filters) + @event_filter ||= + EventFilter.new(params[:event_filter].presence || cookies[:event_filter]).tap do |new_event_filter| + cookies[:event_filter] = new_event_filter.filter + end end # JSON for infinite scroll via Pager object diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 9e30b982b06..3766b64a091 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AutocompleteController < ApplicationController skip_before_action :authenticate_user!, only: [:users, :award_emojis] diff --git a/app/controllers/boards/application_controller.rb b/app/controllers/boards/application_controller.rb index b2675025fc0..eab908ba5ed 100644 --- a/app/controllers/boards/application_controller.rb +++ b/app/controllers/boards/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Boards class ApplicationController < ::ApplicationController respond_to :json diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 071906f1e91..4f3d737e3ce 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Boards class IssuesController < Boards::ApplicationController include BoardsResponses diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb index e8b5934f2a9..ccd02144671 100644 --- a/app/controllers/boards/lists_controller.rb +++ b/app/controllers/boards/lists_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Boards class ListsController < Boards::ApplicationController include BoardsResponses diff --git a/app/controllers/ci/lints_controller.rb b/app/controllers/ci/lints_controller.rb index 738a6a5173e..99ce24bd435 100644 --- a/app/controllers/ci/lints_controller.rb +++ b/app/controllers/ci/lints_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class LintsController < ::ApplicationController before_action :authenticate_user! diff --git a/app/controllers/concerns/accepts_pending_invitations.rb b/app/controllers/concerns/accepts_pending_invitations.rb index 6e8aef52b52..cb66c1a055d 100644 --- a/app/controllers/concerns/accepts_pending_invitations.rb +++ b/app/controllers/concerns/accepts_pending_invitations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module AcceptsPendingInvitations extend ActiveSupport::Concern diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index 961f121548b..5507328f8ae 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == AuthenticatesWithTwoFactor # # Controller concern to handle two-factor authentication diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb index da830ec2cb1..b7e4f9b81f1 100644 --- a/app/controllers/concerns/boards_responses.rb +++ b/app/controllers/concerns/boards_responses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module BoardsResponses include Gitlab::Utils::StrongMemoize diff --git a/app/controllers/concerns/checks_collaboration.rb b/app/controllers/concerns/checks_collaboration.rb index 81367663a06..1fa82f7dcd4 100644 --- a/app/controllers/concerns/checks_collaboration.rb +++ b/app/controllers/concerns/checks_collaboration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChecksCollaboration def can_collaborate_with_project?(project, ref: nil) return true if can?(current_user, :push_code, project) diff --git a/app/controllers/concerns/continue_params.rb b/app/controllers/concerns/continue_params.rb index 8b7355974df..f0e6adf4dec 100644 --- a/app/controllers/concerns/continue_params.rb +++ b/app/controllers/concerns/continue_params.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ContinueParams include InternalRedirect extend ActiveSupport::Concern diff --git a/app/controllers/concerns/controller_with_cross_project_access_check.rb b/app/controllers/concerns/controller_with_cross_project_access_check.rb index a45c3384578..3f72f092683 100644 --- a/app/controllers/concerns/controller_with_cross_project_access_check.rb +++ b/app/controllers/concerns/controller_with_cross_project_access_check.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ControllerWithCrossProjectAccessCheck extend ActiveSupport::Concern diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 709c8aaf337..b3777fd2b0f 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module CreatesCommit extend ActiveSupport::Concern include Gitlab::Utils::StrongMemoize @@ -65,7 +67,7 @@ module CreatesCommit flash[:notice] = nil else target = different_project? ? "project" : "branch" - flash[:notice] << " You can now submit a merge request to get this change into the original #{target}." + flash[:notice] = flash[:notice] + " You can now submit a merge request to get this change into the original #{target}." end end end diff --git a/app/controllers/concerns/cycle_analytics_params.rb b/app/controllers/concerns/cycle_analytics_params.rb index 1ab107168c0..c1ef848e1e7 100644 --- a/app/controllers/concerns/cycle_analytics_params.rb +++ b/app/controllers/concerns/cycle_analytics_params.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module CycleAnalyticsParams extend ActiveSupport::Concern diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb index d5388c4cd20..6be7a2a18a2 100644 --- a/app/controllers/concerns/diff_for_path.rb +++ b/app/controllers/concerns/diff_for_path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module DiffForPath extend ActiveSupport::Concern diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb index 69e5cbed343..71bdef8ce03 100644 --- a/app/controllers/concerns/enforces_two_factor_authentication.rb +++ b/app/controllers/concerns/enforces_two_factor_authentication.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == EnforcesTwoFactorAuthentication # # Controller concern to enforce two-factor authentication requirements diff --git a/app/controllers/concerns/group_tree.rb b/app/controllers/concerns/group_tree.rb index c363cad0ffa..4f56346832c 100644 --- a/app/controllers/concerns/group_tree.rb +++ b/app/controllers/concerns/group_tree.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module GroupTree # rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/controllers/concerns/hooks_execution.rb b/app/controllers/concerns/hooks_execution.rb index a22e46b4860..e8add1f4055 100644 --- a/app/controllers/concerns/hooks_execution.rb +++ b/app/controllers/concerns/hooks_execution.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module HooksExecution extend ActiveSupport::Concern diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb index 10b9852e329..6785e6972d0 100644 --- a/app/controllers/concerns/internal_redirect.rb +++ b/app/controllers/concerns/internal_redirect.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module InternalRedirect extend ActiveSupport::Concern @@ -36,4 +38,10 @@ module InternalRedirect path_with_query = [uri.path, uri.query].compact.join('?') [path_with_query, uri.fragment].compact.join("#") end + + def referer_path(request) + return unless request.referer.presence + + URI(request.referer).path + end end diff --git a/app/controllers/concerns/invalid_utf8_error_handler.rb b/app/controllers/concerns/invalid_utf8_error_handler.rb new file mode 100644 index 00000000000..44c6d6b0da0 --- /dev/null +++ b/app/controllers/concerns/invalid_utf8_error_handler.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module InvalidUTF8ErrorHandler + extend ActiveSupport::Concern + + included do + rescue_from ArgumentError, with: :handle_invalid_utf8 + end + + private + + def handle_invalid_utf8(error) + if error.message == "invalid byte sequence in UTF-8" + render_412 + else + raise(error) + end + end + + def render_412 + respond_to do |format| + format.html { render "errors/precondition_failed", layout: "errors", status: 412 } + format.js { render json: { error: 'Invalid UTF-8' }, status: :precondition_failed, content_type: 'application/json' } + format.any { head :precondition_failed } + end + end +end diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index e723107bd7f..07e01e903ea 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module IssuableActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index d29154d5c60..5217b4be928 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module IssuableCollections extend ActiveSupport::Concern include CookiesHelper diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index 9d58656773d..a75590457d6 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module IssuesAction extend ActiveSupport::Concern include IssuableCollections diff --git a/app/controllers/concerns/issues_calendar.rb b/app/controllers/concerns/issues_calendar.rb index 76e1d1ff4e8..1fdfde4c869 100644 --- a/app/controllers/concerns/issues_calendar.rb +++ b/app/controllers/concerns/issues_calendar.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module IssuesCalendar extend ActiveSupport::Concern diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb index 4584ff782a3..9576eb14fdd 100644 --- a/app/controllers/concerns/lfs_request.rb +++ b/app/controllers/concerns/lfs_request.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This concern assumes: # - a `#project` accessor # - a `#user` accessor diff --git a/app/controllers/concerns/members_presentation.rb b/app/controllers/concerns/members_presentation.rb index e146e7574aa..c6c3598a976 100644 --- a/app/controllers/concerns/members_presentation.rb +++ b/app/controllers/concerns/members_presentation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module MembersPresentation extend ActiveSupport::Concern diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 94a352c0bcc..ca713192c9e 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module MembershipActions include MembersPresentation extend ActiveSupport::Concern diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index b70db99b157..285f2c3a8a0 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module MergeRequestsAction extend ActiveSupport::Concern include IssuableCollections diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb index d92cf8b4894..eccbe35577b 100644 --- a/app/controllers/concerns/milestone_actions.rb +++ b/app/controllers/concerns/milestone_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module MilestoneActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index b63f2eb85f0..3a45d6205ab 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module NotesActions include RendersNotes include Gitlab::Utils::StrongMemoize @@ -41,12 +43,26 @@ module NotesActions @note = Notes::CreateService.new(note_project, current_user, create_params).execute - if @note.is_a?(Note) - prepare_notes_for_rendering([@note], noteable) - end - respond_to do |format| - format.json { render json: note_json(@note) } + format.json do + json = { + commands_changes: @note.commands_changes + } + + if @note.persisted? && return_discussion? + json[:valid] = true + + discussion = @note.discussion + prepare_notes_for_rendering(discussion.notes) + json[:discussion] = discussion_serializer.represent(discussion, context: self) + else + prepare_notes_for_rendering([@note]) + + json.merge!(note_json(@note)) + end + + render json: json + end format.html { redirect_back_or_default } end end @@ -55,10 +71,7 @@ module NotesActions # rubocop:disable Gitlab/ModuleWithInstanceVariables def update @note = Notes::UpdateService.new(project, current_user, note_params).execute(note) - - if @note.is_a?(Note) - prepare_notes_for_rendering([@note]) - end + prepare_notes_for_rendering([@note]) respond_to do |format| format.json { render json: note_json(@note) } @@ -89,14 +102,17 @@ module NotesActions end def note_json(note) - attrs = { - commands_changes: note.commands_changes - } + attrs = {} if note.persisted? attrs[:valid] = true - if use_note_serializer? + if return_discussion? + discussion = note.discussion + prepare_notes_for_rendering(discussion.notes) + + attrs[:discussion] = discussion_serializer.represent(discussion, context: self) + elsif use_note_serializer? attrs.merge!(note_serializer.represent(note)) else attrs.merge!( @@ -216,6 +232,10 @@ module NotesActions ProjectNoteSerializer.new(project: project, noteable: noteable, current_user: current_user) end + def discussion_serializer + DiscussionSerializer.new(project: project, noteable: noteable, current_user: current_user, note_entity: ProjectNoteEntity) + end + def note_project strong_memoize(:note_project) do next nil unless project @@ -235,6 +255,10 @@ module NotesActions end end + def return_discussion? + Gitlab::Utils.to_boolean(params[:return_discussion]) + end + def use_note_serializer? return false if params['html'] diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb index f0a68f23566..d97e22df472 100644 --- a/app/controllers/concerns/oauth_applications.rb +++ b/app/controllers/concerns/oauth_applications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module OauthApplications extend ActiveSupport::Concern diff --git a/app/controllers/concerns/params_backward_compatibility.rb b/app/controllers/concerns/params_backward_compatibility.rb index b0e3d9c7b34..c972d6e3161 100644 --- a/app/controllers/concerns/params_backward_compatibility.rb +++ b/app/controllers/concerns/params_backward_compatibility.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ParamsBackwardCompatibility private diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb index 99123fcb3b0..c61b9fabe9e 100644 --- a/app/controllers/concerns/preview_markdown.rb +++ b/app/controllers/concerns/preview_markdown.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PreviewMarkdown extend ActiveSupport::Concern diff --git a/app/controllers/concerns/renders_blob.rb b/app/controllers/concerns/renders_blob.rb index ba7adcfea86..b8026c7a01d 100644 --- a/app/controllers/concerns/renders_blob.rb +++ b/app/controllers/concerns/renders_blob.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RendersBlob extend ActiveSupport::Concern diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb index b1c9b1e532f..f48e0586211 100644 --- a/app/controllers/concerns/renders_commits.rb +++ b/app/controllers/concerns/renders_commits.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RendersCommits def limited_commits(commits) if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE diff --git a/app/controllers/concerns/renders_member_access.rb b/app/controllers/concerns/renders_member_access.rb index c5b77dacb26..955ac1a1bc8 100644 --- a/app/controllers/concerns/renders_member_access.rb +++ b/app/controllers/concerns/renders_member_access.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RendersMemberAccess def prepare_groups_for_rendering(groups) preload_max_member_access_for_collection(Group, groups) diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb index c5f23e33424..ce36da6b715 100644 --- a/app/controllers/concerns/renders_notes.rb +++ b/app/controllers/concerns/renders_notes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RendersNotes # rubocop:disable Gitlab/ModuleWithInstanceVariables def prepare_notes_for_rendering(notes, noteable = nil) diff --git a/app/controllers/concerns/repository_settings_redirect.rb b/app/controllers/concerns/repository_settings_redirect.rb index f3db3cd563b..0f18735c29e 100644 --- a/app/controllers/concerns/repository_settings_redirect.rb +++ b/app/controllers/concerns/repository_settings_redirect.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RepositorySettingsRedirect extend ActiveSupport::Concern diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb index 88d1b34bb06..426f224d26b 100644 --- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RequiresWhitelistedMonitoringClient extend ActiveSupport::Concern diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb index 0931bdf4c04..88939b002b2 100644 --- a/app/controllers/concerns/routable_actions.rb +++ b/app/controllers/concerns/routable_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RoutableActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/send_file_upload.rb b/app/controllers/concerns/send_file_upload.rb index 382ec91f771..0bb7b7efed0 100644 --- a/app/controllers/concerns/send_file_upload.rb +++ b/app/controllers/concerns/send_file_upload.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module SendFileUpload def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, disposition: 'attachment') if attachment diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb index c1acb50b76c..8bd93a349ef 100644 --- a/app/controllers/concerns/service_params.rb +++ b/app/controllers/concerns/service_params.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ServiceParams extend ActiveSupport::Concern diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb index 120614739aa..8c22490700c 100644 --- a/app/controllers/concerns/snippets_actions.rb +++ b/app/controllers/concerns/snippets_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module SnippetsActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index 922aa58a00f..c3a1b12af84 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module SpammableActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/todos_actions.rb b/app/controllers/concerns/todos_actions.rb index c0acdb3498d..78b65f7961b 100644 --- a/app/controllers/concerns/todos_actions.rb +++ b/app/controllers/concerns/todos_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module TodosActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index ae0b815f85e..97b343f8b1a 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ToggleAwardEmoji extend ActiveSupport::Concern diff --git a/app/controllers/concerns/toggle_subscription_action.rb b/app/controllers/concerns/toggle_subscription_action.rb index 776583579e8..e613bfaeef2 100644 --- a/app/controllers/concerns/toggle_subscription_action.rb +++ b/app/controllers/concerns/toggle_subscription_action.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ToggleSubscriptionAction extend ActiveSupport::Concern diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb index 56772df21d7..7a1c7abfb8f 100644 --- a/app/controllers/concerns/uploads_actions.rb +++ b/app/controllers/concerns/uploads_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module UploadsActions extend ActiveSupport::Concern diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb index 6a8b1a4de7b..77c3d476ac6 100644 --- a/app/controllers/concerns/with_performance_bar.rb +++ b/app/controllers/concerns/with_performance_bar.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module WithPerformanceBar extend ActiveSupport::Concern @@ -8,11 +10,7 @@ module WithPerformanceBar def peek_enabled? return false unless Gitlab::PerformanceBar.enabled?(current_user) - if RequestStore.active? - RequestStore.fetch(:peek_enabled) { cookie_or_default_value } - else - cookie_or_default_value - end + Gitlab::SafeRequestStore.fetch(:peek_enabled) { cookie_or_default_value } end private diff --git a/app/controllers/concerns/workhorse_request.rb b/app/controllers/concerns/workhorse_request.rb index 43c0f1b173c..028f10e866a 100644 --- a/app/controllers/concerns/workhorse_request.rb +++ b/app/controllers/concerns/workhorse_request.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module WorkhorseRequest extend ActiveSupport::Concern diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index 7bc46a6ccc0..2c4aab67448 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ConfirmationsController < Devise::ConfirmationsController include AcceptsPendingInvitations @@ -20,7 +22,7 @@ class ConfirmationsController < Devise::ConfirmationsController after_sign_in(resource) else Gitlab::AppLogger.info("Email Confirmed: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip}") - flash[:notice] += " Please sign in." + flash[:notice] = flash[:notice] + " Please sign in." new_session_path(:user, anchor: 'login-pane') end end diff --git a/app/controllers/dashboard/application_controller.rb b/app/controllers/dashboard/application_controller.rb index 9fb5c525425..cee0753a021 100644 --- a/app/controllers/dashboard/application_controller.rb +++ b/app/controllers/dashboard/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::ApplicationController < ApplicationController include ControllerWithCrossProjectAccessCheck diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb index 79f563bef86..f82cde8e10a 100644 --- a/app/controllers/dashboard/groups_controller.rb +++ b/app/controllers/dashboard/groups_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::GroupsController < Dashboard::ApplicationController include GroupTree diff --git a/app/controllers/dashboard/labels_controller.rb b/app/controllers/dashboard/labels_controller.rb index 9dcb3a0eb6d..89d87c2d5c8 100644 --- a/app/controllers/dashboard/labels_controller.rb +++ b/app/controllers/dashboard/labels_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::LabelsController < Dashboard::ApplicationController def index respond_to do |format| diff --git a/app/controllers/dashboard/milestones_controller.rb b/app/controllers/dashboard/milestones_controller.rb index 78f7f6d4e23..6e17bc212e4 100644 --- a/app/controllers/dashboard/milestones_controller.rb +++ b/app/controllers/dashboard/milestones_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::MilestonesController < Dashboard::ApplicationController include MilestoneActions diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index e8f796f17ca..e9686ed8d06 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::ProjectsController < Dashboard::ApplicationController include ParamsBackwardCompatibility include RendersMemberAccess diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb index 0ba97e4fd59..161c22046f9 100644 --- a/app/controllers/dashboard/snippets_controller.rb +++ b/app/controllers/dashboard/snippets_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::SnippetsController < Dashboard::ApplicationController skip_cross_project_access_check :index diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 231a23427f7..b82caf30a91 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Dashboard::TodosController < Dashboard::ApplicationController include ActionView::Helpers::NumberHelper diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index ff133001b84..c032fb2efb5 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DashboardController < Dashboard::ApplicationController include IssuesAction include MergeRequestsAction @@ -38,7 +40,7 @@ class DashboardController < Dashboard::ApplicationController end @events = EventCollection - .new(projects, offset: params[:offset].to_i, filter: @event_filter) + .new(projects, offset: params[:offset].to_i, filter: event_filter) .to_a Events::RenderService.new(current_user).execute(@events) diff --git a/app/controllers/explore/application_controller.rb b/app/controllers/explore/application_controller.rb index baf54520b9c..8eee3742d89 100644 --- a/app/controllers/explore/application_controller.rb +++ b/app/controllers/explore/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Explore::ApplicationController < ApplicationController skip_before_action :authenticate_user! diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb index fa0a0f68fbc..67db797b80a 100644 --- a/app/controllers/explore/groups_controller.rb +++ b/app/controllers/explore/groups_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Explore::GroupsController < Explore::ApplicationController include GroupTree diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index 03a2ee07fea..7ecbc32cf4e 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Explore::ProjectsController < Explore::ApplicationController include ParamsBackwardCompatibility include RendersMemberAccess diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb index d3f0e033068..76ed142c939 100644 --- a/app/controllers/explore/snippets_controller.rb +++ b/app/controllers/explore/snippets_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Explore::SnippetsController < Explore::ApplicationController def index @snippets = SnippetsFinder.new(current_user).execute diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb index 5551057ff55..dd9f5af61b3 100644 --- a/app/controllers/google_api/authorizations_controller.rb +++ b/app/controllers/google_api/authorizations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module GoogleApi class AuthorizationsController < ApplicationController def callback diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 0a1cf169aca..a1ec144410b 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GraphqlController < ApplicationController # Unauthenticated users have access to the API for public data skip_before_action :authenticate_user! diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 62213561898..5f92333c2c3 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::ApplicationController < ApplicationController include RoutableActions include ControllerWithCrossProjectAccessCheck diff --git a/app/controllers/groups/avatars_controller.rb b/app/controllers/groups/avatars_controller.rb index 35a61b359c8..8e4dc2bb6e9 100644 --- a/app/controllers/groups/avatars_controller.rb +++ b/app/controllers/groups/avatars_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::AvatarsController < Groups::ApplicationController before_action :authorize_admin_group! diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index e892d1f8dbf..8d259b4052e 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::BoardsController < Groups::ApplicationController include BoardsResponses diff --git a/app/controllers/groups/children_controller.rb b/app/controllers/groups/children_controller.rb index 0e8125d6113..d549f793ad7 100644 --- a/app/controllers/groups/children_controller.rb +++ b/app/controllers/groups/children_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Groups class ChildrenController < Groups::ApplicationController before_action :group diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 7dc51f4c357..0bc082246a1 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::GroupMembersController < Groups::ApplicationController include MembershipActions include MembersPresentation diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index 059cf160fa2..cb9ab35de85 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::LabelsController < Groups::ApplicationController include ToggleSubscriptionAction @@ -10,10 +12,7 @@ class Groups::LabelsController < Groups::ApplicationController def index respond_to do |format| format.html do - @labels = @group.labels - .optionally_search(params[:search]) - .order_by(sort) - .page(params[:page]) + @labels = GroupLabelsFinder.new(@group, params.merge(sort: sort)).execute end format.json do render json: LabelSerializer.new.represent_appearance(available_labels) diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 6bdc0f79ef2..a7cee426cf1 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::MilestonesController < Groups::ApplicationController include MilestoneActions diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index 1036b4e6ed3..dd8fbf7a029 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::RunnersController < Groups::ApplicationController # Proper policies should be implemented per # https://gitlab.com/gitlab-org/gitlab-ce/issues/45894 diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 4bf6a2a3ad1..6d9a225b771 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Groups module Settings class CiCdController < Groups::ApplicationController diff --git a/app/controllers/groups/shared_projects_controller.rb b/app/controllers/groups/shared_projects_controller.rb index 7dec1f5f402..30b7bfc70ae 100644 --- a/app/controllers/groups/shared_projects_controller.rb +++ b/app/controllers/groups/shared_projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Groups class SharedProjectsController < Groups::ApplicationController respond_to :json diff --git a/app/controllers/groups/uploads_controller.rb b/app/controllers/groups/uploads_controller.rb index 74760194a1f..7e5cdae0ce3 100644 --- a/app/controllers/groups/uploads_controller.rb +++ b/app/controllers/groups/uploads_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Groups::UploadsController < Groups::ApplicationController include UploadsActions include WorkhorseRequest diff --git a/app/controllers/groups/variables_controller.rb b/app/controllers/groups/variables_controller.rb index 4d8a20de017..4f641de0357 100644 --- a/app/controllers/groups/variables_controller.rb +++ b/app/controllers/groups/variables_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Groups class VariablesController < Groups::ApplicationController before_action :authorize_admin_build! diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 8b46eedae79..062c8c4e9e1 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupsController < Groups::ApplicationController include API::Helpers::RelatedResourcesHelpers include IssuesAction diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb index c3d18991fd4..a2abed7ba4e 100644 --- a/app/controllers/health_check_controller.rb +++ b/app/controllers/health_check_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class HealthCheckController < HealthCheck::HealthCheckController include RequiresWhitelistedMonitoringClient end diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 3fedd5bfb29..ab4bc911e17 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class HealthController < ActionController::Base protect_from_forgery with: :exception, except: :storage_check, prepend: true include RequiresWhitelistedMonitoringClient diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index a394521698c..e5a1fc9d6ff 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class HelpController < ApplicationController skip_before_action :authenticate_user! diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index 96bb2237d90..eeeebe430a7 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IdeController < ApplicationController layout 'fullscreen' diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb index 14b8c6e4137..042b6b1264f 100644 --- a/app/controllers/import/base_controller.rb +++ b/app/controllers/import/base_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::BaseController < ApplicationController private diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index f885e04b198..1b30b4dda36 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::BitbucketController < Import::BaseController before_action :verify_bitbucket_import_enabled before_action :bitbucket_auth, except: :callback diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index df96d181153..5a439e6de78 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::FogbugzController < Import::BaseController before_action :verify_fogbugz_import_enabled before_action :user_map, only: [:new_user_map, :create_user_map] diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb index fbd851c64a7..382c684a408 100644 --- a/app/controllers/import/gitea_controller.rb +++ b/app/controllers/import/gitea_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::GiteaController < Import::GithubController def new if session[access_token_key].present? && session[host_key].present? diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index f8b43b4fde5..1dfa814cdd5 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::GithubController < Import::BaseController before_action :verify_import_enabled before_action :provider_auth, only: [:status, :jobs, :create] diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb index bdc402b0a77..498de0b07b8 100644 --- a/app/controllers/import/gitlab_controller.rb +++ b/app/controllers/import/gitlab_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::GitlabController < Import::BaseController MAX_PROJECT_PAGES = 15 PER_PAGE_PROJECTS = 100 diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index f21c38a4c27..354fba5d204 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::GitlabProjectsController < Import::BaseController before_action :whitelist_query_limiting, only: [:create] before_action :verify_gitlab_project_import_enabled diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb index e9387d0ad14..331f06c3dd6 100644 --- a/app/controllers/import/google_code_controller.rb +++ b/app/controllers/import/google_code_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::GoogleCodeController < Import::BaseController before_action :verify_google_code_import_enabled before_action :user_map, only: [:new_user_map, :create_user_map] diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb index 4ed9dca2475..320cd45b925 100644 --- a/app/controllers/import/manifest_controller.rb +++ b/app/controllers/import/manifest_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Import::ManifestController < Import::BaseController before_action :whitelist_query_limiting, only: [:create] before_action :verify_import_enabled diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 025d8270b7c..315d1375e02 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class InvitesController < ApplicationController before_action :member skip_before_action :authenticate_user!, only: :decline @@ -50,9 +52,9 @@ class InvitesController < ApplicationController def authenticate_user! return if current_user - notice = "To accept this invitation, sign in" - notice << " or create an account" if Gitlab::CurrentSettings.allow_signup? - notice << "." + notice = ["To accept this invitation, sign in"] + notice << "or create an account" if Gitlab::CurrentSettings.allow_signup? + notice = notice.join(' ') + "." store_location_for :user, request.fullpath redirect_to new_user_session_path, notice: notice diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index d172aee5436..f9008a5b67e 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class JwtController < ApplicationController skip_before_action :authenticate_user! skip_before_action :verify_authenticity_token diff --git a/app/controllers/koding_controller.rb b/app/controllers/koding_controller.rb index 745abf3c0f5..72aa9d4f17f 100644 --- a/app/controllers/koding_controller.rb +++ b/app/controllers/koding_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class KodingController < ApplicationController before_action :check_integration! layout 'koding' diff --git a/app/controllers/ldap/omniauth_callbacks_controller.rb b/app/controllers/ldap/omniauth_callbacks_controller.rb index fb24edb8602..5e872804448 100644 --- a/app/controllers/ldap/omniauth_callbacks_controller.rb +++ b/app/controllers/ldap/omniauth_callbacks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Ldap::OmniauthCallbacksController < OmniauthCallbacksController extend ::Gitlab::Utils::Override diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb index 0400ffcfee5..7353be478e1 100644 --- a/app/controllers/metrics_controller.rb +++ b/app/controllers/metrics_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MetricsController < ActionController::Base include RequiresWhitelistedMonitoringClient diff --git a/app/controllers/notification_settings_controller.rb b/app/controllers/notification_settings_controller.rb index 461f26561f1..84dce74ace8 100644 --- a/app/controllers/notification_settings_controller.rb +++ b/app/controllers/notification_settings_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NotificationSettingsController < ApplicationController before_action :authenticate_user! diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index a1fe02dc852..b50f140dc80 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class Oauth::ApplicationsController < Doorkeeper::ApplicationsController include Gitlab::GonHelper include Gitlab::Allowable include PageLayoutHelper include OauthApplications - before_action :verify_user_oauth_applications_enabled + before_action :verify_user_oauth_applications_enabled, except: :index before_action :authenticate_user! before_action :add_gon_variables before_action :load_scopes, only: [:index, :create, :edit] diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index 05190103767..894a6a431e3 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController layout 'profile' diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb index 656107d2b26..a59ade559b3 100644 --- a/app/controllers/oauth/authorized_applications_controller.rb +++ b/app/controllers/oauth/authorized_applications_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicationsController include PageLayoutHelper diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 1547d4b5972..30be50d4595 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class OmniauthCallbacksController < Devise::OmniauthCallbacksController include AuthenticatesWithTwoFactor include Devise::Controllers::Rememberable @@ -135,14 +137,13 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def handle_signup_error label = Gitlab::Auth::OAuth::Provider.label_for(oauth['provider']) - message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed." + message = ["Signing in using your #{label} account without a pre-existing GitLab account is not allowed."] if Gitlab::CurrentSettings.allow_signup? - message << " Create a GitLab account first, and then connect it to your #{label} account." + message << "Create a GitLab account first, and then connect it to your #{label} account." end - flash[:notice] = message - + flash[:notice] = message.join(' ') redirect_to new_user_session_path end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index a1bcf206b65..2912a22411e 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PasswordsController < Devise::PasswordsController skip_before_action :require_no_authentication, only: [:edit, :update] diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb index fd9cb9fca3e..cb3180f4196 100644 --- a/app/controllers/profiles/accounts_controller.rb +++ b/app/controllers/profiles/accounts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::AccountsController < Profiles::ApplicationController include AuthHelper diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb index f1e77d68acd..efe7ede5efa 100644 --- a/app/controllers/profiles/active_sessions_controller.rb +++ b/app/controllers/profiles/active_sessions_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::ActiveSessionsController < Profiles::ApplicationController def index @sessions = ActiveSession.list(current_user) diff --git a/app/controllers/profiles/application_controller.rb b/app/controllers/profiles/application_controller.rb index c8be288b9a0..52b046ef64f 100644 --- a/app/controllers/profiles/application_controller.rb +++ b/app/controllers/profiles/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::ApplicationController < ApplicationController layout 'profile' end diff --git a/app/controllers/profiles/avatars_controller.rb b/app/controllers/profiles/avatars_controller.rb index 4f030ded80f..3378a09628c 100644 --- a/app/controllers/profiles/avatars_controller.rb +++ b/app/controllers/profiles/avatars_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::AvatarsController < Profiles::ApplicationController def destroy @user = current_user diff --git a/app/controllers/profiles/chat_names_controller.rb b/app/controllers/profiles/chat_names_controller.rb index a186c5f36a8..2e78b9e6dc7 100644 --- a/app/controllers/profiles/chat_names_controller.rb +++ b/app/controllers/profiles/chat_names_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::ChatNamesController < Profiles::ApplicationController before_action :chat_name_token, only: [:new] before_action :chat_name_params, only: [:new, :create, :deny] diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb index a39824ec9c8..503eda250b4 100644 --- a/app/controllers/profiles/emails_controller.rb +++ b/app/controllers/profiles/emails_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::EmailsController < Profiles::ApplicationController before_action :find_email, only: [:destroy, :resend_confirmation_instructions] diff --git a/app/controllers/profiles/gpg_keys_controller.rb b/app/controllers/profiles/gpg_keys_controller.rb index c32507756e8..8c34a66c374 100644 --- a/app/controllers/profiles/gpg_keys_controller.rb +++ b/app/controllers/profiles/gpg_keys_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::GpgKeysController < Profiles::ApplicationController before_action :set_gpg_key, only: [:destroy, :revoke] diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index 6035258667e..01801c31327 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::KeysController < Profiles::ApplicationController skip_before_action :authenticate_user!, only: [:get_keys] diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 00bd2040b9a..b719b70c56e 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::NotificationsController < Profiles::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def show diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb index b8ccc6e3c99..a0391d677c4 100644 --- a/app/controllers/profiles/passwords_controller.rb +++ b/app/controllers/profiles/passwords_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::PasswordsController < Profiles::ApplicationController skip_before_action :check_password_expiration, only: [:new, :create] skip_before_action :check_two_factor_requirement, only: [:new, :create] diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index b357741e3fb..4b6ec2697b7 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index set_index_vars diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index ed0f98179eb..37ac11dc6a1 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::PreferencesController < Profiles::ApplicationController before_action :user diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 29ff18a1219..ba94196b2f9 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::TwoFactorAuthsController < Profiles::ApplicationController skip_before_action :check_two_factor_requirement @@ -30,7 +32,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController unless two_factor_grace_period_expired? grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours - flash.now[:alert] << " You need to do this before #{l(grace_period_deadline)}." + flash.now[:alert] = flash.now[:alert] + " You need to do this before #{l(grace_period_deadline)}." end end diff --git a/app/controllers/profiles/u2f_registrations_controller.rb b/app/controllers/profiles/u2f_registrations_controller.rb index e3d7737f44a..e6a154fb6aa 100644 --- a/app/controllers/profiles/u2f_registrations_controller.rb +++ b/app/controllers/profiles/u2f_registrations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Profiles::U2fRegistrationsController < Profiles::ApplicationController def destroy u2f_registration = current_user.u2f_registrations.find(params[:id]) diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index a43d47797f1..15248d2d08f 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProfilesController < Profiles::ApplicationController include ActionView::Helpers::SanitizeHelper diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 695ffd90a85..a2bdcaefa9b 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ApplicationController < ApplicationController include CookiesHelper include RoutableActions diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb index 3e8ffa485dd..bd110d646e5 100644 --- a/app/controllers/projects/artifacts_controller.rb +++ b/app/controllers/projects/artifacts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ArtifactsController < Projects::ApplicationController include ExtractsPath include RendersBlob diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index a8f73ed5cb0..7c93cf36862 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::AutocompleteSourcesController < Projects::ApplicationController before_action :load_autocomplete_service, except: [:members] diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb index 878c82cd183..1c385c0e15a 100644 --- a/app/controllers/projects/avatars_controller.rb +++ b/app/controllers/projects/avatars_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::AvatarsController < Projects::ApplicationController include SendsBlob diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 06ba73d8e8d..c24bf211760 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::BadgesController < Projects::ApplicationController layout 'project_settings' before_action :authorize_admin_project!, only: [:index] diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb index 6461eeac11c..9076bdb9f04 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for viewing a file's blame class Projects::BlameController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index bfe4e7f934f..92d26a13da9 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for viewing a file's blame class Projects::BlobController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index e7354a9e1f7..77b818347c7 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::BoardsController < Projects::ApplicationController include BoardsResponses include IssuableCollections diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index d14795e787b..b7750f4517b 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::BranchesController < Projects::ApplicationController include ActionView::Helpers::SanitizeHelper include SortingHelper diff --git a/app/controllers/projects/build_artifacts_controller.rb b/app/controllers/projects/build_artifacts_controller.rb index 9e99a84fac7..46449a4aae9 100644 --- a/app/controllers/projects/build_artifacts_controller.rb +++ b/app/controllers/projects/build_artifacts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::BuildArtifactsController < Projects::ApplicationController include ExtractsPath include RendersBlob diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 230b072dcea..6b3d70cb720 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::BuildsController < Projects::ApplicationController before_action :authorize_read_build! diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb index a2185572a20..2090af0a111 100644 --- a/app/controllers/projects/ci/lints_controller.rb +++ b/app/controllers/projects/ci/lints_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::Ci::LintsController < Projects::ApplicationController before_action :authorize_create_pipeline! diff --git a/app/controllers/projects/clusters/applications_controller.rb b/app/controllers/projects/clusters/applications_controller.rb index 8c9df51981a..c356f8d2987 100644 --- a/app/controllers/projects/clusters/applications_controller.rb +++ b/app/controllers/projects/clusters/applications_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::Clusters::ApplicationsController < Projects::ApplicationController before_action :cluster before_action :application_class, only: [:create] diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index eb0fad6cbb2..bcdbf48bb35 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ClustersController < Projects::ApplicationController before_action :cluster, except: [:index, :new, :create_gcp, :create_user] before_action :authorize_read_cluster! diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 81f375875b2..00b63f55710 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for a specific Commit # # Not to be confused with CommitsController, plural. diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index cd9c9aa30f1..84a2a461da7 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "base64" class Projects::CommitsController < Projects::ApplicationController diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index cca77903250..c2df7b34f90 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'addressable/uri' class Projects::CompareController < Projects::ApplicationController diff --git a/app/controllers/projects/cycle_analytics/events_controller.rb b/app/controllers/projects/cycle_analytics/events_controller.rb index 26f3c114108..fb43356ff10 100644 --- a/app/controllers/projects/cycle_analytics/events_controller.rb +++ b/app/controllers/projects/cycle_analytics/events_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module CycleAnalytics class EventsController < Projects::ApplicationController diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb index d1b8fd80c4e..8c071496ba9 100644 --- a/app/controllers/projects/cycle_analytics_controller.rb +++ b/app/controllers/projects/cycle_analytics_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::CycleAnalyticsController < Projects::ApplicationController include ActionView::Helpers::DateHelper include ActionView::Helpers::TextHelper diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb index 2555139cd2c..92ef10a9ef5 100644 --- a/app/controllers/projects/deploy_keys_controller.rb +++ b/app/controllers/projects/deploy_keys_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::DeployKeysController < Projects::ApplicationController include RepositorySettingsRedirect respond_to :html diff --git a/app/controllers/projects/deploy_tokens_controller.rb b/app/controllers/projects/deploy_tokens_controller.rb index 83abda64fe0..830b1f4fe4a 100644 --- a/app/controllers/projects/deploy_tokens_controller.rb +++ b/app/controllers/projects/deploy_tokens_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::DeployTokensController < Projects::ApplicationController before_action :authorize_admin_project! diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb index 5a2da7274d1..0a009477d61 100644 --- a/app/controllers/projects/deployments_controller.rb +++ b/app/controllers/projects/deployments_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::DeploymentsController < Projects::ApplicationController before_action :authorize_read_environment! before_action :authorize_read_deployment! diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb index efdddb24290..b62606067c0 100644 --- a/app/controllers/projects/discussions_controller.rb +++ b/app/controllers/projects/discussions_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::DiscussionsController < Projects::ApplicationController include NotesHelper include RendersNotes diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index be22950286e..de10783df1a 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::EnvironmentsController < Projects::ApplicationController layout 'project' before_action :authorize_read_environment! diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb index cf53ad0a670..c026e9ff332 100644 --- a/app/controllers/projects/find_file_controller.rb +++ b/app/controllers/projects/find_file_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for viewing a repository's file structure class Projects::FindFileController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index b709edc8f10..7a1700a206a 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ForksController < Projects::ApplicationController include ContinueParams diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb index a52814e6e52..d439db97252 100644 --- a/app/controllers/projects/git_http_client_controller.rb +++ b/app/controllers/projects/git_http_client_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This file should be identical in GitLab Community Edition and Enterprise Edition class Projects::GitHttpClientController < Projects::ApplicationController diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb index 1dcf837f78e..be708835e30 100644 --- a/app/controllers/projects/git_http_controller.rb +++ b/app/controllers/projects/git_http_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::GitHttpController < Projects::GitHttpClientController include WorkhorseRequest diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index 475d4c86294..925b6ed9bfd 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::GraphsController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb index bc5f38f3c2b..7c713c19762 100644 --- a/app/controllers/projects/group_links_controller.rb +++ b/app/controllers/projects/group_links_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::GroupLinksController < Projects::ApplicationController layout 'project_settings' before_action :authorize_admin_project! diff --git a/app/controllers/projects/hook_logs_controller.rb b/app/controllers/projects/hook_logs_controller.rb index 745e89fc843..a7afc3d77a5 100644 --- a/app/controllers/projects/hook_logs_controller.rb +++ b/app/controllers/projects/hook_logs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::HookLogsController < Projects::ApplicationController include HooksExecution diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index bbf8c7d5cbc..bc84418b79f 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::HooksController < Projects::ApplicationController include HooksExecution diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index 49aa32119ef..e55065c5817 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ImportsController < Projects::ApplicationController include ContinueParams diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 632e498e4ba..4e859de6fde 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::IssuesController < Projects::ApplicationController include RendersNotes include ToggleSubscriptionAction diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 62b74e84c2c..3f85e442be9 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::JobsController < Projects::ApplicationController include SendFileUpload diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 1fd4f0721a7..a0ce3b08d9f 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::LabelsController < Projects::ApplicationController include ToggleSubscriptionAction @@ -138,12 +140,7 @@ class Projects::LabelsController < Projects::ApplicationController end def flash_notice_for(label, group) - notice = ''.html_safe - notice << label.title - notice << ' promoted to ' - notice << view_context.link_to('<u>group label</u>'.html_safe, group_labels_path(group)) - notice << '.' - notice + ''.html_safe + "#{label.title} promoted to " + view_context.link_to('<u>group label</u>'.html_safe, group_labels_path(group)) + '.' end protected diff --git a/app/controllers/projects/lfs_api_controller.rb b/app/controllers/projects/lfs_api_controller.rb index 6d6f88c1075..be40077d389 100644 --- a/app/controllers/projects/lfs_api_controller.rb +++ b/app/controllers/projects/lfs_api_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::LfsApiController < Projects::GitHttpClientController include LfsRequest diff --git a/app/controllers/projects/lfs_locks_api_controller.rb b/app/controllers/projects/lfs_locks_api_controller.rb index 3fff0fd69ae..fc67cd72faa 100644 --- a/app/controllers/projects/lfs_locks_api_controller.rb +++ b/app/controllers/projects/lfs_locks_api_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::LfsLocksApiController < Projects::GitHttpClientController include LfsRequest diff --git a/app/controllers/projects/lfs_storage_controller.rb b/app/controllers/projects/lfs_storage_controller.rb index 930d9a05c50..babeee48ef3 100644 --- a/app/controllers/projects/lfs_storage_controller.rb +++ b/app/controllers/projects/lfs_storage_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::LfsStorageController < Projects::GitHttpClientController include LfsRequest include WorkhorseRequest diff --git a/app/controllers/projects/mattermosts_controller.rb b/app/controllers/projects/mattermosts_controller.rb index 0f6add3e287..085b1bc1498 100644 --- a/app/controllers/projects/mattermosts_controller.rb +++ b/app/controllers/projects/mattermosts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MattermostsController < Projects::ApplicationController include TriggersHelper include ActionView::Helpers::AssetUrlHelper diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb index aa2008722ec..368ee89ff5c 100644 --- a/app/controllers/projects/merge_requests/application_controller.rb +++ b/app/controllers/projects/merge_requests/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MergeRequests::ApplicationController < Projects::ApplicationController before_action :check_merge_requests_available! before_action :merge_request diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb index 366524b0783..ac1969adc6e 100644 --- a/app/controllers/projects/merge_requests/conflicts_controller.rb +++ b/app/controllers/projects/merge_requests/conflicts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::ApplicationController include IssuableActions diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb index 2ccb3896857..86583adc6a4 100644 --- a/app/controllers/projects/merge_requests/creations_controller.rb +++ b/app/controllers/projects/merge_requests/creations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MergeRequests::CreationsController < Projects::MergeRequests::ApplicationController include DiffForPath include DiffHelper diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 666e65b6c5e..25d2c11b7db 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MergeRequests::DiffsController < Projects::MergeRequests::ApplicationController include DiffForPath include DiffHelper @@ -23,7 +25,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic @diffs.write_cache - render json: DiffsSerializer.new(current_user: current_user).represent(@diffs, additional_attributes) + render json: DiffsSerializer.new(current_user: current_user, project: @merge_request.project).represent(@diffs, additional_attributes) end def define_diff_vars diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 75a85fafa3f..dfb69de650b 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationController include ToggleSubscriptionAction include IssuableActions diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index e2c05171cd6..20998c97730 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MilestonesController < Projects::ApplicationController include Gitlab::Utils::StrongMemoize include MilestoneActions @@ -91,12 +93,7 @@ class Projects::MilestonesController < Projects::ApplicationController end def flash_notice_for(milestone, group) - notice = ''.html_safe - notice << milestone.title - notice << ' promoted to ' - notice << view_context.link_to('<u>group milestone</u>'.html_safe, group_milestone_path(group, milestone.iid)) - notice << '.' - notice + ''.html_safe + "#{milestone.title} promoted to " + view_context.link_to('<u>group milestone</u>'.html_safe, group_milestone_path(group, milestone.iid)) + '.' end def destroy diff --git a/app/controllers/projects/mirrors_controller.rb b/app/controllers/projects/mirrors_controller.rb index 3739608e4c0..78d5faf2326 100644 --- a/app/controllers/projects/mirrors_controller.rb +++ b/app/controllers/projects/mirrors_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::MirrorsController < Projects::ApplicationController include RepositorySettingsRedirect diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb index 35fec229db7..ad2466a8588 100644 --- a/app/controllers/projects/network_controller.rb +++ b/app/controllers/projects/network_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::NetworkController < Projects::ApplicationController include ExtractsPath include ApplicationHelper diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 21e2145b73b..4bac763d000 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::NotesController < Projects::ApplicationController include RendersNotes include NotesActions diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index e1eba4f8327..c1ad6707c97 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::PagesController < Projects::ApplicationController layout 'project_settings' diff --git a/app/controllers/projects/pages_domains_controller.rb b/app/controllers/projects/pages_domains_controller.rb index c29b3c953a6..439ec9b1731 100644 --- a/app/controllers/projects/pages_domains_controller.rb +++ b/app/controllers/projects/pages_domains_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::PagesDomainsController < Projects::ApplicationController layout 'project_settings' diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index d8adeffd0b2..acf56f0eb6a 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :schedule, except: [:index, :new, :create] diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 5b2091d68f8..53b29d4146e 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::PipelinesController < Projects::ApplicationController before_action :whitelist_query_limiting, only: [:create, :retry] before_action :pipeline, except: [:index, :new, :create, :charts] diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index 73c613b26f3..192e6d38f36 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::PipelinesSettingsController < Projects::ApplicationController before_action :authorize_admin_pipeline! diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 08d5e377941..8938cfbad54 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ProjectMembersController < Projects::ApplicationController include MembershipActions include MembersPresentation diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index c6b6243b553..3a9f9aab4a5 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Prometheus class MetricsController < Projects::ApplicationController diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb index 64954ac9a42..a860be83e95 100644 --- a/app/controllers/projects/protected_branches_controller.rb +++ b/app/controllers/projects/protected_branches_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ProtectedBranchesController < Projects::ProtectedRefsController protected diff --git a/app/controllers/projects/protected_refs_controller.rb b/app/controllers/projects/protected_refs_controller.rb index cc62ce2f11b..3a3a29ddd0d 100644 --- a/app/controllers/projects/protected_refs_controller.rb +++ b/app/controllers/projects/protected_refs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ProtectedRefsController < Projects::ApplicationController include RepositorySettingsRedirect diff --git a/app/controllers/projects/protected_tags_controller.rb b/app/controllers/projects/protected_tags_controller.rb index 198c938ff35..01cedba95ac 100644 --- a/app/controllers/projects/protected_tags_controller.rb +++ b/app/controllers/projects/protected_tags_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ProtectedTagsController < Projects::ProtectedRefsController protected diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb index 91cf35bc70b..1dd5d1ff2e8 100644 --- a/app/controllers/projects/raw_controller.rb +++ b/app/controllers/projects/raw_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for viewing a file's raw class Projects::RawController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index 0fed7f6576c..b97fbe19bbf 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::RefsController < Projects::ApplicationController include ExtractsPath include TreeHelper diff --git a/app/controllers/projects/registry/application_controller.rb b/app/controllers/projects/registry/application_controller.rb index a56f9c58726..2f891d78c91 100644 --- a/app/controllers/projects/registry/application_controller.rb +++ b/app/controllers/projects/registry/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Registry class ApplicationController < Projects::ApplicationController diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index ef0433795f4..6d60117c37d 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Registry class RepositoriesController < ::Projects::Registry::ApplicationController diff --git a/app/controllers/projects/registry/tags_controller.rb b/app/controllers/projects/registry/tags_controller.rb index e602aa3f393..567d750caae 100644 --- a/app/controllers/projects/registry/tags_controller.rb +++ b/app/controllers/projects/registry/tags_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Registry class TagsController < ::Projects::Registry::ApplicationController diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index caf400ecd92..55827075896 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ReleasesController < Projects::ApplicationController # Authorize before_action :require_non_empty_project diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index ecb2ece7532..4eeaeb860ee 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::RepositoriesController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb index c098c82081e..cbeb32fd610 100644 --- a/app/controllers/projects/runner_projects_controller.rb +++ b/app/controllers/projects/runner_projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::RunnerProjectsController < Projects::ApplicationController before_action :authorize_admin_build! diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index d118cec977c..91f40b90aa8 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::RunnersController < Projects::ApplicationController before_action :authorize_admin_build! before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show] diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index d55046047ae..f1c9d0d0f77 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::ServicesController < Projects::ApplicationController include ServiceParams diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 322ec096ffb..a2d1b7866c2 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Settings class CiCdController < Projects::ApplicationController diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb index d9fecfecc40..388fcb32c35 100644 --- a/app/controllers/projects/settings/integrations_controller.rb +++ b/app/controllers/projects/settings/integrations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Settings class IntegrationsController < Projects::ApplicationController diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index ccd481b4dbd..6d83d24cdb8 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Settings class RepositoryController < Projects::ApplicationController @@ -12,10 +14,10 @@ module Projects @new_deploy_token = DeployTokens::CreateService.new(@project, current_user, deploy_token_params).execute if @new_deploy_token.persisted? - flash.now[:notice] = s_('DeployTokens|Your new project deploy token has been created.') + flash[:notice] = s_('DeployTokens|Your new project deploy token has been created.') end - render_show + redirect_to action: :show end private diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 7c03d8ce827..a44acb12bdf 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::SnippetsController < Projects::ApplicationController include RendersNotes include ToggleAwardEmoji diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index 74bba97987f..c8442ff3592 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::TagsController < Projects::ApplicationController include SortingHelper diff --git a/app/controllers/projects/templates_controller.rb b/app/controllers/projects/templates_controller.rb index 52d6fb82093..7ceea4e5b96 100644 --- a/app/controllers/projects/templates_controller.rb +++ b/app/controllers/projects/templates_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::TemplatesController < Projects::ApplicationController before_action :authenticate_user!, :get_template_class diff --git a/app/controllers/projects/todos_controller.rb b/app/controllers/projects/todos_controller.rb index 93fb9da6510..0b11ee9edc0 100644 --- a/app/controllers/projects/todos_controller.rb +++ b/app/controllers/projects/todos_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::TodosController < Projects::ApplicationController include Gitlab::Utils::StrongMemoize include TodosActions diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index ee9b5458282..3fe300dcfc0 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controller for viewing a repository's file structure class Projects::TreeController < Projects::ApplicationController include ExtractsPath diff --git a/app/controllers/projects/triggers_controller.rb b/app/controllers/projects/triggers_controller.rb index cb12b707087..f5fdfb8accc 100644 --- a/app/controllers/projects/triggers_controller.rb +++ b/app/controllers/projects/triggers_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::TriggersController < Projects::ApplicationController before_action :authorize_admin_build! before_action :authorize_manage_trigger!, except: [:index, :create] diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb index 7a85046164c..4ffcc2ac805 100644 --- a/app/controllers/projects/uploads_controller.rb +++ b/app/controllers/projects/uploads_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::UploadsController < Projects::ApplicationController include UploadsActions include WorkhorseRequest diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb index bf09ea7e4d8..bb658bfcc19 100644 --- a/app/controllers/projects/variables_controller.rb +++ b/app/controllers/projects/variables_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::VariablesController < Projects::ApplicationController before_action :authorize_admin_build! diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index da7aeb26a75..8c6d87a421f 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Projects::WikisController < Projects::ApplicationController include PreviewMarkdown include Gitlab::Utils::StrongMemoize diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 64d9b16a041..7352c5e9bec 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectsController < Projects::ApplicationController include API::Helpers::RelatedResourcesHelpers include IssuableCollections diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index e6d6965036e..8b8d87524a8 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RegistrationsController < Devise::RegistrationsController include Recaptcha::Verify include AcceptsPendingInvitations diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index 651b82f04f4..ebf70f25bda 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # RootController # # This controller exists solely to handle requests to `root_url`. When a user is diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index a928758f325..1b22907c10f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SearchController < ApplicationController include ControllerWithCrossProjectAccessCheck include SearchHelper diff --git a/app/controllers/sent_notifications_controller.rb b/app/controllers/sent_notifications_controller.rb index 93a71103a09..2b76921ebd8 100644 --- a/app/controllers/sent_notifications_controller.rb +++ b/app/controllers/sent_notifications_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SentNotificationsController < ApplicationController skip_before_action :authenticate_user! diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9f2e66dea90..643eb75c83c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SessionsController < Devise::SessionsController include InternalRedirect include AuthenticatesWithTwoFactor diff --git a/app/controllers/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb index 6bdd3568a78..c048254d348 100644 --- a/app/controllers/sherlock/application_controller.rb +++ b/app/controllers/sherlock/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sherlock class ApplicationController < ::ApplicationController before_action :find_transaction diff --git a/app/controllers/sherlock/file_samples_controller.rb b/app/controllers/sherlock/file_samples_controller.rb index 0c3bc100106..900446bb75a 100644 --- a/app/controllers/sherlock/file_samples_controller.rb +++ b/app/controllers/sherlock/file_samples_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sherlock class FileSamplesController < Sherlock::ApplicationController def show diff --git a/app/controllers/sherlock/queries_controller.rb b/app/controllers/sherlock/queries_controller.rb index 63b26aab1a4..49a25c682b5 100644 --- a/app/controllers/sherlock/queries_controller.rb +++ b/app/controllers/sherlock/queries_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sherlock class QueriesController < Sherlock::ApplicationController def show diff --git a/app/controllers/sherlock/transactions_controller.rb b/app/controllers/sherlock/transactions_controller.rb index ae4953c3259..46e382e594e 100644 --- a/app/controllers/sherlock/transactions_controller.rb +++ b/app/controllers/sherlock/transactions_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sherlock class TransactionsController < Sherlock::ApplicationController def index diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb index e992afc0026..091bcb1253d 100644 --- a/app/controllers/snippets/notes_controller.rb +++ b/app/controllers/snippets/notes_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Snippets::NotesController < ApplicationController include NotesActions include ToggleAwardEmoji diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 19d865900e9..694c3a59e2b 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SnippetsController < ApplicationController include RendersNotes include ToggleAwardEmoji diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 3d227b0a955..fa5d84633b5 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UploadsController < ApplicationController include UploadsActions diff --git a/app/controllers/user_callouts_controller.rb b/app/controllers/user_callouts_controller.rb index b8d2deba93b..ebf1dd8ca02 100644 --- a/app/controllers/user_callouts_controller.rb +++ b/app/controllers/user_callouts_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserCalloutsController < ApplicationController def create if ensure_callout.persisted? diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb index 1b1560a2a00..3c16d934b4d 100644 --- a/app/controllers/users/terms_controller.rb +++ b/app/controllers/users/terms_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Users class TermsController < ApplicationController include InternalRedirect diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2f65f4a7403..e509098d778 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UsersController < ApplicationController include RoutableActions include RendersMemberAccess diff --git a/app/finders/admin/runners_finder.rb b/app/finders/admin/runners_finder.rb index 3c2d7ee7d76..fbb1cfc5c66 100644 --- a/app/finders/admin/runners_finder.rb +++ b/app/finders/admin/runners_finder.rb @@ -10,6 +10,7 @@ class Admin::RunnersFinder < UnionFinder def execute search! filter_by_status! + filter_by_runner_type! sort! paginate! @@ -36,10 +37,11 @@ class Admin::RunnersFinder < UnionFinder end def filter_by_status! - status = @params[:status_status] - if status.present? && Ci::Runner::AVAILABLE_STATUSES.include?(status) - @runners = @runners.public_send(status) # rubocop:disable GitlabSecurity/PublicSend - end + filter_by!(:status_status, Ci::Runner::AVAILABLE_STATUSES) + end + + def filter_by_runner_type! + filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES) end def sort! @@ -49,4 +51,12 @@ class Admin::RunnersFinder < UnionFinder def paginate! @runners = @runners.page(@params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE) end + + def filter_by!(scope_name, available_scopes) + scope = @params[scope_name] + + if scope.present? && available_scopes.include?(scope) + @runners = @runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend + end + end end diff --git a/app/finders/group_labels_finder.rb b/app/finders/group_labels_finder.rb new file mode 100644 index 00000000000..903023033ed --- /dev/null +++ b/app/finders/group_labels_finder.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class GroupLabelsFinder + attr_reader :group, :params + + def initialize(group, params = {}) + @group = group + @params = params + end + + def execute + group.labels + .optionally_search(params[:search]) + .order_by(params[:sort]) + .page(params[:page]) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ef4560023af..32fc8e5e9ce 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -7,7 +7,15 @@ module ApplicationHelper # See https://docs.gitlab.com/ee/development/ee_features.html#code-in-app-views # rubocop: disable CodeReuse/ActiveRecord def render_if_exists(partial, locals = {}) - render(partial, locals) if lookup_context.exists?(partial, [], true) + render(partial, locals) if partial_exists?(partial) + end + + def partial_exists?(partial) + lookup_context.exists?(partial, [], true) + end + + def template_exists?(template) + lookup_context.exists?(template, [], false) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 3ebf0162cb6..c9a5431d18e 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -108,10 +108,6 @@ module ApplicationSettingsHelper options_for_select(options, selected) end - def sidekiq_queue_options_for_select - options_for_select(Sidekiq::Queue.all.map(&:name), @application_setting.sidekiq_throttling_queues) - end - def circuitbreaker_failure_count_help_text health_link = link_to(s_('AdminHealthPageLink|health page'), admin_health_check_path) api_link = link_to(s_('CircuitBreakerApiLink|circuitbreaker api'), help_page_path("api/repository_storage_health")) @@ -234,9 +230,6 @@ module ApplicationSettingsHelper :session_expire_delay, :shared_runners_enabled, :shared_runners_text, - :sidekiq_throttling_enabled, - :sidekiq_throttling_factor, - :sidekiq_throttling_queues, :sign_in_text, :signup_enabled, :terminal_max_session_time, @@ -264,4 +257,8 @@ module ApplicationSettingsHelper :web_ide_clientside_preview_enabled ] end + + def expanded_by_default? + Rails.env.test? + end end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index 0c59bdd6abb..53bd43d4861 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -35,7 +35,8 @@ module SortingHelper sort_value_name => sort_title_name, sort_value_oldest_activity => sort_title_oldest_activity, sort_value_oldest_created => sort_title_oldest_created, - sort_value_recently_created => sort_title_recently_created + sort_value_recently_created => sort_title_recently_created, + sort_value_most_stars => sort_title_most_stars } if current_controller?('admin/projects') @@ -246,6 +247,10 @@ module SortingHelper s_('SortOptions|Last Contact') end + def sort_title_most_stars + s_('SortOptions|Most stars') + end + # Values. def sort_value_access_level_asc 'access_level_asc' @@ -370,4 +375,8 @@ module SortingHelper def sort_value_contacted_date 'contacted_asc' end + + def sort_value_most_stars + 'stars_desc' + end end diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb index c133f4e6dbb..2f5b5483e9d 100644 --- a/app/mailers/previews/notify_preview.rb +++ b/app/mailers/previews/notify_preview.rb @@ -9,7 +9,7 @@ class NotifyPreview < ActionMailer::Preview In this notification email, we expect to see: - The note contents (that's what you're looking at) - - A link to view this note on Gitlab + - A link to view this note on GitLab - An explanation for why the user is receiving this notification MD @@ -26,7 +26,7 @@ class NotifyPreview < ActionMailer::Preview - A line saying who started this discussion - The note contents (that's what you're looking at) - - A link to view this discussion on Gitlab + - A link to view this discussion on GitLab - An explanation for why the user is receiving this notification MD @@ -44,7 +44,7 @@ class NotifyPreview < ActionMailer::Preview - A line saying who started this discussion and on what file - The diff - The note contents (that's what you're looking at) - - A link to view this discussion on Gitlab + - A link to view this discussion on GitLab - An explanation for why the user is receiving this notification MD diff --git a/app/models/ability.rb b/app/models/ability.rb index a853106e5bd..1466407d0d1 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -74,7 +74,7 @@ class Ability end def policy_for(user, subject = :global) - cache = RequestStore.active? ? RequestStore : {} + cache = Gitlab::SafeRequestStore.active? ? Gitlab::SafeRequestStore : {} DeclarativePolicy.policy_for(user, subject, cache: cache) end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 645adddb000..5f835a8da75 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -26,7 +26,6 @@ class ApplicationSetting < ActiveRecord::Base serialize :domain_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize - serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiveRecordSerialize cache_markdown_field :sign_in_text cache_markdown_field :help_page_text @@ -131,15 +130,6 @@ class ApplicationSetting < ActiveRecord::Base presence: { message: 'Domain blacklist cannot be empty if Blacklist is enabled.' }, if: :domain_blacklist_enabled? - validates :sidekiq_throttling_factor, - numericality: { greater_than: 0, less_than: 1 }, - presence: { message: 'Throttling factor cannot be empty if Sidekiq Throttling is enabled.' }, - if: :sidekiq_throttling_enabled? - - validates :sidekiq_throttling_queues, - presence: { message: 'Queues to throttle cannot be empty if Sidekiq Throttling is enabled.' }, - if: :sidekiq_throttling_enabled? - validates :housekeeping_incremental_repack_period, presence: true, numericality: { only_integer: true, greater_than: 0 } @@ -282,7 +272,6 @@ class ApplicationSetting < ActiveRecord::Base send_user_confirmation_email: false, shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'], shared_runners_text: nil, - sidekiq_throttling_enabled: false, sign_in_text: nil, signup_enabled: Settings.gitlab['signup_enabled'], terminal_max_session_time: 0, @@ -328,10 +317,6 @@ class ApplicationSetting < ActiveRecord::Base ::Gitlab::Database.cached_column_exists?(:application_settings, :help_page_support_url) end - def sidekiq_throttling_column_exists? - ::Gitlab::Database.cached_column_exists?(:application_settings, :sidekiq_throttling_enabled) - end - def disabled_oauth_sign_in_sources=(sources) sources = (sources || []).map(&:to_s) & Devise.omniauth_providers.map(&:to_s) super(sources) @@ -411,12 +396,6 @@ class ApplicationSetting < ActiveRecord::Base ensure_health_check_access_token! end - def sidekiq_throttling_enabled? - return false unless sidekiq_throttling_column_exists? - - sidekiq_throttling_enabled - end - def usage_ping_can_be_configured? Settings.gitlab.usage_ping_enabled end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 63aaa0f7bcc..3dadb95443a 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -68,8 +68,12 @@ module Ci '', Ci::JobArtifact.select(1).where('ci_builds.id = ci_job_artifacts.job_id').archive) end + scope :with_existing_job_artifacts, ->(query) do + where('EXISTS (?)', ::Ci::JobArtifact.select(1).where('ci_builds.id = ci_job_artifacts.job_id').merge(query)) + end + scope :with_archived_trace, ->() do - where('EXISTS (?)', Ci::JobArtifact.select(1).where('ci_builds.id = ci_job_artifacts.job_id').trace) + with_existing_job_artifacts(Ci::JobArtifact.trace) end scope :without_archived_trace, ->() do @@ -77,10 +81,12 @@ module Ci end scope :with_test_reports, ->() do - includes(:job_artifacts_junit) # Prevent N+1 problem when iterating each ci_job_artifact row - .where('EXISTS (?)', Ci::JobArtifact.select(1).where('ci_builds.id = ci_job_artifacts.job_id').test_reports) + with_existing_job_artifacts(Ci::JobArtifact.test_reports) + .eager_load_job_artifacts end + scope :eager_load_job_artifacts, -> { includes(:job_artifacts) } + scope :with_artifacts_stored_locally, -> { with_artifacts_archive.where(artifacts_file_store: [nil, LegacyArtifactUploader::Store::LOCAL]) } scope :with_archived_trace_stored_locally, -> { with_archived_trace.where(artifacts_file_store: [nil, LegacyArtifactUploader::Store::LOCAL]) } scope :with_artifacts_not_expired, ->() { with_artifacts_archive.where('artifacts_expire_at IS NULL OR artifacts_expire_at > ?', Time.now) } @@ -404,8 +410,8 @@ module Ci trace.exist? end - def has_test_reports? - job_artifacts.test_reports.any? + def has_job_artifacts? + job_artifacts.any? end def has_old_trace? @@ -469,28 +475,23 @@ module Ci end end - def erase_artifacts! - remove_artifacts_file! - remove_artifacts_metadata! - save - end - - def erase_test_reports! - # TODO: Use fast_destroy_all in the context of https://gitlab.com/gitlab-org/gitlab-ce/issues/35240 - job_artifacts_junit&.destroy + # and use that for `ExpireBuildInstanceArtifactsWorker`? + def erase_erasable_artifacts! + job_artifacts.erasable.destroy_all # rubocop: disable DestroyAll + erase_old_artifacts! end def erase(opts = {}) return false unless erasable? - erase_artifacts! - erase_test_reports! + job_artifacts.destroy_all # rubocop: disable DestroyAll + erase_old_artifacts! erase_trace! update_erased!(opts[:erased_by]) end def erasable? - complete? && (artifacts? || has_test_reports? || has_trace?) + complete? && (artifacts? || has_job_artifacts? || has_trace?) end def erased? @@ -648,8 +649,8 @@ module Ci def collect_test_reports!(test_reports) test_reports.get_suite(group_name).tap do |test_suite| - each_test_report do |file_type, blob| - Gitlab::Ci::Parsers.fabricate!(file_type).parse!(blob, test_suite) + each_report(Ci::JobArtifact::TEST_REPORT_FILE_TYPES) do |file_type, blob| + Gitlab::Ci::Parsers::Test.fabricate!(file_type).parse!(blob, test_suite) end end end @@ -669,6 +670,13 @@ module Ci private + def erase_old_artifacts! + # TODO: To be removed once we get rid of + remove_artifacts_file! + remove_artifacts_metadata! + save + end + def successful_deployment_status if success? && last_deployment&.last? return :last @@ -679,14 +687,19 @@ module Ci :creating end - def each_test_report - Ci::JobArtifact::TEST_REPORT_FILE_TYPES.each do |file_type| - public_send("job_artifacts_#{file_type}").each_blob do |blob| # rubocop:disable GitlabSecurity/PublicSend - yield file_type, blob + def each_report(report_types) + job_artifacts_for_types(report_types).each do |report_artifact| + report_artifact.each_blob do |blob| + yield report_artifact.file_type, blob end end end + def job_artifacts_for_types(report_types) + # Use select to leverage cached associations and avoid N+1 queries + job_artifacts.select { |artifact| artifact.file_type.in?(report_types) } + end + def update_artifacts_size self.artifacts_size = legacy_artifacts_file&.size end diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index 93fc1b145b2..259d85e2fe5 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -9,8 +9,28 @@ module Ci NotSupportedAdapterError = Class.new(StandardError) TEST_REPORT_FILE_TYPES = %w[junit].freeze - DEFAULT_FILE_NAMES = { junit: 'junit.xml' }.freeze - TYPE_AND_FORMAT_PAIRS = { archive: :zip, metadata: :gzip, trace: :raw, junit: :gzip }.freeze + NON_ERASABLE_FILE_TYPES = %w[trace].freeze + DEFAULT_FILE_NAMES = { + archive: nil, + metadata: nil, + trace: nil, + junit: 'junit.xml', + sast: 'gl-sast-report.json', + dependency_scanning: 'gl-dependency-scanning-report.json', + container_scanning: 'gl-container-scanning-report.json', + dast: 'gl-dast-report.json' + }.freeze + + TYPE_AND_FORMAT_PAIRS = { + archive: :zip, + metadata: :gzip, + trace: :raw, + junit: :gzip, + sast: :gzip, + dependency_scanning: :gzip, + container_scanning: :gzip, + dast: :gzip + }.freeze belongs_to :project belongs_to :job, class_name: "Ci::Build", foreign_key: :job_id @@ -27,8 +47,18 @@ module Ci scope :with_files_stored_locally, -> { where(file_store: [nil, ::JobArtifactUploader::Store::LOCAL]) } + scope :with_file_types, -> (file_types) do + types = self.file_types.select { |file_type| file_types.include?(file_type) }.values + + where(file_type: types) + end + scope :test_reports, -> do - types = self.file_types.select { |file_type| TEST_REPORT_FILE_TYPES.include?(file_type) }.values + with_file_types(TEST_REPORT_FILE_TYPES) + end + + scope :erasable, -> do + types = self.file_types.reject { |file_type| NON_ERASABLE_FILE_TYPES.include?(file_type) }.values where(file_type: types) end @@ -39,7 +69,11 @@ module Ci archive: 1, metadata: 2, trace: 3, - junit: 4 + junit: 4, + sast: 5, ## EE-specific + dependency_scanning: 6, ## EE-specific + container_scanning: 7, ## EE-specific + dast: 8 ## EE-specific } enum file_format: { diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 3e815937f4b..31330d0682e 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -9,12 +9,24 @@ module Ci include ChronicDurationAttribute include FromUnion + enum access_level: { + not_protected: 0, + ref_protected: 1 + } + + enum runner_type: { + instance_type: 1, + group_type: 2, + project_type: 3 + } + RUNNER_QUEUE_EXPIRY_TIME = 60.minutes ONLINE_CONTACT_TIMEOUT = 1.hour UPDATE_DB_RUNNER_INFO_EVERY = 40.minutes - AVAILABLE_TYPES = %w[specific shared].freeze + AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze + AVAILABLE_TYPES = runner_types.keys.freeze AVAILABLE_STATUSES = %w[active paused online offline].freeze - AVAILABLE_SCOPES = (AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze + AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze ignore_column :is_shared @@ -97,17 +109,6 @@ module Ci after_destroy :cleanup_runner_queue - enum access_level: { - not_protected: 0, - ref_protected: 1 - } - - enum runner_type: { - instance_type: 1, - group_type: 2, - project_type: 3 - } - cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb index 3d84eeed5a8..7be6a14f585 100644 --- a/app/models/clusters/applications/jupyter.rb +++ b/app/models/clusters/applications/jupyter.rb @@ -73,6 +73,11 @@ module Clusters "clientSecret" => oauth_application.secret, "callbackUrl" => callback_url } + }, + "singleuser" => { + "extraEnv" => { + "GITLAB_CLUSTER_ID" => cluster.id + } } } end diff --git a/app/models/concerns/bulk_member_access_load.rb b/app/models/concerns/bulk_member_access_load.rb index c4346d5dd17..041ed3755e0 100644 --- a/app/models/concerns/bulk_member_access_load.rb +++ b/app/models/concerns/bulk_member_access_load.rb @@ -16,9 +16,9 @@ module BulkMemberAccessLoad key = max_member_access_for_resource_key(resource_klass, memoization_index) access = {} - if RequestStore.active? - RequestStore.store[key] ||= {} - access = RequestStore.store[key] + if Gitlab::SafeRequestStore.active? + Gitlab::SafeRequestStore[key] ||= {} + access = Gitlab::SafeRequestStore[key] end # Look up only the IDs we need diff --git a/app/models/concerns/cacheable_attributes.rb b/app/models/concerns/cacheable_attributes.rb index 62b78c3611c..f8034be8376 100644 --- a/app/models/concerns/cacheable_attributes.rb +++ b/app/models/concerns/cacheable_attributes.rb @@ -27,11 +27,7 @@ module CacheableAttributes end def cached - if RequestStore.active? - RequestStore[:"#{name}_cached_attributes"] ||= retrieve_from_cache - else - retrieve_from_cache - end + Gitlab::SafeRequestStore[:"#{name}_cached_attributes"] ||= retrieve_from_cache end def retrieve_from_cache diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb index 20f9b18e4ca..00dec6bb92b 100644 --- a/app/models/legacy_diff_note.rb +++ b/app/models/legacy_diff_note.rb @@ -20,11 +20,7 @@ class LegacyDiffNote < Note end def project_repository - if RequestStore.active? - RequestStore.fetch("project:#{project_id}:repository") { self.project.repository } - else - self.project.repository - end + Gitlab::SafeRequestStore.fetch("project:#{project_id}:repository") { self.project.repository } end def diff_file_hash diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 0289f29211d..c54be778d1b 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -148,8 +148,8 @@ class Namespace < ActiveRecord::Base def find_fork_of(project) return nil unless project.fork_network - if RequestStore.active? - forks_in_namespace = RequestStore.fetch("namespaces:#{id}:forked_projects") do + if Gitlab::SafeRequestStore.active? + forks_in_namespace = Gitlab::SafeRequestStore.fetch("namespaces:#{id}:forked_projects") do Hash.new do |found_forks, project| found_forks[project] = project.fork_network.find_forks_in(projects).first end diff --git a/app/models/project.rb b/app/models/project.rb index 9e4c7f7a2d0..503fbc30768 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -86,7 +86,7 @@ class Project < ActiveRecord::Base after_create :create_project_feature, unless: :project_feature after_create -> { SiteStatistic.track(STATISTICS_ATTRIBUTE) } - before_destroy :untrack_site_statistics + before_destroy -> { SiteStatistic.untrack(STATISTICS_ATTRIBUTE) } after_create :create_ci_cd_settings, unless: :ci_cd_settings, @@ -111,7 +111,7 @@ class Project < ActiveRecord::Base after_create :ensure_storage_path_exists after_save :ensure_storage_path_exists, if: :namespace_id_changed? - acts_as_taggable + acts_as_ordered_taggable attr_accessor :old_path_with_namespace attr_accessor :template_name @@ -331,7 +331,7 @@ class Project < ActiveRecord::Base # last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push scope :sorted_by_activity, -> { reorder("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC") } - scope :sorted_by_stars, -> { reorder('projects.star_count DESC') } + scope :sorted_by_stars, -> { reorder(star_count: :desc) } scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } @@ -481,6 +481,8 @@ class Project < ActiveRecord::Base reorder(last_activity_at: :desc) when 'latest_activity_asc' reorder(last_activity_at: :asc) + when 'stars_desc' + sorted_by_stars else order_by(method) end @@ -2076,12 +2078,6 @@ class Project < ActiveRecord::Base auto_cancel_pending_pipelines == 'enabled' end - # Update the default branch querying the remote to determine its HEAD - def update_root_ref(remote_name) - root_ref = repository.find_remote_root_ref(remote_name) - change_head(root_ref) if root_ref.present? && root_ref != default_branch - end - private # rubocop: disable CodeReuse/ServiceClass @@ -2114,11 +2110,6 @@ 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 - # rubocop: disable CodeReuse/ServiceClass def execute_rename_repository_hooks!(full_path_before) # When we import a project overwriting the original project, there @@ -2270,11 +2261,7 @@ class Project < ActiveRecord::Base end end - if RequestStore.active? - RequestStore.fetch("project-#{id}:branch-#{branch_name}:user-#{user.id}:branch_allows_collaboration") do - check_access.call - end - else + Gitlab::SafeRequestStore.fetch("project-#{id}:branch-#{branch_name}:user-#{user.id}:branch_allows_collaboration") do check_access.call end end diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index d74cb2506ba..4a0324e8b5c 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -21,7 +21,6 @@ class ProjectFeature < ActiveRecord::Base ENABLED = 20 FEATURES = %i(issues merge_requests wiki snippets builds repository).freeze - STATISTICS_ATTRIBUTE = 'wikis_count'.freeze class << self def access_level_attribute(feature) @@ -55,9 +54,6 @@ class ProjectFeature < ActiveRecord::Base default_value_for :wiki_access_level, value: ENABLED, allows_nil: false default_value_for :repository_access_level, value: ENABLED, allows_nil: false - after_create ->(model) { SiteStatistic.track(STATISTICS_ATTRIBUTE) if model.wiki_enabled? } - after_update :update_site_statistics - def feature_available?(feature, user) get_permission(user, access_level(feature)) end @@ -82,30 +78,8 @@ class ProjectFeature < ActiveRecord::Base issues_access_level > DISABLED end - # This is a workaround for the removal hooks not been triggered when removing a Project. - # - # ProjectFeature is removed using database cascade index rule. - # This method is called by Project model when deletion starts. - def untrack_statistics_for_deletion! - return unless wiki_enabled? - - SiteStatistic.untrack(STATISTICS_ATTRIBUTE) - end - private - def update_site_statistics - return unless wiki_access_level_changed? - - if self.wiki_access_level_was == DISABLED - # possible new states are PRIVATE / ENABLED, both should be tracked - SiteStatistic.track(STATISTICS_ATTRIBUTE) - elsif self.wiki_access_level == DISABLED - # old state was either PRIVATE / ENABLED, only untrack if new state is DISABLED - SiteStatistic.untrack(STATISTICS_ATTRIBUTE) - end - end - # Validates builds and merge requests access level # which cannot be higher than repository access level def repository_children_level diff --git a/app/models/project_services/chat_message/merge_message.rb b/app/models/project_services/chat_message/merge_message.rb index cc88d57faf8..6b7a35aaa75 100644 --- a/app/models/project_services/chat_message/merge_message.rb +++ b/app/models/project_services/chat_message/merge_message.rb @@ -26,7 +26,7 @@ module ChatMessage def activity { - title: "Merge Request #{state} by #{user_combined_name}", + title: "Merge Request #{state_or_action_text} by #{user_combined_name}", subtitle: "in #{project_link}", text: merge_request_link, image: user_avatar diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index 761359b3c9f..559e4f99294 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -80,7 +80,7 @@ class ProjectWiki pages(limit: 1).empty? end - # Returns an Array of Gitlab WikiPage instances or an + # Returns an Array of GitLab WikiPage instances or an # empty Array if this Wiki has no pages. def pages(limit: 0) wiki.pages(limit: limit).map { |page| WikiPage.new(self, page, true) } diff --git a/app/models/repository.rb b/app/models/repository.rb index ad65881ff43..4fecdb3c1ad 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -24,7 +24,6 @@ class Repository delegate :ref_name_for_sha, to: :raw_repository delegate :bundle_to_disk, to: :raw_repository - delegate :find_remote_root_ref, to: :raw_repository CreateTreeError = Class.new(StandardError) @@ -511,7 +510,7 @@ class Repository raw_repository.exists? end - cache_method :exists? + cache_method_asymmetrically :exists? # We don't need to cache the output of this method because both exists? and # has_visible_content? are already memoized and cached. There's no guarantee @@ -613,7 +612,7 @@ class Repository Licensee::License.new(license_key) end - cache_method :license, memoize_only: true + memoize_method :license def gitignore file_on_head(:gitignore) @@ -1030,6 +1029,10 @@ class Repository @cache ||= Gitlab::RepositoryCache.new(self) end + def request_store_cache + @request_store_cache ||= Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore) + end + def tags_sorted_by_committed_date tags.sort_by do |tag| # Annotated tags can point to any object (e.g. a blob), but generally diff --git a/app/models/site_statistic.rb b/app/models/site_statistic.rb index 48324570f0b..3a7912ed53a 100644 --- a/app/models/site_statistic.rb +++ b/app/models/site_statistic.rb @@ -4,7 +4,7 @@ class SiteStatistic < ActiveRecord::Base # prevents the creation of multiple rows default_value_for :id, 1 - COUNTER_ATTRIBUTES = %w(repositories_count wikis_count).freeze + COUNTER_ATTRIBUTES = %w(repositories_count).freeze REQUIRED_SCHEMA_VERSION = 20180629153018 # Tracks specific attribute diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 33790afc35e..102907a8bd3 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -51,7 +51,7 @@ class WikiPage validates :title, presence: true validates :content, presence: true - # The Gitlab ProjectWiki instance. + # The GitLab ProjectWiki instance. attr_reader :wiki # The raw Gitlab::Git::WikiPage instance. @@ -127,7 +127,7 @@ class WikiPage version.try(:message) end - # The Gitlab Commit instance for this page. + # The GitLab Commit instance for this page. def version return nil unless persisted? diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb index 00a441a9a1e..c85b1790e73 100644 --- a/app/serializers/build_details_entity.rb +++ b/app/serializers/build_details_entity.rb @@ -7,6 +7,7 @@ class BuildDetailsEntity < JobEntity expose :coverage, :erased_at, :duration expose :tag_list, as: :tags + expose :has_trace?, as: :has_trace expose :user, using: UserEntity expose :runner, using: RunnerEntity expose :pipeline, using: PipelineEntity diff --git a/app/serializers/commit_entity.rb b/app/serializers/commit_entity.rb index ce76659fa46..396e95a03c8 100644 --- a/app/serializers/commit_entity.rb +++ b/app/serializers/commit_entity.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class CommitEntity < API::Entities::Commit + include MarkupHelper include RequestAwareEntity expose :author, using: UserEntity @@ -9,11 +10,19 @@ class CommitEntity < API::Entities::Commit GravatarService.new.execute(commit.author_email) # rubocop: disable CodeReuse/ServiceClass end - expose :commit_url do |commit| - project_commit_url(request.project, commit) + expose :commit_url do |commit, options| + project_commit_url(request.project, commit, params: options.fetch(:commit_url_params, {})) end - expose :commit_path do |commit| - project_commit_path(request.project, commit) + expose :commit_path do |commit, options| + project_commit_path(request.project, commit, params: options.fetch(:commit_url_params, {})) + end + + expose :description_html, if: { type: :full } do |commit| + markdown_field(commit, :description) + end + + expose :title_html, if: { type: :full } do |commit| + markdown_field(commit, :title) end end diff --git a/app/serializers/diffs_entity.rb b/app/serializers/diffs_entity.rb index 878cc5290bd..00dc55fc004 100644 --- a/app/serializers/diffs_entity.rb +++ b/app/serializers/diffs_entity.rb @@ -15,8 +15,11 @@ class DiffsEntity < Grape::Entity merge_request&.target_branch end - expose :commit do |diffs| - options[:commit] + expose :commit do |diffs, options| + CommitEntity.represent options[:commit], options.merge( + type: :full, + commit_url_params: { merge_request_iid: merge_request&.iid } + ) end expose :merge_request_diff, using: MergeRequestDiffEntity do |diffs| diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb index 08088f8c592..c9d3ee31d82 100644 --- a/app/services/files/multi_service.rb +++ b/app/services/files/multi_service.rb @@ -2,7 +2,7 @@ module Files class MultiService < Files::BaseService - UPDATE_FILE_ACTIONS = %w(update move delete).freeze + UPDATE_FILE_ACTIONS = %w(update move delete chmod).freeze def create_commit! transformer = Lfs::FileTransformer.new(project, @branch_name) diff --git a/app/services/notes/build_service.rb b/app/services/notes/build_service.rb index df5fe65de3c..7b92fe6fe14 100644 --- a/app/services/notes/build_service.rb +++ b/app/services/notes/build_service.rb @@ -3,6 +3,7 @@ module Notes class BuildService < ::BaseService def execute + should_resolve = false in_reply_to_discussion_id = params.delete(:in_reply_to_discussion_id) if in_reply_to_discussion_id.present? @@ -15,12 +16,17 @@ module Notes end params.merge!(discussion.reply_attributes) + should_resolve = discussion.resolved? end note = Note.new(params) note.project = project note.author = current_user + if should_resolve + note.resolve_without_save(current_user) + end + note end diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb index 85b9eb02803..9d0877d1ab2 100644 --- a/app/services/projects/update_remote_mirror_service.rb +++ b/app/services/projects/update_remote_mirror_service.rb @@ -12,7 +12,6 @@ module Projects begin remote_mirror.ensure_remote! repository.fetch_remote(remote_mirror.remote_name, no_tags: true) - project.update_root_ref(remote_mirror.remote_name) opts = {} if remote_mirror.only_protected_branches? diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 02d68c3add3..8933bef29ee 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -126,18 +126,16 @@ module QuickActions parse_params do |assignee_param| extract_users(assignee_param) end - # rubocop: disable CodeReuse/ActiveRecord command :assign do |users| next if users.empty? - @updates[:assignee_ids] = - if issuable.allows_multiple_assignees? - issuable.assignees.pluck(:id) + users.map(&:id) - else - [users.first.id] - end + if issuable.allows_multiple_assignees? + @updates[:assignee_ids] ||= issuable.assignees.map(&:id) + @updates[:assignee_ids] += users.map(&:id) + else + @updates[:assignee_ids] = [users.first.id] + end end - # rubocop: enable CodeReuse/ActiveRecord desc do if issuable.allows_multiple_assignees? @@ -164,16 +162,14 @@ module QuickActions # When multiple users are assigned, all will be unassigned if multiple assignees are no longer allowed extract_users(unassign_param) if issuable.allows_multiple_assignees? end - # rubocop: disable CodeReuse/ActiveRecord command :unassign do |users = nil| - @updates[:assignee_ids] = - if users&.any? - issuable.assignees.pluck(:id) - users.map(&:id) - else - [] - end + if issuable.allows_multiple_assignees? && users&.any? + @updates[:assignee_ids] ||= issuable.assignees.map(&:id) + @updates[:assignee_ids] -= users.map(&:id) + else + @updates[:assignee_ids] = [] + end end - # rubocop: enable CodeReuse/ActiveRecord desc 'Set milestone' explanation do |milestone| @@ -290,8 +286,7 @@ module QuickActions end params '#issue | !merge_request' condition do - issuable.persisted? && - current_user.can?(:"update_#{issuable.to_ability_name}", issuable) + current_user.can?(:"update_#{issuable.to_ability_name}", issuable) end parse_params do |issuable_param| extract_references(issuable_param, :issue).first || diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml index d71dac2574c..cb67079853e 100644 --- a/app/views/admin/appearances/_form.html.haml +++ b/app/views/admin/appearances/_form.html.haml @@ -5,7 +5,7 @@ %legend Navigation bar: .form-group.row - = f.label :header_logo, 'Header logo', class: 'col-sm-2 col-form-label' + = f.label :header_logo, 'Header logo', class: 'col-sm-2 col-form-label pt-0' .col-sm-10 - if @appearance.header_logo? = image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview' @@ -22,7 +22,7 @@ %legend Favicon: .form-group.row - = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label' + = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label pt-0' .col-sm-10 - if @appearance.favicon? = image_tag @appearance.favicon_url, class: 'appearance-light-logo-preview' @@ -51,7 +51,7 @@ .hint Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}. .form-group.row - = f.label :logo, class: 'col-sm-2 col-form-label' + = f.label :logo, class: 'col-sm-2 col-form-label pt-0' .col-sm-10 - if @appearance.logo? = image_tag @appearance.logo_url, class: 'appearance-logo-preview' diff --git a/app/views/admin/application_settings/_background_jobs.html.haml b/app/views/admin/application_settings/_background_jobs.html.haml deleted file mode 100644 index 7d1a64b645a..00000000000 --- a/app/views/admin/application_settings/_background_jobs.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-background-settings'), html: { class: 'fieldset-form' } do |f| - = form_errors(@application_setting) - - %fieldset - %p - These settings require a - = link_to 'restart', help_page_path('administration/restart_gitlab') - to take effect. - .form-group - .form-check - = f.check_box :sidekiq_throttling_enabled, class: 'form-check-input' - = f.label :sidekiq_throttling_enabled, class: 'form-check-label' do - Enable Sidekiq Job Throttling - .form-text.text-muted - Limit the amount of resources slow running jobs are assigned. - .form-group - = f.label :sidekiq_throttling_queues, 'Sidekiq queues to throttle', class: 'label-bold' - = f.select :sidekiq_throttling_queues, sidekiq_queue_options_for_select, { include_hidden: false }, multiple: true, class: 'select2 select-wide', data: { field: 'sidekiq_throttling_queues' } - .form-text.text-muted - Choose which queues you wish to throttle. - .form-group - = f.label :sidekiq_throttling_factor, 'Throttling Factor', class: 'label-bold' - = f.number_field :sidekiq_throttling_factor, class: 'form-control', min: '0.01', max: '0.99', step: '0.01' - .form-text.text-muted - The factor by which the queues should be throttled. A value between 0.0 and 1.0, exclusive. - - = f.submit 'Save changes', class: "btn btn-success" diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml new file mode 100644 index 00000000000..db24c9982f7 --- /dev/null +++ b/app/views/admin/application_settings/ci_cd.html.haml @@ -0,0 +1,26 @@ +- breadcrumb_title _("CI/CD") +- page_title _("CI/CD") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Continuous Integration and Deployment') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Auto DevOps, runners and job artifacts') + .settings-content + = render 'ci_cd' + +- if Gitlab.config.registry.enabled + %section.settings.as-registry.no-animate#js-registry-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Container Registry') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Various container registry settings.') + .settings-content + = render 'registry' diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml new file mode 100644 index 00000000000..310e86b1377 --- /dev/null +++ b/app/views/admin/application_settings/integrations.html.haml @@ -0,0 +1,31 @@ +- breadcrumb_title _("Integrations") +- page_title _("Integrations") +- @content_class = "limit-container-width" unless fluid_layout + += render_if_exists 'admin/application_settings/elasticsearch_form', expanded: expanded_by_default? + +%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('PlantUML') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Allow rendering of PlantUML diagrams in Asciidoc documents.') + .settings-content + = render 'plantuml' + += render_if_exists 'admin/application_settings/slack', expanded: expanded_by_default? + +%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Third party offers') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Control the display of third party offers.') + .settings-content + = render 'third_party_offers', application_setting: @application_setting + += render_if_exists 'admin/application_settings/snowplow', expanded: expanded_by_default? diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml new file mode 100644 index 00000000000..f50aca32bdf --- /dev/null +++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml @@ -0,0 +1,50 @@ +- breadcrumb_title _("Metrics and profiling") +- page_title _("Metrics and profiling") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-influx.no-animate#js-influx-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Metrics - Influx') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable and configure InfluxDB metrics.') + .settings-content + = render 'influx' + +%section.settings.as-prometheus.no-animate#js-prometheus-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Metrics - Prometheus') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable and configure Prometheus metrics.') + .settings-content + = render 'prometheus' + +%section.settings.as-performance-bar.no-animate#js-performance-bar-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Profiling - Performance bar') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable the Performance Bar for a given group.') + = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar') + .settings-content + = render 'performance_bar' + +%section.settings.as-usage.no-animate#js-usage-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header#usage-statistics + %h4 + = _('Usage statistics') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable or disable version check and usage ping.') + .settings-content + = render 'usage' + += render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded_by_default? diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml new file mode 100644 index 00000000000..26fd745f45f --- /dev/null +++ b/app/views/admin/application_settings/network.html.haml @@ -0,0 +1,36 @@ +- breadcrumb_title _("Network") +- page_title _("Network") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-performance.no-animate#js-performance-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Performance optimization') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Various settings that affect GitLab performance.') + .settings-content + = render 'performance' + +%section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('User and IP Rate Limits') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure limits for web and API requests.') + .settings-content + = render 'ip_limits' + +%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Outbound requests') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Allow requests to the local network from hooks and services.') + .settings-content + = render 'outbound' diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml new file mode 100644 index 00000000000..00000b86ab7 --- /dev/null +++ b/app/views/admin/application_settings/preferences.html.haml @@ -0,0 +1,58 @@ +- breadcrumb_title _("Preferences") +- page_title _("Preferences") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-email.no-animate#js-email-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Email') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Various email settings.') + .settings-content + = render 'email' + +%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Help page') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Help page text and support page url.') + .settings-content + = render 'help_page' + +%section.settings.as-pages.no-animate#js-pages-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Pages') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Size and domain settings for static websites') + .settings-content + = render 'pages' + +%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Real-time features') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Change this value to influence how frequently the GitLab UI polls for updates.') + .settings-content + = render 'realtime' + +%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Gitaly') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure Gitaly timeouts.') + .settings-content + = render 'gitaly' diff --git a/app/views/admin/application_settings/reporting.html.haml b/app/views/admin/application_settings/reporting.html.haml new file mode 100644 index 00000000000..1c2d9ccdb2d --- /dev/null +++ b/app/views/admin/application_settings/reporting.html.haml @@ -0,0 +1,36 @@ +- breadcrumb_title _("Reporting") +- page_title _("Reporting") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-spam.no-animate#js-spam-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Spam and Anti-bot Protection') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable reCAPTCHA or Akismet and set IP limits.') + .settings-content + = render 'spam' + +%section.settings.as-abuse.no-animate#js-abuse-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Abuse reports') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Set notification email for abuse reports.') + .settings-content + = render 'abuse' + +%section.settings.as-logging.no-animate#js-logging-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Error Reporting and Logging') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Enable Sentry for error reporting and logging.') + .settings-content + = render 'logging' diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml new file mode 100644 index 00000000000..d8029e0c54a --- /dev/null +++ b/app/views/admin/application_settings/repository.html.haml @@ -0,0 +1,36 @@ +- breadcrumb_title _("Repository") +- page_title _("Repository") +- @content_class = "limit-container-width" unless fluid_layout + +%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Repository mirror') + %button.btn.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? 'Collapse' : 'Expand' + %p + = _('Configure push mirrors.') + .settings-content + = render partial: 'repository_mirrors_form' + +%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Repository storage') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure storage path and circuit breaker settings.') + .settings-content + = render 'repository_storage' + +%section.settings.as-repository-check.no-animate#js-repository-check-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Repository maintenance') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure automatic git checks and housekeeping on repositories.') + .settings-content + = render 'repository_check' diff --git a/app/views/admin/application_settings/show.html.haml b/app/views/admin/application_settings/show.html.haml index 194a8157013..e2043183a97 100644 --- a/app/views/admin/application_settings/show.html.haml +++ b/app/views/admin/application_settings/show.html.haml @@ -1,359 +1,93 @@ -- breadcrumb_title "Settings" -- page_title "Settings" +- breadcrumb_title _("Settings") +- page_title _("Settings") - @content_class = "limit-container-width" unless fluid_layout -- expanded = Rails.env.test? -%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded) } +%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Visibility and access controls') %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set default and restrict visibility levels. Configure import sources and git access protocol.') .settings-content = render 'visibility_and_access' -%section.settings.as-account-limit.no-animate#js-account-settings{ class: ('expanded' if expanded) } +%section.settings.as-account-limit.no-animate#js-account-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Account and limit') %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Session expiration, projects limit and attachment size.') .settings-content = render 'account_and_limit' -%section.settings.as-signup.no-animate#js-signup-settings{ class: ('expanded' if expanded) } +%section.settings.as-signup.no-animate#js-signup-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Sign-up restrictions') %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure the way a user creates a new account.') .settings-content = render 'signup' -%section.settings.as-signin.no-animate#js-signin-settings{ class: ('expanded' if expanded) } +%section.settings.as-signin.no-animate#js-signin-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Sign-in restrictions') %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set requirements for a user to sign-in. Enable mandatory two-factor authentication.') .settings-content = render 'signin' -%section.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded) } +%section.qa-terms-settings.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Terms of Service and Privacy Policy') %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Include a Terms of Service agreement and Privacy Policy that all users must accept.') .settings-content = render 'terms' -%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Help page') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Help page text and support page url.') - .settings-content - = render 'help_page' - -%section.settings.as-pages.no-animate#js-pages-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Pages') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Size and domain settings for static websites') - .settings-content - = render 'pages' - -%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Continuous Integration and Deployment') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Auto DevOps, runners and job artifacts') - .settings-content - = render 'ci_cd' - -%section.settings.as-influx.no-animate#js-influx-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Metrics - Influx') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable and configure InfluxDB metrics.') - .settings-content - = render 'influx' - -%section.settings.as-prometheus.no-animate#js-prometheus-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Metrics - Prometheus') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable and configure Prometheus metrics.') - .settings-content - = render 'prometheus' - -%section.settings.as-performance-bar.no-animate#js-performance-bar-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Profiling - Performance bar') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable the Performance Bar for a given group.') - = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar') - .settings-content - = render 'performance_bar' - -%section.settings.as-background.no-animate#js-background-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Background jobs') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Configure Sidekiq job throttling.') - .settings-content - = render 'background_jobs' - -%section.settings.as-spam.no-animate#js-spam-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Spam and Anti-bot Protection') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable reCAPTCHA or Akismet and set IP limits.') - .settings-content - = render 'spam' - -%section.settings.as-abuse.no-animate#js-abuse-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Abuse reports') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Set notification email for abuse reports.') - .settings-content - = render 'abuse' - -%section.settings.as-logging.no-animate#js-logging-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Error Reporting and Logging') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable Sentry for error reporting and logging.') - .settings-content - = render 'logging' - -%section.qa-repository-storage-settings.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Repository storage') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Configure storage path and circuit breaker settings.') - .settings-content - = render 'repository_storage' - -%section.settings.as-repository-check.no-animate#js-repository-check-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Repository maintenance') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Configure automatic git checks and housekeeping on repositories.') - .settings-content - = render 'repository_check' - -- if Gitlab.config.registry.enabled - %section.settings.as-registry.no-animate#js-registry-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Container Registry') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Various container registry settings.') - .settings-content - = render 'registry' - - if koding_enabled? - %section.settings.as-koding.no-animate#js-koding-settings{ class: ('expanded' if expanded) } + %section.settings.as-koding.no-animate#js-koding-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Koding') %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Online IDE integration settings.') .settings-content = render 'koding' -%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('PlantUML') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Allow rendering of PlantUML diagrams in Asciidoc documents.') - .settings-content - = render 'plantuml' - -%section.settings.as-usage.no-animate#js-usage-settings{ class: ('expanded' if expanded) } - .settings-header#usage-statistics - %h4 - = _('Usage statistics') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Enable or disable version check and usage ping.') - .settings-content - = render 'usage' - -%section.settings.as-email.no-animate#js-email-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Email') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Various email settings.') - .settings-content - = render 'email' - -%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Gitaly') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Configure Gitaly timeouts.') - .settings-content - = render 'gitaly' += render_if_exists 'admin/application_settings/external_authorization_service_form', expanded: expanded_by_default? -%section.settings.as-terminal.no-animate#js-terminal-settings{ class: ('expanded' if expanded) } +%section.settings.as-terminal.no-animate#js-terminal-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Web terminal') %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set max session time for web terminal.') .settings-content = render 'terminal' -%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Real-time features') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Change this value to influence how frequently the GitLab UI polls for updates.') - .settings-content - = render 'realtime' - -%section.settings.as-performance.no-animate#js-performance-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Performance optimization') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Various settings that affect GitLab performance.') - .settings-content - = render 'performance' - -%section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('User and IP Rate Limits') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Configure limits for web and API requests.') - .settings-content - = render 'ip_limits' - -%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Outbound requests') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Allow requests to the local network from hooks and services.') - .settings-content - = render 'outbound' - -%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Repository mirror') - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' - %p - = _('Configure push mirrors.') - .settings-content - = render partial: 'repository_mirrors_form' - -= render_if_exists 'admin/application_settings/geo', expanded: expanded - -= render_if_exists 'admin/application_settings/external_authorization_service_form', expanded: expanded - -= render_if_exists 'admin/application_settings/elasticsearch_form', expanded: expanded - -= render_if_exists 'admin/application_settings/slack', expanded: expanded - -= render_if_exists 'admin/application_settings/templates', expanded: expanded - -%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Third party offers') - %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Control the display of third party offers.') - .settings-content - = render 'third_party_offers', application_setting: @application_setting - -= render_if_exists 'admin/application_settings/custom_templates_form', expanded: expanded - -%section.settings.no-animate#js-web-ide-settings{ class: ('expanded' if expanded) } +%section.settings.no-animate#js-web-ide-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Web IDE') %button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') + = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Manage Web IDE features') .settings-content @@ -370,5 +104,3 @@ = s_('IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox client side evaluation.') = f.submit _('Save changes'), class: "btn btn-success" - -= render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml index 585576ec799..12690343f6e 100644 --- a/app/views/admin/applications/_form.html.haml +++ b/app/views/admin/applications/_form.html.haml @@ -21,14 +21,14 @@ for local tests = content_tag :div, class: 'form-group row' do - = f.label :trusted, class: 'col-sm-2 col-form-label' + = f.label :trusted, class: 'col-sm-2 col-form-label pt-0' .col-sm-10 = f.check_box :trusted %span.form-text.text-muted Trusted applications are automatically authorized on GitLab OAuth flow. .form-group.row - = f.label :scopes, class: 'col-sm-2 col-form-label' + = f.label :scopes, class: 'col-sm-2 col-form-label pt-0' .col-sm-10 = render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml index 9c15226f0ec..e4fc2985087 100644 --- a/app/views/admin/runners/_runner.html.haml +++ b/app/views/admin/runners/_runner.html.haml @@ -1,47 +1,65 @@ .gl-responsive-table-row{ id: dom_id(runner) } - = render layout: 'runner_table_cell', locals: { label: _('Type') } do - - if runner.instance_type? - %span.badge.badge-success shared - - elsif runner.group_type? - %span.badge.badge-success group - - else - %span.badge.badge-info specific - - if runner.locked? - %span.badge.badge-warning locked - - unless runner.active? - %span.badge.badge-danger paused - - = render layout: 'runner_table_cell', locals: { label: _('Runner token') } do - = link_to runner.short_sha, admin_runner_path(runner) - - = render layout: 'runner_table_cell', locals: { label: _('Description') } do - = runner.description - - = render layout: 'runner_table_cell', locals: { label: _('Version') } do - = runner.version - - = render layout: 'runner_table_cell', locals: { label: _('IP Address') } do - = runner.ip_address - - = render layout: 'runner_table_cell', locals: { label: _('Projects') } do - - if runner.instance_type? || runner.group_type? - = _('n/a') - - else - = runner.projects.count(:all) - - = render layout: 'runner_table_cell', locals: { label: _('Jobs') } do - = runner.builds.count(:all) - - = render layout: 'runner_table_cell', locals: { label: _('Tags') } do - - runner.tag_list.sort.each do |tag| - %span.badge.badge-primary - = tag - - = render layout: 'runner_table_cell', locals: { label: _('Last contact') } do - - if runner.contacted_at - = time_ago_with_tooltip runner.contacted_at - - else - = _('Never') + .table-section.section-10.section-wrap + .table-mobile-header{ role: 'rowheader' }= _('Type') + .table-mobile-content + - if runner.instance_type? + %span.badge.badge-success shared + - elsif runner.group_type? + %span.badge.badge-success group + - else + %span.badge.badge-info specific + - if runner.locked? + %span.badge.badge-warning locked + - unless runner.active? + %span.badge.badge-danger paused + + .table-section.section-10 + .table-mobile-header{ role: 'rowheader' }= _('Runner token') + .table-mobile-content + = link_to runner.short_sha, admin_runner_path(runner) + + .table-section.section-15 + .table-mobile-header{ role: 'rowheader' }= _('Description') + .table-mobile-content.str-truncated.has-tooltip{ title: runner.description } + = runner.description + + .table-section.section-15 + .table-mobile-header{ role: 'rowheader' }= _('Version') + .table-mobile-content.str-truncated.has-tooltip{ title: runner.version } + = runner.version + + .table-section.section-10 + .table-mobile-header{ role: 'rowheader' }= _('IP Address') + .table-mobile-content + = runner.ip_address + + .table-section.section-5 + .table-mobile-header{ role: 'rowheader' }= _('Projects') + .table-mobile-content + - if runner.instance_type? || runner.group_type? + = _('n/a') + - else + = runner.projects.count(:all) + + .table-section.section-5 + .table-mobile-header{ role: 'rowheader' }= _('Jobs') + .table-mobile-content + = runner.builds.count(:all) + + .table-section.section-10.section-wrap + .table-mobile-header{ role: 'rowheader' }= _('Tags') + .table-mobile-content + - runner.tag_list.sort.each do |tag| + %span.badge.badge-primary + = tag + + .table-section.section-10 + .table-mobile-header{ role: 'rowheader' }= _('Last contact') + .table-mobile-content + - if runner.contacted_at + = time_ago_with_tooltip runner.contacted_at + - else + = _('Never') .table-section.table-button-footer.section-10 .btn-group.table-action-buttons diff --git a/app/views/admin/runners/_runner_table_cell.html.haml b/app/views/admin/runners/_runner_table_cell.html.haml deleted file mode 100644 index 78526ee6d23..00000000000 --- a/app/views/admin/runners/_runner_table_cell.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.table-section.section-10 - .table-mobile-header{ role: 'rowheader' }= label - .table-mobile-content - = yield diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml index 48e0d7ce12e..a5326f4b909 100644 --- a/app/views/admin/runners/index.html.haml +++ b/app/views/admin/runners/index.html.haml @@ -83,12 +83,21 @@ {{hint}} %span.js-filter-tag.dropdown-light-content {{tag}} + #js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu %ul{ data: { dropdown: true } } - Ci::Runner::AVAILABLE_STATUSES.each do |status| %li.filter-dropdown-item{ data: { value: status } } = button_tag class: %w[btn btn-link] do = status.titleize + + #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + - Ci::Runner::AVAILABLE_TYPES.each do |runner_type| + %li.filter-dropdown-item{ data: { value: runner_type } } + = button_tag class: %w[btn btn-link] do + = runner_type.titleize + = button_tag class: %w[clear-search hidden] do = icon('times') .filter-dropdown-container @@ -98,8 +107,16 @@ .runners-content.content-list .table-holder .gl-responsive-table-row.table-row-header{ role: 'row' } - - [_('Type'), _('Runner token'), _('Description'), _('Version'), _('IP Address'), _('Projects'), _('Jobs'), _('Tags'), _('Last contact')].each do |label| - .table-section.section-10{ role: 'rowheader' }= label + .table-section.section-10{ role: 'rowheader' }= _('Type') + .table-section.section-10{ role: 'rowheader' }= _('Runner token') + .table-section.section-15{ role: 'rowheader' }= _('Description') + .table-section.section-15{ role: 'rowheader' }= _('Version') + .table-section.section-10{ role: 'rowheader' }= _('IP Address') + .table-section.section-5{ role: 'rowheader' }= _('Projects') + .table-section.section-5{ role: 'rowheader' }= _('Jobs') + .table-section.section-10{ role: 'rowheader' }= _('Tags') + .table-section.section-10{ role: 'rowheader' }= _('Last contact') + .table-section.section-10{ role: 'rowheader' } - @runners.each do |runner| = render 'admin/runners/runner', runner: runner diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml index 3764e86dd8b..7dced0942f5 100644 --- a/app/views/devise/shared/_tabs_ldap.html.haml +++ b/app/views/devise/shared/_tabs_ldap.html.haml @@ -10,4 +10,4 @@ = link_to 'Standard', '#login-pane', class: 'nav-link qa-standard-tab', 'data-toggle' => 'tab' - if allow_signup? %li.nav-item - = link_to 'Register', '#register-pane', class: 'nav-link', 'data-toggle' => 'tab' + = link_to 'Register', '#register-pane', class: 'nav-link qa-register-tab', 'data-toggle' => 'tab' diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml index b11f441b3ba..1f5c70a6c6e 100644 --- a/app/views/doorkeeper/applications/index.html.haml +++ b/app/views/doorkeeper/applications/index.html.haml @@ -16,6 +16,9 @@ = _('Add new application') = render 'form', application: @application %hr + - else + .bs-callout.bs-callout-disabled + = _('Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission') - if user_oauth_applications? .oauth-applications %h5 diff --git a/app/views/errors/precondition_failed.html.haml b/app/views/errors/precondition_failed.html.haml new file mode 100644 index 00000000000..aa3869f33a9 --- /dev/null +++ b/app/views/errors/precondition_failed.html.haml @@ -0,0 +1,8 @@ +- content_for(:title, 'Encoding Error') +%img{ :alt => "GitLab Logo", :src => image_path('logo.svg') } + %h1 + 412 +.container + %h3 Precondition failed + %hr + %p Page can't be loaded because of invalid parameters. diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml index 935a8889d79..ff59013ed67 100644 --- a/app/views/groups/_group_admin_settings.html.haml +++ b/app/views/groups/_group_admin_settings.html.haml @@ -1,5 +1,5 @@ .form-group.row - = f.label :lfs_enabled, 'Large File Storage', class: 'col-form-label col-sm-2' + = f.label :lfs_enabled, 'Large File Storage', class: 'col-form-label col-sm-2 pt-0' .col-sm-10 .form-check = f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'form-check-input' @@ -11,7 +11,7 @@ %span.descr This setting can be overridden in each project. .form-group.row - = f.label :require_two_factor_authentication, 'Two-factor authentication', class: 'col-form-label col-sm-2' + = f.label :require_two_factor_authentication, 'Two-factor authentication', class: 'col-form-label col-sm-2 pt-0' .col-sm-10 .form-check = f.check_box :require_two_factor_authentication, class: 'form-check-input' diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml index ffce2d4b14f..8dc88ec446c 100644 --- a/app/views/groups/settings/_permissions.html.haml +++ b/app/views/groups/settings/_permissions.html.haml @@ -10,7 +10,7 @@ = render 'shared/allow_request_access', form: f .form-group.row - %label.col-form-label.col-sm-2 + %label.col-form-label.col-sm-2.pt-0 = s_('GroupSettings|Share with group lock') .col-sm-10 .form-check diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index f1bd817f17a..6a293daaf95 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -15,12 +15,12 @@ - new_project_label = _("New project") - new_subgroup_label = _("New subgroup") - if can_create_subgroups - .btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } } - %input.btn.btn-success.dropdown-primary.js-new-group-child{ type: "button", value: new_project_label, data: { action: "new-project" } } - %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } } + .btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } } + %input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } } + %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } } = icon("caret-down", class: "dropdown-btn-icon") %ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } } - %li.droplab-item-selected{ role: "button", data: { value: "new-project", text: new_project_label } } + %li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } } .menu-item .icon-container = icon("check", class: "list-item-checkmark") @@ -28,7 +28,7 @@ %strong= new_project_label %span= s_("GroupsTree|Create a project in this group.") %li.divider.droplap-item-ignore - %li{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } } + %li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } } .menu-item .icon-container = icon("check", class: "list-item-checkmark") diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml index bdd77730dcc..94c25edaf82 100644 --- a/app/views/help/instance_configuration/_gitlab_pages.html.haml +++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml @@ -8,7 +8,7 @@ %p Below are the settings for - = succeed('.') { link_to('Gitlab Pages', gitlab_pages[:url], target: '_blank') } + = succeed('.') { link_to('GitLab Pages', gitlab_pages[:url], target: '_blank') } .table-responsive %table %thead diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 877d945a09b..5e4595d930b 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -10,7 +10,7 @@ .row .form-group.project-name.col-sm-12 = label_tag :name, _('Project name'), class: 'label-bold' - = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true, required: true + = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true .form-group.col-12.col-sm-6 = label_tag :namespace_id, _('Project URL'), class: 'label-bold' .form-group diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index ff25b040913..f912a32ee1a 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -7,14 +7,14 @@ .sidebar-context-title = _('Admin Area') %ul.sidebar-top-level-items - = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do + = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do = link_to admin_root_path, class: 'shortcuts-tree' do .nav-icon-container = sprite_icon('overview') %span.nav-item-name = _('Overview') %ul.sidebar-sub-level-items - = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers), html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: { class: "fly-out-top-item" } ) do = link_to admin_root_path do %strong.fly-out-top-item-name = _('Overview') @@ -23,7 +23,7 @@ = link_to admin_root_path, title: _('Overview') do %span = _('Dashboard') - = nav_link(controller: [:admin, :projects]) do + = nav_link(controller: [:admin, 'admin/projects']) do = link_to admin_projects_path, title: _('Projects') do %span = _('Projects') @@ -199,10 +199,54 @@ = sprite_icon('settings') %span.nav-item-name = _('Settings') - %ul.sidebar-sub-level-items.is-fly-out-only + + %ul.sidebar-sub-level-items = nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do = link_to admin_application_settings_path do %strong.fly-out-top-item-name = _('Settings') + %li.divider.fly-out-top-item + = nav_link(path: 'application_settings#show') do + = link_to admin_application_settings_path, title: _('General') do + %span + = _('General') + = nav_link(path: 'application_settings#integrations') do + = link_to integrations_admin_application_settings_path, title: _('Integrations') do + %span + = _('Integrations') + = nav_link(path: 'application_settings#repository') do + = link_to repository_admin_application_settings_path, title: _('Repository') do + %span + = _('Repository') + - if template_exists?('admin/application_settings/templates') + = nav_link(path: 'application_settings#templates') do + = link_to templates_admin_application_settings_path, title: _('Templates') do + %span + = _('Templates') + = nav_link(path: 'application_settings#ci_cd') do + = link_to ci_cd_admin_application_settings_path, title: _('CI/CD') do + %span + = _('CI/CD') + = nav_link(path: 'application_settings#reporting') do + = link_to reporting_admin_application_settings_path, title: _('Reporting') do + %span + = _('Reporting') + = nav_link(path: 'application_settings#metrics_and_profiling') do + = link_to metrics_and_profiling_admin_application_settings_path, title: _('Metrics and profiling') do + %span + = _('Metrics and profiling') + = nav_link(path: 'application_settings#network') do + = link_to network_admin_application_settings_path, title: _('Network') do + %span + = _('Network') + - if template_exists?('admin/application_settings/geo') + = nav_link(path: 'application_settings#geo') do + = link_to geo_admin_application_settings_path, title: _('Geo') do + %span + = _('Geo') + = nav_link(path: 'application_settings#preferences') do + = link_to preferences_admin_application_settings_path, title: _('Preferences') do + %span + = _('Preferences') = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 4158bb69452..43170587797 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -109,7 +109,7 @@ = link_to edit_group_path(@group) do .nav-icon-container = sprite_icon('settings') - %span.nav-item-name + %span.nav-item-name.qa-settings-item = _('Settings') %ul.sidebar-sub-level-items = nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show], html_options: { class: "fly-out-top-item" } ) do diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index d65f153b451..69167edb1df 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -28,18 +28,17 @@ = link_to profile_account_path do %strong.fly-out-top-item-name = _('Account') - - if Gitlab::CurrentSettings.user_oauth_applications? - = nav_link(controller: 'oauth/applications') do - = link_to applications_profile_path do - .nav-icon-container - = sprite_icon('applications') - %span.nav-item-name - = _('Applications') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do - = link_to applications_profile_path do - %strong.fly-out-top-item-name - = _('Applications') + = nav_link(controller: 'oauth/applications') do + = link_to applications_profile_path do + .nav-icon-container + = sprite_icon('applications') + %span.nav-item-name + = _('Applications') + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do + = link_to applications_profile_path do + %strong.fly-out-top-item-name + = _('Applications') = nav_link(controller: :chat_names) do = link_to profile_chat_names_path do .nav-icon-container diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index db07c475866..cbf89fa8f02 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -7,7 +7,7 @@ .form-group.project-name.col-sm-12 = f.label :name, class: 'label-bold' do %span= _("Project name") - = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, required: true + = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true .form-group.project-path.col-sm-6 = f.label :namespace_id, class: 'label-bold' do %span= s_("Project URL") diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 7951a5ddc9e..c6789e32dbe 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -1,3 +1,7 @@ +-#----------------------------------------------------------------- + WARNING: Please keep changes up-to-date with the following files: + - `assets/javascripts/diffs/components/commit_item.vue` +-#----------------------------------------------------------------- - view_details = local_assigns.fetch(:view_details, false) - merge_request = local_assigns.fetch(:merge_request, nil) - project = local_assigns.fetch(:project) { merge_request&.project } @@ -37,7 +41,7 @@ %button.text-expander.js-toggle-button = sprite_icon('ellipsis_h', size: 12) - .commiter + .committer - commit_author_link = commit_author_link(commit, avatar: false, size: 24) - commit_timeago = time_ago_with_tooltip(commit.authored_date, placement: 'bottom') - commit_text = _('%{commit_author_link} authored %{commit_timeago}') % { commit_author_link: commit_author_link, commit_timeago: commit_timeago } diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 96ab582b050..bfd165d8ba5 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -40,7 +40,7 @@ .form-group = f.label :tag_list, "Tags", class: 'label-bold' - = f.text_field :tag_list, value: @project.tag_list.sort.join(', '), maxlength: 2000, class: "form-control" + = f.text_field :tag_list, value: @project.tag_list.join(', '), maxlength: 2000, class: "form-control" %p.form-text.text-muted Separate tags with commas. %fieldset.features %h5.prepend-top-0= _("Project avatar") diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 8a14146cb87..31c72f2f759 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -2,9 +2,9 @@ .issue-box - if @can_bulk_update .issue-check.hidden - = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected_issue" - .issue-info-container - .issue-main-info + = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected-issuable" + .issuable-info-container + .issuable-main-info .issue-title.title %span.issue-title-text - if issue.confidential? diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml index acc1e17b811..66a3b8b8fd1 100644 --- a/app/views/projects/jobs/_sidebar.html.haml +++ b/app/views/projects/jobs/_sidebar.html.haml @@ -3,63 +3,6 @@ .blocks-container #js-details-block-vue{ data: { terminal_path: can?(current_user, :create_build_terminal, @build) && @build.has_terminal? ? terminal_project_job_path(@project, @build) : nil } } - - if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) - .block - .title - Job artifacts - - if @build.artifacts_expired? - %p.build-detail-row - The artifacts were removed - #{time_ago_with_tooltip(@build.artifacts_expire_at)} - - elsif @build.has_expiring_artifacts? - %p.build-detail-row - The artifacts will be removed - #{time_ago_with_tooltip(@build.artifacts_expire_at)} - - - if @build.artifacts? - .btn-group.d-flex{ role: :group } - - if @build.has_expiring_artifacts? && can?(current_user, :update_build, @build) - = link_to keep_project_job_artifacts_path(@project, @build), class: 'btn btn-sm btn-default', method: :post do - Keep - - = link_to download_project_job_artifacts_path(@project, @build), rel: 'nofollow', download: '', class: 'btn btn-sm btn-default' do - Download - - - if @build.browsable_artifacts? - = link_to browse_project_job_artifacts_path(@project, @build), class: 'btn btn-sm btn-default' do - Browse - - - if @build.trigger_request - .build-widget.block - %h4.title - Trigger - - - if @build.trigger_request&.trigger&.short_token - %p - %span.build-light-text Token: - #{@build.trigger_request.trigger.short_token} - - - if @build.trigger_variables.any? - %p - %button.btn.group.js-reveal-variables Reveal Variables - - %dl.js-build-variables.trigger-build-variables.hide - - @build.trigger_variables.each do |trigger_variable| - %dt.js-build-variable.trigger-build-variable= trigger_variable[:key] - %dd.js-build-value.trigger-build-value= trigger_variable[:value] - - %div{ class: (@build.pipeline.stages_count > 1 ? "block" : "block-last") } - %p - Commit - = link_to @build.pipeline.short_sha, project_commit_path(@project, @build.pipeline.sha), class: 'commit-sha link-commit' - = clipboard_button(text: @build.pipeline.short_sha, title: "Copy commit SHA to clipboard") - - if @build.merge_request - in - = link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request), class: 'link-commit' - - %p.build-light-text.append-bottom-0 - #{@build.pipeline.git_commit_title} - - if @build.pipeline.stages_count > 1 .block-last.dropdown.build-dropdown %div diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index cd3d896fff2..faa070d0389 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -1,10 +1,10 @@ %li{ id: dom_id(merge_request), class: mr_css_classes(merge_request), data: { labels: merge_request.label_ids, id: merge_request.id } } - if @can_bulk_update .issue-check.hidden - = check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected_issue" + = check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected-issuable" - .issue-info-container - .issue-main-info + .issuable-info-container + .issuable-main-info .merge-request-title.title %span.merge-request-title-text = link_to merge_request.title, merge_request_path(merge_request) diff --git a/app/views/projects/merge_requests/diffs/_commit_widget.html.haml b/app/views/projects/merge_requests/diffs/_commit_widget.html.haml index dab95b97346..066c8d5dba6 100644 --- a/app/views/projects/merge_requests/diffs/_commit_widget.html.haml +++ b/app/views/projects/merge_requests/diffs/_commit_widget.html.haml @@ -1,3 +1,7 @@ +-#----------------------------------------------------------------- + WARNING: Please keep changes up-to-date with the following files: + - `assets/javascripts/diffs/components/commit_widget.vue` +-#----------------------------------------------------------------- - if @commit .info-well.d-none.d-sm-block.prepend-top-default .well-segment diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml index 7afb7b3a93b..6612497e7e2 100644 --- a/app/views/shared/_event_filter.html.haml +++ b/app/views/shared/_event_filter.html.haml @@ -2,13 +2,13 @@ .fade-left= icon('angle-left') .fade-right= icon('angle-right') %ul.nav-links.event-filter.scrolling-tabs.nav.nav-tabs - = event_filter_link EventFilter.all, _('All'), s_('EventFilterBy|Filter by all') + = event_filter_link EventFilter::ALL, _('All'), s_('EventFilterBy|Filter by all') - if event_filter_visible(:repository) - = event_filter_link EventFilter.push, _('Push events'), s_('EventFilterBy|Filter by push events') + = event_filter_link EventFilter::PUSH, _('Push events'), s_('EventFilterBy|Filter by push events') - if event_filter_visible(:merge_requests) - = event_filter_link EventFilter.merged, _('Merge events'), s_('EventFilterBy|Filter by merge events') + = event_filter_link EventFilter::MERGED, _('Merge events'), s_('EventFilterBy|Filter by merge events') - if event_filter_visible(:issues) - = event_filter_link EventFilter.issue, _('Issue events'), s_('EventFilterBy|Filter by issue events') + = event_filter_link EventFilter::ISSUE, _('Issue events'), s_('EventFilterBy|Filter by issue events') - if comments_visible? - = event_filter_link EventFilter.comments, _('Comments'), s_('EventFilterBy|Filter by comments') - = event_filter_link EventFilter.team, _('Team'), s_('EventFilterBy|Filter by team') + = event_filter_link EventFilter::COMMENTS, _('Comments'), s_('EventFilterBy|Filter by comments') + = event_filter_link EventFilter::TEAM, _('Team'), s_('EventFilterBy|Filter by team') diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml index 01ce1225b8d..ba37b37a3b1 100644 --- a/app/views/shared/_visibility_level.html.haml +++ b/app/views/shared/_visibility_level.html.haml @@ -2,7 +2,7 @@ .form-group.row.visibility-level-setting - if with_label - = f.label :visibility_level, class: 'col-form-label col-sm-2' do + = f.label :visibility_level, class: 'col-form-label col-sm-2 pt-0' do Visibility Level = link_to icon('question-circle'), help_page_path("public_access/public_access") %div{ :class => (with_label ? "col-sm-10" : "col-sm-12") } diff --git a/app/views/shared/issuable/form/_title.html.haml b/app/views/shared/issuable/form/_title.html.haml index e49bdec386a..56c4b021eab 100644 --- a/app/views/shared/issuable/form/_title.html.haml +++ b/app/views/shared/issuable/form/_title.html.haml @@ -9,7 +9,7 @@ autocomplete: 'off', class: 'form-control pad qa-issuable-form-title', placeholder: _('Title') - if issuable.respond_to?(:work_in_progress?) - %p.form-text.text-muted + .form-text.text-muted .js-wip-explanation %a.js-toggle-wip{ href: '', tabindex: -1 } Remove the diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index af29c0fe59e..2682d92fc56 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -22,7 +22,7 @@ %strong Blocked - if user.two_factor_enabled? - %label.label.label-info + %label.badge.badge-info 2FA - if source.instance_of?(Group) && source != @group diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml index f01915107e3..c8a5e199674 100644 --- a/app/views/snippets/new.html.haml +++ b/app/views/snippets/new.html.haml @@ -1,5 +1,6 @@ - @hide_top_links = true -- breadcrumb_title "Snippets" +- add_to_breadcrumbs "Snippets", dashboard_snippets_path +- breadcrumb_title "New" - page_title "New Snippet" %h3.page-title New Snippet diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index 4fcd1e5bd24..94426dcf921 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -13,7 +13,7 @@ class ExpireBuildInstanceArtifactsWorker return unless build&.project && !build.project.pending_delete Rails.logger.info "Removing artifacts for build #{build.id}..." - build.erase_artifacts! + build.erase_erasable_artifacts! end # rubocop: enable CodeReuse/ActiveRecord end diff --git a/bin/pkgr_before_precompile.sh b/bin/pkgr_before_precompile.sh index 5a2007f4ab0..54ff32c711b 100755 --- a/bin/pkgr_before_precompile.sh +++ b/bin/pkgr_before_precompile.sh @@ -6,7 +6,7 @@ for file in config/*.yml.example; do cp ${file} config/$(basename ${file} .example) done -# Allow to override the Gitlab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments. +# Allow to override the GitLab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments. config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml) echo "$config" > config/gitlab.yml sed -i "s/host: localhost/host: <%= gitlab_url.host %>/" config/gitlab.yml diff --git a/changelogs/archive.md b/changelogs/archive.md index fe461a6ac5e..b57440f7dc6 100644 --- a/changelogs/archive.md +++ b/changelogs/archive.md @@ -739,7 +739,7 @@ - Update duration at the end of pipeline - ExpireBuildArtifactsWorker query builds table without ordering enqueuing one job per build to cleanup - Add group level labels. (!6425) -- Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun) +- Add an example for testing a phoenix application with GitLab CI in the docs (Manthan Mallikarjun) - Cancelled pipelines could be retried. !6927 - Updating verbiage on git basics to be more intuitive - Fix project_feature record not generated on project creation @@ -768,7 +768,7 @@ - Log LDAP lookup errors and don't swallow unrelated exceptions. !6103 (Markus Koller) - Replace unique keyframes mixin with keyframe mixin with specific names (ClemMakesApps) - Add more tests for calendar contribution (ClemMakesApps) -- Update Gitlab Shell to fix some problems with moving projects between storages +- Update GitLab Shell to fix some problems with moving projects between storages - Cache rendered markdown in the database, rather than Redis - Add todo toggle event (ClemMakesApps) - Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references @@ -815,7 +815,7 @@ - Replace static issue fixtures by script !6059 (winniehell) - Append issue template to existing description !6149 (Joseph Frazier) - Trending projects now only show public projects and the list of projects is cached for a day -- Memoize Gitlab Shell's secret token (!6599, Justin DiPierro) +- Memoize GitLab Shell's secret token (!6599, Justin DiPierro) - Revoke button in Applications Settings underlines on hover. - Use higher size on Gitlab::Redis connection pool on Sidekiq servers - Add missing values to linter !6276 (Katarzyna Kobierska Ula Budziszewska) @@ -930,7 +930,7 @@ ## 8.12.3 - - Update Gitlab Shell to support low IO priority for storage moves + - Update GitLab Shell to support low IO priority for storage moves ## 8.12.2 @@ -1001,7 +1001,7 @@ - Added ability to specify URL in environment configuration in gitlab-ci.yml - Escape search term before passing it to Regexp.new !6241 (winniehell) - Fix pinned sidebar behavior in smaller viewports !6169 - - Fix file permissions change when updating a file on the Gitlab UI !5979 + - Fix file permissions change when updating a file on the GitLab UI !5979 - Added horizontal padding on build page sidebar on code coverage block. !6196 (Vitaly Baev) - Change merge_error column from string to text type - Fix issue with search filter labels not displaying @@ -1688,7 +1688,7 @@ - Fix commit avatar alignment in compare view. !5128 - Fix broken migration in MySQL. !5005 - Overwrite Host and X-Forwarded-Host headers in NGINX !5213 - - Keeps issue number when importing from Gitlab.com + - Keeps issue number when importing from GitLab.com - Add Pending tab for Builds (Katarzyna Kobierska, Urszula Budziszewska) ## 8.9.5 @@ -4786,7 +4786,7 @@ ## 3.1.0 - Updated gems -- Services: Gitlab CI integration +- Services: GitLab CI integration - Events filter on dashboard - Own namespace for redis/resque - Optimized commit diff views @@ -4869,7 +4869,7 @@ ## 2.8.0 -- Gitlab Flavored Markdown +- GitLab Flavored Markdown - Bulk issues update - Issues API - Cucumber coverage increased diff --git a/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml b/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml deleted file mode 100644 index f7521ff9225..00000000000 --- a/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml +++ /dev/null @@ -1,4 +0,0 @@ -title: First Improvements made to the contributor on-boarding experience. -merge_request: 20682 -author: Eddie Stubbington -type: added diff --git a/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml b/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml new file mode 100644 index 00000000000..4ceaa7e3139 --- /dev/null +++ b/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml @@ -0,0 +1,5 @@ +--- +title: "Allow events filter to be set in the URL in addition to cookie" +merge_request: 21557 +author: Igor @igas +type: added diff --git a/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml b/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml deleted file mode 100644 index 8e8c3cf53b4..00000000000 --- a/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Fix breadcrumb link to issues on new issue page" -merge_request: 21305 -author: J.D. Bean -type: fixed diff --git a/changelogs/unreleased/21326-avoid-nil-safe-message.yml b/changelogs/unreleased/21326-avoid-nil-safe-message.yml deleted file mode 100644 index ca1a89191a8..00000000000 --- a/changelogs/unreleased/21326-avoid-nil-safe-message.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Avoid nil safe message" -merge_request: 21326 -author: Yi Siliang -type: fixed diff --git a/changelogs/unreleased/21371-avatar-fix.yml b/changelogs/unreleased/21371-avatar-fix.yml deleted file mode 100644 index 6e00a4ba360..00000000000 --- a/changelogs/unreleased/21371-avatar-fix.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Vertically centres landscape avatars." -merge_request: 21371 -author: Vicary Archangel -type: fixed diff --git a/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml b/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml new file mode 100644 index 00000000000..d835d25f39b --- /dev/null +++ b/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml @@ -0,0 +1,5 @@ +--- +title: Fix resolved discussions being unresolved when commented on +merge_request: 21881 +author: +type: fixed diff --git a/changelogs/unreleased/25990-web-terminal-improvements.yml b/changelogs/unreleased/25990-web-terminal-improvements.yml deleted file mode 100644 index 99a4a82ea66..00000000000 --- a/changelogs/unreleased/25990-web-terminal-improvements.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Make terminal button more visible -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/2747-protected-environments-backend-ce.yml b/changelogs/unreleased/2747-protected-environments-backend-ce.yml deleted file mode 100644 index dcec74a33a7..00000000000 --- a/changelogs/unreleased/2747-protected-environments-backend-ce.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: CE Port of Protected Environments backend -merge_request: 20859 -author: -type: other diff --git a/changelogs/unreleased/28930-add-project-reference-filter.yml b/changelogs/unreleased/28930-add-project-reference-filter.yml deleted file mode 100644 index c7679c5fe76..00000000000 --- a/changelogs/unreleased/28930-add-project-reference-filter.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add the ability to reference projects in comments and other markdown text. -merge_request: 20285 -author: Reuben Pereira -type: added diff --git a/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml b/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml deleted file mode 100644 index ad9136b69c2..00000000000 --- a/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Re-add project name field on "Create new project" page -merge_request: 21386 -author: -type: other diff --git a/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml b/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml deleted file mode 100644 index c182946b299..00000000000 --- a/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Support Kubernetes RBAC for GitLab Managed Apps when adding a existing cluster -merge_request: 21127 -author: -type: changed diff --git a/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml b/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml deleted file mode 100644 index c5788a40dba..00000000000 --- a/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Move project settings for default branch under "Repository" -merge_request: 21380 -author: -type: changed diff --git a/changelogs/unreleased/36534-show-commit-behind-mr-api.yml b/changelogs/unreleased/36534-show-commit-behind-mr-api.yml deleted file mode 100644 index 06471146fa3..00000000000 --- a/changelogs/unreleased/36534-show-commit-behind-mr-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds diverged_commits_count field to GET api/v4/projects/:project_id/merge_requests/:merge_request_iid -merge_request: 21405 -author: Jacopo Beschi @jacopo-beschi -type: added diff --git a/changelogs/unreleased/37356-relative-submodule-link.yml b/changelogs/unreleased/37356-relative-submodule-link.yml deleted file mode 100644 index 99d1577609d..00000000000 --- a/changelogs/unreleased/37356-relative-submodule-link.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix git submodule link for subgroup projects with relative path -merge_request: 21154 -author: -type: fixed diff --git a/changelogs/unreleased/38208-due-dates-system-notes.yml b/changelogs/unreleased/38208-due-dates-system-notes.yml deleted file mode 100644 index 60e09ff64de..00000000000 --- a/changelogs/unreleased/38208-due-dates-system-notes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add system note when due date is changed -merge_request: -author: Eva Kadlecova -type: added diff --git a/changelogs/unreleased/39665-restrict-issue-reopen.yml b/changelogs/unreleased/39665-restrict-issue-reopen.yml deleted file mode 100644 index 204baafb700..00000000000 --- a/changelogs/unreleased/39665-restrict-issue-reopen.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Restrict reopening locked issues for non authorized issue authors -merge_request: 21299 -author: -type: changed diff --git a/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml b/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml deleted file mode 100644 index 76b411e9e8c..00000000000 --- a/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable Auto DevOps for project upon first pipeline failure -merge_request: 21172 -author: -type: added diff --git a/changelogs/unreleased/41040-long-webhook-url-problem.yml b/changelogs/unreleased/41040-long-webhook-url-problem.yml new file mode 100644 index 00000000000..4057e1ff325 --- /dev/null +++ b/changelogs/unreleased/41040-long-webhook-url-problem.yml @@ -0,0 +1,5 @@ +--- +title: Fix long webhook URL overflow for custom integration. +merge_request: +author: Kukovskii Vladimir +type: fixed diff --git a/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml b/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml deleted file mode 100644 index 830c02510f2..00000000000 --- a/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix project transfer name validation issues causing a redirect loop -merge_request: 21408 -author: -type: fixed 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 deleted file mode 100644 index c23676a3104..00000000000 --- a/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add target branch name to cherrypick confirmation message -merge_request: 20846 -author: George Andrinopoulos -type: other diff --git a/changelogs/unreleased/41729-enable-auto-devops-instance-wide-for-everyone.yml b/changelogs/unreleased/41729-enable-auto-devops-instance-wide-for-everyone.yml deleted file mode 100644 index ff925c4fc55..00000000000 --- a/changelogs/unreleased/41729-enable-auto-devops-instance-wide-for-everyone.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable Auto DevOps Instance Wide Default -merge_request: 21157 -author: -type: changed diff --git a/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml b/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml deleted file mode 100644 index bc0150c6586..00000000000 --- a/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml +++ /dev/null @@ -1,5 +0,0 @@ ----
-title: "Fix If-Check the result that a function was executed several times"
-merge_request: 20640
-author: Max Dicker
-type: fixed
diff --git a/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml b/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml deleted file mode 100644 index e452a91d8b7..00000000000 --- a/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Solve tooltip appears under modal -merge_request: 21017 -author: -type: fixed diff --git a/changelogs/unreleased/42754-runners-pagination.yml b/changelogs/unreleased/42754-runners-pagination.yml deleted file mode 100644 index 8e77b857538..00000000000 --- a/changelogs/unreleased/42754-runners-pagination.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Does not collapse runners section when using pagination -merge_request: -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 deleted file mode 100644 index f4744c868ef..00000000000 --- a/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve performance when fetching related merge requests for an issue -merge_request: 21237 -author: -type: performance diff --git a/changelogs/unreleased/43140-reduce-logs-tree-load.yml b/changelogs/unreleased/43140-reduce-logs-tree-load.yml deleted file mode 100644 index 5b0f1996bb3..00000000000 --- a/changelogs/unreleased/43140-reduce-logs-tree-load.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bulk-render commit titles in the tree view to improve performance -merge_request: 21500 -author: -type: performance diff --git a/changelogs/unreleased/43625-increase-modal-checkout.yml b/changelogs/unreleased/43625-increase-modal-checkout.yml deleted file mode 100644 index 877550924c1..00000000000 --- a/changelogs/unreleased/43625-increase-modal-checkout.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Increase width of checkout branch modal box -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml b/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml new file mode 100644 index 00000000000..cea1436ae8b --- /dev/null +++ b/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml @@ -0,0 +1,5 @@ +--- +title: Allows to chmod file with commits API +merge_request: 21866 +author: Jacopo Beschi @jacopo-beschi +type: added diff --git a/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml b/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml deleted file mode 100644 index a828ee36eb4..00000000000 --- a/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Overhaul listing of projects in the group overview page -merge_request: 20262 -author: -type: added diff --git a/changelogs/unreleased/44704-improve-project-overview-ui.yml b/changelogs/unreleased/44704-improve-project-overview-ui.yml deleted file mode 100644 index 6fb8359f2dc..00000000000 --- a/changelogs/unreleased/44704-improve-project-overview-ui.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update design of project overview page -merge_request: 20536 -author: -type: changed diff --git a/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml b/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml deleted file mode 100644 index a378aaec750..00000000000 --- a/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update presentation for SSO providers on log in page -merge_request: 21233 -author: -type: other diff --git a/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml b/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml new file mode 100644 index 00000000000..4b398e9419d --- /dev/null +++ b/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml @@ -0,0 +1,5 @@ +--- +title: Split admin settings into multiple sub pages +merge_request: 21467 +author: +type: other diff --git a/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml b/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml deleted file mode 100644 index 6d664511e6e..00000000000 --- a/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "`/tag` quick action on Commit comments" -merge_request: 20694 -author: Peter Leitzen -type: added diff --git a/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml b/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml deleted file mode 100644 index f3016a639d9..00000000000 --- a/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Handle database statement timeouts in usage ping -merge_request: 21523 -author: -type: fixed diff --git a/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml b/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml deleted file mode 100644 index b93d2378d85..00000000000 --- a/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove extra spaces from MR discussion notes -merge_request: 18946 -author: Takuya Noguchi -type: other diff --git a/changelogs/unreleased/46591-fix-ide-height-issues.yml b/changelogs/unreleased/46591-fix-ide-height-issues.yml deleted file mode 100644 index d161bda6ab1..00000000000 --- a/changelogs/unreleased/46591-fix-ide-height-issues.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix IDE issues with persistent banners -merge_request: 21283 -author: -type: fixed diff --git a/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml b/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml new file mode 100644 index 00000000000..e0dc26301d4 --- /dev/null +++ b/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml @@ -0,0 +1,6 @@ +--- +title: Allow user to revoke an authorized application even if User OAuth applications + setting is disabled in admin settings +merge_request: 21835 +author: +type: changed diff --git a/changelogs/unreleased/47440-recognize-unlicense-license-file.yml b/changelogs/unreleased/47440-recognize-unlicense-license-file.yml deleted file mode 100644 index 3521dd613b0..00000000000 --- a/changelogs/unreleased/47440-recognize-unlicense-license-file.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Recognize 'UNLICENSE' license files -merge_request: 21508 -author: J.D. Bean -type: added diff --git a/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml b/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml deleted file mode 100644 index 81ca632947d..00000000000 --- a/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix buttons on the new file page wrapping outside of the container -merge_request: 21015 -author: -type: fixed diff --git a/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml b/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml deleted file mode 100644 index ad09527b329..00000000000 --- a/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Importing a project no longer fails when visibility level holds a string value - type -merge_request: 21242 -author: -type: fixed diff --git a/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml b/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml deleted file mode 100644 index 3f85f75bef4..00000000000 --- a/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "#47845 Add failure_reason to job webhook" -merge_request: 21143 -author: matemaciek -type: added diff --git a/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml b/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml deleted file mode 100644 index b9f68e1c46c..00000000000 --- a/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show deprecation message on project milestone page for category tabs -merge_request: 21236 -author: -type: changed diff --git a/changelogs/unreleased/48145-illustration.yml b/changelogs/unreleased/48145-illustration.yml deleted file mode 100644 index 7d84075c2b3..00000000000 --- a/changelogs/unreleased/48145-illustration.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixes SVGs for empty states in job page overflowing on mobile -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml b/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml deleted file mode 100644 index a8fcce2eeb8..00000000000 --- a/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix outdated discussions being shown on Merge Request Changes tab -merge_request: 21543 -author: -type: fixed diff --git a/changelogs/unreleased/48320-cancel-a-created-job.yml b/changelogs/unreleased/48320-cancel-a-created-job.yml deleted file mode 100644 index 3e7a9e9ae52..00000000000 --- a/changelogs/unreleased/48320-cancel-a-created-job.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allows to cancel a Created job -merge_request: 20635 -author: Jacopo Beschi @jacopo-beschi -type: added diff --git a/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml b/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml deleted file mode 100644 index 4ddbc118e86..00000000000 --- a/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update Import/Export to only use new storage uploaders logic -merge_request: 21409 -author: -type: added diff --git a/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml b/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml deleted file mode 100644 index 88ba8028e2c..00000000000 --- a/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow spaces in wiki markdown links when using CommonMark -merge_request: 20417 -author: -type: fixed diff --git a/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml b/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml deleted file mode 100644 index 26851fc2dec..00000000000 --- a/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Change 'Backlog' list title to 'Open' in Issue Boards -merge_request: 21131 -author: -type: changed diff --git a/changelogs/unreleased/48967-disable-statement-timeout.yml b/changelogs/unreleased/48967-disable-statement-timeout.yml deleted file mode 100644 index 2da800ed41e..00000000000 --- a/changelogs/unreleased/48967-disable-statement-timeout.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: disable_statement_timeout no longer leak to other migrations -merge_request: 20503 -author: -type: fixed diff --git a/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml b/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml new file mode 100644 index 00000000000..e82bda6819f --- /dev/null +++ b/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml @@ -0,0 +1,5 @@ +--- +title: Dont create license_management build when not included in license +merge_request: 21958 +author: +type: performance diff --git a/changelogs/unreleased/49110-update-mr-widget-styles.yml b/changelogs/unreleased/49110-update-mr-widget-styles.yml deleted file mode 100644 index e54866a0908..00000000000 --- a/changelogs/unreleased/49110-update-mr-widget-styles.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Truncate branch names and update "commits behind" text in MR page -merge_request: 21206 -author: -type: changed diff --git a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml deleted file mode 100644 index 69089cfe357..00000000000 --- a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add group name badge under group milestone -merge_request: 21384 -author: -type: added diff --git a/changelogs/unreleased/49329-mr-show-commit-details.yml b/changelogs/unreleased/49329-mr-show-commit-details.yml new file mode 100644 index 00000000000..23cfc0c675e --- /dev/null +++ b/changelogs/unreleased/49329-mr-show-commit-details.yml @@ -0,0 +1,5 @@ +--- +title: Show commit details for selected commit in MR diffs +merge_request: 21784 +author: +type: fixed diff --git a/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml b/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml deleted file mode 100644 index eae5da45524..00000000000 --- a/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Make cluster page settings easier to read -merge_request: 21550 -author: -type: other diff --git a/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml b/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml deleted file mode 100644 index a2ae582fb1c..00000000000 --- a/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Make margin of user status emoji consistent -merge_request: 21268 -author: -type: other diff --git a/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml b/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml deleted file mode 100644 index 00e1f6e638a..00000000000 --- a/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixes input alignment in user admin form with errors -merge_request: 21108 -author: Jacopo Beschi @jacopo-beschi -type: fixed diff --git a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml b/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml deleted file mode 100644 index bb7633abdb1..00000000000 --- a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Fix: Project deletion may not log audit events during group deletion' -merge_request: 21162 -author: -type: fixed diff --git a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml b/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml deleted file mode 100644 index a8e3d590a4a..00000000000 --- a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Fix: Project deletion may not log audit events during user deletion' -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/49905-fix-checkboxes-runners.yml b/changelogs/unreleased/49905-fix-checkboxes-runners.yml deleted file mode 100644 index af40e5348b8..00000000000 --- a/changelogs/unreleased/49905-fix-checkboxes-runners.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix checkboxes on runner admin settings - The labels are now clickable -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml b/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml deleted file mode 100644 index 82423092792..00000000000 --- a/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add ability to suppress the global "You won't be able to use SSH" message -merge_request: 21027 -author: Ævar Arnfjörð Bjarmason -type: added diff --git a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml deleted file mode 100644 index df05bf3f3e2..00000000000 --- a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Split remembering sorting for issues and merge requests -merge_request: 21153 -author: Jacopo Beschi @jacopo-beschi -type: fixed diff --git a/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml b/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml deleted file mode 100644 index 8057819b223..00000000000 --- a/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove redundant header from metrics page -merge_request: 21282 -author: -type: changed diff --git a/changelogs/unreleased/50047-spam-logs-pagination.yml b/changelogs/unreleased/50047-spam-logs-pagination.yml deleted file mode 100644 index ca5f432cd8c..00000000000 --- a/changelogs/unreleased/50047-spam-logs-pagination.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add gitlab theme to spam logs pagination -merge_request: 21145 -author: -type: fixed diff --git a/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml b/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml deleted file mode 100644 index ca17a41d611..00000000000 --- a/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added missing i18n strings to issue boards lables dropdown -merge_request: 21081 -author: -type: other diff --git a/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml b/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml deleted file mode 100644 index f98d111a337..00000000000 --- a/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Send artifact information in job API -merge_request: 50460 -author: -type: other diff --git a/changelogs/unreleased/50101-aritfacts-block.yml b/changelogs/unreleased/50101-aritfacts-block.yml deleted file mode 100644 index 435e9d9d486..00000000000 --- a/changelogs/unreleased/50101-aritfacts-block.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates Vue component for artifacts block on job page -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-builds-dropdown.yml b/changelogs/unreleased/50101-builds-dropdown.yml deleted file mode 100644 index 9194b0e0d31..00000000000 --- a/changelogs/unreleased/50101-builds-dropdown.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Creates vue components for stage dropdowns and job list container for job log - view -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-commit-block.yml b/changelogs/unreleased/50101-commit-block.yml deleted file mode 100644 index f6bad4c8154..00000000000 --- a/changelogs/unreleased/50101-commit-block.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates vue component for commit block in job log page -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-empty-state-component.yml b/changelogs/unreleased/50101-empty-state-component.yml deleted file mode 100644 index ee99b65d964..00000000000 --- a/changelogs/unreleased/50101-empty-state-component.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates empty state vue component for job view -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-env-block.yml b/changelogs/unreleased/50101-env-block.yml deleted file mode 100644 index 11e603e7a79..00000000000 --- a/changelogs/unreleased/50101-env-block.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates vue component for environments information in job log view -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-erased-block.yml b/changelogs/unreleased/50101-erased-block.yml deleted file mode 100644 index 5a5c9bc0fc4..00000000000 --- a/changelogs/unreleased/50101-erased-block.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates vue component for erased block on job view -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-job-log-component.yml b/changelogs/unreleased/50101-job-log-component.yml deleted file mode 100644 index 0759e7cfbd9..00000000000 --- a/changelogs/unreleased/50101-job-log-component.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates vue component for job log trace -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-stuck-component.yml b/changelogs/unreleased/50101-stuck-component.yml deleted file mode 100644 index bfe4009a2b3..00000000000 --- a/changelogs/unreleased/50101-stuck-component.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates Vvue component for warning block about stuck runners -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-trigger.yml b/changelogs/unreleased/50101-trigger.yml deleted file mode 100644 index df4243afa63..00000000000 --- a/changelogs/unreleased/50101-trigger.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates Vue component for trigger variables block in job log page -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50101-truncated-job-information.yml b/changelogs/unreleased/50101-truncated-job-information.yml deleted file mode 100644 index b873b8b7bf6..00000000000 --- a/changelogs/unreleased/50101-truncated-job-information.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Creates vue component for job log top bar with controllers -merge_request: -author: -type: other diff --git a/changelogs/unreleased/50126-blocked-user-card.yml b/changelogs/unreleased/50126-blocked-user-card.yml deleted file mode 100644 index a42d62e5530..00000000000 --- a/changelogs/unreleased/50126-blocked-user-card.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix blocked user card style -merge_request: 21095 -author: -type: fixed diff --git a/changelogs/unreleased/50180-fa-icon-google-audit.yml b/changelogs/unreleased/50180-fa-icon-google-audit.yml deleted file mode 100644 index fb1771a7570..00000000000 --- a/changelogs/unreleased/50180-fa-icon-google-audit.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Show google icon in audit log -merge_request: 21207 -author: Jan Beckmann -type: fixed diff --git a/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml b/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml deleted file mode 100644 index 0f6208d0c7a..00000000000 --- a/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Vendor Auto-DevOps.gitlab-ci.yml with new proxy env vars passed through to - docker -merge_request: 21159 -author: kinolaev -type: added diff --git a/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml b/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml new file mode 100644 index 00000000000..7aee8720888 --- /dev/null +++ b/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml @@ -0,0 +1,5 @@ +--- +title: Update all gitlab CI templates from gitlab-org/gitlab-ci-yml +merge_request: 21929 +author: +type: added diff --git a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml deleted file mode 100644 index 4c5182b843b..00000000000 --- a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Feature flag to disable Hashed Storage migration when renaming a repository -merge_request: 21291 -author: -type: added diff --git a/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml b/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml deleted file mode 100644 index 1694fb2376d..00000000000 --- a/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds Rubocop rule to enforce class_methods over module ClassMethods -merge_request: 21379 -author: Jacopo Beschi @jacopo-beschi -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 deleted file mode 100644 index 3e360f8d6bb..00000000000 --- a/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Removing a group no longer triggers hooks for project deletion twice -merge_request: 21366 -author: -type: fixed diff --git a/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml b/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml deleted file mode 100644 index 4738f7652a4..00000000000 --- a/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Fix breadcrumb link to merge requests on new merge request page" -merge_request: 21502 -author: J.D. Bean -type: fixed diff --git a/changelogs/unreleased/50524-artifacts-sm.yml b/changelogs/unreleased/50524-artifacts-sm.yml deleted file mode 100644 index 22bd097f911..00000000000 --- a/changelogs/unreleased/50524-artifacts-sm.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Shows download artifacts button for pipelines on small screens -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml b/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml deleted file mode 100644 index 23d4d504f04..00000000000 --- a/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Display banner on project page if AutoDevOps is implicitly enabled -merge_request: 21503 -author: -type: added diff --git a/changelogs/unreleased/50564-chat-service-refactoring.yml b/changelogs/unreleased/50564-chat-service-refactoring.yml deleted file mode 100644 index aec5e8fab0a..00000000000 --- a/changelogs/unreleased/50564-chat-service-refactoring.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use sample data for push event when no commits created -merge_request: 21440 -author: Takuya Noguchi -type: fixed diff --git a/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml b/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml deleted file mode 100644 index 2a6666e362c..00000000000 --- a/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Move usage ping payload from User Cohorts page to admin application settings -merge_request: 21343 -author: -type: other diff --git a/changelogs/unreleased/50584-fix-ide-commit-twice.yml b/changelogs/unreleased/50584-fix-ide-commit-twice.yml deleted file mode 100644 index 92b292cf4ab..00000000000 --- a/changelogs/unreleased/50584-fix-ide-commit-twice.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Web IDE unable to commit to same file twice -merge_request: 21372 -author: -type: fixed diff --git a/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml b/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml deleted file mode 100644 index 65419d3ac77..00000000000 --- a/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Merge request copies all associated issue labels and milestone on creation -merge_request: 21383 -author: -type: added 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 deleted file mode 100644 index 6e57a215367..00000000000 --- a/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Don't show flash messages for performance bar errors -merge_request: 21411 -author: -type: other diff --git a/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml b/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml deleted file mode 100644 index 924e8867701..00000000000 --- a/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix links in RSS feed elements -merge_request: 21424 -author: Marc Schwede -type: fixed diff --git a/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml b/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml deleted file mode 100644 index 37922eb82f6..00000000000 --- a/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Auto-DevOps.gitlab-ci.yml: fix redeploying deleted app gives helm error' -merge_request: 21429 -author: -type: fixed diff --git a/changelogs/unreleased/50879-unused-css-container-fluid.yml b/changelogs/unreleased/50879-unused-css-container-fluid.yml deleted file mode 100644 index 3f706472523..00000000000 --- a/changelogs/unreleased/50879-unused-css-container-fluid.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove unused CSS part in mobile framework -merge_request: 21439 -author: Takuya Noguchi -type: other diff --git a/changelogs/unreleased/50904-move-job-page-vue.yml b/changelogs/unreleased/50904-move-job-page-vue.yml new file mode 100644 index 00000000000..e907c6301ec --- /dev/null +++ b/changelogs/unreleased/50904-move-job-page-vue.yml @@ -0,0 +1,5 @@ +--- +title: Use Vue components and new API to render Artifacts, Trigger Variables and Commit blocks on Job page +merge_request: 21777 +author: +type: other diff --git a/changelogs/unreleased/50904-update-scroll-utils.yml b/changelogs/unreleased/50904-update-scroll-utils.yml new file mode 100644 index 00000000000..e301de1a40b --- /dev/null +++ b/changelogs/unreleased/50904-update-scroll-utils.yml @@ -0,0 +1,5 @@ +--- +title: Extracts scroll position check into reusable functions +merge_request: +author: +type: other diff --git a/changelogs/unreleased/50904-use-vuex-store-job.yml b/changelogs/unreleased/50904-use-vuex-store-job.yml new file mode 100644 index 00000000000..5b1112a4f5b --- /dev/null +++ b/changelogs/unreleased/50904-use-vuex-store-job.yml @@ -0,0 +1,5 @@ +--- +title: Uses Vuex store in job details page and removes old mediator pattern +merge_request: +author: +type: other diff --git a/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml b/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml deleted file mode 100644 index be5cc60df64..00000000000 --- a/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update rubyzip to 1.2.2 (CVE-2018-1000544) -merge_request: 21460 -author: Takuya Noguchi -type: security diff --git a/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml b/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml deleted file mode 100644 index 87265506e24..00000000000 --- a/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Run review-docs-cleanup job for gitlab-org repos only -merge_request: 21463 -author: Takuya Noguchi -type: other diff --git a/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml b/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml deleted file mode 100644 index ac18565090a..00000000000 --- a/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix import error when archive does not have the correct extension -merge_request: 21765 -author: -type: fixed diff --git a/changelogs/unreleased/50956-web-terminal.yml b/changelogs/unreleased/50956-web-terminal.yml deleted file mode 100644 index 73317b0224c..00000000000 --- a/changelogs/unreleased/50956-web-terminal.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Include correct CSS file for xterm in environments page -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/51050-fix.yml b/changelogs/unreleased/51050-fix.yml new file mode 100644 index 00000000000..b58f9ae34f8 --- /dev/null +++ b/changelogs/unreleased/51050-fix.yml @@ -0,0 +1,5 @@ +--- +title: Fix broken styling when issue board is collapsed +merge_request: 21868 +author: Andrea Leone +type: fixed diff --git a/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml b/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml deleted file mode 100644 index cb5ab15d285..00000000000 --- a/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Make MR diff file filter input Clear button functional -merge_request: 21556 -author: -type: fixed diff --git a/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml b/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml deleted file mode 100644 index f6faa9549be..00000000000 --- a/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add terminal_path to job API response -merge_request: 21537 -author: -type: other diff --git a/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml b/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml deleted file mode 100644 index 67354d6a610..00000000000 --- a/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update ffi to 1.9.25 -merge_request: 21561 -author: Takuya Noguchi -type: other diff --git a/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml b/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml deleted file mode 100644 index 2ca74b4bc48..00000000000 --- a/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixes double +/- on inline diff view -merge_request: 21634 -author: -type: fixed diff --git a/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml b/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml new file mode 100644 index 00000000000..1d2075ae549 --- /dev/null +++ b/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml @@ -0,0 +1,5 @@ +--- +title: Add link to User Snippets in breadcrumbs of New User Snippet page +merge_request: +author: J.D. Bean +type: add diff --git a/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml b/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml deleted file mode 100644 index c0f7e88f2b7..00000000000 --- a/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix broken exports when they include a projet avatar -merge_request: 21649 -author: -type: fixed diff --git a/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml b/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml deleted file mode 100644 index 5d245f672f2..00000000000 --- a/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add margin between username and subsequent text in issuable header -merge_request: 21697 -author: -type: other diff --git a/changelogs/unreleased/51509-remove-sidekiq-limit-fetch.yml b/changelogs/unreleased/51509-remove-sidekiq-limit-fetch.yml new file mode 100644 index 00000000000..fcc5aae2bda --- /dev/null +++ b/changelogs/unreleased/51509-remove-sidekiq-limit-fetch.yml @@ -0,0 +1,5 @@ +--- +title: Remove background job throttling feature +merge_request: 21748 +author: +type: removed diff --git a/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml b/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml new file mode 100644 index 00000000000..06b7c9c7b34 --- /dev/null +++ b/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml @@ -0,0 +1,5 @@ +--- +title: Removes the 'required' attribute from the 'project name' field +merge_request: 21770 +author: +type: other diff --git a/changelogs/unreleased/51549-runners-table.yml b/changelogs/unreleased/51549-runners-table.yml new file mode 100644 index 00000000000..fe36bfc1b30 --- /dev/null +++ b/changelogs/unreleased/51549-runners-table.yml @@ -0,0 +1,5 @@ +--- +title: Fixes admin runners table not wrapping content +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/51569-performance-bar.yml b/changelogs/unreleased/51569-performance-bar.yml new file mode 100644 index 00000000000..ab62e7d3b3e --- /dev/null +++ b/changelogs/unreleased/51569-performance-bar.yml @@ -0,0 +1,5 @@ +--- +title: Fixes performance bar looking for a key in a undefined prop +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml b/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml new file mode 100644 index 00000000000..b3caa119253 --- /dev/null +++ b/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml @@ -0,0 +1,5 @@ +--- +title: Doesn't synchronize the default branch for push mirrors +merge_request: 21861 +author: +type: fixed diff --git a/changelogs/unreleased/51747-gitlab-com-unable-to-import-a-project-that-was-just-exported.yml b/changelogs/unreleased/51747-gitlab-com-unable-to-import-a-project-that-was-just-exported.yml new file mode 100644 index 00000000000..29f7fd872bc --- /dev/null +++ b/changelogs/unreleased/51747-gitlab-com-unable-to-import-a-project-that-was-just-exported.yml @@ -0,0 +1,5 @@ +--- +title: Fix NULL pipeline import problem and pipeline user mapping issue +merge_request: 21875 +author: +type: fixed diff --git a/changelogs/unreleased/51839-remove-sorting-on-project-tags.yml b/changelogs/unreleased/51839-remove-sorting-on-project-tags.yml new file mode 100644 index 00000000000..38a7c06b34c --- /dev/null +++ b/changelogs/unreleased/51839-remove-sorting-on-project-tags.yml @@ -0,0 +1,5 @@ +--- +title: Preserve order of project tags list +merge_request: 21897 +author: +type: changed diff --git a/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml b/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml new file mode 100644 index 00000000000..eade86d97ac --- /dev/null +++ b/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml @@ -0,0 +1,5 @@ +--- +title: Expose has_trace in job API +merge_request: 21950 +author: +type: other diff --git a/changelogs/unreleased/6010_remove_gemnasium_service.yml b/changelogs/unreleased/6010_remove_gemnasium_service.yml deleted file mode 100644 index 900e84c9eed..00000000000 --- a/changelogs/unreleased/6010_remove_gemnasium_service.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove Gemnasium service -merge_request: 21185 -author: -type: removed diff --git a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml deleted file mode 100644 index 94098dd0144..00000000000 --- a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -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/6717_extend_reports_for_security_products.yml b/changelogs/unreleased/6717_extend_reports_for_security_products.yml new file mode 100644 index 00000000000..184c3212e54 --- /dev/null +++ b/changelogs/unreleased/6717_extend_reports_for_security_products.yml @@ -0,0 +1,5 @@ +--- +title: Extend reports feature to support Security Products +merge_request: 21892 +author: +type: added diff --git a/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml b/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml deleted file mode 100644 index 4611a1f1f29..00000000000 --- a/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Fix absent Click to Expand link on diffs not rendered on first load of Merge - Requests Changes tab -merge_request: 21716 -author: -type: fixed diff --git a/changelogs/unreleased/_acet-disable-ide-button.yml b/changelogs/unreleased/_acet-disable-ide-button.yml deleted file mode 100644 index 2fff3847052..00000000000 --- a/changelogs/unreleased/_acet-disable-ide-button.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable Web IDE button if user is not allowed to push the source branch. -merge_request: 21288 -author: -type: added diff --git a/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml b/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml deleted file mode 100644 index bfea57d79e0..00000000000 --- a/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add migration to cleanup internal_ids inconsistency. -merge_request: 20926 -author: -type: fixed diff --git a/changelogs/unreleased/add-background-migration-for-legacy-traces.yml b/changelogs/unreleased/add-background-migration-for-legacy-traces.yml deleted file mode 100644 index 3d5a0b4e452..00000000000 --- a/changelogs/unreleased/add-background-migration-for-legacy-traces.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add background migrations for legacy artifacts -merge_request: 18615 -author: -type: performance diff --git a/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml b/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml deleted file mode 100644 index d963dc5bac3..00000000000 --- a/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add an example of the configuration of archive trace cron worker in gitlab.yml.example -merge_request: 20583 -author: -type: other diff --git a/changelogs/unreleased/add-most-stars-for-filter-option.yml b/changelogs/unreleased/add-most-stars-for-filter-option.yml new file mode 100644 index 00000000000..be95d6db55f --- /dev/null +++ b/changelogs/unreleased/add-most-stars-for-filter-option.yml @@ -0,0 +1,5 @@ +--- +title: Allows to sort projects by most stars +merge_request: 21762 +author: Jacopo Beschi @jacopo-beschi +type: added diff --git a/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml b/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml deleted file mode 100644 index b82344e3c9c..00000000000 --- a/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add rake command to migrate archived traces from local storage to object storage -merge_request: 21193 -author: -type: added diff --git a/changelogs/unreleased/add_google_noto_color_emoji_font.yml b/changelogs/unreleased/add_google_noto_color_emoji_font.yml deleted file mode 100644 index 9ba46262767..00000000000 --- a/changelogs/unreleased/add_google_noto_color_emoji_font.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add Noto Color Emoji font support -merge_request: 19036 -author: Alexander Popov -type: changed diff --git a/changelogs/unreleased/align-form-labels.yml b/changelogs/unreleased/align-form-labels.yml new file mode 100644 index 00000000000..fd781e3b910 --- /dev/null +++ b/changelogs/unreleased/align-form-labels.yml @@ -0,0 +1,5 @@ +--- +title: Align form labels following Bootstrap 4 docs +merge_request: 21752 +author: +type: fixed diff --git a/changelogs/unreleased/an-ap_log_gitaly_calls.yml b/changelogs/unreleased/an-ap_log_gitaly_calls.yml deleted file mode 100644 index 65bac55a73e..00000000000 --- a/changelogs/unreleased/an-ap_log_gitaly_calls.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add gitaly_calls attribute to API logs -merge_request: 21496 -author: -type: other diff --git a/changelogs/unreleased/an-api-route-logger.yml b/changelogs/unreleased/an-api-route-logger.yml deleted file mode 100644 index cca3ef44f36..00000000000 --- a/changelogs/unreleased/an-api-route-logger.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add route information to lograge structured logging for API logs -merge_request: 21487 -author: -type: other diff --git a/changelogs/unreleased/api-empty-commit-message.yml b/changelogs/unreleased/api-empty-commit-message.yml deleted file mode 100644 index 34ddc020644..00000000000 --- a/changelogs/unreleased/api-empty-commit-message.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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 deleted file mode 100644 index 7b8c7c9e48d..00000000000 --- a/changelogs/unreleased/api-empty-project-snippets.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'API: Catch empty code content for project snippets' -merge_request: 21325 -author: Robert Schilling -type: fixed diff --git a/changelogs/unreleased/api-promote-find-branch.yml b/changelogs/unreleased/api-promote-find-branch.yml deleted file mode 100644 index cfa767809b2..00000000000 --- a/changelogs/unreleased/api-promote-find-branch.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'API: Use find_branch! in all places' -merge_request: 21614 -author: Robert Schilling -type: fixed diff --git a/changelogs/unreleased/api-protected-tags.yml b/changelogs/unreleased/api-protected-tags.yml deleted file mode 100644 index 6e7ecf24b6e..00000000000 --- a/changelogs/unreleased/api-protected-tags.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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 deleted file mode 100644 index 3d569de65fa..00000000000 --- a/changelogs/unreleased/api-shared_group_expires-at.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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 deleted file mode 100644 index 2ecbc5e8174..00000000000 --- a/changelogs/unreleased/arguments-keyword-sast.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Don't use arguments keyword in gettext script -merge_request: 21296 -author: gfyoung -type: fixed diff --git a/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml b/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml deleted file mode 100644 index c145c744cef..00000000000 --- a/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Support a custom action, such as proxying to another server, after /api/v4/internal/allowed check succeeds' -merge_request: 21034 -author: -type: changed diff --git a/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml b/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml deleted file mode 100644 index a1625193189..00000000000 --- a/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28' -merge_request: 21191 -author: sgerrand -type: fixed diff --git a/changelogs/unreleased/bvl-add-czech.yml b/changelogs/unreleased/bvl-add-czech.yml deleted file mode 100644 index 49e0e4a74b7..00000000000 --- a/changelogs/unreleased/bvl-add-czech.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add Czech as an available language. -merge_request: 21201 -author: -type: added diff --git a/changelogs/unreleased/bvl-add-galician.yml b/changelogs/unreleased/bvl-add-galician.yml deleted file mode 100644 index e7035901ace..00000000000 --- a/changelogs/unreleased/bvl-add-galician.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add Galician as an available language. -merge_request: 21202 -author: -type: added diff --git a/changelogs/unreleased/bvl-merge-base-api.yml b/changelogs/unreleased/bvl-merge-base-api.yml deleted file mode 100644 index 78fb3ce0897..00000000000 --- a/changelogs/unreleased/bvl-merge-base-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Get the merge base of two refs through the API -merge_request: 20929 -author: -type: added diff --git a/changelogs/unreleased/bw-commonmark-for-files.yml b/changelogs/unreleased/bw-commonmark-for-files.yml deleted file mode 100644 index f932ccb704f..00000000000 --- a/changelogs/unreleased/bw-commonmark-for-files.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Render files (`.md`) and wikis using CommonMark -merge_request: 21228 -author: -type: changed diff --git a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml deleted file mode 100644 index 12ef6e3f790..00000000000 --- a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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 deleted file mode 100644 index c08578cddba..00000000000 --- a/changelogs/unreleased/ccr-48800-ping_for_boards.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -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/ccr-6699_image_for_object_error.yml b/changelogs/unreleased/ccr-6699_image_for_object_error.yml deleted file mode 100644 index dec1adaceff..00000000000 --- a/changelogs/unreleased/ccr-6699_image_for_object_error.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Handles exception during file upload - replaces the stack trace with a small - error message. -merge_request: 21528 -author: -type: fixed diff --git a/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml b/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml deleted file mode 100644 index 0c6a1071cdd..00000000000 --- a/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Optimize querying User#manageable_groups -merge_request: 21050 -author: -type: performance diff --git a/changelogs/unreleased/ci-builds-status-index.yml b/changelogs/unreleased/ci-builds-status-index.yml deleted file mode 100644 index 8b7252f09e5..00000000000 --- a/changelogs/unreleased/ci-builds-status-index.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove redundant ci_builds (status) index -merge_request: 21070 -author: -type: performance diff --git a/changelogs/unreleased/dm-create-note-return-discussion.yml b/changelogs/unreleased/dm-create-note-return-discussion.yml new file mode 100644 index 00000000000..49ab5c0ca14 --- /dev/null +++ b/changelogs/unreleased/dm-create-note-return-discussion.yml @@ -0,0 +1,5 @@ +--- +title: Increase performance when creating discussions on diff +merge_request: +author: +type: performance diff --git a/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml b/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml new file mode 100644 index 00000000000..bfc1ff7b8af --- /dev/null +++ b/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml @@ -0,0 +1,6 @@ +--- +title: Don't ignore first action when assign and unassign quick actions are used in + the same comment +merge_request: 21749 +author: +type: fixed diff --git a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml deleted file mode 100644 index 67926f3738a..00000000000 --- a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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-group-labels-search.yml b/changelogs/unreleased/dz-group-labels-search.yml deleted file mode 100644 index bb4719df22d..00000000000 --- a/changelogs/unreleased/dz-group-labels-search.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add search to a group labels page -merge_request: 21480 -author: -type: added diff --git a/changelogs/unreleased/ee-6381-multiseries.yml b/changelogs/unreleased/ee-6381-multiseries.yml deleted file mode 100644 index a749e31d27c..00000000000 --- a/changelogs/unreleased/ee-6381-multiseries.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow gaps in multiseries metrics charts -merge_request: 21427 -author: -type: fixed diff --git a/changelogs/unreleased/emoji-cutoff-1px.yml b/changelogs/unreleased/emoji-cutoff-1px.yml deleted file mode 100644 index 815d9c177e8..00000000000 --- a/changelogs/unreleased/emoji-cutoff-1px.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix 1px cutoff of emojis -merge_request: 21180 -author: gfyoung -type: fixed diff --git a/changelogs/unreleased/enable-force-write-auth-keys-restore.yml b/changelogs/unreleased/enable-force-write-auth-keys-restore.yml new file mode 100644 index 00000000000..f6c83cc7950 --- /dev/null +++ b/changelogs/unreleased/enable-force-write-auth-keys-restore.yml @@ -0,0 +1,5 @@ +--- +title: Enable the ability to use the force env for rebuilding authorized_keys during a restore +merge_request: 21896 +author: +type: fixed diff --git a/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml b/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml deleted file mode 100644 index 1453d39934b..00000000000 --- a/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Expose all artifacts sizes in jobs api -merge_request: 20821 -author: Peter Marko -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 deleted file mode 100644 index 0b8ae527214..00000000000 --- a/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Expose user's id in /admin/users/ show page -merge_request: -author: Eva Kadlecova -type: changed diff --git a/changelogs/unreleased/fa-handle_invalid_utf8_errors.yml b/changelogs/unreleased/fa-handle_invalid_utf8_errors.yml new file mode 100644 index 00000000000..9cae193d858 --- /dev/null +++ b/changelogs/unreleased/fa-handle_invalid_utf8_errors.yml @@ -0,0 +1,5 @@ +--- +title: Render 412 when invalid UTF-8 parameters are passed to controller +merge_request: +author: +type: other diff --git a/changelogs/unreleased/feat-add-default-avatar-to-group.yml b/changelogs/unreleased/feat-add-default-avatar-to-group.yml deleted file mode 100644 index 56d8f2ccd6d..00000000000 --- a/changelogs/unreleased/feat-add-default-avatar-to-group.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add default avatar to group -merge_request: 17271 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/feat-update-contribution-calendar.yml b/changelogs/unreleased/feat-update-contribution-calendar.yml deleted file mode 100644 index 4ada8b1fcd5..00000000000 --- a/changelogs/unreleased/feat-update-contribution-calendar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Include private contributions to contributions calendar -merge_request: 17296 -author: George Tsiolis -type: added diff --git a/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml b/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml deleted file mode 100644 index a99ecc9a67e..00000000000 --- a/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add default parameter to branches API -merge_request: 21294 -author: Riccardo Padovani -type: changed diff --git a/changelogs/unreleased/feature-add-public-email-to-users-api.yml b/changelogs/unreleased/feature-add-public-email-to-users-api.yml new file mode 100644 index 00000000000..1f5d3fb113d --- /dev/null +++ b/changelogs/unreleased/feature-add-public-email-to-users-api.yml @@ -0,0 +1,5 @@ +--- +title: Adds the user's public_email attribute to the API +merge_request: 21909 +author: Alexis Reigel +type: added diff --git a/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml b/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml deleted file mode 100644 index b46dfd47e7a..00000000000 --- a/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add support for extendable CI/CD config with -merge_request: 21243 -author: -type: added diff --git a/changelogs/unreleased/feature-git-v2-flag.yml b/changelogs/unreleased/feature-git-v2-flag.yml deleted file mode 100644 index c105c477666..00000000000 --- a/changelogs/unreleased/feature-git-v2-flag.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add git_v2 feature flag -merge_request: 21520 -author: -type: added diff --git a/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml b/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml new file mode 100644 index 00000000000..e7812cd0944 --- /dev/null +++ b/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml @@ -0,0 +1,5 @@ +--- +title: Add a type filter to the admin runners view +merge_request: 19649 +author: Alexis Reigel +type: added diff --git a/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml b/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml deleted file mode 100644 index 7a3bd11c119..00000000000 --- a/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add an option to whitelist users based on email address as internal when the "New user set to external" setting is enabled. -merge_request: 17711 -author: Roger Rüttimann -type: added diff --git a/changelogs/unreleased/filter-web-hooks-by-branch.yml b/changelogs/unreleased/filter-web-hooks-by-branch.yml deleted file mode 100644 index 7bd2c191d7f..00000000000 --- a/changelogs/unreleased/filter-web-hooks-by-branch.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add branch filter to project webhooks -merge_request: 20338 -author: Duana Saskia -type: added diff --git a/changelogs/unreleased/fix-api-group-createdat.yml b/changelogs/unreleased/fix-api-group-createdat.yml deleted file mode 100644 index e628facf1bf..00000000000 --- a/changelogs/unreleased/fix-api-group-createdat.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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-chat-notification-service-for-ee.yml b/changelogs/unreleased/fix-chat-notification-service-for-ee.yml new file mode 100644 index 00000000000..b69d08b95db --- /dev/null +++ b/changelogs/unreleased/fix-chat-notification-service-for-ee.yml @@ -0,0 +1,5 @@ +--- +title: Fix activity titles for MRs in chat notification services +merge_request: 21834 +author: +type: fixed diff --git a/changelogs/unreleased/fix-closing-issues.yml b/changelogs/unreleased/fix-closing-issues.yml deleted file mode 100644 index ba80f371580..00000000000 --- a/changelogs/unreleased/fix-closing-issues.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix closing issue default pattern -merge_request: 21531 -author: Samuele Kaplun -type: fixed diff --git a/changelogs/unreleased/fix-committer-typo.yml b/changelogs/unreleased/fix-committer-typo.yml new file mode 100644 index 00000000000..6033912b6c0 --- /dev/null +++ b/changelogs/unreleased/fix-committer-typo.yml @@ -0,0 +1,5 @@ +--- +title: Fix committer typo +merge_request: 21899 +author: George Tsiolis +type: other diff --git a/changelogs/unreleased/fix-download-dropdown-link.yml b/changelogs/unreleased/fix-download-dropdown-link.yml deleted file mode 100644 index 998476b07bd..00000000000 --- a/changelogs/unreleased/fix-download-dropdown-link.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Hide PAT creation advice for HTTP clone if PAT exists -merge_request: 18208 -author: George Thomas @thegeorgeous -type: fixed diff --git a/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml b/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml new file mode 100644 index 00000000000..4ac192cd056 --- /dev/null +++ b/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml @@ -0,0 +1,5 @@ +--- +title: Fix wrong text color of help text in merge request creation +merge_request: +author: Gerard Montemayor +type: fixed diff --git a/changelogs/unreleased/fix-junit-parser.yml b/changelogs/unreleased/fix-junit-parser.yml deleted file mode 100644 index e0a9ad8f210..00000000000 --- a/changelogs/unreleased/fix-junit-parser.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix edge cases of JUnitParser -merge_request: 21469 -author: -type: fixed diff --git a/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml b/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml deleted file mode 100644 index d215d034917..00000000000 --- a/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix label list item container height when there is no label description -merge_request: 21106 -author: -type: fixed diff --git a/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml b/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml new file mode 100644 index 00000000000..38b2486a475 --- /dev/null +++ b/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml @@ -0,0 +1,5 @@ +--- +title: Fix leading slash in redirects and add rubocop cop +merge_request: 21828 +author: Sanad Liaquat +type: fixed diff --git a/changelogs/unreleased/fix-mr-title-fallback-logic.yml b/changelogs/unreleased/fix-mr-title-fallback-logic.yml deleted file mode 100644 index 5056c38573b..00000000000 --- a/changelogs/unreleased/fix-mr-title-fallback-logic.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix fallback logic for automatic MR title assignment -merge_request: 20930 -author: Franz Liedke -type: fixed diff --git a/changelogs/unreleased/fix-namespace-upload.yml b/changelogs/unreleased/fix-namespace-upload.yml deleted file mode 100644 index 383d79a998f..00000000000 --- a/changelogs/unreleased/fix-namespace-upload.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix workhorse temp path for namespace uploads -merge_request: 21650 -author: -type: fixed diff --git a/changelogs/unreleased/fix-namespace-uploader.yml b/changelogs/unreleased/fix-namespace-uploader.yml deleted file mode 100644 index 081adc9a6f1..00000000000 --- a/changelogs/unreleased/fix-namespace-uploader.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix NamespaceUploader.base_dir for remote uploads -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-pipeline-fixture-seeder.yml b/changelogs/unreleased/fix-pipeline-fixture-seeder.yml deleted file mode 100644 index 02b83062e07..00000000000 --- a/changelogs/unreleased/fix-pipeline-fixture-seeder.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix pipeline fixture seeder -merge_request: 21088 -author: -type: fixed diff --git a/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml b/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml deleted file mode 100644 index a9c1b88a61c..00000000000 --- a/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Emojis cutting in the right way -merge_request: -author: Alexander Popov -type: fixed diff --git a/changelogs/unreleased/fix_event_api_permissions.yml b/changelogs/unreleased/fix_event_api_permissions.yml deleted file mode 100644 index dee280e93ad..00000000000 --- a/changelogs/unreleased/fix_event_api_permissions.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Events API now requires the read_user or api scope.' -merge_request: 20627 -author: Warren Parad -type: fixed diff --git a/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml b/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml deleted file mode 100644 index ee197572385..00000000000 --- a/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added atom feed for tags -merge_request: 21428 -author: -type: added diff --git a/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml b/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml deleted file mode 100644 index 8c1f0e3dbf2..00000000000 --- a/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Store wiki uploads inside git repository -merge_request: 21362 -author: -type: added diff --git a/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml b/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml deleted file mode 100644 index ed2af81f779..00000000000 --- a/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed bug when the project logo file is stored in LFS -merge_request: 20948 -author: -type: fixed diff --git a/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml b/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml deleted file mode 100644 index a6464807e01..00000000000 --- a/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Replace white spaces in wiki attachments file names -merge_request: 21569 -author: -type: fixed diff --git a/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml b/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml deleted file mode 100644 index 068681dfe19..00000000000 --- a/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Reduce differences between CE and EE code base in reports components -merge_request: -author: -type: other diff --git a/changelogs/unreleased/frozen-string-enable-app-vestigial.yml b/changelogs/unreleased/frozen-string-app-controller-more.yml index 8cb7bd43784..ea2c81e7afc 100644 --- a/changelogs/unreleased/frozen-string-enable-app-vestigial.yml +++ b/changelogs/unreleased/frozen-string-app-controller-more.yml @@ -1,5 +1,5 @@ --- -title: Enable frozen string in vestigial app files +title: Enable more frozen string in app/controllers/ merge_request: author: gfyoung type: performance diff --git a/changelogs/unreleased/frozen-string-app-controller.yml b/changelogs/unreleased/frozen-string-app-controller.yml new file mode 100644 index 00000000000..95fea4eae63 --- /dev/null +++ b/changelogs/unreleased/frozen-string-app-controller.yml @@ -0,0 +1,5 @@ +--- +title: Enable frozen string in app/controllers/**/*.rb +merge_request: gfyoung +author: +type: performance diff --git a/changelogs/unreleased/frozen-string-app-controllers-much-more.yml b/changelogs/unreleased/frozen-string-app-controllers-much-more.yml new file mode 100644 index 00000000000..6e32d5ba039 --- /dev/null +++ b/changelogs/unreleased/frozen-string-app-controllers-much-more.yml @@ -0,0 +1,5 @@ +--- +title: Enable even more frozen string in app/controllers +merge_request: +author: gfyoung +type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-mailers.yml b/changelogs/unreleased/frozen-string-enable-app-mailers.yml deleted file mode 100644 index 2cd247ca76c..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-mailers.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen in app/mailers/**/*.rb -merge_request: 21147 -author: gfyoung -type: performance diff --git a/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml b/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml deleted file mode 100644 index a77f3baeed3..00000000000 --- a/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enable frozen string in rest of app/models/**/*.rb -merge_request: gfyoung -author: -type: performance diff --git a/changelogs/unreleased/gitaly-install-path.yml b/changelogs/unreleased/gitaly-install-path.yml deleted file mode 100644 index 4b24cd81dc7..00000000000 --- a/changelogs/unreleased/gitaly-install-path.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove storage path dependency of gitaly install task -merge_request: 21101 -author: -type: changed diff --git a/changelogs/unreleased/ide-commit-panel-improved.yml b/changelogs/unreleased/ide-commit-panel-improved.yml deleted file mode 100644 index 245214185e5..00000000000 --- a/changelogs/unreleased/ide-commit-panel-improved.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improved commit panel in Web IDE -merge_request: 21471 -author: -type: changed diff --git a/changelogs/unreleased/ide-delete-new-files-state.yml b/changelogs/unreleased/ide-delete-new-files-state.yml deleted file mode 100644 index 500115d19d0..00000000000 --- a/changelogs/unreleased/ide-delete-new-files-state.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed IDE deleting new files creating wrong state -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/ide-file-templates.yml b/changelogs/unreleased/ide-file-templates.yml deleted file mode 100644 index 68983670b25..00000000000 --- a/changelogs/unreleased/ide-file-templates.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added file templates to the Web IDE -merge_request: -author: -type: added diff --git a/changelogs/unreleased/ide-header-buttons-tooltip.yml b/changelogs/unreleased/ide-header-buttons-tooltip.yml deleted file mode 100644 index 4c8f6fd554f..00000000000 --- a/changelogs/unreleased/ide-header-buttons-tooltip.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added tooltips to tree list header -merge_request: 21138 -author: -type: added diff --git a/changelogs/unreleased/ide-job-top-bar-ui-polish.yml b/changelogs/unreleased/ide-job-top-bar-ui-polish.yml deleted file mode 100644 index d917c14e5f8..00000000000 --- a/changelogs/unreleased/ide-job-top-bar-ui-polish.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improved styling of top bar in IDE job trace pane -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/ide-multiple-file-uploads.yml b/changelogs/unreleased/ide-multiple-file-uploads.yml deleted file mode 100644 index 6bb73739864..00000000000 --- a/changelogs/unreleased/ide-multiple-file-uploads.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Enabled multiple file uploads in the Web IDE -merge_request: -author: -type: added diff --git a/changelogs/unreleased/ide-open-empty-merge-request.yml b/changelogs/unreleased/ide-open-empty-merge-request.yml deleted file mode 100644 index 05f2de5d31c..00000000000 --- a/changelogs/unreleased/ide-open-empty-merge-request.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix empty merge requests not opening in the Web IDE -merge_request: 21102 -author: -type: fixed diff --git a/changelogs/unreleased/ide-row-hover-scroll.yml b/changelogs/unreleased/ide-row-hover-scroll.yml deleted file mode 100644 index 24c273b4f25..00000000000 --- a/changelogs/unreleased/ide-row-hover-scroll.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed IDE file row scrolling into view when hovering -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/import-all-common-metrics-into-database.yml b/changelogs/unreleased/import-all-common-metrics-into-database.yml deleted file mode 100644 index 524112fe115..00000000000 --- a/changelogs/unreleased/import-all-common-metrics-into-database.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Import all common metrics into database -merge_request: 21459 -author: -type: changed diff --git a/changelogs/unreleased/issue_36138.yml b/changelogs/unreleased/issue_36138.yml deleted file mode 100644 index 2fb2eea65f5..00000000000 --- a/changelogs/unreleased/issue_36138.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow to delete group milestones -merge_request: -author: -type: added diff --git a/changelogs/unreleased/issue_50488.yml b/changelogs/unreleased/issue_50488.yml deleted file mode 100644 index dad7ae55a0d..00000000000 --- a/changelogs/unreleased/issue_50488.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Move project services log to a separate file -merge_request: -author: -type: other diff --git a/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml b/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml new file mode 100644 index 00000000000..c21301bf6b3 --- /dev/null +++ b/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml @@ -0,0 +1,5 @@ +--- +title: Fix resizing of monitoring dashboard +merge_request: 21730 +author: +type: fixed diff --git a/changelogs/unreleased/jprovazn-fix-form-uploads.yml b/changelogs/unreleased/jprovazn-fix-form-uploads.yml deleted file mode 100644 index 8bcee335e93..00000000000 --- a/changelogs/unreleased/jprovazn-fix-form-uploads.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Accept upload files in public/uplaods/tmp when using accelerated uploads. -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/label-event.yml b/changelogs/unreleased/label-event.yml deleted file mode 100644 index e543abe5649..00000000000 --- a/changelogs/unreleased/label-event.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Use separate model for tracking resource label changes and render label system - notes based on data from this model. -merge_request: -author: -type: added diff --git a/changelogs/unreleased/leipert-fix-mr-widget-header-margins.yml b/changelogs/unreleased/leipert-fix-mr-widget-header-margins.yml new file mode 100644 index 00000000000..9c23244d48b --- /dev/null +++ b/changelogs/unreleased/leipert-fix-mr-widget-header-margins.yml @@ -0,0 +1,5 @@ +--- +title: Fix merge request header margins +merge_request: 21878 +author: +type: other diff --git a/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml b/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml deleted file mode 100644 index 09d97d200de..00000000000 --- a/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Limit navbar search for current project or group for small viewports -merge_request: 18634 -author: George Tsiolis -type: changed diff --git a/changelogs/unreleased/sh-set-secure-cookies.yml b/changelogs/unreleased/mk-asymmetric-exists-cache.yml index da741288b42..b6eec7d1fc6 100644 --- a/changelogs/unreleased/sh-set-secure-cookies.yml +++ b/changelogs/unreleased/mk-asymmetric-exists-cache.yml @@ -1,5 +1,6 @@ --- -title: Set issuable_sort, diff_view, and perf_bar_enabled cookies to secure when possible -merge_request: 21442 +title: 'Resolve "Geo: Does not mark repositories as missing on primary due to stale + cache"' +merge_request: 21789 author: -type: security +type: fixed diff --git a/changelogs/unreleased/mk-bump-rainbow-gem.yml b/changelogs/unreleased/mk-bump-rainbow-gem.yml deleted file mode 100644 index 31c003fb4d9..00000000000 --- a/changelogs/unreleased/mk-bump-rainbow-gem.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix bin/secpick error and security branch prefixing -merge_request: 21210 -author: -type: fixed diff --git a/changelogs/unreleased/monaco-upgrade.yml b/changelogs/unreleased/monaco-upgrade.yml deleted file mode 100644 index ec441ba182b..00000000000 --- a/changelogs/unreleased/monaco-upgrade.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Upgrade Monaco editor -merge_request: -author: -type: other diff --git a/changelogs/unreleased/more-table-widths.yml b/changelogs/unreleased/more-table-widths.yml new file mode 100644 index 00000000000..61956e7068e --- /dev/null +++ b/changelogs/unreleased/more-table-widths.yml @@ -0,0 +1,5 @@ +--- +title: Adds an extra width to the responsive tables +merge_request: 21928 +author: +type: other diff --git a/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml b/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml deleted file mode 100644 index b8bf8306546..00000000000 --- a/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed resolved discussions not toggling expanded state on changes tab -merge_request: 21676 -author: -type: fixed diff --git a/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml b/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml deleted file mode 100644 index bcf3d2c8e16..00000000000 --- a/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Combines emoji award spec files into single user_interacts_with_awards_in_issue_spec.rb - file -merge_request: 21126 -author: Nate Geslin -type: other diff --git a/changelogs/unreleased/osw-clean-up-phase-for-diff-files-removal.yml b/changelogs/unreleased/osw-clean-up-phase-for-diff-files-removal.yml new file mode 100644 index 00000000000..03189d934a7 --- /dev/null +++ b/changelogs/unreleased/osw-clean-up-phase-for-diff-files-removal.yml @@ -0,0 +1,5 @@ +--- +title: Add clean-up phase for ScheduleDiffFilesDeletion migration +merge_request: 21734 +author: +type: other diff --git a/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml b/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml deleted file mode 100644 index 3c50448e3ff..00000000000 --- a/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Send max_patch_bytes to Gitaly via Gitaly::CommitDiffRequest -merge_request: 21575 -author: -type: other diff --git a/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml b/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml deleted file mode 100644 index 4fba33decfa..00000000000 --- a/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Write diff highlighting cache upon MR creation (refactors caching) -merge_request: 21489 -author: -type: performance diff --git a/changelogs/unreleased/pedroms-master-patch-57786.yml b/changelogs/unreleased/pedroms-master-patch-57786.yml new file mode 100644 index 00000000000..cdf179046aa --- /dev/null +++ b/changelogs/unreleased/pedroms-master-patch-57786.yml @@ -0,0 +1,5 @@ +--- +title: Fix blue, orange, and red color inconsistencies +merge_request: 21972 +author: +type: other diff --git a/changelogs/unreleased/rails5-explicit-hashed-path-check.yml b/changelogs/unreleased/rails5-explicit-hashed-path-check.yml deleted file mode 100644 index 93fe4a38411..00000000000 --- a/changelogs/unreleased/rails5-explicit-hashed-path-check.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Explicit hashed path check for trace, prevents background migration from accessing - file_location column that doesn't exist -merge_request: 21533 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml b/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml deleted file mode 100644 index e31768773b1..00000000000 --- a/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 fix specs duplicate key value violates unique constraint 'index_gpg_signatures_on_commit_sha' -merge_request: 21119 -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 deleted file mode 100644 index 661bd748333..00000000000 --- a/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails5: fix can''t quote ActiveSupport::HashWithIndifferentAccess' -merge_request: 21397 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml b/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml deleted file mode 100644 index a70bfafb1c9..00000000000 --- a/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 'Rails 5: fix hashed_path? method that looks up file_location that doesn''t - exist when running certain migration specs' -merge_request: 21510 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml b/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml deleted file mode 100644 index 2dea84bc266..00000000000 --- a/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails 5: include opclasses in rails 5 schema dump' -merge_request: 21416 -author: Jasper Maes -type: fixed diff --git a/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml b/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml deleted file mode 100644 index c4eb0ddac4c..00000000000 --- a/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails 5: support schema t.index for mysql' -merge_request: 21485 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-silence-stream.yml b/changelogs/unreleased/rails5-silence-stream.yml deleted file mode 100644 index df4fd14a077..00000000000 --- a/changelogs/unreleased/rails5-silence-stream.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails 5: replace removed silence_stream' -merge_request: 21387 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-update-gemfile-lock.yml b/changelogs/unreleased/rails5-update-gemfile-lock.yml deleted file mode 100644 index 3891b16e2b8..00000000000 --- a/changelogs/unreleased/rails5-update-gemfile-lock.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rails5 update Gemfile.rails5.lock -merge_request: 21388 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rails5-verbose-query-logs.yml b/changelogs/unreleased/rails5-verbose-query-logs.yml deleted file mode 100644 index 7585e75d30b..00000000000 --- a/changelogs/unreleased/rails5-verbose-query-logs.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Rails5: Enable verbose query logs' -merge_request: 21231 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml b/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml deleted file mode 100644 index f464b6dda5b..00000000000 --- a/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow admins to configure the maximum Git push size -merge_request: 20758 -author: -type: added diff --git a/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml b/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml deleted file mode 100644 index 429ab6c59e3..00000000000 --- a/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove health check feature flag in BackgroundMigrationWorker -merge_request: -author: -type: changed diff --git a/changelogs/unreleased/remove-zebra-table-background.yml b/changelogs/unreleased/remove-zebra-table-background.yml deleted file mode 100644 index dafba72035d..00000000000 --- a/changelogs/unreleased/remove-zebra-table-background.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove striped table styling of Find files and Admin Area Applications views -merge_request: 21560 -author: Andreas Kämmerle -type: other diff --git a/changelogs/unreleased/rename-local-variable.yml b/changelogs/unreleased/rename-local-variable.yml new file mode 100644 index 00000000000..70281dfef08 --- /dev/null +++ b/changelogs/unreleased/rename-local-variable.yml @@ -0,0 +1,5 @@ +--- +title: Rename block scope local variable in table pagination spec +merge_request: 21969 +author: George Tsiolis +type: other diff --git a/changelogs/unreleased/rename-squash-before-merge-vue-component.yml b/changelogs/unreleased/rename-squash-before-merge-vue-component.yml new file mode 100644 index 00000000000..66eeeb225dd --- /dev/null +++ b/changelogs/unreleased/rename-squash-before-merge-vue-component.yml @@ -0,0 +1,5 @@ +--- +title: Rename squash before merge vue component +merge_request: 21851 +author: George Tsiolis +type: other diff --git a/changelogs/unreleased/repopulate_site_statistics.yml b/changelogs/unreleased/repopulate_site_statistics.yml deleted file mode 100644 index 1961088061d..00000000000 --- a/changelogs/unreleased/repopulate_site_statistics.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Migrate NULL wiki_access_level to correct number so we count active wikis correctly -merge_request: 21030 -author: -type: changed diff --git a/changelogs/unreleased/runners-online.yml b/changelogs/unreleased/runners-online.yml deleted file mode 100644 index a732d9cb723..00000000000 --- a/changelogs/unreleased/runners-online.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Clarify current runners online text -merge_request: 21151 -author: Ben Bodenmiller -type: other diff --git a/changelogs/unreleased/schema-changed-ee-backport.yml b/changelogs/unreleased/schema-changed-ee-backport.yml deleted file mode 100644 index f3b16fc0c27..00000000000 --- a/changelogs/unreleased/schema-changed-ee-backport.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Backport schema_changed.sh from EE which prints the diff if the schema is different -merge_request: 21422 -author: Jasper Maes -type: other diff --git a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml deleted file mode 100644 index dc15d356c1c..00000000000 --- a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed persistent XSS rendering/escaping of diff location lines -merge_request: -author: -type: security diff --git a/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml b/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml deleted file mode 100644 index eec55bd3a24..00000000000 --- a/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add User-Agent to production_json.log -merge_request: 21546 -author: -type: other diff --git a/changelogs/unreleased/sh-block-link-local-master.yml b/changelogs/unreleased/sh-block-link-local-master.yml deleted file mode 100644 index 0a6017479af..00000000000 --- a/changelogs/unreleased/sh-block-link-local-master.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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 deleted file mode 100644 index b5fa55e53a5..00000000000 --- a/changelogs/unreleased/sh-bump-fog-google.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -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-gitlab-pages-v1-1-0.yml b/changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml deleted file mode 100644 index bc5b6b36ac5..00000000000 --- a/changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump GitLab Pages to v1.1.0 -merge_request: 21419 -author: -type: fixed diff --git a/changelogs/unreleased/sh-bump-unauth-expiration.yml b/changelogs/unreleased/sh-bump-unauth-expiration.yml deleted file mode 100644 index 107069f3b30..00000000000 --- a/changelogs/unreleased/sh-bump-unauth-expiration.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Bump unauthenticated session time from 1 hour to 2 hours -merge_request: 21453 -author: -type: other diff --git a/changelogs/unreleased/sh-delete-container-registry-async.yml b/changelogs/unreleased/sh-delete-container-registry-async.yml deleted file mode 100644 index dfe0e812112..00000000000 --- a/changelogs/unreleased/sh-delete-container-registry-async.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Delete a container registry asynchronously -merge_request: 21553 -author: -type: fixed diff --git a/changelogs/unreleased/sh-disable-sidekiq-session.yml b/changelogs/unreleased/sh-disable-sidekiq-session.yml deleted file mode 100644 index d018bbed841..00000000000 --- a/changelogs/unreleased/sh-disable-sidekiq-session.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable the Sidekiq Admin Rack session -merge_request: 21441 -author: -type: security diff --git a/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml b/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml deleted file mode 100644 index 386410484fe..00000000000 --- a/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable project avatar validation if avatar has not changed -merge_request: -author: -type: performance diff --git a/changelogs/unreleased/sh-fix-attachments-inline.yml b/changelogs/unreleased/sh-fix-attachments-inline.yml deleted file mode 100644 index 2926edca97a..00000000000 --- a/changelogs/unreleased/sh-fix-attachments-inline.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix attachments not displaying inline with Google Cloud Storage -merge_request: 21265 -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml b/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml deleted file mode 100644 index 3f7044833f1..00000000000 --- a/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Bitbucket Cloud importer omitting replies -merge_request: 21076 -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-confidential-note-option.yml b/changelogs/unreleased/sh-fix-confidential-note-option.yml deleted file mode 100644 index 14d70281760..00000000000 --- a/changelogs/unreleased/sh-fix-confidential-note-option.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix "Confidential comments" button not saving in project hooks -merge_request: 21289 -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-dedupe-group-importer.yml b/changelogs/unreleased/sh-fix-dedupe-group-importer.yml deleted file mode 100644 index 1b874c64718..00000000000 --- a/changelogs/unreleased/sh-fix-dedupe-group-importer.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix importers not assigning a new default group -merge_request: 21456 -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml b/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml deleted file mode 100644 index d80d4952ba5..00000000000 --- a/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix Error 500s due to encoding issues when Wiki hooks fire -merge_request: 21414 -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-issue-50562.yml b/changelogs/unreleased/sh-fix-issue-50562.yml deleted file mode 100644 index a207dd28622..00000000000 --- a/changelogs/unreleased/sh-fix-issue-50562.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix remote mirrors failing if Git remotes have not been added -merge_request: 21351 -author: -type: fixed diff --git a/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml b/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml new file mode 100644 index 00000000000..7233f6f3d7b --- /dev/null +++ b/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml @@ -0,0 +1,5 @@ +--- +title: Guard against a login attempt with invalid CSRF token +merge_request: 21934 +author: +type: fixed diff --git a/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml b/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml deleted file mode 100644 index c94ff959f1c..00000000000 --- a/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add JSON logging for Bitbucket Server importer -merge_request: 21378 -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 deleted file mode 100644 index 116929b2f53..00000000000 --- a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Bitbucket Server importer: Eliminate most idle-in-transaction issues' -merge_request: -author: -type: performance diff --git a/changelogs/unreleased/sh-limit-commit-renderering.yml b/changelogs/unreleased/sh-limit-commit-renderering.yml deleted file mode 100644 index c44c67bcc90..00000000000 --- a/changelogs/unreleased/sh-limit-commit-renderering.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Speed up diff comparisons by limiting number of commit messages rendered -merge_request: 21335 -author: -type: performance diff --git a/changelogs/unreleased/sh-remove-orphaned-label-links.yml b/changelogs/unreleased/sh-remove-orphaned-label-links.yml deleted file mode 100644 index b035b57ff1b..00000000000 --- a/changelogs/unreleased/sh-remove-orphaned-label-links.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Remove orphaned label links -merge_request: 21552 -author: -type: fixed diff --git a/changelogs/unreleased/sh-sanitize-project-import-names.yml b/changelogs/unreleased/sh-sanitize-project-import-names.yml deleted file mode 100644 index 6e0284bda08..00000000000 --- a/changelogs/unreleased/sh-sanitize-project-import-names.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use slugs for default project path and sanitize names before import -merge_request: 21367 -author: -type: fixed diff --git a/changelogs/unreleased/sh-send-put-headers-object-storage.yml b/changelogs/unreleased/sh-send-put-headers-object-storage.yml deleted file mode 100644 index cbd8b6deb5b..00000000000 --- a/changelogs/unreleased/sh-send-put-headers-object-storage.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Send back required object storage PUT headers in /uploads/authorize API -merge_request: 21319 -author: -type: changed diff --git a/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml b/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml deleted file mode 100644 index 56d236d0029..00000000000 --- a/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Ignore irrelevant sql commands in metrics -merge_request: 21498 -author: -type: other diff --git a/changelogs/unreleased/tc-api-fork-owners.yml b/changelogs/unreleased/tc-api-fork-owners.yml deleted file mode 100644 index feaa3c1705e..00000000000 --- a/changelogs/unreleased/tc-api-fork-owners.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow project owners to set up forking relation through API -merge_request: 18104 -author: -type: changed diff --git a/changelogs/unreleased/toon-copy-meta-data-fix.yml b/changelogs/unreleased/toon-copy-meta-data-fix.yml new file mode 100644 index 00000000000..f2f8a1a82a4 --- /dev/null +++ b/changelogs/unreleased/toon-copy-meta-data-fix.yml @@ -0,0 +1,5 @@ +--- +title: Allow /copy_metadata for new issues and MRs +merge_request: 21953 +author: +type: changed diff --git a/changelogs/unreleased/tz-mr-incremental-rendering.yml b/changelogs/unreleased/tz-mr-incremental-rendering.yml deleted file mode 100644 index a35fa200363..00000000000 --- a/changelogs/unreleased/tz-mr-incremental-rendering.yml +++ /dev/null @@ -1,4 +0,0 @@ -title: Incremental rendering with Vue on merge request page -merge_request: 21063 -author: -type: performance diff --git a/changelogs/unreleased/update-gitlab-shell-8-3-3.yml b/changelogs/unreleased/update-gitlab-shell-8-3-3.yml deleted file mode 100644 index 3f9cca59528..00000000000 --- a/changelogs/unreleased/update-gitlab-shell-8-3-3.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update GitLab Shell to v8.3.3 -merge_request: 21750 -author: -type: fixed diff --git a/changelogs/unreleased/update-gitlab-shell.yml b/changelogs/unreleased/update-gitlab-shell.yml deleted file mode 100644 index f5d0e30a7be..00000000000 --- a/changelogs/unreleased/update-gitlab-shell.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update GitLab Shell to v8.3.2 -merge_request: 21701 -author: -type: fixed diff --git a/changelogs/unreleased/update-padding-markdown.yml b/changelogs/unreleased/update-padding-markdown.yml deleted file mode 100644 index 51037200bd1..00000000000 --- a/changelogs/unreleased/update-padding-markdown.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Increase padding in code blocks -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/usage_consent.yml b/changelogs/unreleased/usage_consent.yml deleted file mode 100644 index 56e00879b9a..00000000000 --- a/changelogs/unreleased/usage_consent.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Ask user explicitly about usage stats agreement on single user deployments. -merge_request: 21423 -author: -type: added diff --git a/changelogs/unreleased/visual-improvements-language-bar.yml b/changelogs/unreleased/visual-improvements-language-bar.yml deleted file mode 100644 index 23cae22b962..00000000000 --- a/changelogs/unreleased/visual-improvements-language-bar.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve visuals of language bar on projects -merge_request: 21006 -author: -type: changed diff --git a/changelogs/unreleased/winh-default-status-emoji.yml b/changelogs/unreleased/winh-default-status-emoji.yml deleted file mode 100644 index 00cca4db0a6..00000000000 --- a/changelogs/unreleased/winh-default-status-emoji.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Display default status emoji if only message is entered -merge_request: 21330 -author: -type: changed diff --git a/changelogs/unreleased/winh-move-badge-settings.yml b/changelogs/unreleased/winh-move-badge-settings.yml deleted file mode 100644 index 9638ba04c1e..00000000000 --- a/changelogs/unreleased/winh-move-badge-settings.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Move badge settings to general settings -merge_request: 21333 -author: -type: changed diff --git a/changelogs/unreleased/winh-page-title-margin.yml b/changelogs/unreleased/winh-page-title-margin.yml new file mode 100644 index 00000000000..f21f07d396b --- /dev/null +++ b/changelogs/unreleased/winh-page-title-margin.yml @@ -0,0 +1,5 @@ +--- +title: Change vertical margin of page titles to 16px +merge_request: 21888 +author: +type: changed diff --git a/changelogs/unreleased/zj-cleanup-port-gitaly.yml b/changelogs/unreleased/zj-cleanup-port-gitaly.yml deleted file mode 100644 index 25e13b0fd50..00000000000 --- a/changelogs/unreleased/zj-cleanup-port-gitaly.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Administrative cleanup rake tasks now leverage Gitaly -merge_request: 21588 -author: -type: changed diff --git a/config/application.rb b/config/application.rb index 79fdd8a1a63..9074cf02c46 100644 --- a/config/application.rb +++ b/config/application.rb @@ -205,7 +205,7 @@ module Gitlab ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH'] ENV['GIT_TERMINAL_PROMPT'] = '0' - # Gitlab Read-only middleware support + # GitLab Read-only middleware support config.middleware.insert_after ActionDispatch::Flash, ::Gitlab::Middleware::ReadOnly config.generators do |g| diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 476eaabfed8..6c1079faad1 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -55,8 +55,6 @@ Sidekiq.configure_server do |config| end Sidekiq::Cron::Job.load_from_hash! cron_jobs - Gitlab::SidekiqThrottler.execute! - Gitlab::SidekiqVersioning.install! config = Gitlab::Database.config || diff --git a/config/initializers/warden.rb b/config/initializers/warden.rb index 33f55069c3e..1d2bb2bce0a 100644 --- a/config/initializers/warden.rb +++ b/config/initializers/warden.rb @@ -31,6 +31,11 @@ Rails.application.configure do |config| Warden::Manager.before_logout(scope: :user) do |user, auth, opts| user ||= auth.user + + # Rails CSRF protection may attempt to log out a user before that + # user even logs in + next unless user + activity = Gitlab::Auth::Activity.new(opts) tracker = Gitlab::Auth::BlockedUserTracker.new(user, auth) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index fa1f79a90be..7489b01ded6 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -110,6 +110,7 @@ namespace :admin do put :reset_runners_token put :reset_health_check_token put :clear_repository_check_states + get :integrations, :repository, :templates, :ci_cd, :reporting, :metrics_and_profiling, :network, :geo, :preferences end resources :labels diff --git a/config/routes/instance_statistics.rb b/config/routes/instance_statistics.rb index 824ef47cda3..1102ef6b017 100644 --- a/config/routes/instance_statistics.rb +++ b/config/routes/instance_statistics.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true namespace :instance_statistics do - root to: redirect('/-/instance_statistics/conversational_development_index') + root to: redirect('-/instance_statistics/conversational_development_index') resources :cohorts, only: :index resources :conversational_development_index, only: :index diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb index cd3828b743c..1a07b1c206b 100644 --- a/config/routes/wiki.rb +++ b/config/routes/wiki.rb @@ -2,7 +2,7 @@ scope(controller: :wikis) do scope(path: 'wikis', as: :wikis) do get :git_access get :pages - get '/', to: redirect('/%{namespace_id}/%{project_id}/wikis/home') + get '/', to: redirect('%{namespace_id}/%{project_id}/wikis/home') post '/', to: 'wikis#create' end diff --git a/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb b/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb new file mode 100644 index 00000000000..ed9422a3894 --- /dev/null +++ b/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class ConsumeRemainingDiffFilesDeletionJobs < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + MIGRATION = 'ScheduleDiffFilesDeletion'.freeze + TMP_INDEX = 'tmp_partial_diff_id_with_files_index'.freeze + + def up + # Perform any ongoing background migration that might still be scheduled. + Gitlab::BackgroundMigration.steal(MIGRATION) + + remove_concurrent_index_by_name(:merge_request_diffs, TMP_INDEX) + end + + def down + add_concurrent_index(:merge_request_diffs, :id, where: "(state NOT IN ('without_files', 'empty'))", name: TMP_INDEX) + end +end diff --git a/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb b/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb new file mode 100644 index 00000000000..b3ed0d3f1e9 --- /dev/null +++ b/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class RemoveSidekiqThrottlingFromApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + remove_column :application_settings, :sidekiq_throttling_enabled, :boolean, default: false + remove_column :application_settings, :sidekiq_throttling_queues, :string + remove_column :application_settings, :sidekiq_throttling_factor, :decimal + + Rails.cache.delete("ApplicationSetting:#{Gitlab::VERSION}:#{Rails.version}") + end +end diff --git a/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb b/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb new file mode 100644 index 00000000000..0a39abe3bdf --- /dev/null +++ b/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +class RemoveWikisCountFromSiteStatistics < ActiveRecord::Migration + def change + remove_column :site_statistics, :wikis_count, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index b299cde4898..f92d8005dfb 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: 20180907015926) do +ActiveRecord::Schema.define(version: 20180917172041) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -119,9 +119,6 @@ ActiveRecord::Schema.define(version: 20180907015926) do t.integer "housekeeping_incremental_repack_period", default: 10, null: false t.integer "housekeeping_full_repack_period", default: 50, null: false t.integer "housekeeping_gc_period", default: 200, null: false - t.boolean "sidekiq_throttling_enabled", default: false - t.string "sidekiq_throttling_queues" - t.decimal "sidekiq_throttling_factor" t.boolean "html_emails_enabled", default: true t.string "plantuml_url" t.boolean "plantuml_enabled" @@ -1911,7 +1908,6 @@ ActiveRecord::Schema.define(version: 20180907015926) do create_table "site_statistics", force: :cascade do |t| t.integer "repositories_count", default: 0, null: false - t.integer "wikis_count", default: 0, null: false end create_table "snippets", force: :cascade do |t| diff --git a/doc/README.md b/doc/README.md index 4248f62c08c..7548240bfef 100644 --- a/doc/README.md +++ b/doc/README.md @@ -191,7 +191,7 @@ instant how code changes impact your production environment. ### User account - [User account](user/profile/index.md): Manage your account - - [Authentication](topics/authentication/index.md): Account security with two-factor authentication, setup your ssh keys and deploy keys for secure access to your projects. + - [Authentication](topics/authentication/index.md): Account security with two-factor authentication, set up your ssh keys and deploy keys for secure access to your projects. - [Profile settings](user/profile/index.md#profile-settings): Manage your profile settings, two factor authentication and more. - [User permissions](user/permissions.md): Learn what each role in a project (external/guest/reporter/developer/maintainer/owner) can do. diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md index 5c7392b99d0..54ded25291a 100644 --- a/doc/administration/auth/ldap.md +++ b/doc/administration/auth/ldap.md @@ -111,7 +111,7 @@ main: uid: 'sAMAccountName' # This should be the attribute, not the value that maps to uid. ## - ## Examples: 'america\\momo' or 'CN=Gitlab Git,CN=Users,DC=mydomain,DC=com' + ## Examples: 'america\momo' or 'CN=Gitlab Git,CN=Users,DC=mydomain,DC=com' ## bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' password: '_the_password_of_the_bind_user' @@ -132,7 +132,7 @@ main: ## Enables SSL certificate verification if encryption method is ## "start_tls" or "simple_tls". Defaults to true since GitLab 10.0 for ## security. This may break installations upon upgrade to 10.0, that did - ## not know their LDAP SSL certificates were not setup properly. + ## not know their LDAP SSL certificates were not set up properly. ## verify_certificates: true diff --git a/doc/administration/external_database.md b/doc/administration/external_database.md index 31199f2cdc7..ec2d30c82d1 100644 --- a/doc/administration/external_database.md +++ b/doc/administration/external_database.md @@ -9,7 +9,7 @@ separate from the GitLab Omnibus package. If you use a cloud-managed service, or provide your own PostgreSQL instance: -1. Setup PostgreSQL according to the +1. Set up PostgreSQL according to the [database requirements document](../install/requirements.md#database). 1. Set up a `gitlab` username with a password of your choice. The `gitlab` user needs privileges to create the `gitlabhq_production` database. diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md index 964758837e5..b5e2b5448f7 100644 --- a/doc/administration/gitaly/index.md +++ b/doc/administration/gitaly/index.md @@ -101,6 +101,12 @@ documentation on configuring Gitaly authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication) . +Gitaly must trigger some callbacks to GitLab via GitLab Shell. As a result, +the GitLab Shell secret must be the same between the other GitLab servers and +the Gitaly server. The easiest way to accomplish this is to copy `/etc/gitlab/gitlab-secrets.json` +from an existing GitLab server to the Gitaly server. Without this shared secret, +Git operations in GitLab will result in an API error. + > **NOTE:** In most or all cases the storage paths below end in `/repositories` which is different than `path` in `git_data_dirs` of Omnibus installations. Check the directory layout on your Gitaly server to be sure. @@ -213,7 +219,7 @@ repository from your GitLab server over HTTP. If you are running Gitaly [as a remote service](#running-gitaly-on-its-own-server) you may want to disable -the local Gitaly service that runs on your Gitlab server by default. +the local Gitaly service that runs on your GitLab server by default. > 'Disabling Gitaly' only makes sense when you run GitLab in a custom cluster configuration, where different services run on different diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md index b5124b1d540..c1eeb40b98f 100644 --- a/doc/administration/high_availability/database.md +++ b/doc/administration/high_availability/database.md @@ -13,7 +13,7 @@ Database Service (RDS) that runs PostgreSQL. If you use a cloud-managed service, or provide your own PostgreSQL: -1. Setup PostgreSQL according to the +1. Set up PostgreSQL according to the [database requirements document](../../install/requirements.md#database). 1. Set up a `gitlab` username with a password of your choice. The `gitlab` user needs privileges to create the `gitlabhq_production` database. diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md index e05bebbef18..b5d1ff698c6 100644 --- a/doc/administration/high_availability/redis.md +++ b/doc/administration/high_availability/redis.md @@ -81,7 +81,7 @@ When a **Master** fails to respond, it's the application's responsibility (in our case GitLab) to handle timeout and reconnect (querying a **Sentinel** for a new **Master**). -To get a better understanding on how to correctly setup Sentinel, please read +To get a better understanding on how to correctly set up Sentinel, please read the [Redis Sentinel documentation](http://redis.io/topics/sentinel) first, as failing to configure it correctly can lead to data loss or can bring your whole cluster down, invalidating the failover effort. @@ -217,7 +217,7 @@ Pick the one that suits your needs. and configure Sentinel, jump directly to the Sentinel section in the [Redis HA installation from source](redis_source.md#step-3-configuring-the-redis-sentinel-instances) documentation. - [Omnibus GitLab **Enterprise Edition** (EE) package][ee]: Both Redis and Sentinel - are bundled in the package, so you can use the EE package to setup the whole + are bundled in the package, so you can use the EE package to set up the whole Redis HA infrastructure (master, slave and Sentinel) which is described in this document. - If you have installed GitLab using the Omnibus GitLab packages (CE or EE), @@ -228,7 +228,7 @@ Pick the one that suits your needs. ## Configuring Redis HA -This is the section where we install and setup the new Redis instances. +This is the section where we install and set up the new Redis instances. > **Notes:** > - We assume that you have installed GitLab and all HA components from scratch. If you @@ -370,7 +370,7 @@ You must have at least `3` Redis Sentinel servers, and they need to be each in an independent machine. You can configure them in the same machines where you've configured the other Redis servers. -With GitLab Enterprise Edition, you can use the Omnibus package to setup +With GitLab Enterprise Edition, you can use the Omnibus package to set up multiple machines with the Sentinel daemon. --- @@ -535,7 +535,7 @@ In this example we consider that all servers have an internal network interface with IPs in the `10.0.0.x` range, and that they can connect to each other using these IPs. -In a real world usage, you would also setup firewall rules to prevent +In a real world usage, you would also set up firewall rules to prevent unauthorized access from other machines and block traffic from the outside (Internet). diff --git a/doc/administration/high_availability/redis_source.md b/doc/administration/high_availability/redis_source.md index 8b7a515a076..5823c575251 100644 --- a/doc/administration/high_availability/redis_source.md +++ b/doc/administration/high_availability/redis_source.md @@ -24,7 +24,7 @@ the Omnibus Redis HA documentation. ## Configuring your own Redis server -This is the section where we install and setup the new Redis instances. +This is the section where we install and set up the new Redis instances. ### Prerequisites @@ -204,7 +204,7 @@ In this example we consider that all servers have an internal network interface with IPs in the `10.0.0.x` range, and that they can connect to each other using these IPs. -In a real world usage, you would also setup firewall rules to prevent +In a real world usage, you would also set up firewall rules to prevent unauthorized access from other machines, and block traffic from the outside ([Internet][it]). diff --git a/doc/administration/index.md b/doc/administration/index.md index 8b6a42b0ca5..702d8e554a8 100644 --- a/doc/administration/index.md +++ b/doc/administration/index.md @@ -60,7 +60,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. - [Raketasks](../raketasks/README.md): Perform various tasks for maintenance, backups, automatic webhooks setup, etc. - [Backup and restore](../raketasks/backup_restore.md): Backup and restore your GitLab instance. -- [Operations](operations/index.md): Keeping GitLab up and running (clean up Redis sessions, moving repositories, Sidekiq Job throttling, Sidekiq MemoryKiller, Unicorn). +- [Operations](operations/index.md): Keeping GitLab up and running (clean up Redis sessions, moving repositories, Sidekiq MemoryKiller, Unicorn). - [Restart GitLab](restart_gitlab.md): Learn how to restart GitLab and its components. #### Updating GitLab diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md index 1f3bc611cdf..757865ea2c5 100644 --- a/doc/administration/job_artifacts.md +++ b/doc/administration/job_artifacts.md @@ -127,6 +127,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a | `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com | | `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) | | `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false | +| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false **In Omnibus installations:** diff --git a/doc/administration/logs.md b/doc/administration/logs.md index 98134075b94..a8cdd20581d 100644 --- a/doc/administration/logs.md +++ b/doc/administration/logs.md @@ -13,7 +13,7 @@ This guide talks about how to read and use these system log files. This file lives in `/var/log/gitlab/gitlab-rails/production_json.log` for Omnibus GitLab packages or in `/home/git/gitlab/log/production_json.log` for -installations from source. (When Gitlab is running in an environment +installations from source. (When GitLab is running in an environment other than production, the corresponding logfile is shown here.) It contains a structured log for Rails controller requests received from @@ -42,7 +42,7 @@ In addition, the log contains the IP address from which the request originated This file lives in `/var/log/gitlab/gitlab-rails/production.log` for Omnibus GitLab packages or in `/home/git/gitlab/log/production.log` for -installations from source. (When Gitlab is running in an environment +installations from source. (When GitLab is running in an environment other than production, the corresponding logfile is shown here.) It contains information about all performed requests. You can see the @@ -187,7 +187,7 @@ This file lives in `/var/log/gitlab/gitlab-shell/gitlab-shell.log` for Omnibus GitLab packages or in `/home/git/gitlab-shell/gitlab-shell.log` for installations from source. -GitLab shell is used by Gitlab for executing Git commands and provide +GitLab shell is used by GitLab for executing Git commands and provide SSH access to Git repositories. For example: ``` diff --git a/doc/administration/operations/img/sidekiq_job_throttling.png b/doc/administration/operations/img/sidekiq_job_throttling.png Binary files differdeleted file mode 100644 index abd09f3b115..00000000000 --- a/doc/administration/operations/img/sidekiq_job_throttling.png +++ /dev/null diff --git a/doc/administration/operations/index.md b/doc/administration/operations/index.md index e9cad99c4b0..dea98cb8197 100644 --- a/doc/administration/operations/index.md +++ b/doc/administration/operations/index.md @@ -9,8 +9,6 @@ GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis database after you upgrade to GitLab 7.3. - [Moving repositories](moving_repositories.md): Moving all repositories managed by GitLab to another file system or another server. -- [Sidekiq job throttling](sidekiq_job_throttling.md): Throttle Sidekiq queues -that to prioritize important jobs. - [Sidekiq MemoryKiller](sidekiq_memory_killer.md): Configure Sidekiq MemoryKiller to restart Sidekiq. - [Unicorn](unicorn.md): Understand Unicorn and unicorn-worker-killer. diff --git a/doc/administration/operations/sidekiq_job_throttling.md b/doc/administration/operations/sidekiq_job_throttling.md deleted file mode 100644 index ddeaa22e288..00000000000 --- a/doc/administration/operations/sidekiq_job_throttling.md +++ /dev/null @@ -1,33 +0,0 @@ -# Sidekiq Job throttling - -> Note: Introduced with GitLab 8.14 - -When your GitLab installation needs to handle tens of thousands of background -jobs, it can be convenient to throttle queues that do not need to be executed -immediately, e.g. long running jobs like Pipelines, thus allowing jobs that do -need to be executed immediately to have access to more resources. - -In order to accomplish this, you can limit the amount of workers that certain -slow running queues can have available. This is what we call Sidekiq Job -Throttling. Depending on your infrastructure, you might have different slow -running queues, which is why you can choose which queues you want to throttle -and by how much you want to throttle them. - -These settings are available in the Application Settings of your GitLab -installation. - - - -The throttle factor determines the maximum number of workers a queue can run on. -This value gets multiplied by `:concurrency` value set in the Sidekiq settings -and rounded up to the closest full integer. - -So, for example, you set the `:concurrency` to 25 and the `Throttling factor` to -0.1, the maximum workers assigned to the selected queues would be 3. - -```ruby -queue_limit = (factor * Sidekiq.options[:concurrency]).ceil -``` - -After enabling the job throttling, you will need to restart your GitLab -instance, in order for the changes to take effect.
\ No newline at end of file diff --git a/doc/administration/operations/ssh_certificates.md b/doc/administration/operations/ssh_certificates.md index 9edccd25ced..b00301fec1c 100644 --- a/doc/administration/operations/ssh_certificates.md +++ b/doc/administration/operations/ssh_certificates.md @@ -31,7 +31,7 @@ uploading user SSH keys to GitLab entirely. ## Setting up SSH certificate lookup via GitLab Shell -How to fully setup SSH certificates is outside the scope of this +How to fully set up SSH certificates is outside the scope of this document. See [OpenSSH's PROTOCOL.certkeys](https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD) for how it works, and e.g. [RedHat's documentation about @@ -132,7 +132,7 @@ message about this being an invalid user. ## Interaction with the `authorized_keys` file SSH certificates can be used in conjunction with the `authorized_keys` -file, and if setup as configured above the `authorized_keys` file will +file, and if set up as configured above the `authorized_keys` file will still serve as a fallback. This is because if the `AuthorizedPrincipalsCommand` can't diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index 2b4252a7b1d..29af07d12dc 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -56,11 +56,11 @@ Runs the following rake tasks: - `gitlab:sidekiq:check` - `gitlab:app:check` -It will check that each component was setup according to the installation guide and suggest fixes for issues found. +It will check that each component was set up according to the installation guide and suggest fixes for issues found. -You may also have a look at our Trouble Shooting Guides: -- [Trouble Shooting Guide (GitLab)](http://docs.gitlab.com/ee/README.html#troubleshooting) -- [Trouble Shooting Guide (Omnibus Gitlab)](http://docs.gitlab.com/omnibus/README.html#troubleshooting) +You may also have a look at our Troubleshooting Guides: +- [Troubleshooting Guide (GitLab)](http://docs.gitlab.com/ee/README.html#troubleshooting) +- [Troubleshooting Guide (Omnibus Gitlab)](http://docs.gitlab.com/omnibus/README.html#troubleshooting) **Omnibus Installation** diff --git a/doc/administration/reply_by_email.md b/doc/administration/reply_by_email.md index 426245c7aca..6d7069dd461 100644 --- a/doc/administration/reply_by_email.md +++ b/doc/administration/reply_by_email.md @@ -5,7 +5,7 @@ replying to notification emails. ## Requirement -Make sure [incoming email](incoming_email.md) is setup. +Make sure [incoming email](incoming_email.md) is set up. ## How it works? diff --git a/doc/administration/reply_by_email_postfix_setup.md b/doc/administration/reply_by_email_postfix_setup.md index 3e8b78e56d5..d1a03219542 100644 --- a/doc/administration/reply_by_email_postfix_setup.md +++ b/doc/administration/reply_by_email_postfix_setup.md @@ -245,7 +245,7 @@ Courier, which we will install later to add IMAP authentication, requires mailbo 220 gitlab.example.com ESMTP Postfix (Ubuntu) ``` - If you get a `Connection refused` error instead, make sure your firewall is setup to allow inbound traffic on port 25. + If you get a `Connection refused` error instead, make sure your firewall is set up to allow inbound traffic on port 25. 1. Send the `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt: diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md index efeec9db517..715bc0cd08c 100644 --- a/doc/administration/repository_checks.md +++ b/doc/administration/repository_checks.md @@ -18,7 +18,8 @@ repositories and wiki repositories in order to detect data corruption. A project will be checked no more than once per month. If any projects fail their repository checks all GitLab administrators will receive an email notification of the situation. This notification is sent out once a week, -by default, midnight at the start of Sunday. +by default, midnight at the start of Sunday. Repositories with known check +failures can be found at `/admin/projects?last_repository_check_failed=1`. ## Disabling periodic checks diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md index 467deb43644..aec9a359ada 100644 --- a/doc/administration/uploads.md +++ b/doc/administration/uploads.md @@ -18,7 +18,7 @@ below. >**Notes:** For historical reasons, uploads are stored into a base directory, which by default is `uploads/-/system`. It is strongly discouraged to change this configuration option on an existing GitLab installation. -_The uploads are stored by default in `/var/opt/gitlab/gitlab-rails/public/uploads/-/system`._ +_The uploads are stored by default in `/var/opt/gitlab/gitlab-rails/uploads/-/system`._ 1. To change the storage path for example to `/mnt/storage/uploads`, edit `/etc/gitlab/gitlab.rb` and add the following line: @@ -86,6 +86,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a | `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com | | `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) | | `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false | +| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false **In Omnibus installations:** diff --git a/doc/api/commits.md b/doc/api/commits.md index 624ed529009..5ff1e1f60e0 100644 --- a/doc/api/commits.md +++ b/doc/api/commits.md @@ -83,12 +83,13 @@ POST /projects/:id/repository/commits | `actions[]` Attribute | Type | Required | Description | | --------------------- | ---- | -------- | ----------- | -| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update` | +| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update`, `chmod`| | `file_path` | string | yes | Full path to the file. Ex. `lib/class.rb` | -| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb` | -| `content` | string | no | File content, required for all except `delete`. Optional for `move` | +| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb`. Only considered for `move` action. | +| `content` | string | no | File content, required for all except `delete` and `chmod`. Optional for `move` | | `encoding` | string | no | `text` or `base64`. `text` is default. | | `last_commit_id` | string | no | Last known file commit id. Will be only considered in update, move and delete actions. | +| `execute_filemode` | boolean | no | When `true/false` enables/disables the execute flag on the file. Only considered for `chmod` action. | ```bash PAYLOAD=$(cat << 'JSON' @@ -115,6 +116,11 @@ PAYLOAD=$(cat << 'JSON' "action": "update", "file_path": "foo/bar5", "content": "new content" + }, + { + "action": "chmod", + "file_path": "foo/bar5", + "execute_filemode": true } ] } diff --git a/doc/api/deployments.md b/doc/api/deployments.md index fd11894ea8f..1963b0a21de 100644 --- a/doc/api/deployments.md +++ b/doc/api/deployments.md @@ -46,19 +46,21 @@ Example of response "status": "success", "tag": false, "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "http://gitlab.dev/root", + "created_at": "2015-12-21T13:14:24.077Z", "bio": null, - "created_at": "2016-08-11T07:09:20.351Z", - "id": 1, - "linkedin": "", "location": null, - "name": "Administrator", + "public_email": "", "skype": "", - "state": "active", + "linkedin": "", "twitter": "", - "username": "root", - "web_url": "http://localhost:3000/root", - "website_url": "" + "website_url": "", + "organization": "" } }, "environment": { @@ -103,19 +105,21 @@ Example of response "status": "success", "tag": false, "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "http://gitlab.dev/root", + "created_at": "2015-12-21T13:14:24.077Z", "bio": null, - "created_at": "2016-08-11T07:09:20.351Z", - "id": 1, - "linkedin": "", "location": null, - "name": "Administrator", + "public_email": "", "skype": "", - "state": "active", + "linkedin": "", "twitter": "", - "username": "root", - "web_url": "http://localhost:3000/root", - "website_url": "" + "website_url": "", + "organization": "" } }, "environment": { @@ -188,19 +192,20 @@ Example of response "started_at": null, "finished_at": "2016-08-11T11:32:35.145Z", "user": { + "id": 1, "name": "Administrator", "username": "root", - "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "web_url": "http://localhost:3000/root", - "created_at": "2016-08-11T07:09:20.351Z", + "web_url": "http://gitlab.dev/root", + "created_at": "2015-12-21T13:14:24.077Z", "bio": null, "location": null, "skype": "", "linkedin": "", "twitter": "", - "website_url": "" + "website_url": "", + "organization": "" }, "commit": { "id": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", diff --git a/doc/api/jobs.md b/doc/api/jobs.md index cf292adf150..aa290ff4cf8 100644 --- a/doc/api/jobs.md +++ b/doc/api/jobs.md @@ -53,18 +53,21 @@ Example of response "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/6", "user": { - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "bio": null, - "created_at": "2015-12-21T13:14:24.077Z", "id": 1, - "linkedin": "", "name": "Administrator", - "skype": "", - "state": "active", - "twitter": "", "username": "root", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.dev/root", - "website_url": "" + "created_at": "2015-12-21T13:14:24.077Z", + "bio": null, + "location": null, + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "" } }, { @@ -109,18 +112,21 @@ Example of response "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/7", "user": { - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "bio": null, - "created_at": "2015-12-21T13:14:24.077Z", "id": 1, - "linkedin": "", "name": "Administrator", - "skype": "", - "state": "active", - "twitter": "", "username": "root", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.dev/root", - "website_url": "" + "created_at": "2015-12-21T13:14:24.077Z", + "bio": null, + "location": null, + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "" } } ] @@ -180,18 +186,21 @@ Example of response "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/6", "user": { - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "bio": null, - "created_at": "2015-12-21T13:14:24.077Z", "id": 1, - "linkedin": "", "name": "Administrator", - "skype": "", - "state": "active", - "twitter": "", "username": "root", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.dev/root", - "website_url": "" + "created_at": "2015-12-21T13:14:24.077Z", + "bio": null, + "location": null, + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "" } }, { @@ -236,18 +245,21 @@ Example of response "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/7", "user": { - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "bio": null, - "created_at": "2015-12-21T13:14:24.077Z", "id": 1, - "linkedin": "", "name": "Administrator", - "skype": "", - "state": "active", - "twitter": "", "username": "root", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.dev/root", - "website_url": "" + "created_at": "2015-12-21T13:14:24.077Z", + "bio": null, + "location": null, + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "" } } ] @@ -305,18 +317,21 @@ Example of response "tag": false, "web_url": "https://example.com/foo/bar/-/jobs/8", "user": { - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", - "bio": null, - "created_at": "2015-12-21T13:14:24.077Z", "id": 1, - "linkedin": "", "name": "Administrator", - "skype": "", - "state": "active", - "twitter": "", "username": "root", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.dev/root", - "website_url": "" + "created_at": "2015-12-21T13:14:24.077Z", + "bio": null, + "location": null, + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "" } } ``` diff --git a/doc/api/keys.md b/doc/api/keys.md index ddcf7830621..06b31a67d6a 100644 --- a/doc/api/keys.md +++ b/doc/api/keys.md @@ -27,10 +27,16 @@ Parameters: "web_url": "http://localhost:3000/john_smith", "created_at": "2015-09-03T07:24:01.670Z", "bio": null, + "location": null, + "public_email": "john@example.com", "skype": "", "linkedin": "", "twitter": "", "website_url": "", + "organization": null, + "last_sign_in_at": "2015-09-03T07:24:01.670Z", + "confirmed_at": "2015-09-03T07:24:01.670Z", + "last_activity_on": "2015-09-03", "email": "john@example.com", "theme_id": 2, "color_scheme_id": 1, @@ -40,6 +46,8 @@ Parameters: "can_create_group": true, "can_create_project": true, "two_factor_enabled": false + "external": false, + "private_profile": null } } ``` diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 9e6676d62fe..4c099581f07 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -437,6 +437,11 @@ Parameters: "id" : 1, "name" : "Administrator" }, + "diff_refs": { + "base_sha": "1111111111111111111111111111111111111111", + "head_sha": "2222222222222222222222222222222222222222", + "start_sha": "3333333333333333333333333333333333333333" + }, "diverged_commits_count": 2 } ``` diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md index 77bb7a55d8c..8a1e6b52092 100644 --- a/doc/api/oauth2.md +++ b/doc/api/oauth2.md @@ -1,6 +1,6 @@ # GitLab as an OAuth2 provider -This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow other services access Gitlab resources on user's behalf. +This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow other services access GitLab resources on user's behalf. If you want GitLab to be an OAuth authentication service provider to sign into other services please see the [OAuth2 provider](../integration/oauth_provider.md) documentation. @@ -9,7 +9,7 @@ This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-ge ## Supported OAuth2 Flows -Gitlab currently supports following authorization flows: +GitLab currently supports following authorization flows: * *Web Application Flow* - Most secure and common type of flow, designed for the applications with secure server-side. * *Implicit Flow* - This flow is designed for user-agent only apps (e.g. single page web application running on GitLab Pages). @@ -76,7 +76,7 @@ Check [RFC spec](http://tools.ietf.org/html/rfc6749#section-4.2) for a detailed Unlike the web flow, the client receives an `access token` immediately as a result of the authorization request. The flow does not use client secret or authorization code because all of the application code and storage is easily accessible, therefore __secrets__ can leak easily. ->**Important:** Avoid using this flow for applications that store data outside of the Gitlab instance. If you do, make sure to verify `application id` +>**Important:** Avoid using this flow for applications that store data outside of the GitLab instance. If you do, make sure to verify `application id` associated with access token before granting access to the data (see [/oauth/token/info](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo)). @@ -146,7 +146,7 @@ access_token = client.password.get_token('user@example.com', 'secret') puts access_token.token ``` -## Access Gitlab API with `access token` +## Access GitLab API with `access token` The `access token` allows you to make requests to the API on a behalf of a user. You can pass the token either as GET parameter ``` diff --git a/doc/api/runners.md b/doc/api/runners.md index 66476e7db64..0bcbd0aebf0 100644 --- a/doc/api/runners.md +++ b/doc/api/runners.md @@ -11,11 +11,15 @@ Get a list of specific runners available to the user. ``` GET /runners GET /runners?scope=active +GET /runners?type=project_type +GET /runners?status=active ``` | Attribute | Type | Required | Description | |-----------|---------|----------|---------------------| -| `scope` | string | no | The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided | +| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided | +| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | +| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | ``` curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners" @@ -56,11 +60,15 @@ is restricted to users with `admin` privileges. ``` GET /runners/all GET /runners/all?scope=online +GET /runners/all?type=project_type +GET /runners/all?status=active ``` | Attribute | Type | Required | Description | |-----------|---------|----------|---------------------| -| `scope` | string | no | The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided | +| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided | +| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | +| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | ``` curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners/all" @@ -286,6 +294,7 @@ Example response: "created_at": "2017-11-16T18:38:46.000Z", "bio": null, "location": null, + "public_email": "", "skype": "", "linkedin": "", "twitter": "", @@ -336,11 +345,17 @@ usage is enabled in the project's settings. ``` GET /projects/:id/runners +GET /projects/:id/runners?scope=active +GET /projects/:id/runners?type=project_type +GET /projects/:id/runners?status=active ``` -| Attribute | Type | Required | Description | -|-----------|---------|----------|---------------------| +| 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 | +| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided | +| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | +| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | ``` curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners" diff --git a/doc/api/settings.md b/doc/api/settings.md index 83fa9b055d1..1c41b3345ad 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -193,7 +193,7 @@ are listed in the descriptions of the relevant settings. | `metrics_port` | integer | required by: `metrics_enabled` | The UDP port to use for connecting to InfluxDB. | | `metrics_sample_interval` | integer | required by: `metrics_enabled` | The sampling interval in seconds. | | `metrics_timeout` | integer | required by: `metrics_enabled` | The amount of seconds after which InfluxDB will time out. | -| `mirror_available` | boolean | no | Allow mirrors to be setup for projects. If disabled, only admins will be able to setup mirrors in projects. | +| `mirror_available` | boolean | no | Allow mirrors to be set up for projects. If disabled, only admins will be able to set up mirrors in projects. | | `pages_domain_verification_enabled` | boolean | no | Require users to prove ownership of custom domains. Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. | | `password_authentication_enabled_for_git` | boolean | no | Enable authentication for Git over HTTP(S) via a GitLab account password. Default is `true`. | | `password_authentication_enabled_for_web` | boolean | no | Enable authentication for the web interface via a GitLab account password. Default is `true`. | @@ -219,9 +219,6 @@ are listed in the descriptions of the relevant settings. | `session_expire_delay` | integer | no | Session duration in minutes. GitLab restart is required to apply changes | | `shared_runners_enabled` | boolean | no | (**If enabled, requires:** `shared_runners_text`) Enable shared runners for new projects. | | `shared_runners_text` | string | required by: `shared_runners_enabled` | Shared runners text. | -| `sidekiq_throttling_enabled` | boolean | no | (**If enabled, requires:** `sidekiq_throttling_factor` and `sidekiq_throttling_queues`) Enable Sidekiq Job Throttling. | -| `sidekiq_throttling_factor` | decimal | required by: `sidekiq_throttling_enabled` | The factor by which the queues should be throttled. A value between `0.0` and `1.0`, exclusive. | -| `sidekiq_throttling_queues` | array of strings | required by: `sidekiq_throttling_enabled` | Choose which queues you wish to throttle. | | `sign_in_text` | string | no | Text on the login page. | | `signin_enabled` | string | no | (Deprecated: Use `password_authentication_enabled_for_web` instead) Flag indicating if password authentication is enabled for the web interface. | | `signup_enabled` | boolean | no | Enable registration. Default is `true`. | diff --git a/doc/api/users.md b/doc/api/users.md index b0ae455a025..762ea53edee 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -199,6 +199,7 @@ Parameters: "created_at": "2012-05-23T08:00:58Z", "bio": null, "location": null, + "public_email": "john@example.com", "skype": "", "linkedin": "", "twitter": "", @@ -230,6 +231,7 @@ Parameters: "is_admin": false, "bio": null, "location": null, + "public_email": "john@example.com", "skype": "", "linkedin": "", "twitter": "", @@ -367,6 +369,7 @@ GET /user "created_at": "2012-05-23T08:00:58Z", "bio": null, "location": null, + "public_email": "john@example.com", "skype": "", "linkedin": "", "twitter": "", @@ -415,6 +418,7 @@ GET /user "is_admin": false, "bio": null, "location": null, + "public_email": "john@example.com", "skype": "", "linkedin": "", "twitter": "", diff --git a/doc/ci/README.md b/doc/ci/README.md index d782d64e971..dba1f38abe2 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -132,5 +132,3 @@ your whole GitLab instance as well as in each project. - [New CI job permissions model](../user/project/new_ci_build_permissions_model.md) Read about what changed in GitLab 8.12 and how that affects your jobs. There's a new way to access your Git submodules and LFS objects in jobs. - -[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml diff --git a/doc/ci/autodeploy/quick_start_guide.md b/doc/ci/autodeploy/quick_start_guide.md index cc6c9ec0e0a..3836216e951 100644 --- a/doc/ci/autodeploy/quick_start_guide.md +++ b/doc/ci/autodeploy/quick_start_guide.md @@ -11,7 +11,7 @@ We made a minimal [Ruby application](https://gitlab.com/gitlab-examples/minimal- Let’s start by forking our sample application. Go to [the project page](https://gitlab.com/gitlab-examples/minimal-ruby-app) and press the `Fork` button. Soon you should have a project under your namespace with the necessary files. -## Setup your own cluster on Google Kubernetes Engine +## Set up your own cluster on Google Kubernetes Engine If you do not already have a Google Cloud account, create one at https://console.cloud.google.com. @@ -71,7 +71,7 @@ Use this IP address to configure your DNS. This part heavily depends on your pre Use `nslookup minimal-ruby-app-staging.<yourdomain>` to confirm that domain is assigned to the cluster IP. -## Setup Auto Deploy +## Set up Auto Deploy Visit the home page of your GitLab.com project and press "Set up Auto Deploy" button. diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md index b41101695f6..f479dc74d1f 100644 --- a/doc/ci/caching/index.md +++ b/doc/ci/caching/index.md @@ -178,8 +178,8 @@ runs of jobs for things like dependencies and commonly used libraries so they don't have to be re-fetched from the public internet. NOTE: **Note:** -For more examples, check the [GitLab CI Yml](https://gitlab.com/gitlab-org/gitlab-ci-yml) -project. +For more examples, check out our [GitLab CI/CD +templates](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates). ### Caching Nodejs dependencies @@ -190,7 +190,7 @@ Nodejs modules are installed in `node_modules/` and are cached per-branch: ```yaml # -# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Nodejs.gitlab-ci.yml +# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml # image: node:latest @@ -217,7 +217,7 @@ are cached per-branch: ```yaml # -# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/PHP.gitlab-ci.yml +# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/PHP.gitlab-ci.yml # image: php:7.2 @@ -246,7 +246,7 @@ pip's cache is defined under `.cache/pip/` and both are cached per-branch: ```yaml # -# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Python.gitlab-ci.yml +# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml # image: python:latest @@ -286,7 +286,7 @@ jobs inherit it. Gems are installed in `vendor/ruby/` and are cached per-branch: ```yaml # -# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Ruby.gitlab-ci.yml +# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml # image: ruby:2.5 diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md index aa997d15b64..0b64c8caba7 100644 --- a/doc/ci/docker/using_docker_build.md +++ b/doc/ci/docker/using_docker_build.md @@ -314,8 +314,8 @@ build: stage: build script: - docker pull $CONTAINER_IMAGE:latest || true - - docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:$CI_BUILD_REF --tag $CONTAINER_IMAGE:latest . - - docker push $CONTAINER_IMAGE:$CI_BUILD_REF + - docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:$CI_COMMIT_SHA --tag $CONTAINER_IMAGE:latest . + - docker push $CONTAINER_IMAGE:$CI_COMMIT_SHA - docker push $CONTAINER_IMAGE:latest ``` diff --git a/doc/ci/environments.md b/doc/ci/environments.md index f1e5b00e927..4d740c32fd6 100644 --- a/doc/ci/environments.md +++ b/doc/ci/environments.md @@ -370,7 +370,7 @@ review_app: url: https://$CI_COMMIT_REF_SLUG.example.com ``` -It is assumed that the user has already setup NGINX and GitLab Runner in the +It is assumed that the user has already set up NGINX and GitLab Runner in the server this job will run on. >**Note:** diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md index 8eb96ae10b2..fdf09d332a5 100644 --- a/doc/ci/examples/README.md +++ b/doc/ci/examples/README.md @@ -4,8 +4,8 @@ comments: false # GitLab CI/CD Examples -A collection of `.gitlab-ci.yml` template files is maintained at the [GitLab CI/CD YAML project][gitlab-ci-templates]. When you create a new file via the UI, -GitLab will give you the option to choose one of the templates existent on this project. +A collection of [`.gitlab-ci.yml` template files][gitlab-ci-templates] is maintained in GitLab. When you create a new file via the UI, +GitLab will give you the option to choose one of these templates. If your favorite programming language or framework are missing we would love your help by sending a merge request with a new `.gitlab-ci.yml` to this project. @@ -87,4 +87,4 @@ language users and GitLab by sending a merge request with a guide for that langu You may want to apply for the [GitLab Community Writers Program](https://about.gitlab.com/community-writers/) to get paid for writing complete articles for GitLab. -[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml +[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates diff --git a/doc/ci/examples/browser_performance.md b/doc/ci/examples/browser_performance.md index 0dab07a7f80..d36e97ebfd3 100644 --- a/doc/ci/examples/browser_performance.md +++ b/doc/ci/examples/browser_performance.md @@ -110,4 +110,4 @@ performance: - sitespeed-results/ ``` -A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml). +A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml). diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md index c226b5bfb71..b75ed87bc91 100644 --- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md +++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md @@ -520,7 +520,7 @@ a lot of breathing room in quickly getting changes to players. Here are some ideas to further investigate that can speed up or improve your pipeline: - [Yarn](https://yarnpkg.com) instead of npm -- Setup a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ci-yml) image that can preload dependencies and tools (like AWS CLI) +- Set up a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ci-yml) image that can preload dependencies and tools (like AWS CLI) - Forward a [custom domain](http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html) to your game's S3 static website - Combine jobs if you find it unnecessary for a small project - Avoid the queues and set up your own [custom GitLab CI/CD runner](https://about.gitlab.com/2016/03/01/gitlab-runner-with-docker/) diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md index 39c65399332..ab429e0ded3 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md @@ -13,7 +13,7 @@ date: 2017-08-31 GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. -In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). +In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and set up our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). We assume you have a basic experience with Laravel, Linux servers, and you know how to use GitLab. @@ -23,7 +23,7 @@ It has a great community with a [fantastic documentation](https://laravel.com/do Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others. We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner based on PHP. -It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan). +It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to set up tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan). ## Initialize our Laravel app on GitLab @@ -372,7 +372,7 @@ At the end, our `Envoy.blade.php` file will look like this: One more thing we should do before any deployment is to manually copy our application `storage` folder to the `/var/www/app` directory on the server for the first time. You might want to create another Envoy task to do that for you. -We also create the `.env` file in the same path to setup our production environment variables for Laravel. +We also create the `.env` file in the same path to set up our production environment variables for Laravel. These are persistent data and will be shared to every new release. Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../environments.md), which will be described [later](#setting-up-gitlab-ci-cd) in this tutorial. @@ -587,7 +587,7 @@ unit_test: script: # Install app dependencies - composer install - # Setup .env + # Set up .env - cp .env.example .env # Generate an environment key - php artisan key:generate diff --git a/doc/ci/examples/php.md b/doc/ci/examples/php.md index a2ba29a4ee2..df4805ea7ac 100644 --- a/doc/ci/examples/php.md +++ b/doc/ci/examples/php.md @@ -199,7 +199,7 @@ pecl install <extension> ``` It's not advised to add this to `.gitlab-ci.yml`. You should execute this -command once, only to setup the build environment. +command once, only to set up the build environment. ## Extend your tests diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md index 09d83c33f95..b3961ec91f3 100644 --- a/doc/ci/examples/test-scala-application.md +++ b/doc/ci/examples/test-scala-application.md @@ -1,6 +1,6 @@ # Test and deploy to Heroku a Scala application -This example demonstrates the integration of Gitlab CI with Scala +This example demonstrates the integration of GitLab CI with Scala applications using SBT. Checkout the example [project](https://gitlab.com/gitlab-examples/scala-sbt) and [build status](https://gitlab.com/gitlab-examples/scala-sbt/builds). diff --git a/doc/ci/interactive_web_terminal/index.md b/doc/ci/interactive_web_terminal/index.md index 8ce4fe55cec..7990917f809 100644 --- a/doc/ci/interactive_web_terminal/index.md +++ b/doc/ci/interactive_web_terminal/index.md @@ -3,7 +3,7 @@ > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/50144) in GitLab 11.3. Interactive web terminals give the user access to a terminal in GitLab for -running one-of commands for their CI pipeline. +running one-off commands for their CI pipeline. NOTE: **Note:** This is not available for the shared Runners on GitLab.com. diff --git a/doc/ci/junit_test_reports.md b/doc/ci/junit_test_reports.md index cf22450914c..3fd54647abb 100644 --- a/doc/ci/junit_test_reports.md +++ b/doc/ci/junit_test_reports.md @@ -140,6 +140,27 @@ java: - target/failsafe-reports/TEST-*.xml ``` +### C/C++ example + +There are a few tools that can produce JUnit reports in C/C++. + +#### GoogleTest + +In the following example, `gtest` is used to generate the test reports. +If there are multiple gtest executables created for different architectures (`x86`, `x64` or `arm`), +you will be required to run each test providing a unique filename. The results +will then be aggregated together. + +```yaml +cpp: + stage: test + script: + - gtest.exe --gtest_output="xml:report.xml" + artifacts: + reports: + junit: report.xml +``` + ## Limitations Currently, the following tools might not work because their XML formats are unsupported in GitLab. diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index 7859d2ec631..83e0fa34ad6 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -29,7 +29,7 @@ are: - **Specific Runners** are useful for jobs that have special requirements or for projects with a specific demand. If a job has certain requirements, you can set up the specific Runner with this in mind, while not having to do this for all - Runners. For example, if you want to deploy a certain project, you can setup + Runners. For example, if you want to deploy a certain project, you can set up a specific Runner to have the right credentials for this. The [usage of tags](#using-tags) may be useful in this case. Specific Runners process jobs using a [FIFO] queue. - **Group Runners** are useful when you have multiple projects under one group @@ -222,7 +222,7 @@ should keep in mind. ### Using tags -You must setup a Runner to be able to run all the different types of jobs +You must set up a Runner to be able to run all the different types of jobs that it may encounter on the projects it's shared over. This would be problematic for large amounts of projects, if it wasn't for tags. @@ -298,7 +298,7 @@ and using more secure [Runner Executors](https://docs.gitlab.com/runner/executor ### Forks Whenever a project is forked, it copies the settings of the jobs that relate -to it. This means that if you have shared Runners setup for a project and +to it. This means that if you have shared Runners set up for a project and someone forks that project, the shared Runners will also serve jobs of this project. diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 31a065bc196..e38628b288b 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -188,7 +188,7 @@ used for time of the job. The configuration of this feature is covered in ## `before_script` and `after_script` -> Introduced in GitLab 8.7 and requires Gitlab Runner v1.2 +> Introduced in GitLab 8.7 and requires GitLab Runner v1.2 `before_script` is used to define the command that should be run before all jobs, including deploy jobs, but after the restoration of [artifacts](#artifacts). @@ -492,6 +492,7 @@ osx job: `allow_failure` is used when you want to allow a job to fail without impacting the rest of the CI suite. Failed jobs don't contribute to the commit status. +The default value is `false`. When enabled and the job fails, the pipeline will be successful/green for all intents and purposes, but a "CI build passed with warnings" message will be diff --git a/doc/development/README.md b/doc/development/README.md index d8dbc993442..43d3865da0e 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -7,7 +7,7 @@ description: 'Learn how to contribute to GitLab.' ## Get started! -- Setup GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md) +- Set up GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md) - [GitLab contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) - [Architecture](architecture.md) of GitLab - [Rake tasks](rake_tasks.md) for development @@ -94,6 +94,7 @@ description: 'Learn how to contribute to GitLab.' - [Verifying database capabilities](verifying_database_capabilities.md) - [Database Debugging and Troubleshooting](database_debugging.md) - [Query Count Limits](query_count_limits.md) +- [Database helper modules](database_helpers.md) ## Testing guides diff --git a/doc/development/automatic_ce_ee_merge.md b/doc/development/automatic_ce_ee_merge.md index f6509b5c1dd..9dd78806a12 100644 --- a/doc/development/automatic_ce_ee_merge.md +++ b/doc/development/automatic_ce_ee_merge.md @@ -63,7 +63,7 @@ EE version of your CE merge request. For each commit (except on `master`), the `ee_compat_check` CI job tries to detect if the current branch's changes will conflict during the CE->EE merge. -The job reports what files are conflicting and how to setup a merge request +The job reports what files are conflicting and how to set up a merge request against EE. #### How the job works diff --git a/doc/development/contributing/community_roles.md b/doc/development/contributing/community_roles.md new file mode 100644 index 00000000000..c508969f7f4 --- /dev/null +++ b/doc/development/contributing/community_roles.md @@ -0,0 +1,12 @@ +### Community members & roles + +GitLab community members and their privileges/responsibilities. + +| Roles | Responsibilities | Requirements | +|-------|------------------|--------------| +| Maintainer | Accepts merge requests on several GitLab projects | Added to the [team page](https://about.gitlab.com/team/). An expert on code reviews and knows the product/code base | +| Reviewer | Performs code reviews on MRs | Added to the [team page](https://about.gitlab.com/team/) | +| Developer |Has access to GitLab internal infrastructure & issues (e.g. HR-related) | GitLab employee or a Core Team member (with an NDA) | +| Contributor | Can make contributions to all GitLab public projects | Have a GitLab.com account | + +[List of current reviewers/maintainers](https://about.gitlab.com/handbook/engineering/projects/#gitlab-ce)
\ No newline at end of file diff --git a/doc/development/contributing/design.md b/doc/development/contributing/design.md index 45fe8c26591..be7891061f9 100644 --- a/doc/development/contributing/design.md +++ b/doc/development/contributing/design.md @@ -1,13 +1,4 @@ -<!-- START doctoc generated TOC please keep comment here to allow auto update --> -<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - -- [Implement design & UI elements](#implement-design--ui-elements) -- [Style guides](#style-guides) - -<!-- END doctoc generated TOC please keep comment here to allow auto update --> - -## Implement design & UI elements +# Implement design & UI elements For guidance on UX implementation at GitLab, please refer to our [Design System](https://design.gitlab.com/). @@ -34,27 +25,27 @@ In order to complete a product discovery issue in a release, you must complete t ## Style guides -1. [Ruby](https://github.com/bbatsov/ruby-style-guide). - Important sections include [Source Code Layout][rss-source] and - [Naming][rss-naming]. Use: - - multi-line method chaining style **Option A**: dot `.` on the second line - - string literal quoting style **Option A**: single quoted by default -1. [Rails](https://github.com/bbatsov/rails-style-guide) -1. [Newlines styleguide][newlines-styleguide] -1. [Testing][testing] -1. [JavaScript styleguide][js-styleguide] -1. [SCSS styleguide][scss-styleguide] -1. [Shell commands](../shell_commands.md) created by GitLab - contributors to enhance security -1. [Database Migrations](../migration_style_guide.md) -1. [Markdown](http://www.cirosantilli.com/markdown-styleguide) -1. [Documentation styleguide](https://docs.gitlab.com/ee/development/documentation/styleguide.html) -1. Interface text should be written subjectively instead of objectively. It - should be the GitLab core team addressing a person. It should be written in - present time and never use past tense (has been/was). For example instead - of _prohibited this user from being saved due to the following errors:_ the - text should be _sorry, we could not create your account because:_ -1. Code should be written in [US English][us-english] +1. [Ruby](https://github.com/bbatsov/ruby-style-guide). + Important sections include [Source Code Layout][rss-source] and + [Naming][rss-naming]. Use: + - multi-line method chaining style **Option A**: dot `.` on the second line + - string literal quoting style **Option A**: single quoted by default +1. [Rails](https://github.com/bbatsov/rails-style-guide) +1. [Newlines styleguide][newlines-styleguide] +1. [Testing][testing] +1. [JavaScript styleguide][js-styleguide] +1. [SCSS styleguide][scss-styleguide] +1. [Shell commands](../shell_commands.md) created by GitLab + contributors to enhance security +1. [Database Migrations](../migration_style_guide.md) +1. [Markdown](http://www.cirosantilli.com/markdown-styleguide) +1. [Documentation styleguide](https://docs.gitlab.com/ee/development/documentation/styleguide.html) +1. Interface text should be written subjectively instead of objectively. It + should be the GitLab core team addressing a person. It should be written in + present time and never use past tense (has been/was). For example instead + of _prohibited this user from being saved due to the following errors:_ the + text should be _sorry, we could not create your account because:_ +1. Code should be written in [US English][us-english] This is also the style used by linting tools such as [RuboCop](https://github.com/bbatsov/rubocop), diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md index eac7cb44c40..f4486ae3549 100644 --- a/doc/development/contributing/index.md +++ b/doc/development/contributing/index.md @@ -1,41 +1,4 @@ -<!-- START doctoc generated TOC please keep comment here to allow auto update --> -<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - -- [Contribute to GitLab](#contribute-to-gitlab) -- [Security vulnerability disclosure](#security-vulnerability-disclosure) -- [Code of conduct](#code-of-conduct) -- [Closing policy for issues and merge requests](#closing-policy-for-issues-and-merge-requests) -- [Helping others](#helping-others) -- [I want to contribute!](#i-want-to-contribute) -- [Contribution Flow](#contribution-flow) -- [Workflow labels](#workflow-labels) - - [Type labels](#type-labels) - - [Subject labels](#subject-labels) - - [Team labels](#team-labels) - - [Milestone labels](#milestone-labels) - - [Bug Priority labels](#bug-priority-labels) - - [Bug Severity labels](#bug-severity-labels) - - [Severity impact guidance](#severity-impact-guidance) - - [Label for community contributors](#label-for-community-contributors) -- [Implement design & UI elements](#implement-design--ui-elements) -- [Issue tracker](#issue-tracker) - - [Issue triaging](#issue-triaging) - - [Feature proposals](#feature-proposals) - - [Issue tracker guidelines](#issue-tracker-guidelines) - - [Issue weight](#issue-weight) - - [Regression issues](#regression-issues) - - [Technical and UX debt](#technical-and-ux-debt) - - [Stewardship](#stewardship) -- [Merge requests](#merge-requests) - - [Merge request guidelines](#merge-request-guidelines) - - [Contribution acceptance criteria](#contribution-acceptance-criteria) -- [Definition of done](#definition-of-done) -- [Style guides](#style-guides) - -<!-- END doctoc generated TOC please keep comment here to allow auto update --> - -## Contribute to GitLab +# Contribute to GitLab For a first-time step-by-step guide to the contribution process, see ["Contributing to GitLab"](https://about.gitlab.com/contributing/). diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md index 08042fa2aec..fed29d37b26 100644 --- a/doc/development/contributing/issue_workflow.md +++ b/doc/development/contributing/issue_workflow.md @@ -1,27 +1,4 @@ -<!-- START doctoc generated TOC please keep comment here to allow auto update --> -<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - -- [Workflow labels](#workflow-labels) - - [Type labels](#type-labels) - - [Subject labels](#subject-labels) - - [Team labels](#team-labels) - - [Release Scoping labels](#release-scoping-labels) - - [Priority labels](#priority-labels) - - [Severity labels](#severity-labels) - - [Severity impact guidance](#severity-impact-guidance) - - [Label for community contributors](#label-for-community-contributors) - - [Issue triaging](#issue-triaging) - - [Feature proposals](#feature-proposals) - - [Issue tracker guidelines](#issue-tracker-guidelines) - - [Issue weight](#issue-weight) - - [Regression issues](#regression-issues) - - [Technical and UX debt](#technical-and-ux-debt) - - [Stewardship](#stewardship) - -<!-- END doctoc generated TOC please keep comment here to allow auto update --> - -## Workflow labels +# Workflow labels To allow for asynchronous issue handling, we use [milestones][milestones-page] and [labels][labels-page]. Leads and product managers handle most of the @@ -45,7 +22,7 @@ labels, you can _always_ add the team and type, and often also the subject. [milestones-page]: https://gitlab.com/gitlab-org/gitlab-ce/milestones [labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels -### Type labels +## Type labels Type labels are very important. They define what kind of issue this is. Every issue should have one or more. @@ -61,7 +38,7 @@ already reserved for subject labels). The descriptions on the [labels page][labels-page] explain what falls under each type label. -### Subject labels +## Subject labels Subject labels are labels that define what area or feature of GitLab this issue hits. They are not always necessary, but very convenient. @@ -75,7 +52,7 @@ issue is labeled with a subject label corresponding to your expertise. Subject labels are always all-lowercase. -### Team labels +## Team labels Team labels specify what team is responsible for this issue. Assigning a team label makes sure issues get the attention of the appropriate @@ -107,7 +84,7 @@ indicate if an issue needs backend work, frontend work, or both. Team labels are always capitalized so that they show up as the first label for any issue. -### Release Scoping labels +## Release Scoping labels Release Scoping labels help us clearly communicate expectations of the work for the release. There are three levels of Release Scoping labels: @@ -138,7 +115,7 @@ This label documents the planned timeline & urgency which is used to measure aga | ~P3 | Medium Priority | Within the next 3 releases (approx one quarter) | | ~P4 | Low Priority | Anything outside the next 3 releases (approx beyond one quarter) | -### Severity labels +## Severity labels Severity labels help us clearly communicate the impact of a ~bug on users. @@ -149,7 +126,7 @@ Severity labels help us clearly communicate the impact of a ~bug on users. | ~S3 | Major Severity | Broken Feature, workaround acceptable | Can create merge requests only from the Merge Requests page, not through the Issue. | | ~S4 | Low Severity | Functionality inconvenience or cosmetic issue | Label colors are incorrect / not being displayed. | -#### Severity impact guidance +### Severity impact guidance Severity levels can be applied further depending on the facet of the impact; e.g. Affected customers, GitLab.com availability, performance and etc. The below is a guideline. @@ -160,7 +137,7 @@ Severity levels can be applied further depending on the facet of the impact; e.g | ~S3 | A few users or a single paid customer affected | Limited impact on important portions of GitLab.com | Degradation is likely to occur in the near future | | ~S4 | No paid users/customer affected, or expected to in the near future | Minor impact on on GitLab.com | Degradation _may_ occur but it's not likely | -### Label for community contributors +## Label for community contributors Issues that are beneficial to our users, 'nice to haves', that we currently do not have the capacity for or want to give the priority to, are labeled as @@ -200,7 +177,7 @@ If you've decided that you would like to work on an issue, please @-mention the [appropriate product manager](https://about.gitlab.com/handbook/product/#who-to-talk-to-for-what) as soon as possible. The product manager will then pull in appropriate GitLab team members to further discuss scope, design, and technical considerations. This will -ensure that that your contribution is aligned with the GitLab product and minimize +ensure that your contribution is aligned with the GitLab product and minimize any rework and delay in getting it merged into master. GitLab team members who apply the ~"Accepting Merge Requests" label to an issue @@ -210,8 +187,7 @@ any potential community contributor to @-mention per above. [up-for-grabs]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=Accepting+Merge+Requests&scope=all&sort=weight_asc&state=opened [firt-timers]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=Accepting+Merge+Requests&scope=all&sort=upvotes_desc&state=opened&weight=1 - -### Issue triaging +## Issue triaging Our issue triage policies are [described in our handbook]. You are very welcome to help the GitLab team triage issues. We also organize [issue bash events] once @@ -224,7 +200,7 @@ on those issues. Please select someone with relevant experience from the the commit history for the affected files to find someone. We also use [GitLab Triage] to automate some triaging policies. This is -currently setup as a [scheduled pipeline] running on [quality/triage-ops] +currently set up as a [scheduled pipeline] running on [quality/triage-ops] project. [described in our handbook]: https://about.gitlab.com/handbook/engineering/issue-triage/ @@ -233,7 +209,7 @@ project. [scheduled pipeline]: https://gitlab.com/gitlab-org/quality/triage-ops/pipeline_schedules/10512/edit [quality/triage-ops]: https://gitlab.com/gitlab-org/quality/triage-ops -### Feature proposals +## Feature proposals To create a feature proposal for CE, open an issue on the [issue tracker of CE][ce-tracker]. @@ -250,7 +226,7 @@ code snippet right after your description in a new line: `~"feature proposal"`. Please keep feature proposals as small and simple as possible, complex ones might be edited to make them small and simple. -Please submit Feature Proposals using the ['Feature Proposal' issue template](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/issue_templates/Feature%20Proposal.md) provided on the issue tracker. +Please submit Feature Proposals using the ['Feature Proposal' issue template](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/issue_templates/Feature%20proposal.md) provided on the issue tracker. For changes in the interface, it is helpful to include a mockup. Issues that add to, or change, the interface should be given the ~"UX" label. This will allow the UX team to provide input and guidance. You may @@ -259,7 +235,7 @@ need to ask one of the [core team] members to add the label, if you do not have If you want to create something yourself, consider opening an issue first to discuss whether it is interesting to include this in GitLab. -### Issue tracker guidelines +## Issue tracker guidelines **[Search the issue tracker][ce-tracker]** for similar entries before submitting your own, there's a good chance somebody else had the same issue or @@ -271,7 +247,7 @@ The text in the parenthesis is there to help you with what to include. Omit it when submitting the actual issue. You can copy-paste it and then edit as you see fit. -### Issue weight +## Issue weight Issue weight allows us to get an idea of the amount of work required to solve one or multiple issues. This makes it possible to schedule work more accurately. @@ -293,7 +269,7 @@ is probably 1, adding a new Git Hook maybe 4 or 5, big features 7-9. issues or chunks. You can simply not set the weight of a parent issue and set weights to children issues. -### Regression issues +## Regression issues Every monthly release has a corresponding issue on the CE issue tracker to keep track of functionality broken by that release and any fixes that need to be @@ -313,7 +289,7 @@ addressed. [8.3 Regressions]: https://gitlab.com/gitlab-org/gitlab-ce/issues/4127 [update the notes]: https://gitlab.com/gitlab-org/release-tools/blob/master/doc/pro-tips.md#update-the-regression-issue -### Technical and UX debt +## Technical and UX debt In order to track things that can be improved in GitLab's codebase, we use the ~"technical debt" label in [GitLab's issue tracker][ce-tracker]. @@ -337,7 +313,7 @@ for a release by the appropriate person. Make sure to mention the merge request that the ~"technical debt" issue or ~"UX debt" issue is associated with in the description of the issue. -### Stewardship +## Stewardship For issues related to the open source stewardship of GitLab, there is the ~"stewardship" label. diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md index 685287f7a0c..a286e74908c 100644 --- a/doc/development/contributing/merge_request_workflow.md +++ b/doc/development/contributing/merge_request_workflow.md @@ -1,15 +1,4 @@ -<!-- START doctoc generated TOC please keep comment here to allow auto update --> -<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - -- [Merge requests](#merge-requests) - - [Merge request guidelines](#merge-request-guidelines) - - [Contribution acceptance criteria](#contribution-acceptance-criteria) -- [Definition of done](#definition-of-done) - -<!-- END doctoc generated TOC please keep comment here to allow auto update --> - -## Merge requests +# Merge requests We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The issues that are specifically suitable for @@ -36,7 +25,7 @@ some potentially easy issues. To start with GitLab development download the [GitLab Development Kit][gdk] and see the [Development section](../README.md) for some guidelines. -### Merge request guidelines +## Merge request guidelines If you can, please submit a merge request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test @@ -114,7 +103,7 @@ Please ensure that your merge request meets the contribution acceptance criteria When having your code reviewed and when reviewing merge requests please take the [code review guidelines](../code_review.md) into account. -### Contribution acceptance criteria +## Contribution acceptance criteria 1. The change is as small as possible 1. Include proper tests and make all tests pass (unless it contains a test diff --git a/doc/development/database_debugging.md b/doc/development/database_debugging.md index 9c31265e417..b2c804b2ff0 100644 --- a/doc/development/database_debugging.md +++ b/doc/development/database_debugging.md @@ -33,7 +33,7 @@ If your test DB is giving you problems, it is safe to nuke it because it doesn't - `bundle exec rake db:migrate RAILS_ENV=development`: Execute any pending migrations that you may have picked up from a MR - `bundle exec rake db:migrate:status RAILS_ENV=development`: Check if all migrations are `up` or `down` - `bundle exec rake db:migrate:down VERSION=20170926203418 RAILS_ENV=development`: Tear down a migration - - `bundle exec rake db:migrate:up VERSION=20170926203418 RAILS_ENV=development`: Setup a migration + - `bundle exec rake db:migrate:up VERSION=20170926203418 RAILS_ENV=development`: Set up a migration - `bundle exec rake db:migrate:redo VERSION=20170926203418 RAILS_ENV=development`: Re-run a specific migration diff --git a/doc/development/database_helpers.md b/doc/development/database_helpers.md new file mode 100644 index 00000000000..21e4e725de6 --- /dev/null +++ b/doc/development/database_helpers.md @@ -0,0 +1,63 @@ +# Database helpers + +There are a number of useful helper modules defined in `/lib/gitlab/database/`. + +## Subquery + +In some cases it is not possible to perform an operation on a query. +For example: + +```ruby +Geo::EventLog.where('id < 100').limit(10).delete_all +``` + +Will give this error: + +> ActiveRecord::ActiveRecordError: delete_all doesn't support limit + +One solution would be to wrap it in another `where`: + +```ruby +Geo::EventLog.where(id: Geo::EventLog.where('id < 100').limit(10)).delete_all +``` + +This works with PostgreSQL, but with MySQL it gives this error: + +> ActiveRecord::StatementInvalid: Mysql2::Error: This version of MySQL +> doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' + +Also, that query doesn't have very good performance. Using a +`INNER JOIN` with itself is better. + +So instead of this query: + +```sql +SELECT geo_event_log.* +FROM geo_event_log +WHERE geo_event_log.id IN + (SELECT geo_event_log.id + FROM geo_event_log + WHERE (id < 100) + LIMIT 10) +``` + +It's better to write: + +```sql +SELECT geo_event_log.* +FROM geo_event_log +INNER JOIN + (SELECT geo_event_log.* + FROM geo_event_log + WHERE (id < 100) + LIMIT 10) t2 ON geo_event_log.id = t2.id +``` + +And this is where `Gitlab::Database::Subquery.self_join` can help +you. So you can rewrite the above statement as: + +```ruby +Gitlab::Database::Subquery.self_join(Geo::EventLog.where('id < 100').limit(10)).delete_all +``` + +And this also works with MySQL, so you don't need to worry about that. diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index d6ae4cb39f0..2db78e4a365 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -43,13 +43,13 @@ how to structure GitLab docs. Currently GitLab docs use Redcarpet as [markdown](../../user/markdown.md) engine, but there's an [open discussion](https://gitlab.com/gitlab-com/gitlab-docs/issues/50) for implementing Kramdown in the near future. -All the docs follow the [documentation style guidelines](styleguide.md). +All the docs follow the [documentation style guidelines](styleguide.md). See [Linting](#linting) for help to follow the guidelines. ## Documentation directory structure The documentation is structured based on the GitLab UI structure itself, separated by [`user`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/user), -[`administrator`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/administration), and [`contributor`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/development). +[`administrator`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/administration), and [`contributor`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/development). In order to have a [solid site structure](https://searchengineland.com/seo-benefits-developing-solid-site-structure-277456) for our documentation, all docs should be linked. Every new document should be cross-linked to its related documentation, and linked from its topic-related index, when existent. @@ -223,6 +223,108 @@ redirect_from: 'https://docs.gitlab.com/my-old-location/README.html' Note: it is necessary to include the file name in the `redirect_from` URL, even if it's `index.html` or `README.html`. +## Linting + +To help adhere to the [documentation style guidelines](styleguide.md), and to improve the content + added to documentation, consider locally installing and running documentation linters. This will + help you catch common issues before raising merge requests for review of documentation. + +The following are some suggested linters you can install locally and sample configuration: + +- `proselint` +- `markdownlint` + +NOTE: **Note:** +This list does not limit what other linters you can add to your local documentation writing + toolchain. + +### `proselint` + +`proselint` checks for common problems with English prose. It provides a + [plethora of checks](http://proselint.com/checks/) that are helpful for technical writing. + +`proselint` can be used [on the command line](http://proselint.com/utility/), either on a single + Markdown file or on all Markdown files in a project. For example, to run `proselint` on all + documentation in the [`gitlab-ce` project](https://gitlab.com/gitlab-org/gitlab-ce), run the + following commands from within the `gitlab-ce` project: + +```sh +cd doc +proselint **/*.md +``` + +`proselint` can also be run from within editors using plugins. For example, the following plugins + are available: + +- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-proselint) +- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=PatrykPeszko.vscode-proselint) +- [Others](https://github.com/amperser/proselint#plugins-for-other-software) + +#### Sample `proselint` configuration + +All of the checks are good to use. However, excluding the `typography.symbols` checks might reduce + noise. The following sample `proselint` configuration disables the `typography.symbols` checks: + +```json +{ + "checks": { + "typography.symbols": false + } +} +``` + +A file with `proselint` configuration must be placed in a + [valid location](https://github.com/amperser/proselint#checks). For example, `~/.config/proselint/config`. + +### `markdownlint` + +`markdownlint` checks that certain rules ([example](https://github.com/DavidAnson/markdownlint/blob/master/README.md#rules--aliases)) + are followed for Markdown syntax. Our [style guidelines](styleguide.md) elaborate on which choices + must be made when selecting Markdown syntax for GitLab documentation and this tool helps + catch deviations from those guidelines. + +`markdownlint` can be used [on the command line](https://github.com/igorshubovych/markdownlint-cli#markdownlint-cli--), + either on a single Markdown file or on all Markdown files in a project. For example, to run + `markdownlint` on all documentation in the [`gitlab-ce` project](https://gitlab.com/gitlab-org/gitlab-ce), + run the following commands from within the `gitlab-ce` project: + +```sh +cd doc +markdownlint **/*.md +``` + +`markdownlint` can also be run from within editors using plugins. For example, the following plugins + are available: + +- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint) +- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) +- [Others](https://github.com/DavidAnson/markdownlint#related) + +#### Sample `markdownlint` configuration + +The following sample `markdownlint` configuration modifies the available default rules to: + +- Adhere to the [style guidelines](styleguide.md). +- Apply conventions found in the GitLab documentation. + +```json +{ + "default": true, + "header-style": { "style": "atx" }, + "ul-style": { "style": "dash" }, + "line-length": false, + "no-trailing-punctuation": false, + "ol-prefix": { "style": "one" }, + "blanks-around-fences": false, + "hr-style": { "style": "---" }, + "fenced-code-language": false +} +``` + +For [`markdownlint`](https://gitahub.com/DavidAnson/markdownlint/), this configuration must be + placed in a [valid location](https://github.com/igorshubovych/markdownlint-cli#configuration). For + example, `~/.markdownlintrc`. + ## Testing We treat documentation as code, thus have implemented some testing. @@ -278,7 +380,6 @@ for GitLab Team members. - Label the MR `Documentation` - Assign the correct milestone (see note below) - NOTE: **Note:** If the release version you want to add the documentation to has already been frozen or released, use the label `Pick into X.Y` to get it merged into diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md index 8083f219d4a..c43f91278de 100644 --- a/doc/development/documentation/styleguide.md +++ b/doc/development/documentation/styleguide.md @@ -10,6 +10,8 @@ GitLab documentation. Check the Check the GitLab handbook for the [writing styles guidelines](https://about.gitlab.com/handbook/communication/#writing-style-guidelines). +For help adhering to the guidelines, see [Linting](index.md#linting). + ## Files - [Directory structure](index.md#location-and-naming-documents): place the docs @@ -251,7 +253,7 @@ below. (in that order) that introduced it. The above quote would be then transformed to: ```md - > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/1242) in GitLab 8.3. + > [Introduced](<link-to-issue>) in GitLab 8.3. ``` - If the feature is only available in GitLab Enterprise Edition, don't forget to mention @@ -259,10 +261,22 @@ below. the feature is available in: ```md - > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/1242) - in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3. + > [Introduced](<link-to-issue>) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3. ``` +#### Early versions of EE + +If the feature was created before GitLab 9.2 (before [different EE tiers were introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1851)): + +- Declare it as "Introduced in GitLab Enterprise Edition X.Y". +- Note which tier the feature is available in. + +For example: + +```md +> [Introduced](<link-to-issue>) in GitLab Enterprise Edition 9.0. Available in [GitLab Premium](https://about.gitlab.com/pricing/). +``` + ### Product badges When a feature is available in EE-only tiers, add the corresponding tier according to the diff --git a/doc/development/fe_guide/components.md b/doc/development/fe_guide/components.md index 66a8abe42f7..ee0c2d534ff 100644 --- a/doc/development/fe_guide/components.md +++ b/doc/development/fe_guide/components.md @@ -42,7 +42,7 @@ See also the [corresponding UX guide](../ux_guide/components.md#dropdowns). See also the [corresponding UX guide](../ux_guide/components.md#modals). -We have a reusable Vue component for modals: [vue_shared/components/gl-modal.vue](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/vue_shared/components/gl-modal.vue) +We have a reusable Vue component for modals: [vue_shared/components/gl_modal.vue](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/vue_shared/components/gl_modal.vue) Here is an example of how to use it: diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md index 4f9ca1920a5..f4784c19359 100644 --- a/doc/development/gitaly.md +++ b/doc/development/gitaly.md @@ -9,7 +9,7 @@ status of the migration. ## Developing new Git features -Starting with Gitlab 10.8, all new Git features should be developed in +Starting with GitLab 10.8, all new Git features should be developed in Gitaly. > This is a new process that is not clearly defined yet. If you want diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md index 7054ff39da0..5e13c725e15 100644 --- a/doc/development/i18n/proofreader.md +++ b/doc/development/i18n/proofreader.md @@ -30,6 +30,7 @@ are very appreciative of the work done by translators and proofreaders! - Korean - Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [Crowdin](https://crowdin.com/profile/zzazang) - Huang Tao - [GitLab](https://gitlab.com/htve), [Crowdin](https://crowdin.com/profile/htve) + - Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [Crowdin](https://crowdin.com/profile/BawAppie) - Polish - Filip Mech - [GitLab](https://gitlab.com/mehenz), [Crowdin](https://crowdin.com/profile/mehenz) - Portuguese, Brazilian diff --git a/doc/development/merge_request_performance_guidelines.md b/doc/development/merge_request_performance_guidelines.md index 12badbe39b2..ee01c89e0ed 100644 --- a/doc/development/merge_request_performance_guidelines.md +++ b/doc/development/merge_request_performance_guidelines.md @@ -168,6 +168,7 @@ user objects for every username we can remove the need for running the same query for every mention of `@alice`. Caching data per transaction can be done using -[RequestStore](https://github.com/steveklabnik/request_store). Caching data in -Redis can be done using [Rails' caching +[RequestStore](https://github.com/steveklabnik/request_store) (use +`Gitlab::SafeRequestStore` to avoid having to remember to check +`RequestStore.active?`). Caching data in Redis can be done using [Rails' caching system](http://guides.rubyonrails.org/caching_with_rails.html). diff --git a/doc/development/module_with_instance_variables.md b/doc/development/module_with_instance_variables.md index 48a1b7f847e..7bdfa04fc57 100644 --- a/doc/development/module_with_instance_variables.md +++ b/doc/development/module_with_instance_variables.md @@ -60,7 +60,7 @@ as long as it's contained in the same module; that is, no other modules or objects are touching them, then it would be an acceptable use. We especially allow the case where a single instance variable is used with -`||=` to setup the value. This would look like: +`||=` to set up the value. This would look like: ``` ruby module M diff --git a/doc/development/ordering_table_columns.md b/doc/development/ordering_table_columns.md index 5d00e1f7a0c..e9c6481635b 100644 --- a/doc/development/ordering_table_columns.md +++ b/doc/development/ordering_table_columns.md @@ -1,32 +1,49 @@ -# Ordering Table Columns +# Ordering Table Columns in PostgreSQL Similar to C structures the space of a table is influenced by the order of columns. This is because the size of columns is aligned depending on the type of -the column. Take the following column order for example: +the following column. Let's consider an example: -* id (integer, 4 bytes) -* name (text, variable) -* user_id (integer, 4 bytes) +- `id` (integer, 4 bytes) +- `name` (text, variable) +- `user_id` (integer, 4 bytes) -Integers are aligned to the word size. This means that on a 64 bit platform the -actual size of each column would be: 8 bytes, variable, 8 bytes. This means that -each row will require at least 16 bytes for the two integers, and a variable -amount for the text field. If a table has a few rows this is not an issue, but -once you start storing millions of rows you can save space by using a different -order. For the above example a more ideal column order would be the following: +The first column is a 4-byte integer. The next is text of variable length. The +`text` data type requires 1-word alignment, and on 64-bit platform, 1 word is 8 +bytes. To meet the alignment requirements, four zeros are to be added right +after the first column, so `id` occupies 4 bytes, then 4 bytes of alignment +padding, and only next `name` is being stored. Therefore, in this case, 8 bytes +will be spent for storing a 4-byte integer. -* id (integer, 4 bytes) -* user_id (integer, 4 bytes) -* name (text, variable) +The space between rows is also subject to alignment padding. The `user_id` +column takes only 4 bytes, and on 64-bit platform, 4 zeroes will be added for +alignment padding, to allow storing the next row beginning with the "clear" word. -In this setup the `id` and `user_id` columns can be packed together, which means -we only need 8 bytes to store _both_ of them. This in turn each row will require -8 bytes less of space. +As a result, the actual size of each column would be (ommiting variable length +data and 24-byte tuple header): 8 bytes, variable, 8 bytes. This means that +each row will require at least 16 bytes for the two 4-byte integers. If a table +has a few rows this is not an issue. However, once you start storing millions of +rows you can save space by using a different order. For the above example, the +ideal column order would be the following: + +- `id` (integer, 4 bytes) +- `user_id` (integer, 4 bytes) +- `name` (text, variable) + +or + +- `name` (text, variable) +- `id` (integer, 4 bytes) +- `user_id` (integer, 4 bytes) + +In these examples, the `id` and `user_id` columns are packed together, which +means we only need 8 bytes to store _both_ of them. This in turn means each row +will require 8 bytes less space. For GitLab we require that columns of new tables are ordered based to use the least amount of space. An easy way of doing this is to order them based on the -type size in descending order with variable sizes (string and text columns for -example) at the end. +type size in descending order with variable sizes (`text`, `varchar`, arrays, +`json`, `jsonb`, and so on) at the end. ## Type Sizes @@ -36,7 +53,7 @@ of information we will list the sizes of common types here so it's easier to look them up. Here "word" refers to the word size, which is 4 bytes for a 32 bits platform and 8 bytes for a 64 bits platform. -| Type | Size | Aligned To | +| Type | Size | Alignment needed | |:-----------------|:-------------------------------------|:-----------| | smallint | 2 bytes | 1 word | | integer | 4 bytes | 1 word | @@ -58,7 +75,7 @@ always be at the end of a table. ## Real Example -Let's use the "events" table as an example, which currently has the following +Let's use the `events` table as an example, which currently has the following layout: | Column | Type | Size | @@ -89,8 +106,8 @@ divided into fixed size chunks as follows: | 8 bytes | updated_at | | 8 bytes | action, author_id | -This means that excluding the variable sized data we need at least 48 bytes per -row. +This means that excluding the variable sized data and tuple header, we need at +least 8 * 6 = 48 bytes per row. We can optimise this by using the following column order instead: @@ -120,8 +137,8 @@ This would produce the following chunks: | variable | title | | variable | data | -Here we only need 40 bytes per row excluding the variable sized data. 8 bytes -being saved may not sound like much, but for tables as large as the "events" -table it does begin to matter. For example, when storing 80 000 000 rows this -translates to a space saving of at least 610 MB: all by just changing the order -of a few columns. +Here we only need 40 bytes per row excluding the variable sized data and 24-byte +tuple header. 8 bytes being saved may not sound like much, but for tables as +large as the `events` table it does begin to matter. For example, when storing +80 000 000 rows this translates to a space saving of at least 610 MB, all by +just changing the order of a few columns. diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md index fc51b74da1d..2ad748d4802 100644 --- a/doc/development/rake_tasks.md +++ b/doc/development/rake_tasks.md @@ -1,6 +1,6 @@ # Rake tasks for developers -## Setup db with developer seeds +## Set up db with developer seeds Note that if your db user does not have advanced privileges you must create the db manually before running this command. diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md index 38ea2f1dde1..25c6371f3d7 100644 --- a/doc/development/testing_guide/review_apps.md +++ b/doc/development/testing_guide/review_apps.md @@ -74,7 +74,7 @@ on making Review Apps automatically deployed by each pipeline, both in CE and EE [review-apps-ee]: https://console.cloud.google.com/kubernetes/clusters/details/us-central1-b/review-apps-ee?project=gitlab-review-apps [review-apps.sh]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/review-apps.sh [automated_cleanup.rb]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/automated_cleanup.rb -[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml +[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml [gitlab-k8s-integration]: https://docs.gitlab.com/ee/user/project/clusters/index.html --- diff --git a/doc/development/ux_guide/users.md b/doc/development/ux_guide/users.md index 6afb33cfc36..f9c395b2dff 100644 --- a/doc/development/ux_guide/users.md +++ b/doc/development/ux_guide/users.md @@ -154,7 +154,7 @@ He credits himself as being entirely responsible for moving his company to GitLa #### Updating to the latest release Matthieu introduced his company to GitLab. He is responsible for maintaining and managing the company's installation in addition to his day job. He feels updates are too frequent and he doesn't always have sufficient time to update GitLab. As a result, he's not up to date with releases. -Matthieu tried to set up automatic updates, however, as he isn't a Systems Administrator, he wasn't confident in his set-up. He feels he should be able to "upgrade without users even noticing" but hasn't figured out how to do this yet. Matthieu would like the "update process to be triggered from the Admin Panel, perhaps accompanied with a changelog and the option to skip updates." +Matthieu tried to set up automatic updates, however, as he isn't a Systems Administrator, he wasn't confident in his setup. He feels he should be able to "upgrade without users even noticing" but hasn't figured out how to do this yet. Matthieu would like the "update process to be triggered from the Admin Panel, perhaps accompanied with a changelog and the option to skip updates." Matthieu is looking for confirmation that his update procedure is "secure and efficient" so more tutorials related to this topic would be useful to him. @@ -242,7 +242,7 @@ Some of GitLab EE's features are too basic, in particular, issues boards which d James and his team use CI quite heavily for several projects. Whilst they've welcomed improvements to the builds and pipelines interface, they still have some difficulty following build process on the different tabs under Pipelines. Some confusion has arisen from not knowing where to find different pieces of information or how to get to the next stages logs from the current stage's log output screen. They feel more intuitive linking and flow may alleviate the problem. Generally, they feel GitLab's navigation needs to reviewed and optimized. #### Permissions ->"There is no granular control over user or group permissions. The permissions for a project are too tightly coupled to the permissions for Gitlab CI/build pipelines." +>"There is no granular control over user or group permissions. The permissions for a project are too tightly coupled to the permissions for GitLab CI/build pipelines." ### Goals @@ -290,7 +290,7 @@ JavaScript and SQL Web development, mobile development, UX, open source, gaming, and travel. ### Motivations -Karolina has been using GitLab.com for around a year. She roughly spends 8 hours every week programming, of that, 2 hours is spent contributing to open source projects. Karolina contributes to open source projects to gain programming experience and to give back to the community. She likes GitLab.com for its free private repositories and range of features which provide her with everything she needs for her personal projects. Karolina is also a massive fan of GitLab's values and the fact that it isn't a "behemoth of a company". She explains that "displaying every single thing (doc, culture, assumptions, development...) in the open gives me greater confidence to choose Gitlab personally and to recommend it at work." She's also an avid reader of GitLab's blog. +Karolina has been using GitLab.com for around a year. She roughly spends 8 hours every week programming, of that, 2 hours is spent contributing to open source projects. Karolina contributes to open source projects to gain programming experience and to give back to the community. She likes GitLab.com for its free private repositories and range of features which provide her with everything she needs for her personal projects. Karolina is also a massive fan of GitLab's values and the fact that it isn't a "behemoth of a company". She explains that "displaying every single thing (doc, culture, assumptions, development...) in the open gives me greater confidence to choose GitLab personally and to recommend it at work." She's also an avid reader of GitLab's blog. Karolina works for a software development company which currently hires around 500 people. Karolina would love to use GitLab at work but the company has used GitHub Enterprise for a number of years. She describes management at her company as "old fashioned" and explains that it's "less of a technical issue and more of a cultural issue" to convince upper management to move to GitLab. Karolina is also relatively new to the company so she's apprehensive about pushing too hard to change version control platforms. diff --git a/doc/gitlab-basics/add-image.md b/doc/gitlab-basics/add-image.md index 1a44123aa81..17c210c43e0 100644 --- a/doc/gitlab-basics/add-image.md +++ b/doc/gitlab-basics/add-image.md @@ -5,7 +5,7 @@ in Windows, or...), put the image file into the GitLab project. You can find the project as a regular folder in your files. Go to your [shell](command-line-commands.md), and move into the folder of your -Gitlab project. This usually means running the following command until you get +GitLab project. This usually means running the following command until you get to the desired destination: ``` diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md index 570bd18c172..7835401cc0b 100644 --- a/doc/install/azure/index.md +++ b/doc/install/azure/index.md @@ -74,7 +74,7 @@ The first items we need to configure are the basic settings of the underlying vi > **Note:** if you're unsure which authentication type to use, select **Password** 1. If you chose **SSH public key** - enter your `SSH public key` into the field provided - _(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to setup SSH + _(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to set up SSH public keys)_ 1. If you chose **Password** - enter the password you wish to use _(this is the password that you will use later in this tutorial to [SSH] into the VM, so make sure it's a strong password/passphrase)_ @@ -154,7 +154,7 @@ on the Azure Dashboard (you may need to refresh the page): The new VM can also be accessed by clicking the `All resources` or `Virtual machines` icons in the Azure Portal sidebar navigation menu. -## Setup a domain name +## Set up a domain name The VM will have a public IP address (static by default), but Azure allows us to assign a friendly DNS name to the VM, so let's go ahead and do that. @@ -296,7 +296,7 @@ homepage for the project:  If you scroll further down the project's home page, you'll see some basic instructions on how to -setup a local clone of your new repository and push and pull from it: +set up a local clone of your new repository and push and pull from it:  @@ -347,7 +347,7 @@ If you're running [SSH] from the command-line (terminal), then type in the follo connect to your VM, substituting `username` and `your-azure-domain-name.com` for the correct values. Again, remember that your Azure VM domain name will be the one you -[setup previously in the tutorial](#set-up-a-domain-name). If you didn't setup a domain name for +[set up previously in the tutorial](#set-up-a-domain-name). If you didn't set up a domain name for your VM, you can use the IP address in its place in the following command: ```bash @@ -401,7 +401,7 @@ is now showing **"up-to-date"**: Naturally, we believe that GitLab is a great git repository tool. However, GitLab is a whole lot more than that too. GitLab unifies issues, code review, CI and CD into a single UI, helping you to move faster from idea to production, and in this tutorial we showed you how quick and easy it is to -setup and run your own instance of GitLab on Azure, Microsoft's cloud service. +set up and run your own instance of GitLab on Azure, Microsoft's cloud service. Azure is a great way to experiment with GitLab, and if you decide (as we hope) that GitLab is for you, you can continue to use Azure as your secure, scalable cloud provider or of course run GitLab @@ -424,7 +424,7 @@ Check out our other [Technical Articles][GitLab-Technical-Articles] or browse th - [Azure - Properly Shutdown an Azure VM][Azure-Properly-Shutdown-VM] - [SSH], [PuTTY] and [Using SSH in PuTTY][Using-SSH-In-Putty] -[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Setup a GitLab Instance on Microsoft Azure" +[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Set up a GitLab Instance on Microsoft Azure" [GitLab-Docs]: https://docs.gitlab.com/ce/README.html "GitLab Documentation" [GitLab-Technical-Articles]: https://docs.gitlab.com/ce/articles/index.html "GitLab Technical Articles" [GitLab-Docs-SSH]: https://docs.gitlab.com/ce/ssh/README.html "GitLab Documentation: SSH" diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md index 4cf18f53239..acaed53e052 100644 --- a/doc/install/database_mysql.md +++ b/doc/install/database_mysql.md @@ -79,7 +79,7 @@ After installation or upgrade, remember to [convert any new tables](#tables-and- --- -GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7420) requiring `utf8mb4` encoding to be supported in your GitLab MySQL Database, which is not the case if you have setup your database before GitLab 8.16. +GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7420) requiring `utf8mb4` encoding to be supported in your GitLab MySQL Database, which is not the case if you have set up your database before GitLab 8.16. Follow the below instructions to ensure you use the most up to date requirements for your GitLab MySQL Database. diff --git a/doc/install/digitaloceandocker.md b/doc/install/digitaloceandocker.md index 8efc0530b8a..676392eacf2 100644 --- a/doc/install/digitaloceandocker.md +++ b/doc/install/digitaloceandocker.md @@ -87,7 +87,7 @@ You can add this to your `~/.bash_profile` file to ensure the `docker` client us + Container name: `gitlab-test-8.10` + GitLab version: **EE** `8.10.8-ee.0` -##### Setup container settings +##### Set up container settings ``` export SSH_PORT=2222 diff --git a/doc/install/installation.md b/doc/install/installation.md index 85431a80a81..7df81fbc46f 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -515,7 +515,7 @@ Make GitLab start on boot: sudo update-rc.d gitlab defaults 21 -### Setup Logrotate +### Set up 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 09f5aaa04a7..6d1bc4aedc4 100644 --- a/doc/install/kubernetes/gitlab_chart.md +++ b/doc/install/kubernetes/gitlab_chart.md @@ -93,7 +93,7 @@ You can access the GitLab instance by visiting the domain name beginning with 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 +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): diff --git a/doc/install/openshift_and_gitlab/index.md b/doc/install/openshift_and_gitlab/index.md index 70bc3ff770f..5c8a830ac8f 100644 --- a/doc/install/openshift_and_gitlab/index.md +++ b/doc/install/openshift_and_gitlab/index.md @@ -80,7 +80,7 @@ This will download the VirtualBox image and fire up the VM with some preconfigur values as you can see in the Vagrantfile. As you may have noticed, you need plenty of RAM (5GB in our example), so make sure you have enough. -Now that OpenShift is setup, let's see how the web console looks like. +Now that OpenShift is set up, let's see how the web console looks like. ### Explore the OpenShift web console diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md index 2f5d4142d04..5f129fd3bd1 100644 --- a/doc/install/relative_url.md +++ b/doc/install/relative_url.md @@ -124,5 +124,5 @@ To disable the relative URL: 1. Follow the same as above starting from 2. and set up the GitLab URL to one that doesn't contain a relative path. -[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab" +[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to set up relative URL in Omnibus GitLab" [restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab" diff --git a/doc/install/requirements.md b/doc/install/requirements.md index df59ce9837c..13a6a1c68ad 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -103,7 +103,7 @@ features of GitLab work with MySQL/MariaDB: 1. MySQL support for subgroups was [dropped with GitLab 9.3][post]. See [issue #30472][30472] for more information. -1. Geo **[STARTER ONLY]** does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication). This means no supported Disaster Recovery solution if using MySQL. +1. Geo does [not support MySQL](https://docs.gitlab.com/ee/administration/geo/replication/database.html#mysql-replication). This means no supported Disaster Recovery solution if using MySQL. **[PREMIUM ONLY]** 1. [Zero downtime migrations][../update/README.md#upgrading-without-downtime] do not work with MySQL. 1. GitLab [optimizes the loading of dashboard events](https://gitlab.com/gitlab-org/gitlab-ce/issues/31806) using [PostgreSQL LATERAL JOINs](https://blog.heapanalytics.com/postgresqls-powerful-new-join-type-lateral/). 1. In general, SQL optimized for PostgreSQL may run much slower in MySQL due to diff --git a/doc/integration/github.md b/doc/integration/github.md index 680712f9e01..7a83b8e4b35 100644 --- a/doc/integration/github.md +++ b/doc/integration/github.md @@ -19,7 +19,7 @@ GitHub will generate an application ID and secret key for you to use. - Application name: This can be anything. Consider something like `<Organization>'s GitLab` or `<Your Name>'s GitLab` or something else descriptive. - Homepage URL: The URL to your GitLab installation. 'https://gitlab.company.com' - Application description: Fill this in if you wish. - - Authorization callback URL is 'http(s)://${YOUR_DOMAIN}'. Please make sure the port is included if your Gitlab instance is not configured on default port. + - Authorization callback URL is 'http(s)://${YOUR_DOMAIN}'. Please make sure the port is included if your GitLab instance is not configured on default port. 1. Select "Register application". 1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot). @@ -154,7 +154,7 @@ You will also need to disable Git SSL verification on the server hosting GitLab. $ git config --global http.sslVerify false ``` -For the changes to take effect, [reconfigure Gitlab] if you installed +For the changes to take effect, [reconfigure GitLab] if you installed via Omnibus, or [restart GitLab] if you installed from source. [reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure diff --git a/doc/integration/gmail_action_buttons_for_gitlab.md b/doc/integration/gmail_action_buttons_for_gitlab.md index 05a91d9bef9..c19320471e3 100644 --- a/doc/integration/gmail_action_buttons_for_gitlab.md +++ b/doc/integration/gmail_action_buttons_for_gitlab.md @@ -2,7 +2,7 @@ GitLab supports [Google actions in email](https://developers.google.com/gmail/markup/actions/actions-overview). -If correctly setup, emails that require an action will be marked in Gmail. +If correctly set up, emails that require an action will be marked in Gmail.  diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md index 1d29f6d4e43..2b9cce6539f 100644 --- a/doc/raketasks/backup_restore.md +++ b/doc/raketasks/backup_restore.md @@ -523,7 +523,7 @@ more of the following options: - `BACKUP=timestamp_of_backup` - Required if more than one backup exists. Read what the [backup timestamp is about](#backup-timestamp). -- `force=yes` - Does not ask if the authorized_keys file should get regenerated and assumes 'yes' for warning that database tables will be removed. +- `force=yes` - Does not ask if the authorized_keys file should get regenerated and assumes 'yes' for warning that database tables will be removed, enabling the "Write to authorized_keys file" setting, and updating LDAP providers. If you are restoring into directories that are mountpoints you will need to make sure these directories are empty before attempting a restore. Otherwise GitLab @@ -591,10 +591,11 @@ This procedure assumes that: First make sure your backup tar file is in the backup directory described in the `gitlab.rb` configuration `gitlab_rails['backup_path']`. The default is -`/var/opt/gitlab/backups`. +`/var/opt/gitlab/backups`. It needs to be owned by the `git` user. ```shell sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/ +sudo chown git.git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar ``` Stop the processes that are connected to the database. Leave the rest of GitLab diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md index f02f7b807cf..cd290a80314 100644 --- a/doc/security/two_factor_authentication.md +++ b/doc/security/two_factor_authentication.md @@ -11,7 +11,7 @@ You can read more about it here: ## Enforcing 2FA for all users Users on GitLab, can enable it without any admin's intervention. If you want to -enforce everyone to setup 2FA, you can choose from two different ways: +enforce everyone to set up 2FA, you can choose from two different ways: 1. Enforce on next login 2. Suggest on next login, but allow a grace period before enforcing. diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md index 48c79cd4769..8c07e11dcb1 100644 --- a/doc/security/user_email_confirmation.md +++ b/doc/security/user_email_confirmation.md @@ -1,6 +1,6 @@ # User email confirmation at sign-up -Gitlab admin can enable email confirmation on sign-up, if you want to confirm all +GitLab admin can enable email confirmation on sign-up, if you want to confirm all user emails before they are able to sign-in. In the Admin area under **Settings** (`/admin/application_settings`), go to section diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md index a8aa11265d0..a645f65938f 100644 --- a/doc/topics/authentication/index.md +++ b/doc/topics/authentication/index.md @@ -44,6 +44,6 @@ This page gathers all the resources for the topic **Authentication** within GitL - [Kanboard Plugin GitLab Authentication](https://kanboard.net/plugin/gitlab-auth) - [Jenkins GitLab OAuth Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitLab+OAuth+Plugin) -- [Setup Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/) +- [Set up Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/) - [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/) - [Openshift - Configuring Authentication and User Agent](https://docs.openshift.org/latest/install_config/configuring_authentication.html#GitLab) diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index e778f1d83df..681dc8ff20d 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -71,11 +71,6 @@ For an overview on the creation of Auto DevOps, read the blog post [From 2/3 of ## Requirements -TIP: **Tip:** -For self-hosted installations, the easiest way to make use of Auto DevOps is to -install GitLab inside a Kubernetes cluster using the [GitLab Omnibus Helm Chart] -which automatically installs and configures everything you need! - To make full use of Auto DevOps, you will need: 1. **GitLab Runner** (needed for all stages) - Your Runner needs to be @@ -101,10 +96,6 @@ To make full use of Auto DevOps, you will need: Kubernetes cluster using the [`nginx-ingress`](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress) Helm chart. - 1. **Wildcard TLS termination** - You can deploy the - [`kube-lego`](https://github.com/kubernetes/charts/tree/master/stable/kube-lego) - Helm chart to your Kubernetes cluster to automatically issue certificates - for your domains using Let's Encrypt. 1. **Prometheus** (needed for Auto Monitoring) - To enable Auto Monitoring, you will need Prometheus installed somewhere (inside or outside your cluster) and configured to scrape your Kubernetes cluster. To get response metrics @@ -148,18 +139,13 @@ Auto DevOps base domain to `1.2.3.4.nip.io`. Once set up, all requests will hit the load balancer, which in turn will route them to the Kubernetes pods that run your application(s). -NOTE: **Note:** -If GitLab is installed using the [GitLab Omnibus Helm Chart], there are two -options: provide a static IP, or have one assigned. For more information see the -relevant docs on the [network prerequisites](../../install/kubernetes/gitlab_omnibus.md#networking-prerequisites). - ## Using multiple Kubernetes clusters **[PREMIUM]** When using Auto DevOps, you may want to deploy different environments to different Kubernetes clusters. This is possible due to the 1:1 connection that [exists between them](../../user/project/clusters/index.md#multiple-kubernetes-clusters). -In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml) +In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) (used behind the scenes by Auto DevOps), there are currently 3 defined environment names that you need to know: - `review/` (every environment starting with `review/`) @@ -482,10 +468,7 @@ The metrics include: - **Response Metrics:** latency, throughput, error rate - **System Metrics:** CPU utilization, memory utilization -If GitLab has been deployed using the [GitLab Omnibus Helm Chart], no -configuration is required. - -If you have installed GitLab using a different method, you need to: +In order to make use of monitoring you need to: 1. [Deploy Prometheus](../../user/project/integrations/prometheus.md#configuring-your-own-prometheus-server-within-kubernetes) into your Kubernetes cluster 1. If you would like response metrics, ensure you are running at least version @@ -849,7 +832,6 @@ curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https:/ [review-app]: ../../ci/review_apps/index.md [container-registry]: ../../user/project/container_registry.md [postgresql]: https://www.postgresql.org/ -[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml -[GitLab Omnibus Helm Chart]: ../../install/kubernetes/gitlab_omnibus.md +[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml [ee]: https://about.gitlab.com/pricing/ [ce-19507]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19507 diff --git a/doc/university/README.md b/doc/university/README.md index 203981b85ec..5edf92b3b09 100644 --- a/doc/university/README.md +++ b/doc/university/README.md @@ -11,7 +11,7 @@ and [Blog Articles](https://about.gitlab.com/blog/). Would you like to contribute to GitLab University? Then please take a look at our contribution [process](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/PROCESS.md) for more information. -## Gitlab University Curriculum +## GitLab University Curriculum The curriculum is composed of GitLab videos, screencasts, presentations, projects and external GitLab content hosted on other services and has been organized into the following sections. diff --git a/doc/university/glossary/README.md b/doc/university/glossary/README.md index 89516dba60b..6ff27e495fb 100644 --- a/doc/university/glossary/README.md +++ b/doc/university/glossary/README.md @@ -395,7 +395,7 @@ Allow you to [organize issues](../../user/project/milestones/index.md) and merge ### Mirror Repositories -A project that is setup to automatically have its branches, tags, and commits [updated from an upstream repository](https://docs.gitlab.com/ee/workflow/repository_mirroring.html). This is useful when a repository you're interested in is located on a different server, and you want to be able to browse its content and activity using the familiar GitLab interface. +A project that is set up to automatically have its branches, tags, and commits [updated from an upstream repository](https://docs.gitlab.com/ee/workflow/repository_mirroring.html). This is useful when a repository you're interested in is located on a different server, and you want to be able to browse its content and activity using the familiar GitLab interface. ### MIT License @@ -673,7 +673,7 @@ Version control is a system that records changes to a file or set of files over ### Virtual Private Cloud (VPC) -A [VPC](https://docs.gitlab.com/ce/university/glossary/README.html#virtual-private-cloud-vpc) is an on demand configurable pool of shared computing resources allocated within a public cloud environment, providing some isolation between the different users using the resources. GitLab users need to create a new Amazon VPC in order to [setup High Availability](https://docs.gitlab.com/ce/university/high-availability/aws/). +A [VPC](https://docs.gitlab.com/ce/university/glossary/README.html#virtual-private-cloud-vpc) is an on demand configurable pool of shared computing resources allocated within a public cloud environment, providing some isolation between the different users using the resources. GitLab users need to create a new Amazon VPC in order to [set up High Availability](https://docs.gitlab.com/ce/university/high-availability/aws/). ### Virtual private server (VPS) diff --git a/doc/university/high-availability/aws/README.md b/doc/university/high-availability/aws/README.md index 1bff1488746..0a7ce922de1 100644 --- a/doc/university/high-availability/aws/README.md +++ b/doc/university/high-availability/aws/README.md @@ -286,7 +286,7 @@ to make the EFS integration easier to manage. gitlab_rails['redis_port'] = 6379 Finally run reconfigure, you might find it useful to run a check and -a service status to make sure everything has been setup correctly. +a service status to make sure everything has been set up correctly. sudo gitlab-ctl reconfigure sudo gitlab-rake gitlab:check diff --git a/doc/university/support/README.md b/doc/university/support/README.md index 0cbae71d1f5..805af253367 100644 --- a/doc/university/support/README.md +++ b/doc/university/support/README.md @@ -37,7 +37,7 @@ Continue to look over remaining portions of the [University Overview](../README. Get your development machine ready to familiarize yourself with the codebase, the components, and to be prepared to reproduce issues that our users encounter - Install the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit) - - [Setup OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap) + - [Set up OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap) #### Become comfortable with the Installation processes that we support diff --git a/doc/university/training/end-user/README.md b/doc/university/training/end-user/README.md index 9b8a8db58e2..e5eb5d97e3b 100644 --- a/doc/university/training/end-user/README.md +++ b/doc/university/training/end-user/README.md @@ -80,7 +80,7 @@ git config --global user.name "Your Name" git config --global user.email you@example.com ``` -- If you don't use the global flag you can setup a different author for +- If you don't use the global flag you can set up a different author for each project - Check settings with: diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md index 311664b2bc1..d292327efbd 100644 --- a/doc/update/4.2-to-5.0.md +++ b/doc/update/4.2-to-5.0.md @@ -32,7 +32,7 @@ cd /home/git/ sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git /home/git/gitlab-shell ``` -## 3. setup gitlab-shell +## 3. set up gitlab-shell ```bash # chmod all repos and files under git diff --git a/doc/update/7.5-to-7.6.md b/doc/update/7.5-to-7.6.md index f0dfb177b79..0d45a9528b9 100644 --- a/doc/update/7.5-to-7.6.md +++ b/doc/update/7.5-to-7.6.md @@ -82,7 +82,7 @@ git diff origin/7-5-stable:config/gitlab.yml.example origin/7-6-stable:config/gi * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`][nginx] but with your settings * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your setting -#### Setup time zone (optional) +#### Set up time zone (optional) Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it. diff --git a/doc/update/7.6-to-7.7.md b/doc/update/7.6-to-7.7.md index 85de6b0c546..5e0b2ca7bcd 100644 --- a/doc/update/7.6-to-7.7.md +++ b/doc/update/7.6-to-7.7.md @@ -82,7 +82,7 @@ git diff origin/7-6-stable:config/gitlab.yml.example origin/7-7-stable:config/gi * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`][nginx] but with your settings * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your setting -#### Setup time zone (optional) +#### Set up time zone (optional) Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it. diff --git a/doc/update/7.7-to-7.8.md b/doc/update/7.7-to-7.8.md index 7cee5f79a13..f5b1ebf0a9c 100644 --- a/doc/update/7.7-to-7.8.md +++ b/doc/update/7.7-to-7.8.md @@ -83,7 +83,7 @@ git diff origin/7-7-stable:config/gitlab.yml.example origin/7-8-stable:config/gi * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings. * A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. -#### Setup time zone (optional) +#### Set up time zone (optional) Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it. diff --git a/doc/update/7.8-to-7.9.md b/doc/update/7.8-to-7.9.md index 5a8b689dbc1..0db7698936b 100644 --- a/doc/update/7.8-to-7.9.md +++ b/doc/update/7.8-to-7.9.md @@ -85,7 +85,7 @@ git diff origin/7-8-stable:config/gitlab.yml.example origin/7-9-stable:config/gi * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings. * A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. -#### Setup time zone (optional) +#### Set up time zone (optional) Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it. diff --git a/doc/update/7.9-to-7.10.md b/doc/update/7.9-to-7.10.md index 99df51dbb99..782fb0736e6 100644 --- a/doc/update/7.9-to-7.10.md +++ b/doc/update/7.9-to-7.10.md @@ -81,7 +81,7 @@ git diff origin/7-9-stable:config/gitlab.yml.example origin/7-10-stable:config/g * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings. * A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. -#### Setup time zone (optional) +#### Set up time zone (optional) Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it. diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md index 0b9395914f9..e14e716a5eb 100644 --- a/doc/user/gitlab_com/index.md +++ b/doc/user/gitlab_com/index.md @@ -221,7 +221,7 @@ and the following environment variables: ## Cron jobs -Periodically executed jobs by Sidekiq, to self-heal Gitlab, do external +Periodically executed jobs by Sidekiq, to self-heal GitLab, do external synchronizations, run scheduled pipelines, etc.: | Setting | GitLab.com | Default | diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md index b55946a788f..8db36c4a0e8 100644 --- a/doc/user/group/subgroups/index.md +++ b/doc/user/group/subgroups/index.md @@ -1,9 +1,8 @@ # Subgroups -> **Notes:** -> - [Introduced][ce-2772] in GitLab 9.0. -> - Not available when using MySQL as external database (support removed in -> GitLab 9.3 [due to performance reasons][issue]). +NOTE: **Note:** +[Introduced][ce-2772] in GitLab 9.0. Not available when using MySQL as external +database (support removed in GitLab 9.3 [due to performance reasons][issue]). With subgroups (aka nested groups or hierarchical groups) you can have up to 20 levels of nested groups, which among other things can help you to: @@ -79,14 +78,14 @@ structure. ## Creating a subgroup -> **Notes:** -> - You need to be an Owner of a group in order to be able to create -> a subgroup. For more information check the [permissions table][permissions]. -> - For a list of words that are not allowed to be used as group names see the -> [reserved names][reserved]. -> - Users can always create subgroups if they are explicitly added as an Owner to -> a parent group even if group creation is disabled by an administrator in their -> settings. +NOTE: **Note:** +You need to be an Owner of a group in order to be able to create a subgroup. For +more information check the [permissions table][permissions]. +For a list of words that are not allowed to be used as group names see the +[reserved names][reserved]. +Users can always create subgroups if they are explicitly added as an Owner to +a parent group even if group creation is disabled by an administrator in their +settings. To create a subgroup: @@ -136,12 +135,15 @@ From the image above, we can deduct the following things: ### Overriding the ancestor group membership ->**Note:** +NOTE: **Note:** You need to be an Owner of a group in order to be able to add members to it. +NOTE: **Note:** +A user's permissions in a subgroup cannot be lower than in any of its ancestor groups. +Therefore, you cannot reduce a user's permissions in a subgroup with respect to its ancestor groups. + To override a user's membership of an ancestor group (the first group they were -added to), simply add the user in the new subgroup again, but with different -permissions. +added to), add the user to the new subgroup again with a higher set of permissions. For example, if User0 was first added to group `group-1/group-1-1` with Developer permissions, then they will inherit those permissions in every other subgroup diff --git a/doc/user/index.md b/doc/user/index.md index 649c0b664a5..08995032cb1 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -96,7 +96,7 @@ directly from GitLab. No third-party integrations needed. - [GitLab Auto Deploy](../ci/autodeploy/index.md): Deploy your application out-of-the-box with GitLab Auto Deploy. - [Review Apps](../ci/review_apps/index.md): Live-preview the changes introduced by a merge request with Review Apps. - [GitLab Pages](project/pages/index.md): Publish your static site directly from -GitLab with Gitlab Pages. You can build, test, and deploy any Static Site Generator with Pages. +GitLab with GitLab Pages. You can build, test, and deploy any Static Site Generator with Pages. - [GitLab Container Registry](project/container_registry.md): Build and deploy Docker images with Container Registry. diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md index 910bd20f882..49f0ce2cd79 100644 --- a/doc/user/profile/account/delete_account.md +++ b/doc/user/profile/account/delete_account.md @@ -1,5 +1,8 @@ # Deleting a User Account +NOTE: **Note:** +Deleting a user will delete all projects in that user namespace. + - As a user, you can delete your own account by navigating to **Settings** > **Account** and selecting **Delete account** - As an admin, you can delete a user account by navigating to the **Admin Area**, selecting the **Users** tab, selecting a user, and clicking on **Delete user** diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md index 8838efb18fe..e5411662511 100644 --- a/doc/user/profile/account/two_factor_authentication.md +++ b/doc/user/profile/account/two_factor_authentication.md @@ -69,7 +69,7 @@ of recovery codes. 1. Go to **Account**. 1. Click **Enable Two-Factor Authentication**. 1. Plug in your U2F device. -1. Click on **Setup New U2F Device**. +1. Click on **Set up New U2F Device**. 1. A light will start blinking on your device. Activate it by pressing its button. You will see a message indicating that your device was successfully set up. diff --git a/doc/user/project/container_registry.md b/doc/user/project/container_registry.md index df850d4f68d..2709ebb6f05 100644 --- a/doc/user/project/container_registry.md +++ b/doc/user/project/container_registry.md @@ -27,7 +27,7 @@ to enable it. 1. First, ask your system administrator to enable GitLab Container Registry following the [administration documentation](../../administration/container_registry.md). If you are using GitLab.com, this is enabled by default so you can start using - the Registry immediately. Currently there is a soft (10GB) size restriction for + the Registry immediately. Currently there is a soft (10GB) size restriction for registry on GitLab.com, as part of the [repository size limit](repository/index.html#repository-size). 1. Go to your [project's General settings](settings/index.md#sharing-and-permissions) and enable the **Container Registry** feature on your project. For new @@ -216,7 +216,7 @@ needs to trust the mitmproxy SSL certificates for this to work. The following installation instructions assume you are running Ubuntu: -1. Install mitmproxy (see http://docs.mitmproxy.org/en/stable/install.html) +1. [Install mitmproxy](https://docs.mitmproxy.org/stable/overview-installation/). 1. Run `mitmproxy --port 9000` to generate its certificates. Enter <kbd>CTRL</kbd>-<kbd>C</kbd> to quit. 1. Install the certificate from `~/.mitmproxy` to your system: @@ -245,7 +245,7 @@ This will run mitmproxy on port `9000`. In another window, run: curl --proxy http://localhost:9000 https://httpbin.org/status/200 ``` -If everything is setup correctly, you will see information on the mitmproxy window and +If everything is set up correctly, you will see information on the mitmproxy window and no errors from the curl commands. #### Running the Docker daemon with a proxy @@ -293,4 +293,4 @@ Once the right permissions were set, the error will go away. [docker-docs]: https://docs.docker.com/engine/userguide/intro/ [pat]: ../profile/personal_access_tokens.md [pdt]: ../project/deploy_tokens/index.md -[reconfigure]: ../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
\ No newline at end of file +[reconfigure]: ../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure diff --git a/doc/user/project/cycle_analytics.md b/doc/user/project/cycle_analytics.md index 7e788ae6220..ea843054f8e 100644 --- a/doc/user/project/cycle_analytics.md +++ b/doc/user/project/cycle_analytics.md @@ -154,7 +154,7 @@ You can [read more about permissions][permissions] in general. Learn more about Cycle Analytics in the following resources: -- [Cycle Analytics feature page](https://about.gitlab.com/solutions/cycle-analytics/) +- [Cycle Analytics feature page](https://about.gitlab.com/features/cycle-analytics/) - [Cycle Analytics feature preview](https://about.gitlab.com/2016/09/16/feature-preview-introducing-cycle-analytics/) - [Cycle Analytics feature highlight](https://about.gitlab.com/2016/09/21/cycle-analytics-feature-highlight/) diff --git a/doc/user/project/deploy_tokens/index.md b/doc/user/project/deploy_tokens/index.md index 0b9b49f326f..ff647b2f0a2 100644 --- a/doc/user/project/deploy_tokens/index.md +++ b/doc/user/project/deploy_tokens/index.md @@ -51,7 +51,7 @@ To download a repository using a Deploy Token, you just need to: ```bash -git clone http://<username>:<deploy_token>@gitlab.example.com/tanuki/awesome_project.git +git clone https://<username>:<deploy_token>@gitlab.example.com/tanuki/awesome_project.git ``` Just replace `<username>` and `<deploy_token>` with the proper values diff --git a/doc/user/project/img/issue_board_milestone_lists.png b/doc/user/project/img/issue_board_milestone_lists.png Binary files differnew file mode 100644 index 00000000000..91926f58f87 --- /dev/null +++ b/doc/user/project/img/issue_board_milestone_lists.png diff --git a/doc/user/project/img/issue_board_summed_weights.png b/doc/user/project/img/issue_board_summed_weights.png Binary files differnew file mode 100644 index 00000000000..2288d767d8c --- /dev/null +++ b/doc/user/project/img/issue_board_summed_weights.png diff --git a/doc/user/project/img/issue_boards_core.png b/doc/user/project/img/issue_boards_core.png Binary files differnew file mode 100755 index 00000000000..9e819160861 --- /dev/null +++ b/doc/user/project/img/issue_boards_core.png diff --git a/doc/user/project/img/issue_boards_premium.png b/doc/user/project/img/issue_boards_premium.png Binary files differnew file mode 100755 index 00000000000..bd9164b2961 --- /dev/null +++ b/doc/user/project/img/issue_boards_premium.png diff --git a/doc/user/project/integrations/hangouts_chat.md b/doc/user/project/integrations/hangouts_chat.md index 47525617d95..20a71da927c 100644 --- a/doc/user/project/integrations/hangouts_chat.md +++ b/doc/user/project/integrations/hangouts_chat.md @@ -15,7 +15,7 @@ See also [the Hangouts Chat documentation for configuring incoming webhooks](htt ## On GitLab -When you have the **Webhook URL** for your Hangouts Chat room webhook, you can setup the GitLab service. +When you have the **Webhook URL** for your Hangouts Chat room webhook, you can set up the GitLab service. 1. Navigate to the [Integrations page](project_services.md#accessing-the-project-services) in your project's settings, i.e. **Project > Settings > Integrations**. 1. Select the **Hangouts Chat** project service to configure it. diff --git a/doc/user/project/integrations/img/webhooks_ssl.png b/doc/user/project/integrations/img/webhooks_ssl.png Binary files differindex f023e9665f2..e5777a2e99b 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/integrations/jira.md b/doc/user/project/integrations/jira.md index b3821cf8391..ba8b79b911b 100644 --- a/doc/user/project/integrations/jira.md +++ b/doc/user/project/integrations/jira.md @@ -49,7 +49,7 @@ We have split this stage in steps so it is easier to follow. 1. The next step is to create a new user (e.g., `gitlab`) who has write access to projects in JIRA. Enter the user's name and a _valid_ e-mail address - since JIRA sends a verification e-mail to set-up the password. + since JIRA sends a verification e-mail to set up the password. _**Note:** JIRA creates the username automatically by using the e-mail prefix. You can change it later if you want._ diff --git a/doc/user/project/integrations/mattermost.md b/doc/user/project/integrations/mattermost.md index 3e77823a6aa..89de1fe4dcb 100644 --- a/doc/user/project/integrations/mattermost.md +++ b/doc/user/project/integrations/mattermost.md @@ -38,7 +38,7 @@ At the end, fill in your Mattermost details: | Field | Description | | ----- | ----------- | -| **Webhook** | The incoming webhook URL which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo… | +| **Webhook** | The incoming webhook URL which you have to set up on Mattermost, it will be something like: http://mattermost.example/hooks/5xo… | | **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. | | **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. | diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md index 488f61c77a3..e031dcad2c3 100644 --- a/doc/user/project/integrations/mattermost_slash_commands.md +++ b/doc/user/project/integrations/mattermost_slash_commands.md @@ -102,7 +102,7 @@ in a new slash command.  -1. After you setup all the values, copy the token (we will use it below) and +1. After you set up all the values, copy the token (we will use it below) and click **Done**.  diff --git a/doc/user/project/integrations/microsoft_teams.md b/doc/user/project/integrations/microsoft_teams.md index 140c6738a49..ca32689910c 100644 --- a/doc/user/project/integrations/microsoft_teams.md +++ b/doc/user/project/integrations/microsoft_teams.md @@ -25,7 +25,7 @@ At the end fill in your Microsoft Teams details: | Field | Description | | ----- | ----------- | -| **Webhook** | The incoming webhook URL which you have to setup on Microsoft Teams. | +| **Webhook** | The incoming webhook URL which you have to set up on Microsoft Teams. | | **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. | After you are all done, click **Save changes** for the changes to take effect. diff --git a/doc/user/project/integrations/mock_ci.md b/doc/user/project/integrations/mock_ci.md index 6aefe5dbded..8b1908c46fe 100644 --- a/doc/user/project/integrations/mock_ci.md +++ b/doc/user/project/integrations/mock_ci.md @@ -2,7 +2,7 @@ **NB: This service is only listed if you are in a development environment!** -To setup the mock CI service server, respond to the following endpoints +To set up the mock CI service server, respond to the following endpoints - `commit_status`: `#{project.namespace.path}/#{project.path}/status/#{sha}.json` - Have your service return `200 { status: ['failed'|'canceled'|'running'|'pending'|'success'|'success_with_warnings'|'skipped'|'not_found'] }` diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md index f687027e8c8..0b61a41aab0 100644 --- a/doc/user/project/integrations/prometheus.md +++ b/doc/user/project/integrations/prometheus.md @@ -8,7 +8,7 @@ within the GitLab interface.  -There are two ways to setup Prometheus integration, depending on where your apps are running: +There are two ways to set up Prometheus integration, depending on where your apps are running: * For deployments on Kubernetes, GitLab can automatically [deploy and manage Prometheus](#managed-prometheus-on-kubernetes) * For other deployment targets, simply [specify the Prometheus server](#manual-configuration-of-prometheus). diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md index 6104eadde35..5a38f5d8aed 100644 --- a/doc/user/project/integrations/webhooks.md +++ b/doc/user/project/integrations/webhooks.md @@ -57,6 +57,14 @@ You can turn this off in the webhook settings in your GitLab projects.  +## Branch filtering + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/20338) in GitLab 11.3. + +Push events can be filtered by branch using a branch name or wildcard pattern +to limit which push events are sent to your webhook endpoint. By default the +field is blank causing all push events to be sent to your webhook endpoint. + ## Events Below are described the supported events. @@ -1162,7 +1170,7 @@ You can trigger the webhook manually. Sample data from the project will be used. ## Troubleshoot webhooks -Gitlab stores each perform of the webhook. +GitLab stores each perform of the webhook. You can find records for last 2 days in "Recent Deliveries" section on the edit page of each webhook.  diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md index 7c6d547d626..464fa5987c1 100644 --- a/doc/user/project/issue_board.md +++ b/doc/user/project/issue_board.md @@ -2,13 +2,44 @@ > [Introduced][ce-5554] in [GitLab 8.11](https://about.gitlab.com/2016/08/22/gitlab-8-11-released/#issue-board). +## Overview + The GitLab Issue Board is a software project management tool used to plan, organize, and visualize a workflow for a feature or product release. It can be used as a [Kanban] or a [Scrum] board. - +It provides perfect pairing between issue tracking and project management, +keeping everything in the same place, so that you don't need to jump +between different platforms to organize your workflow. -## Overview +With GitLab Issue Boards, you organize your issues in lists that correspond to +their assigned labels, visualizing issues designed as cards throughout that lists. + +You define your process and GitLab organizes it for you. You add your labels +then create the corresponding list to pull in your existing issues. When +you're ready, you can drag and drop your issue cards from one step to the next. + + + +**<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> +Watch a [video presentation](https://youtu.be/UWsJ8tkHAa8) of +Issue Boards** (version introduced in GitLab 8.11 - August 2016). + +### Advanced features of Issue Boards + +With [GitLab Starter](https://about.gitlab.com/pricing/), you can create +[multiple issue boards](#multiple-issue-boards) for a given project. **[STARTER]** + +With [GitLab Premium](https://about.gitlab.com/pricing/), you can also create multiple +issue boards for your groups, and add lists for [assignees](#assignee-lists) and +[milestones](#milestone-lists). **[PREMIUM]** + +Check all the [advanced features of Issue Boards](#gitlab-enterprise-features-for-issue-boards) +below. + + + +## How it works The Issue Board builds on GitLab's existing [issue tracking functionality](issues/index.md#issue-tracker) and @@ -28,15 +59,12 @@ and deploy from one single platform. Issue Boards help you to visualize and manage the entire process _in_ GitLab. With [Multiple Issue Boards](#use-cases-for-multiple-issue-boards), available -only in [GitLab Enterprise Edition](#features-per-tier), +only in [different tiers of GitLab Enterprise Edition](#gitlab-enterprise-features-for-issue-boards), you go even further, as you can not only keep yourself and your project organized from a broader perspective with one Issue Board per project, but also allow your team members to organize their own workflow by creating multiple Issue Boards within the same project. -For a visual overview, see our [Issue Board feature page](https://about.gitlab.com/features/issueboard/) -on about.gitlab.com or our [video introduction to Issue Boards](https://www.youtube.com/watch?v=UWsJ8tkHAa8). - ## Use cases There are many ways to use GitLab Issue Boards tailored to your own preferred workflow. @@ -111,11 +139,6 @@ to improve their workflow with multiple boards. Create lists for each of your team members and quickly drag-and-drop issues onto each team member. -## Permissions - -[Developers and up](../permissions.md) can use all the functionality of the -Issue Board, that is, create or delete lists and drag issues from one list to another. - ## Issue Board terminology - **Issue Board** - Each board represents a unique view for your issues. It can have multiple lists with each list consisting of issues represented by cards. @@ -126,6 +149,139 @@ Issue Board, that is, create or delete lists and drag issues from one list to an - **Closed** (default): shows all closed issues. Always appears as the rightmost list. - **Card** - A box in the list that represents an individual issue. The information you can see on a card consists of the issue number, the issue title, the assignee, and the labels associated with the issue. You can drag cards from one list to another to change their label or assignee from that of the source list to that of the destination list. +## Permissions + +[Developers and up](../permissions.md) can use all the functionality of the +Issue Board, that is, create or delete lists and drag issues from one list to another. + +## GitLab Enterprise features for Issue Boards + +GitLab Issue Boards are available on GitLab Core and GitLab.com Free, but some +advanced functionalities are only present in higher tiers: GitLab.com Bronze, +Silver, or Gold, or GitLab self-managed Starter, Premium, and Ultimate, as described +on the following sections. + +For a collection of [features per tier](#summary-of-features-per-tier), check the summary below. + +### Multiple Issue Boards **[STARTER]** + +> Introduced in [GitLab Enterprise Edition 8.13](https://about.gitlab.com/2016/10/22/gitlab-8-13-released/#multiple-issue-boards-ee). + +Multiple Issue Boards, as the name suggests, allow for more than one Issue Board +for a given project or group. This is great for large projects with more than one team +or in situations where a repository is used to host the code of multiple +products. + +Clicking on the current board name in the upper left corner will reveal a +menu from where you can create another Issue Board and rename or delete the +existing one. + +NOTE: **Note:** +The Multiple Issue Boards feature is available for +**projects in GitLab Starter Edition** and for **groups in GitLab Premium Edition**. + + + +### Configurable Issue Boards **[STARTER]** + +> Introduced in [GitLab Starter Edition 10.2](https://about.gitlab.com/2017/11/22/gitlab-10-2-released/#issue-boards-configuration). + +An Issue Board can be associated with a GitLab [Milestone](milestones/index.md#milestones), +[Labels](labels.md), Assignee and Weight +which will automatically filter the Board issues according to these fields. +This allows you to create unique boards according to your team's need. + + + +You can define the scope of your board when creating it or by clicking on the "Edit board" button. Once a milestone, assignee or weight is assigned to an Issue Board, you will no longer be able to filter +through these in the search bar. In order to do that, you need to remove the desired scope (e.g. milestone, assignee or weight) from the Issue Board. + + + +If you don't have editing permission in a board, you're still able to see the configuration by clicking on "View scope". + + + +### Focus mode **[STARTER]** + +> Introduced in [GitLab Starter 9.1](https://about.gitlab.com/2017/04/22/gitlab-9-1-released/#issue-boards-focus-mode-ees-eep). + +Click the button at the top right to toggle focus mode on and off. In focus mode, the navigation UI is hidden, allowing you to focus on issues in the board. + + + +### Sum of Issue Weights **[STARTER]** + +The top of each list indicates the sum of issue weights for the issues that +belong to that list. This is useful when using boards for capacity allocation, +especially in combination with [assignee lists](#assignee-lists). + + + +### Group Issue Boards **[PREMIUM]** + +> Introduced in [GitLab Premium 10.0](https://about.gitlab.com/2017/09/22/gitlab-10-0-released/#group-issue-boards). + +Accessible at the group navigation level, a group issue board offers the same features as a project-level board, +but it can display issues from all projects in that +group and its descendant subgroups. Similarly, you can only filter by group labels for these +boards. When updating milestones and labels for an issue through the sidebar update mechanism, again only +group-level objects are available. + +NOTE: **Note:** +Multiple group issue boards were originally introduced in [GitLab 10.0 Premium](https://about.gitlab.com/2017/09/22/gitlab-10-0-released/#group-issue-boards) and +one group issue board per group was made available in GitLab 10.6 Core. + + + +### Assignee lists **[PREMIUM]** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/5784) in GitLab 11.0 Premium. + +Like a regular list that shows all issues that have the list label, you can add +an assignee list that shows all issues assigned to the given user. +You can have a board with both label lists and assignee lists. To add an +assignee list: + +1. Click **Add list**. +1. Select the **Assignee list** tab. +1. Search and click on the user you want to add as an assignee. + +Now that the assignee list is added, you can assign or unassign issues to that user +by [dragging issues](#dragging-issues-between-lists) to and/or from an assignee list. +To remove an assignee list, just as with a label list, click the trash icon. + + + +### Milestone lists **[PREMIUM]** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/6469) in GitLab 11.2 Premium. + +As of 11.2, you're also able to create lists of a milestone. As the name states, +these are lists that filter issues by the assigned milestone, giving you more +freedom and visibility on the Issue Board. To do so: + +1. Click **Add list**. +1. Select the **Milestone** tab. +1. Search and click on the milestone. + +Similar to the assignee lists, you're now able to [drag issues](#dragging-issues-between-lists) +to and/or from a milestone list to manipulate the milestone of the dragged issues. +As on another list types, click on the trash icon to remove it. + + + +### Summary of features per tier + +Different issue board features are available in different [GitLab tiers](https://about.gitlab.com/pricing/), as shown in the following table: + +| Tier | Number of Project Issue Boards | Number of Group Issue Boards | Configurable Issue Boards | Assignee Lists | +|----------|--------------------------------|------------------------------|---------------------------|----------------| +| Core / Free | 1 | 1 | No | No | +| Starter / Bronze | Multiple | 1 | Yes | No | +| Premium / Silver | Multiple | Multiple | Yes | Yes | +| Ultimate / Gold | Multiple | Multiple | Yes | Yes | + ## Actions you can take on an Issue Board - [Create a new list](#creating-a-new-list). @@ -142,7 +298,7 @@ Issue Board, that is, create or delete lists and drag issues from one list to an If you are not able to perform one or more of the things above, make sure you have the right [permissions](#permissions). -## First time using the Issue Board +### First time using the Issue Board The first time you navigate to your Issue Board, you will be presented with a default list (**Done**) and a welcoming message that gives @@ -157,7 +313,7 @@ which means the system has no way of populating them automatically. That's of course if the predefined labels don't already exist. If any of them does exist, the list will be created and filled with the issues that have that label. -## Creating a new list +### Creating a new list Create a new list by clicking on the **Add list** button at the upper right corner of the Issue Board. @@ -172,7 +328,7 @@ To create a list for a label that doesn't yet exist, simply create the label by choosing **Create new label**. The label will be created on-the-fly and it will be immediately added to the dropdown. You can now choose it to create a list. -## Deleting a list +### Deleting a list To delete a list from the Issue Board use the small trash icon that is present in the list's heading. A confirmation dialog will appear for you to confirm. @@ -180,7 +336,7 @@ in the list's heading. A confirmation dialog will appear for you to confirm. Deleting a list doesn't have any effect in issues and labels, it's just the list view that is removed. You can always add it back later if you need. -## Adding issues to a list +### Adding issues to a list You can add issues to a list by clicking the **Add issues** button that is present in the upper right corner of the Issue Board. This will open up a modal @@ -192,7 +348,7 @@ the list by filtering by author, assignee, milestone and label.  -## Removing an issue from a list +### Removing an issue from a list Removing an issue from a list can be done by clicking on the issue card and then clicking the **Remove from board** button in the sidebar. Under the hood, the @@ -201,7 +357,7 @@ board itself.  -## Issue ordering in a list +### Issue ordering in a list When visiting a board, issues appear ordered in any list. You are able to change that order simply by dragging and dropping the issues. The changed order will be saved @@ -224,7 +380,7 @@ a given board inside your GitLab instance, any time those two issues are subsequ loaded in any board in the same instance (could be a different project board or a different group board, for example), that ordering will be maintained. -## Filtering issues +### Filtering issues You should be able to use the filters on top of your Issue Board to show only the results you want. This is similar to the filtering used in the issue tracker @@ -232,7 +388,7 @@ since the metadata from the issues and labels are re-used in the Issue Board. You can filter by author, assignee, milestone and label. -## Creating workflows +### Creating workflows By reordering your lists, you can create workflows. As lists in Issue Boards are based on labels, it works out of the box with your existing issues. So if you've @@ -267,89 +423,7 @@ to another list the label changes and a system not is recorded.  -## Multiple Issue Boards **[STARTER]** - -> Introduced in [GitLab Enterprise Edition 8.13](https://about.gitlab.com/2016/10/22/gitlab-8-13-released/#multiple-issue-boards-ee). - -Multiple Issue Boards, as the name suggests, allow for more than one Issue Board -for a given project or group. This is great for large projects with more than one team -or in situations where a repository is used to host the code of multiple -products. - -Clicking on the current board name in the upper left corner will reveal a -menu from where you can create another Issue Board and rename or delete the -existing one. - -NOTE: **Note:** -The Multiple Issue Boards feature is available for -**projects in GitLab Starter Edition** and for **groups in GitLab Premium Edition**. - - - -## Configurable Issue Boards **[STARTER]** - -> Introduced in [GitLab Starter Edition 10.2](https://about.gitlab.com/2017/11/22/gitlab-10-2-released/#issue-boards-configuration). - -An Issue Board can be associated with GitLab [Milestone](milestones/index.md#milestones), -[Labels](labels.md), Assignee and Weight -which will automatically filter the Board issues according to these fields. -This allows you to create unique boards according to your team's need. - - - -You can define the scope of your board when creating it or by clicking on the "Edit board" button. Once a milestone, assignee or weight is assigned to an Issue Board, you will no longer be able to filter -through these in the search bar. In order to do that, you need to remove the desired scope (e.g. milestone, assignee or weight) from the Issue Board. - - - -If you don't have editing permission in a board, you're still able to see the configuration by clicking on "View scope". - - - -## Focus mode **[STARTER]** - -> Introduced in [GitLab Starter 9.1](https://about.gitlab.com/2017/04/22/gitlab-9-1-released/#issue-boards-focus-mode-ees-eep). - -Click the button at the top right to toggle focus mode on and off. In focus mode, the navigation UI is hidden, allowing you to focus on issues in the board. - - - -## Group Issue Boards **[PREMIUM]** - -> Introduced in [GitLab Premium 10.0](https://about.gitlab.com/2017/09/22/gitlab-10-0-released/#group-issue-boards). - -Accessible at the group navigation level, a group issue board offers the same features as a project-level board, -but it can display issues from all projects in that -group and its descendant subgroups. Similarly, you can only filter by group labels for these -boards. When updating milestones and labels for an issue through the sidebar update mechanism, again only -group-level objects are available. - -NOTE: **Note:** -Multiple group issue boards were originally introduced in [GitLab 10.0 Premium](https://about.gitlab.com/2017/09/22/gitlab-10-0-released/#group-issue-boards) and -one group issue board per group was made available in GitLab 10.6 Core. - - - -## Assignee lists **[PREMIUM]** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/5784) in GitLab 11.0 Premium. - -Like a regular list that shows all issues that have the list label, you can add -an assignee list that shows all issues assigned to the given user. -You can have a board with both label lists and assignee lists. To add an -assignee list: - -1. Click **Add list**. -1. Select the **Assignee list** tab. -1. Search and click on the user you want to add as an assignee. - -Now that the assignee list is added, you can assign or unassign issues to that user -by [dragging issues](#dragging-issues-between-lists) to and/or from an assignee list. -To remove an assignee list, just as with a label list, click the trash icon. - - - -## Dragging issues between lists +### Dragging issues between lists When dragging issues between lists, different behavior occurs depending on the source list and the target list. @@ -360,17 +434,6 @@ When dragging issues between lists, different behavior occurs depending on the s | From label `A` list | `A` removed | Issue closed | `A` removed<br/>`B` added | `Bob` assigned | | From assignee `Alice` list | `Alice` unassigned | Issue closed | `B` added | `Alice` unassigned<br/>`Bob` assigned | -## Features per tier - -Different issue board features are available in different [GitLab tiers](https://about.gitlab.com/pricing/), as shown in the following table: - -| Tier | Number of Project Issue Boards | Number of Group Issue Boards | Configurable Issue Boards | Assignee Lists | -|----------|--------------------------------|------------------------------|---------------------------|----------------| -| Core | 1 | 1 | No | No | -| Starter | Multiple | 1 | Yes | No | -| Premium | Multiple | Multiple | Yes | Yes | -| Ultimate | Multiple | Multiple | Yes | Yes | - ## Tips A few things to remember: diff --git a/doc/user/project/issues/issues_functionalities.md b/doc/user/project/issues/issues_functionalities.md index 46f25417fde..631f511b5fa 100644 --- a/doc/user/project/issues/issues_functionalities.md +++ b/doc/user/project/issues/issues_functionalities.md @@ -69,7 +69,7 @@ Learn more on the [Time Tracking documentation](../../../workflow/time_tracking. #### 6. Due date When you work on a tight schedule, and it's important to -have a way to setup a deadline for implementations and for solving +have a way to set up a deadline for implementations and for solving problems. This can be facilitated by the [due date](due_dates.md)). Due dates can be changed as many times as needed. diff --git a/doc/user/project/pipelines/job_artifacts.md b/doc/user/project/pipelines/job_artifacts.md index fc3970e2014..a8b47558c99 100644 --- a/doc/user/project/pipelines/job_artifacts.md +++ b/doc/user/project/pipelines/job_artifacts.md @@ -151,6 +151,20 @@ For example: https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/master/browse?job=coverage ``` +There is also a URL to specific files, including html files that +are shown in [GitLab Pages](../../../administration/pages/index.md): + +``` +https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/file/<path>?job=<job_name> +``` + +For example, when a job `coverage` creates the artifact `htmlcov/index.html`, +you can access it at: + +``` +https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/master/file/htmlcov/index.html?job=coverage +``` + The latest builds are also exposed in the UI in various places. Specifically, look for the download button in: diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md index 1c3915a5fdd..4d016277824 100644 --- a/doc/user/project/repository/index.md +++ b/doc/user/project/repository/index.md @@ -158,7 +158,9 @@ Find it under your project's **Repository > Graph**. ## Repository Languages For the default branch of each repository, GitLab will determine what programming languages -were used and display this on the projects pages. +were used and display this on the projects pages. If this information is missing, it will +be added after updating the default branch on the project. This process can take up to 5 +minutes.  diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md index ad0ef60373c..127a30d6669 100644 --- a/doc/user/project/wiki/index.md +++ b/doc/user/project/wiki/index.md @@ -40,11 +40,6 @@ support Markdown, RDoc and AsciiDoc. For Markdown based pages, all the [Markdown features](../../markdown.md) are supported and for links there is some [wiki specific](../../markdown.md#wiki-specific-markdown) behavior. ->**Note:** -The wiki is based on a Git repository and contains only text files. Uploading -files via the web interface will upload them in GitLab itself, and they will -not be available if you clone the wiki repo locally. - In the web interface the commit message is optional, but the GitLab Wiki is based on Git and needs a commit message, so one will be created for you if you do not enter one. @@ -53,6 +48,14 @@ When you're ready, click the **Create page** and the new page will be created.  +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/33475) in GitLab 11.3. + +Starting with GitLab 11.3, any file that is uploaded to the wiki via GitLab's +interface will be stored in the wiki Git repository, and it will be available +if you clone the wiki repository locally. All uploaded files prior to GitLab +11.3 are stored in GitLab itself. If you want them to be part of the wiki's Git +repository, you will have to upload them again. + ## Editing a wiki page To edit a page, simply click on the **Edit** button. From there on, you can diff --git a/doc/workflow/lfs/lfs_administration.md b/doc/workflow/lfs/lfs_administration.md index 3f9ffedd61a..ec5943fd51b 100644 --- a/doc/workflow/lfs/lfs_administration.md +++ b/doc/workflow/lfs/lfs_administration.md @@ -54,7 +54,7 @@ to offload local hard disk R/W operations, and free up disk space significantly. GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](http://fog.io/about/provider_documentation.html) to check which storage services can be integrated with GitLab. You can also use external object storage in a private local network. For example, -[Minio](https://www.minio.io/) is a standalone object storage service, is easy to setup, and works well with GitLab instances. +[Minio](https://www.minio.io/) is a standalone object storage service, is easy to set up, and works well with GitLab instances. GitLab provides two different options for the uploading mechanism: "Direct upload" and "Background upload". @@ -95,6 +95,7 @@ Here is a configuration example with S3. | `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com | | `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) | | `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false | +| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false Here is a configuration example with GCS. diff --git a/lib/api/commits.rb b/lib/api/commits.rb index fcaff35459e..5aeffc8fb99 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -73,7 +73,26 @@ module API params do requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.', allow_blank: false requires :commit_message, type: String, desc: 'Commit message' - requires :actions, type: Array[Hash], desc: 'Actions to perform in commit' + requires :actions, type: Array, desc: 'Actions to perform in commit' do + requires :action, type: String, desc: 'The action to perform, `create`, `delete`, `move`, `update`, `chmod`', values: %w[create update move delete chmod].freeze + requires :file_path, type: String, desc: 'Full path to the file. Ex. `lib/class.rb`' + given action: ->(action) { action == 'move' } do + requires :previous_path, type: String, desc: 'Original full path to the file being moved. Ex. `lib/class1.rb`' + end + given action: ->(action) { %w[create move].include? action } do + optional :content, type: String, desc: 'File content' + end + given action: ->(action) { action == 'update' } do + requires :content, type: String, desc: 'File content' + end + optional :encoding, type: String, desc: '`text` or `base64`', default: 'text', values: %w[text base64] + given action: ->(action) { %w[update move delete].include? action } do + optional :last_commit_id, type: String, desc: 'Last known file commit id' + end + given action: ->(action) { action == 'chmod' } do + requires :execute_filemode, type: Boolean, desc: 'When `true/false` enables/disables the execute flag on the file.' + end + end optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from' optional :author_email, type: String, desc: 'Author email for commit' optional :author_name, type: String, desc: 'Author name for commit' diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0fec3dc3dc4..12c4340c1ba 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -53,7 +53,7 @@ module API class User < UserBasic expose :created_at, if: ->(user, opts) { Ability.allowed?(opts[:current_user], :read_user_profile, user) } - expose :bio, :location, :skype, :linkedin, :twitter, :website_url, :organization + expose :bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization end class UserActivity < Grape::Entity diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 30abd0b63e9..9bcdfc8cb15 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -11,10 +11,18 @@ module API params do optional :scope, type: String, values: Ci::Runner::AVAILABLE_STATUSES, desc: 'The scope of specific runners to show' + optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES, + desc: 'The type of the runners to show' + optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES, + desc: 'The status of the runners to show' use :pagination end get do - runners = filter_runners(current_user.ci_owned_runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES) + runners = current_user.ci_owned_runners + runners = filter_runners(runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES) + runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES) + runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES) + present paginate(runners), with: Entities::Runner end @@ -24,11 +32,20 @@ module API params do optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES, desc: 'The scope of specific runners to show' + optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES, + desc: 'The type of the runners to show' + optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES, + desc: 'The status of the runners to show' use :pagination end get 'all' do authenticated_as_admin! - runners = filter_runners(Ci::Runner.all, params[:scope]) + + runners = Ci::Runner.all + runners = filter_runners(runners, params[:scope]) + runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES) + runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES) + present paginate(runners), with: Entities::Runner end @@ -116,10 +133,18 @@ module API params do optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES, desc: 'The scope of specific runners to show' + optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES, + desc: 'The type of the runners to show' + optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES, + desc: 'The status of the runners to show' use :pagination end get ':id/runners' do - runners = filter_runners(Ci::Runner.owned_or_instance_wide(user_project.id), params[:scope]) + runners = Ci::Runner.owned_or_instance_wide(user_project.id) + runners = filter_runners(runners, params[:scope]) + runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES) + runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES) + present paginate(runners), with: Entities::Runner end diff --git a/lib/api/settings.rb b/lib/api/settings.rb index c80d9890706..8d71bd9dff1 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -117,11 +117,6 @@ module API given shared_runners_enabled: ->(val) { val } do requires :shared_runners_text, type: String, desc: 'Shared runners text ' end - optional :sidekiq_throttling_enabled, type: Boolean, desc: 'Enable Sidekiq Job Throttling' - given sidekiq_throttling_enabled: ->(val) { val } do - requires :sidekiq_throttling_factor, type: Float, desc: 'The factor by which the queues should be throttled. A value between 0.0 and 1.0, exclusive.' - requires :sidekiq_throttling_queues, type: Array[String], desc: 'Choose which queues you wish to throttle' - end optional :sign_in_text, type: String, desc: 'The sign in text of the GitLab application' optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5 optional :signup_enabled, type: Boolean, desc: 'Flag indicating if sign up is enabled' diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb index ad0806df8e6..4764f8e1e19 100644 --- a/lib/banzai/filter/abstract_reference_filter.rb +++ b/lib/banzai/filter/abstract_reference_filter.rb @@ -296,7 +296,7 @@ module Banzai # Returns projects for the given paths. def find_for_paths(paths) - if RequestStore.active? + if Gitlab::SafeRequestStore.active? cache = refs_cache to_query = paths - cache.keys @@ -340,7 +340,7 @@ module Banzai end def refs_cache - RequestStore["banzai_#{parent_type}_refs".to_sym] ||= {} + Gitlab::SafeRequestStore["banzai_#{parent_type}_refs".to_sym] ||= {} end def parent_type diff --git a/lib/banzai/filter/external_issue_reference_filter.rb b/lib/banzai/filter/external_issue_reference_filter.rb index b4a7a44e109..8159dcfed72 100644 --- a/lib/banzai/filter/external_issue_reference_filter.rb +++ b/lib/banzai/filter/external_issue_reference_filter.rb @@ -97,9 +97,7 @@ module Banzai private def external_issues_cached(attribute) - return project.public_send(attribute) unless RequestStore.active? # rubocop:disable GitlabSecurity/PublicSend - - cached_attributes = RequestStore[:banzai_external_issues_tracker_attributes] ||= Hash.new { |h, k| h[k] = {} } + cached_attributes = Gitlab::SafeRequestStore[:banzai_external_issues_tracker_attributes] ||= Hash.new { |h, k| h[k] = {} } cached_attributes[project.id][attribute] = project.public_send(attribute) if cached_attributes[project.id][attribute].nil? # rubocop:disable GitlabSecurity/PublicSend cached_attributes[project.id][attribute] end diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb index 68752f5bb5a..3ab154a7b1c 100644 --- a/lib/banzai/reference_parser/base_parser.rb +++ b/lib/banzai/reference_parser/base_parser.rb @@ -166,7 +166,7 @@ module Banzai # objects that have not yet been queried. For objects that have already # been queried the object is returned from the cache. def collection_objects_for_ids(collection, ids) - if RequestStore.active? + if Gitlab::SafeRequestStore.active? ids = ids.map(&:to_i) cache = collection_cache[collection_cache_key(collection)] to_query = ids - cache.keys @@ -248,7 +248,7 @@ module Banzai end def collection_cache - RequestStore[:banzai_collection_cache] ||= Hash.new do |hash, key| + Gitlab::SafeRequestStore[:banzai_collection_cache] ||= Hash.new do |hash, key| hash[key] = {} end end diff --git a/lib/banzai/request_store_reference_cache.rb b/lib/banzai/request_store_reference_cache.rb index 426131442a2..9a9704f9837 100644 --- a/lib/banzai/request_store_reference_cache.rb +++ b/lib/banzai/request_store_reference_cache.rb @@ -1,8 +1,8 @@ module Banzai module RequestStoreReferenceCache def cached_call(request_store_key, cache_key, path: []) - if RequestStore.active? - cache = RequestStore[request_store_key] ||= Hash.new do |hash, key| + if Gitlab::SafeRequestStore.active? + cache = Gitlab::SafeRequestStore[request_store_key] ||= Hash.new do |hash, key| hash[key] = Hash.new { |h, k| h[k] = {} } end diff --git a/lib/event_filter.rb b/lib/event_filter.rb index f756a211a12..24fdcd6fbb1 100644 --- a/lib/event_filter.rb +++ b/lib/event_filter.rb @@ -1,76 +1,42 @@ -class EventFilter - attr_accessor :params - - class << self - def all - 'all' - end - - def push - 'push' - end - - def merged - 'merged' - end +# frozen_string_literal: true - def issue - 'issue' - end - - def comments - 'comments' - end - - def team - 'team' - end +class EventFilter + attr_accessor :filter + + ALL = 'all' + PUSH = 'push' + MERGED = 'merged' + ISSUE = 'issue' + COMMENTS = 'comments' + TEAM = 'team' + FILTERS = [ALL, PUSH, MERGED, ISSUE, COMMENTS, TEAM].freeze + + def initialize(filter) + # Split using comma to maintain backward compatibility Ex/ "filter1,filter2" + filter = filter.to_s.split(',')[0].to_s + @filter = FILTERS.include?(filter) ? filter : ALL end - def initialize(params) - @params = if params - params.dup - else - [] # EventFilter.default_filter - end + def active?(key) + filter == key.to_s end # rubocop: disable CodeReuse/ActiveRecord def apply_filter(events) - return events if params.blank? || params == EventFilter.all - - case params - when EventFilter.push + case filter + when PUSH events.where(action: Event::PUSHED) - when EventFilter.merged + when MERGED events.where(action: Event::MERGED) - when EventFilter.comments + when COMMENTS events.where(action: Event::COMMENTED) - when EventFilter.team + when TEAM events.where(action: [Event::JOINED, Event::LEFT, Event::EXPIRED]) - when EventFilter.issue + when ISSUE events.where(action: [Event::CREATED, Event::UPDATED, Event::CLOSED, Event::REOPENED]) - end - end - # rubocop: enable CodeReuse/ActiveRecord - - def options(key) - filter = params.dup - - if filter.include? key - filter.delete key else - filter << key - end - - filter - end - - def active?(key) - if params.present? - params.include? key - else - key == EventFilter.all + events end end + # rubocop: enable CodeReuse/ActiveRecord end diff --git a/lib/feature.rb b/lib/feature.rb index f4b57376313..0e90ad9a333 100644 --- a/lib/feature.rb +++ b/lib/feature.rb @@ -28,11 +28,7 @@ class Feature end def persisted_names - if RequestStore.active? - RequestStore[:flipper_persisted_names] ||= FlipperFeature.feature_names - else - FlipperFeature.feature_names - end + Gitlab::SafeRequestStore[:flipper_persisted_names] ||= FlipperFeature.feature_names end def persisted?(feature) @@ -76,11 +72,7 @@ class Feature end def flipper - if RequestStore.active? - RequestStore[:flipper] ||= build_flipper_instance - else - @flipper ||= build_flipper_instance - end + @flipper ||= (Gitlab::SafeRequestStore[:flipper] ||= build_flipper_instance) end def build_flipper_instance diff --git a/lib/gitlab/auth/ldap/access.rb b/lib/gitlab/auth/ldap/access.rb index eeab7791643..f323d2e0f7a 100644 --- a/lib/gitlab/auth/ldap/access.rb +++ b/lib/gitlab/auth/ldap/access.rb @@ -92,12 +92,12 @@ module Gitlab if provider Gitlab::AppLogger.info( "LDAP account \"#{ldap_identity.extern_uid}\" #{reason}, " \ - "blocking Gitlab user \"#{user.name}\" (#{user.email})" + "blocking GitLab user \"#{user.name}\" (#{user.email})" ) else Gitlab::AppLogger.info( "Account is not provided by LDAP, " \ - "blocking Gitlab user \"#{user.name}\" (#{user.email})" + "blocking GitLab user \"#{user.name}\" (#{user.email})" ) end end @@ -107,7 +107,7 @@ module Gitlab Gitlab::AppLogger.info( "LDAP account \"#{ldap_identity.extern_uid}\" #{reason}, " \ - "unblocking Gitlab user \"#{user.name}\" (#{user.email})" + "unblocking GitLab user \"#{user.name}\" (#{user.email})" ) end end diff --git a/lib/gitlab/cache/request_cache.rb b/lib/gitlab/cache/request_cache.rb index 671b8e7e1b1..b96e161a5b6 100644 --- a/lib/gitlab/cache/request_cache.rb +++ b/lib/gitlab/cache/request_cache.rb @@ -26,8 +26,8 @@ module Gitlab define_method(method_name) do |*args| store = - if RequestStore.active? - RequestStore.store + if Gitlab::SafeRequestStore.active? + Gitlab::SafeRequestStore.store else ivar_name = # ! and ? cannot be used as ivar name "@cache_#{method_name.to_s.tr('!?', "\u2605\u2606")}" diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb index 5963f3eb90c..7bc482a6f48 100644 --- a/lib/gitlab/ci/config/entry/reports.rb +++ b/lib/gitlab/ci/config/entry/reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Gitlab module Ci class Config @@ -9,7 +11,7 @@ module Gitlab include Validatable include Attributable - ALLOWED_KEYS = %i[junit].freeze + ALLOWED_KEYS = %i[junit sast dependency_scanning container_scanning dast].freeze attributes ALLOWED_KEYS @@ -19,6 +21,10 @@ module Gitlab with_options allow_nil: true do validates :junit, array_of_strings_or_string: true + validates :sast, array_of_strings_or_string: true + validates :dependency_scanning, array_of_strings_or_string: true + validates :container_scanning, array_of_strings_or_string: true + validates :dast, array_of_strings_or_string: true end end diff --git a/lib/gitlab/ci/parsers.rb b/lib/gitlab/ci/parsers.rb deleted file mode 100644 index a4eccc08dfc..00000000000 --- a/lib/gitlab/ci/parsers.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gitlab - module Ci - module Parsers - def self.fabricate!(file_type) - "Gitlab::Ci::Parsers::#{file_type.classify}".constantize.new - end - end - end -end diff --git a/lib/gitlab/ci/parsers/junit.rb b/lib/gitlab/ci/parsers/junit.rb deleted file mode 100644 index d1c136f2009..00000000000 --- a/lib/gitlab/ci/parsers/junit.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Gitlab - module Ci - module Parsers - class Junit - JunitParserError = Class.new(StandardError) - - def parse!(xml_data, test_suite) - root = Hash.from_xml(xml_data) - - all_cases(root) do |test_case| - test_case = create_test_case(test_case) - test_suite.add_test_case(test_case) - end - rescue REXML::ParseException => e - raise JunitParserError, "XML parsing failed: #{e.message}" - rescue => e - raise JunitParserError, "JUnit parsing failed: #{e.message}" - end - - private - - def all_cases(root, parent = nil, &blk) - return unless root.present? - - [root].flatten.compact.map do |node| - next unless node.is_a?(Hash) - - # we allow only one top-level 'testsuites' - all_cases(node['testsuites'], root, &blk) unless parent - - # we require at least one level of testsuites or testsuite - each_case(node['testcase'], &blk) if parent - - # we allow multiple nested 'testsuite' (eg. PHPUnit) - all_cases(node['testsuite'], root, &blk) - end - end - - def each_case(testcase, &blk) - return unless testcase.present? - - [testcase].flatten.compact.map(&blk) - end - - def create_test_case(data) - if data['failure'] - status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED - system_output = data['failure'] - else - status = ::Gitlab::Ci::Reports::TestCase::STATUS_SUCCESS - system_output = nil - end - - ::Gitlab::Ci::Reports::TestCase.new( - classname: data['classname'], - name: data['name'], - file: data['file'], - execution_time: data['time'], - status: status, - system_output: system_output - ) - end - end - end - end -end diff --git a/lib/gitlab/ci/parsers/test.rb b/lib/gitlab/ci/parsers/test.rb new file mode 100644 index 00000000000..c6bc9662b07 --- /dev/null +++ b/lib/gitlab/ci/parsers/test.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Parsers + module Test + ParserNotFoundError = Class.new(StandardError) + + PARSERS = { + junit: ::Gitlab::Ci::Parsers::Test::Junit + }.freeze + + def self.fabricate!(file_type) + PARSERS.fetch(file_type.to_sym).new + rescue KeyError + raise ParserNotFoundError, "Cannot find any parser matching file type '#{file_type}'" + end + end + end + end +end diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb new file mode 100644 index 00000000000..5d7d9a751d8 --- /dev/null +++ b/lib/gitlab/ci/parsers/test/junit.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Parsers + module Test + class Junit + JunitParserError = Class.new(StandardError) + + def parse!(xml_data, test_suite) + root = Hash.from_xml(xml_data) + + all_cases(root) do |test_case| + test_case = create_test_case(test_case) + test_suite.add_test_case(test_case) + end + rescue REXML::ParseException => e + raise JunitParserError, "XML parsing failed: #{e.message}" + rescue => e + raise JunitParserError, "JUnit parsing failed: #{e.message}" + end + + private + + def all_cases(root, parent = nil, &blk) + return unless root.present? + + [root].flatten.compact.map do |node| + next unless node.is_a?(Hash) + + # we allow only one top-level 'testsuites' + all_cases(node['testsuites'], root, &blk) unless parent + + # we require at least one level of testsuites or testsuite + each_case(node['testcase'], &blk) if parent + + # we allow multiple nested 'testsuite' (eg. PHPUnit) + all_cases(node['testsuite'], root, &blk) + end + end + + def each_case(testcase, &blk) + return unless testcase.present? + + [testcase].flatten.compact.map(&blk) + end + + def create_test_case(data) + if data['failure'] + status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED + system_output = data['failure'] + else + status = ::Gitlab::Ci::Reports::TestCase::STATUS_SUCCESS + system_output = nil + end + + ::Gitlab::Ci::Reports::TestCase.new( + classname: data['classname'], + name: data['name'], + file: data['file'], + execution_time: data['time'], + status: status, + system_output: system_output + ) + end + end + end + end + end +end diff --git a/vendor/gitlab-ci-yml/Android.gitlab-ci.yml b/lib/gitlab/ci/templates/Android.gitlab-ci.yml index 5f9d54ff574..5f9d54ff574 100644 --- a/vendor/gitlab-ci-yml/Android.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Android.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml index 33ae9c6ad7e..d8fcdfac266 100644 --- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @@ -49,7 +49,7 @@ variables: POSTGRES_DB: $CI_ENVIRONMENT_SLUG KUBERNETES_VERSION: 1.8.6 - HELM_VERSION: 2.6.1 + HELM_VERSION: 2.10.0 DOCKER_DRIVER: overlay2 @@ -122,6 +122,9 @@ license_management: paths: [gl-license-management-report.json] only: - branches + only: + variables: + - $GITLAB_FEATURES =~ /\blicense_management\b/ except: variables: - $LICENSE_MANAGEMENT_DISABLED @@ -484,15 +487,11 @@ rollout 100%: } function license_management() { - if echo $GITLAB_FEATURES |grep license_management > /dev/null ; then - # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable" - LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') + # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable" + LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') - docker run --volume "$PWD:/code" \ - "registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code - else - echo "License management is not available in your subscription" - fi + docker run --volume "$PWD:/code" \ + "registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code } function sast() { @@ -605,7 +604,6 @@ rollout 100%: --set postgresql.postgresPassword="$POSTGRES_PASSWORD" \ --set postgresql.postgresDatabase="$POSTGRES_DB" \ --namespace="$KUBE_NAMESPACE" \ - --version="$CI_PIPELINE_ID-$CI_JOB_ID" \ "$name" \ chart/ diff --git a/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml index 2d218b2e164..2d218b2e164 100644 --- a/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/C++.gitlab-ci.yml b/lib/gitlab/ci/templates/C++.gitlab-ci.yml index c83c49d8c95..c83c49d8c95 100644 --- a/vendor/gitlab-ci-yml/C++.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/C++.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Chef.gitlab-ci.yml b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml index 4d5b6484d6e..4d5b6484d6e 100644 --- a/vendor/gitlab-ci-yml/Chef.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Clojure.gitlab-ci.yml b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml index f066285b1ad..f066285b1ad 100644 --- a/vendor/gitlab-ci-yml/Clojure.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml index 36386a19fdc..36386a19fdc 100644 --- a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Django.gitlab-ci.yml b/lib/gitlab/ci/templates/Django.gitlab-ci.yml index 57afcbbe8b5..57afcbbe8b5 100644 --- a/vendor/gitlab-ci-yml/Django.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Django.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml b/lib/gitlab/ci/templates/Docker.gitlab-ci.yml index eeefadaa019..eeefadaa019 100644 --- a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Docker.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml index cf9c731637c..cf9c731637c 100644 --- a/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml b/lib/gitlab/ci/templates/Go.gitlab-ci.yml index d572d7a1edc..d572d7a1edc 100644 --- a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Go.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml index 48d98dddfad..48d98dddfad 100644 --- a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Grails.gitlab-ci.yml b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml index 7fc698d50cf..7fc698d50cf 100644 --- a/vendor/gitlab-ci-yml/Grails.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Julia.gitlab-ci.yml b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml index 140cb4635f3..04c21b4725d 100644 --- a/vendor/gitlab-ci-yml/Julia.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml @@ -1,4 +1,4 @@ -# An example .gitlab-ci.yml file to test (and optionally report the coverage +# This is an example .gitlab-ci.yml file to test (and optionally report the coverage # results of) your [Julia][1] packages. Please refer to the [documentation][2] # for more information about package development in Julia. # @@ -6,7 +6,7 @@ # whatever name you have given to your package. # # [1]: http://julialang.org/ -# [2]: http://julia.readthedocs.org/ +# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html # Below is the template to run your tests in Julia .test_template: &test_definition @@ -18,25 +18,30 @@ script: # Let's run the tests. Substitute `coverage = false` below, if you do not # want coverage results. - - /opt/julia/bin/julia -e 'Pkg.clone(pwd()); Pkg.test("MyPackage", - coverage = true)' + - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("MyPackage"); Pkg.test("MyPackage"; coverage = true)' # Comment out below if you do not want coverage results. - - /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("MyPackage")); + - julia -e 'using Pkg; Pkg.add("Coverage"); + import MyPackage; cd(joinpath(dirname(pathof(MyPackage)), "..")); using Coverage; cl, tl = get_summary(process_folder()); println("(", cl/tl*100, "%) covered")' # Name a test and select an appropriate image. -test:0.4.6: - image: julialang/julia:v0.4.6 +# images comes from Docker hub +test:0.7: + image: julia:0.7 + <<: *test_definition + +test:1.0: + image: julia:1.0 <<: *test_definition # Maybe you would like to test your package against the development branch: -test:0.5.0-dev: - image: julialang/julia:v0.5.0-dev - # ... allowing for failures, since we are testing against the development - # branch: - allow_failure: true - <<: *test_definition +# test:1.1-dev (not sure there is such an image in docker, so not tested yet): +# image: julia:v1.1-dev +# # ... allowing for failures, since we are testing against the development +# # branch: +# allow_failure: true +# <<: *test_definition # REMARK: Do not forget to enable the coverage feature for your project, if you # are using code coverage reporting above. This can be done by @@ -44,11 +49,28 @@ test:0.5.0-dev: # - Navigating to the `CI/CD Pipelines` settings of your project, # - Copying and pasting the default `Simplecov` regex example provided, i.e., # `\(\d+.\d+\%\) covered` in the `test coverage parsing` textfield. -# -# WARNING: This template is using the `julialang/julia` images from [Docker + +# Example documentation deployment +pages: + image: julia:0.7 + stage: deploy + script: + - apt-get update -qq && apt-get install -y git # needed by Documenter + - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("MyPackage");' # rebuild Julia (can be put somewhere else I'm sure + - julia -e 'using Pkg; import MyPackage; Pkg.add("Documenter")' # install Documenter + - julia --color=yes docs/make.jl # make documentation + - mv docs/build public # move to the directory picked up by Gitlab pages + artifacts: + paths: + - public + only: + - master + + +# WARNING: This template is using the `julia` images from [Docker # Hub][3]. One can use custom Julia images and/or the official ones found # in the same place. However, care must be taken to correctly locate the binary # file (`/opt/julia/bin/julia` above), which is usually given on the image's # description page. # -# [3]: http://hub.docker.com/ +# [3]: https://hub.docker.com/_/julia/ diff --git a/vendor/gitlab-ci-yml/LaTeX.gitlab-ci.yml b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml index a4aed36889e..a4aed36889e 100644 --- a/vendor/gitlab-ci-yml/LaTeX.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml index 0688f77a1d2..0688f77a1d2 100644 --- a/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml b/lib/gitlab/ci/templates/Maven.gitlab-ci.yml index d61ff239e13..d61ff239e13 100644 --- a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Maven.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Mono.gitlab-ci.yml b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml index 3585f99760f..3585f99760f 100644 --- a/vendor/gitlab-ci-yml/Mono.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml index 41de1458582..41de1458582 100644 --- a/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml index 290b9997084..290b9997084 100644 --- a/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml index 33f44ee9222..33f44ee9222 100644 --- a/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Packer.gitlab-ci.yml b/lib/gitlab/ci/templates/Packer.gitlab-ci.yml index fa296057c72..fa296057c72 100644 --- a/vendor/gitlab-ci-yml/Packer.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Packer.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Brunch.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Brunch.gitlab-ci.yml index 7fcc0b436b5..7fcc0b436b5 100644 --- a/vendor/gitlab-ci-yml/Pages/Brunch.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Brunch.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Doxygen.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Doxygen.gitlab-ci.yml index 791afdd23f1..791afdd23f1 100644 --- a/vendor/gitlab-ci-yml/Pages/Doxygen.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Doxygen.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml index 9df2a4797b2..9df2a4797b2 100644 --- a/vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/HTML.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml index 249a168aa33..249a168aa33 100644 --- a/vendor/gitlab-ci-yml/Pages/HTML.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Harp.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Harp.gitlab-ci.yml index dd3ef149668..dd3ef149668 100644 --- a/vendor/gitlab-ci-yml/Pages/Harp.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Harp.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Hexo.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hexo.gitlab-ci.yml index 02d02250bbf..02d02250bbf 100644 --- a/vendor/gitlab-ci-yml/Pages/Hexo.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Hexo.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hugo.gitlab-ci.yml index b8cfb0f56f6..b8cfb0f56f6 100644 --- a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Hugo.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Hyde.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hyde.gitlab-ci.yml index f5b40f2b9f1..f5b40f2b9f1 100644 --- a/vendor/gitlab-ci-yml/Pages/Hyde.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Hyde.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/JBake.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/JBake.gitlab-ci.yml index 7abfaf53e8e..7abfaf53e8e 100644 --- a/vendor/gitlab-ci-yml/Pages/JBake.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/JBake.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml index 37f50554036..37f50554036 100644 --- a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml diff --git a/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml new file mode 100644 index 00000000000..0e5fb410a4e --- /dev/null +++ b/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml @@ -0,0 +1,42 @@ +# Jigsaw is a simple static sites generator with Laravel's Blade. +# +# Full project: https://github.com/tightenco/jigsaw + +image: php:7.2 + +# These folders are cached between builds +cache: + paths: + - vendor/ + - node_modules/ + +before_script: + # Update packages + - apt-get update -yqq + + # Install dependencies + - apt-get install -yqq gnupg zlib1g-dev libpng-dev + + # Install Node 8 + - curl -sL https://deb.nodesource.com/setup_8.x | bash - + - apt-get install -yqq nodejs + + # Install php extensions + - docker-php-ext-install zip + + # Install Composer and project dependencies. + - curl -sS https://getcomposer.org/installer | php + - php composer.phar install + + # Install Node dependencies. + - npm install + +pages: + script: + - npm run production + - mv build_production public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/Lektor.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Lektor.gitlab-ci.yml index c5c44a5d86c..c5c44a5d86c 100644 --- a/vendor/gitlab-ci-yml/Pages/Lektor.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Lektor.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Metalsmith.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Metalsmith.gitlab-ci.yml index 50e8b7ccd46..50e8b7ccd46 100644 --- a/vendor/gitlab-ci-yml/Pages/Metalsmith.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Metalsmith.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Middleman.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Middleman.gitlab-ci.yml index 9f4cc0574d6..9f4cc0574d6 100644 --- a/vendor/gitlab-ci-yml/Pages/Middleman.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Middleman.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Nanoc.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Nanoc.gitlab-ci.yml index b469b316ba5..b469b316ba5 100644 --- a/vendor/gitlab-ci-yml/Pages/Nanoc.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Nanoc.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Octopress.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Octopress.gitlab-ci.yml index 4762ec9acfd..4762ec9acfd 100644 --- a/vendor/gitlab-ci-yml/Pages/Octopress.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Octopress.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Pages/Pelican.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Pelican.gitlab-ci.yml index c5f3154f587..c5f3154f587 100644 --- a/vendor/gitlab-ci-yml/Pages/Pelican.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Pages/Pelican.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Python.gitlab-ci.yml b/lib/gitlab/ci/templates/Python.gitlab-ci.yml index 2e0589de652..2e0589de652 100644 --- a/vendor/gitlab-ci-yml/Python.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Python.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml index 93cb31f48c0..93cb31f48c0 100644 --- a/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml index cab087c48c7..cab087c48c7 100644 --- a/vendor/gitlab-ci-yml/Rust.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Scala.gitlab-ci.yml b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml index b4208ed9d7d..b4208ed9d7d 100644 --- a/vendor/gitlab-ci-yml/Scala.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/Swift.gitlab-ci.yml b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml index b97bfd460f2..ba8a802ba4f 100644 --- a/vendor/gitlab-ci-yml/Swift.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml @@ -1,5 +1,5 @@ # Lifted from: https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/ -# This file assumes an own GitLab CI runner, set up on a macOS system. +# This file assumes an own GitLab CI runner, setup on a macOS system. stages: - build - archive diff --git a/vendor/gitlab-ci-yml/Terraform.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml index 7160fce26a8..7160fce26a8 100644 --- a/vendor/gitlab-ci-yml/Terraform.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/dotNET.gitlab-ci.yml b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml index fc3d4ecdbba..fc3d4ecdbba 100644 --- a/vendor/gitlab-ci-yml/dotNET.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index c9dbd2d2e5f..de7c959e706 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -2,11 +2,7 @@ module Gitlab module CurrentSettings class << self def current_application_settings - if RequestStore.active? - RequestStore.fetch(:current_application_settings) { ensure_application_settings! } - else - ensure_application_settings! - end + Gitlab::SafeRequestStore.fetch(:current_application_settings) { ensure_application_settings! } end def fake_application_settings(attributes = {}) diff --git a/lib/gitlab/database/subquery.rb b/lib/gitlab/database/subquery.rb new file mode 100644 index 00000000000..36e4559b554 --- /dev/null +++ b/lib/gitlab/database/subquery.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Gitlab + module Database + module Subquery + class << self + def self_join(relation) + t = relation.arel_table + t2 = if !Gitlab.rails5? + relation.arel.as('t2') + else + # Work around a bug in Rails 5, where LIMIT causes trouble + # See https://gitlab.com/gitlab-org/gitlab-ce/issues/51729 + r = relation.limit(nil).arel + r.take(relation.limit_value) if relation.limit_value + r.as('t2') + end + + relation.unscoped.joins(t.join(t2).on(t[:id].eq(t2[:id])).join_sources.first) + end + end + end + end +end diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb index 4b6016e00bc..fc280f96ec1 100644 --- a/lib/gitlab/diff/position.rb +++ b/lib/gitlab/diff/position.rb @@ -101,18 +101,14 @@ module Gitlab return @diff_file if defined?(@diff_file) @diff_file = begin - if RequestStore.active? - key = { - project_id: repository.project.id, - start_sha: start_sha, - head_sha: head_sha, - path: file_path - } - - RequestStore.fetch(key) { find_diff_file(repository) } - else - find_diff_file(repository) - end + key = { + project_id: repository.project.id, + start_sha: start_sha, + head_sha: head_sha, + path: file_path + } + + Gitlab::SafeRequestStore.fetch(key) { find_diff_file(repository) } end end diff --git a/lib/gitlab/favicon.rb b/lib/gitlab/favicon.rb index 4850a6c0430..050a1ad3a0b 100644 --- a/lib/gitlab/favicon.rb +++ b/lib/gitlab/favicon.rb @@ -47,7 +47,7 @@ module Gitlab end def appearance - RequestStore.store[:appearance] ||= (Appearance.current || Appearance.new) + Gitlab::SafeRequestStore[:appearance] ||= (Appearance.current || Appearance.new) end def appearance_favicon diff --git a/lib/gitlab/git/hook_env.rb b/lib/gitlab/git/hook_env.rb index 455e8451c10..620568d8817 100644 --- a/lib/gitlab/git/hook_env.rb +++ b/lib/gitlab/git/hook_env.rb @@ -17,18 +17,18 @@ module Gitlab ].freeze def self.set(gl_repository, env) - return unless RequestStore.active? + return unless Gitlab::SafeRequestStore.active? raise "missing gl_repository" if gl_repository.blank? - RequestStore.store[:gitlab_git_env] ||= {} - RequestStore.store[:gitlab_git_env][gl_repository] = whitelist_git_env(env) + Gitlab::SafeRequestStore[:gitlab_git_env] ||= {} + Gitlab::SafeRequestStore[:gitlab_git_env][gl_repository] = whitelist_git_env(env) end def self.all(gl_repository) - return {} unless RequestStore.active? + return {} unless Gitlab::SafeRequestStore.active? - h = RequestStore.fetch(:gitlab_git_env) { {} } + h = Gitlab::SafeRequestStore.fetch(:gitlab_git_env) { {} } h.fetch(gl_repository, {}) end diff --git a/lib/gitlab/git/storage/circuit_breaker.rb b/lib/gitlab/git/storage/circuit_breaker.rb index 62427ac9cc4..fcee9ae566c 100644 --- a/lib/gitlab/git/storage/circuit_breaker.rb +++ b/lib/gitlab/git/storage/circuit_breaker.rb @@ -11,7 +11,7 @@ module Gitlab to: :failure_info def self.for_storage(storage) - cached_circuitbreakers = RequestStore.fetch(:circuitbreaker_cache) do + cached_circuitbreakers = Gitlab::SafeRequestStore.fetch(:circuitbreaker_cache) do Hash.new do |hash, storage_name| hash[storage_name] = build(storage_name) end diff --git a/lib/gitlab/git/storage/failure_info.rb b/lib/gitlab/git/storage/failure_info.rb index 387279c110d..1d28a850049 100644 --- a/lib/gitlab/git/storage/failure_info.rb +++ b/lib/gitlab/git/storage/failure_info.rb @@ -10,7 +10,7 @@ module Gitlab redis.del(*all_storage_keys) unless all_storage_keys.empty? end - RequestStore.delete(:circuitbreaker_cache) + Gitlab::SafeRequestStore.delete(:circuitbreaker_cache) end def self.load(cache_key) diff --git a/lib/gitlab/git/wiki.rb b/lib/gitlab/git/wiki.rb index ae92a624e05..d2dc4f2e688 100644 --- a/lib/gitlab/git/wiki.rb +++ b/lib/gitlab/git/wiki.rb @@ -115,11 +115,7 @@ module Gitlab def version(commit_id) commit_find_proc = -> { Gitlab::Git::Commit.find(@repository, commit_id) } - if RequestStore.active? - RequestStore.fetch([:wiki_version_commit, commit_id]) { commit_find_proc.call } - else - commit_find_proc.call - end + Gitlab::SafeRequestStore.fetch([:wiki_version_commit, commit_id]) { commit_find_proc.call } end def assert_type!(object, klass) diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb index 12307338972..500aabcbbb8 100644 --- a/lib/gitlab/gitaly_client.rb +++ b/lib/gitlab/gitaly_client.rb @@ -174,10 +174,29 @@ module Gitlab end private_class_method :current_transaction_labels + # For some time related tasks we can't rely on `Time.now` since it will be + # affected by Timecop in some tests, and the clock of some gitaly-related + # components (grpc's c-core and gitaly server) use system time instead of + # timecop's time, so tests will fail. + # `Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))` will circumvent + # timecop. + def self.real_time + Time.at(Process.clock_gettime(Process::CLOCK_REALTIME)) + end + private_class_method :real_time + + def self.authorization_token(storage) + token = token(storage).to_s + issued_at = real_time.to_i.to_s + hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, token, issued_at) + + "v2.#{hmac}.#{issued_at}" + end + private_class_method :authorization_token + def self.request_kwargs(storage, timeout, remote_storage: nil) - encoded_token = Base64.strict_encode64(token(storage).to_s) metadata = { - 'authorization' => "Bearer #{encoded_token}", + 'authorization' => "Bearer #{authorization_token(storage)}", 'client_name' => CLIENT_NAME } @@ -195,12 +214,7 @@ module Gitlab return result unless timeout > 0 - # Do not use `Time.now` for deadline calculation, since it - # will be affected by Timecop in some tests, but grpc's c-core - # uses system time instead of timecop's time, so tests will fail - # `Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))` will - # circumvent timecop - deadline = Time.at(Process.clock_gettime(Process::CLOCK_REALTIME)) + timeout + deadline = real_time + timeout result[:deadline] = deadline result @@ -302,7 +316,7 @@ module Gitlab # Ensures that Gitaly is not being abuse through n+1 misuse etc def self.enforce_gitaly_request_limits(call_site) # Only count limits in request-response environments (not sidekiq for example) - return unless RequestStore.active? + return unless Gitlab::SafeRequestStore.active? # This is this actual number of times this call was made. Used for information purposes only actual_call_count = increment_call_count("gitaly_#{call_site}_actual") @@ -326,7 +340,7 @@ module Gitlab end def self.allow_n_plus_1_calls - return yield unless RequestStore.active? + return yield unless Gitlab::SafeRequestStore.active? begin increment_call_count(:gitaly_call_count_exception_block_depth) @@ -337,25 +351,25 @@ module Gitlab end def self.get_call_count(key) - RequestStore.store[key] || 0 + Gitlab::SafeRequestStore[key] || 0 end private_class_method :get_call_count def self.increment_call_count(key) - RequestStore.store[key] ||= 0 - RequestStore.store[key] += 1 + Gitlab::SafeRequestStore[key] ||= 0 + Gitlab::SafeRequestStore[key] += 1 end private_class_method :increment_call_count def self.decrement_call_count(key) - RequestStore.store[key] -= 1 + Gitlab::SafeRequestStore[key] -= 1 end private_class_method :decrement_call_count # Returns an estimate of the number of Gitaly calls made for this # request def self.get_request_count - return 0 unless RequestStore.active? + return 0 unless Gitlab::SafeRequestStore.active? gitaly_migrate_count = get_call_count("gitaly_migrate_actual") gitaly_call_count = get_call_count("gitaly_call_actual") @@ -372,28 +386,28 @@ module Gitlab end def self.reset_counts - return unless RequestStore.active? + return unless Gitlab::SafeRequestStore.active? %w[migrate call].each do |call_site| - RequestStore.store["gitaly_#{call_site}_actual"] = 0 - RequestStore.store["gitaly_#{call_site}_permitted"] = 0 + Gitlab::SafeRequestStore["gitaly_#{call_site}_actual"] = 0 + Gitlab::SafeRequestStore["gitaly_#{call_site}_permitted"] = 0 end end def self.add_call_details(details) id = details.delete(:id) - return unless id && RequestStore.active? && RequestStore.store[:peek_enabled] + return unless id && Gitlab::SafeRequestStore[:peek_enabled] - RequestStore.store['gitaly_call_details'] ||= {} - RequestStore.store['gitaly_call_details'][id] ||= {} - RequestStore.store['gitaly_call_details'][id].merge!(details) + Gitlab::SafeRequestStore['gitaly_call_details'] ||= {} + Gitlab::SafeRequestStore['gitaly_call_details'][id] ||= {} + Gitlab::SafeRequestStore['gitaly_call_details'][id].merge!(details) end def self.list_call_details - return {} unless RequestStore.active? && RequestStore.store[:peek_enabled] + return {} unless Gitlab::SafeRequestStore[:peek_enabled] - RequestStore.store['gitaly_call_details'] || {} + Gitlab::SafeRequestStore['gitaly_call_details'] || {} end def self.expected_server_version @@ -431,22 +445,22 @@ module Gitlab # Count a stack. Used for n+1 detection def self.count_stack - return unless RequestStore.active? + return unless Gitlab::SafeRequestStore.active? stack_string = Gitlab::Profiler.clean_backtrace(caller).drop(1).join("\n") - RequestStore.store[:stack_counter] ||= Hash.new + Gitlab::SafeRequestStore[:stack_counter] ||= Hash.new - count = RequestStore.store[:stack_counter][stack_string] || 0 - RequestStore.store[:stack_counter][stack_string] = count + 1 + count = Gitlab::SafeRequestStore[:stack_counter][stack_string] || 0 + Gitlab::SafeRequestStore[:stack_counter][stack_string] = count + 1 end private_class_method :count_stack # Returns a count for the stack which called Gitaly the most times. Used for n+1 detection def self.max_call_count - return 0 unless RequestStore.active? + return 0 unless Gitlab::SafeRequestStore.active? - stack_counter = RequestStore.store[:stack_counter] + stack_counter = Gitlab::SafeRequestStore[:stack_counter] return 0 unless stack_counter stack_counter.values.max @@ -455,9 +469,9 @@ module Gitlab # Returns the stacks that calls Gitaly the most times. Used for n+1 detection def self.max_stacks - return nil unless RequestStore.active? + return nil unless Gitlab::SafeRequestStore.active? - stack_counter = RequestStore.store[:stack_counter] + stack_counter = Gitlab::SafeRequestStore[:stack_counter] return nil unless stack_counter max = max_call_count diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb index 6c95abdcb4b..07e5e204b68 100644 --- a/lib/gitlab/gitaly_client/commit_service.rb +++ b/lib/gitlab/gitaly_client/commit_service.rb @@ -240,22 +240,23 @@ module Gitlab end def find_commit(revision) - if RequestStore.active? - # We don't use RequeStstore.fetch(key) { ... } directly because `revision` - # can be a branch name, so we can't use it as a key as it could point - # to another commit later on (happens a lot in tests). + if Gitlab::SafeRequestStore.active? + # We don't use Gitlab::SafeRequestStore.fetch(key) { ... } directly + # because `revision` can be a branch name, so we can't use it as a key + # as it could point to another commit later on (happens a lot in + # tests). key = { storage: @gitaly_repo.storage_name, relative_path: @gitaly_repo.relative_path, commit_id: revision } - return RequestStore[key] if RequestStore.exist?(key) + return Gitlab::SafeRequestStore[key] if Gitlab::SafeRequestStore.exist?(key) commit = call_find_commit(revision) return unless commit key[:commit_id] = commit.id - RequestStore[key] = commit + Gitlab::SafeRequestStore[key] = commit else call_find_commit(revision) end diff --git a/lib/gitlab/gitaly_client/operation_service.rb b/lib/gitlab/gitaly_client/operation_service.rb index 54c78fdb680..0f148614b20 100644 --- a/lib/gitlab/gitaly_client/operation_service.rb +++ b/lib/gitlab/gitaly_client/operation_service.rb @@ -333,7 +333,8 @@ module Gitlab action: action[:action].upcase.to_sym, file_path: encode_binary(action[:file_path]), previous_path: encode_binary(action[:previous_path]), - base64_content: action[:encoding] == 'base64' + base64_content: action[:encoding] == 'base64', + execute_filemode: !!action[:execute_filemode] ) rescue RangeError raise ArgumentError, "Unknown action '#{action[:action]}'" diff --git a/lib/gitlab/gitaly_client/storage_settings.rb b/lib/gitlab/gitaly_client/storage_settings.rb index 8e530de174d..26d1f53f26c 100644 --- a/lib/gitlab/gitaly_client/storage_settings.rb +++ b/lib/gitlab/gitaly_client/storage_settings.rb @@ -13,7 +13,7 @@ module Gitlab Storage is invalid because it has no `path` key. For source installations, update your config/gitlab.yml Refer to gitlab.yml.example for an updated example. - If you're using the Gitlab Development Kit, you can update your configuration running `gdk reconfigure`. + If you're using the GitLab Development Kit, you can update your configuration running `gdk reconfigure`. MSG # This class will give easily recognizable NoMethodErrors diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 00ea4b833e2..3d693d23c99 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -136,9 +136,18 @@ module Gitlab return if tree_hash[relation_key].blank? tree_array = [tree_hash[relation_key]].flatten + null_iid_pipelines = [] # Avoid keeping a possible heavy object in memory once we are done with it - while relation_item = tree_array.shift + while relation_item = (tree_array.shift || null_iid_pipelines.shift) + if nil_iid_pipeline?(relation_key, relation_item) && tree_array.any? + # Move pipelines with NULL IIDs to the end + # so they don't clash with existing IIDs. + null_iid_pipelines << relation_item + + next + end + # The transaction at this level is less speedy than one single transaction # But we can't have it in the upper level or GC won't get rid of the AR objects # after we save the batch. @@ -201,6 +210,10 @@ module Gitlab def excluded_keys_for_relation(relation) reader.attributes_finder.find_excluded_keys(relation) end + + def nil_iid_pipeline?(relation_key, relation_item) + relation_key == 'pipelines' && relation_item['iid'].nil? + end end end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 81807ed659c..2486b1e4921 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -86,7 +86,6 @@ module Gitlab case @relation_name when :merge_request_diff_files then setup_diff when :notes then setup_note - when 'Ci::Pipeline' then setup_pipeline end update_user_references @@ -94,6 +93,8 @@ module Gitlab update_group_references remove_duplicate_assignees + setup_pipeline if @relation_name == 'Ci::Pipeline' + reset_tokens! remove_encrypted_attributes! end diff --git a/lib/gitlab/issuables_count_for_state.rb b/lib/gitlab/issuables_count_for_state.rb index 505810964bc..b5657a36998 100644 --- a/lib/gitlab/issuables_count_for_state.rb +++ b/lib/gitlab/issuables_count_for_state.rb @@ -1,7 +1,7 @@ module Gitlab # Class for counting and caching the number of issuables per state. class IssuablesCountForState - # The name of the RequestStore cache key. + # The name of the Gitlab::SafeRequestStore cache key. CACHE_KEY = :issuables_count_for_state # The state values that can be safely casted to a Symbol. @@ -10,12 +10,7 @@ module Gitlab # finder - The finder class to use for retrieving the issuables. def initialize(finder) @finder = finder - @cache = - if RequestStore.active? - RequestStore[CACHE_KEY] ||= initialize_cache - else - initialize_cache - end + @cache = Gitlab::SafeRequestStore[CACHE_KEY] ||= initialize_cache end def for_state_or_opened(state = nil) diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb index e58927a40b9..3d7c049c17f 100644 --- a/lib/gitlab/logger.rb +++ b/lib/gitlab/logger.rb @@ -30,7 +30,7 @@ module Gitlab end def self.build - RequestStore[self.cache_key] ||= new(self.full_log_path) + Gitlab::SafeRequestStore[self.cache_key] ||= new(self.full_log_path) end def self.full_log_path diff --git a/lib/gitlab/null_request_store.rb b/lib/gitlab/null_request_store.rb new file mode 100644 index 00000000000..8db331dcb9f --- /dev/null +++ b/lib/gitlab/null_request_store.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# Used by Gitlab::SafeRequestStore +module Gitlab + # The methods `begin!`, `clear!`, and `end!` are not defined because they + # should only be called directly on `RequestStore`. + class NullRequestStore + def store + {} + end + + def active? + end + + def read(key) + end + + def [](key) + end + + def write(key, value) + value + end + + def []=(key, value) + value + end + + def exist?(key) + false + end + + def fetch(key, &block) + yield + end + + def delete(key, &block) + yield(key) if block_given? + end + end +end diff --git a/lib/gitlab/performance_bar/peek_query_tracker.rb b/lib/gitlab/performance_bar/peek_query_tracker.rb index f2825db59ae..37ff32b1296 100644 --- a/lib/gitlab/performance_bar/peek_query_tracker.rb +++ b/lib/gitlab/performance_bar/peek_query_tracker.rb @@ -23,7 +23,7 @@ module Gitlab end subscribe('sql.active_record') do |_, start, finish, _, data| - if RequestStore.active? && RequestStore.store[:peek_enabled] + if Gitlab::SafeRequestStore.store[:peek_enabled] # data[:cached] is only available starting from Rails 5.1.0 # https://github.com/rails/rails/blob/v5.1.0/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb#L113 # Before that, data[:name] was set to 'CACHE' diff --git a/lib/gitlab/repository_cache.rb b/lib/gitlab/repository_cache.rb index b1bf3ca4143..a03ce07b6a1 100644 --- a/lib/gitlab/repository_cache.rb +++ b/lib/gitlab/repository_cache.rb @@ -29,5 +29,21 @@ module Gitlab def read(key) backend.read(cache_key(key)) end + + def write(key, value) + backend.write(cache_key(key), value) + end + + def fetch_without_caching_false(key, &block) + value = read(key) + return value if value + + value = yield + + # Don't cache false values + write(key, value) if value + + value + end end end diff --git a/lib/gitlab/repository_cache_adapter.rb b/lib/gitlab/repository_cache_adapter.rb index 2ec871f0754..d95024fccf7 100644 --- a/lib/gitlab/repository_cache_adapter.rb +++ b/lib/gitlab/repository_cache_adapter.rb @@ -1,23 +1,80 @@ module Gitlab module RepositoryCacheAdapter extend ActiveSupport::Concern + include Gitlab::Utils::StrongMemoize class_methods do - # Wraps around the given method and caches its output in Redis and an instance - # variable. + # Caches and strongly memoizes the method. # # This only works for methods that do not take any arguments. - def cache_method(name, fallback: nil, memoize_only: false) - original = :"_uncached_#{name}" + # + # name - The name of the method to be cached. + # fallback - A value to fall back to if the repository does not exist, or + # in case of a Git error. Defaults to nil. + def cache_method(name, fallback: nil) + uncached_name = alias_uncached_method(name) + + define_method(name) do + cache_method_output(name, fallback: fallback) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend + end + end + end - alias_method(original, name) + # Caches truthy values from the method. All values are strongly memoized, + # and cached in RequestStore. + # + # Currently only used to cache `exists?` since stale false values are + # particularly troublesome. This can occur, for example, when an NFS mount + # is temporarily down. + # + # This only works for methods that do not take any arguments. + # + # name - The name of the method to be cached. + def cache_method_asymmetrically(name) + uncached_name = alias_uncached_method(name) define_method(name) do - cache_method_output(name, fallback: fallback, memoize_only: memoize_only) do - __send__(original) # rubocop:disable GitlabSecurity/PublicSend + cache_method_output_asymmetrically(name) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend end end end + + # Strongly memoizes the method. + # + # This only works for methods that do not take any arguments. + # + # name - The name of the method to be memoized. + # fallback - A value to fall back to if the repository does not exist, or + # in case of a Git error. Defaults to nil. The fallback value + # is not memoized. + def memoize_method(name, fallback: nil) + uncached_name = alias_uncached_method(name) + + define_method(name) do + memoize_method_output(name, fallback: fallback) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend + end + end + end + + # Prepends "_uncached_" to the target method name + # + # Returns the uncached method name + def alias_uncached_method(name) + uncached_name = :"_uncached_#{name}" + + alias_method(uncached_name, name) + + uncached_name + end + end + + # RequestStore-backed RepositoryCache to be used. Should be overridden by + # the including class + def request_store_cache + raise NotImplementedError end # RepositoryCache to be used. Should be overridden by the including class @@ -30,65 +87,93 @@ module Gitlab raise NotImplementedError end - # Caches the supplied block both in a cache and in an instance variable. + # Caches and strongly memoizes the supplied block. # - # The cache key and instance variable are named the same way as the value of - # the `key` argument. + # name - The name of the method to be cached. + # fallback - A value to fall back to if the repository does not exist, or + # in case of a Git error. Defaults to nil. + def cache_method_output(name, fallback: nil, &block) + memoize_method_output(name, fallback: fallback) do + cache.fetch(name, &block) + end + end + + # Caches truthy values from the supplied block. All values are strongly + # memoized, and cached in RequestStore. # - # This method will return `nil` if the corresponding instance variable is also - # set to `nil`. This ensures we don't keep yielding the block when it returns - # `nil`. + # Currently only used to cache `exists?` since stale false values are + # particularly troublesome. This can occur, for example, when an NFS mount + # is temporarily down. # - # key - The name of the key to cache the data in. - # fallback - A value to fall back to in the event of a Git error. - def cache_method_output(key, fallback: nil, memoize_only: false, &block) - ivar = cache_instance_variable_name(key) - - if instance_variable_defined?(ivar) - instance_variable_get(ivar) - else - # If the repository doesn't exist and a fallback was specified we return - # that value inmediately. This saves us Rugged/gRPC invocations. - return fallback unless fallback.nil? || cache.repository.exists? - - begin - value = - if memoize_only - yield - else - cache.fetch(key, &block) - end - - instance_variable_set(ivar, value) - rescue Gitlab::Git::Repository::NoRepository - # Even if the above `#exists?` check passes these errors might still - # occur (for example because of a non-existing HEAD). We want to - # gracefully handle this and not cache anything - fallback + # name - The name of the method to be cached. + def cache_method_output_asymmetrically(name, &block) + memoize_method_output(name) do + request_store_cache.fetch(name) do + cache.fetch_without_caching_false(name, &block) end end end + # Strongly memoizes the supplied block. + # + # name - The name of the method to be memoized. + # fallback - A value to fall back to if the repository does not exist, or + # in case of a Git error. Defaults to nil. The fallback value is + # not memoized. + def memoize_method_output(name, fallback: nil, &block) + no_repository_fallback(name, fallback: fallback) do + strong_memoize(memoizable_name(name), &block) + end + end + + # Returns the fallback value if the repository does not exist + def no_repository_fallback(name, fallback: nil, &block) + # Avoid unnecessary gRPC invocations + return fallback if fallback && fallback_early?(name) + + yield + rescue Gitlab::Git::Repository::NoRepository + # Even if the `#exists?` check in `fallback_early?` passes, these errors + # might still occur (for example because of a non-existing HEAD). We + # want to gracefully handle this and not memoize anything. + fallback + end + # Expires the caches of a specific set of methods def expire_method_caches(methods) - methods.each do |key| - unless cached_methods.include?(key.to_sym) - Rails.logger.error "Requested to expire non-existent method '#{key}' for Repository" + methods.each do |name| + unless cached_methods.include?(name.to_sym) + Rails.logger.error "Requested to expire non-existent method '#{name}' for Repository" next end - cache.expire(key) + cache.expire(name) - ivar = cache_instance_variable_name(key) - - remove_instance_variable(ivar) if instance_variable_defined?(ivar) + clear_memoization(memoizable_name(name)) end + + expire_request_store_method_caches(methods) end private - def cache_instance_variable_name(key) - :"@#{key.to_s.tr('?!', '')}" + def memoizable_name(name) + "#{name.to_s.tr('?!', '')}" + end + + def expire_request_store_method_caches(methods) + methods.each do |name| + request_store_cache.expire(name) + end + end + + # All cached repository methods depend on the existence of a Git repository, + # so if the repository doesn't exist, we already know not to call it. + def fallback_early?(method_name) + # Avoid infinite loop + return false if method_name == :exists? + + !exists? end end end diff --git a/lib/gitlab/request_context.rb b/lib/gitlab/request_context.rb index fef536ecb0b..8562d4515aa 100644 --- a/lib/gitlab/request_context.rb +++ b/lib/gitlab/request_context.rb @@ -2,7 +2,7 @@ module Gitlab class RequestContext class << self def client_ip - RequestStore[:client_ip] + Gitlab::SafeRequestStore[:client_ip] end end @@ -13,7 +13,7 @@ module Gitlab def call(env) req = Rack::Request.new(env) - RequestStore[:client_ip] = req.ip + Gitlab::SafeRequestStore[:client_ip] = req.ip @app.call(env) end diff --git a/lib/gitlab/safe_request_store.rb b/lib/gitlab/safe_request_store.rb new file mode 100644 index 00000000000..4e82353adb6 --- /dev/null +++ b/lib/gitlab/safe_request_store.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Gitlab + module SafeRequestStore + NULL_STORE = Gitlab::NullRequestStore.new + + class << self + # These methods should always run directly against RequestStore + delegate :clear!, :begin!, :end!, :active?, to: :RequestStore + + # These methods will run against NullRequestStore if RequestStore is disabled + delegate :read, :[], :write, :[]=, :exist?, :fetch, :delete, to: :store + end + + def self.store + if RequestStore.active? + RequestStore + else + NULL_STORE + end + end + end +end diff --git a/lib/gitlab/sidekiq_throttler.rb b/lib/gitlab/sidekiq_throttler.rb deleted file mode 100644 index 5512afa45a8..00000000000 --- a/lib/gitlab/sidekiq_throttler.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Gitlab - class SidekiqThrottler - class << self - def execute! - if Gitlab::CurrentSettings.sidekiq_throttling_enabled? - require 'sidekiq-limit_fetch' - - Gitlab::CurrentSettings.current_application_settings.sidekiq_throttling_queues.each do |queue| - Sidekiq::Queue[queue].limit = queue_limit - end - end - end - - private - - def queue_limit - @queue_limit ||= - begin - factor = Gitlab::CurrentSettings.current_application_settings.sidekiq_throttling_factor - (factor * Sidekiq.options[:concurrency]).ceil - end - end - end - end -end diff --git a/lib/gitlab/template/finders/global_template_finder.rb b/lib/gitlab/template/finders/global_template_finder.rb index 831da45191f..b08d9a99e99 100644 --- a/lib/gitlab/template/finders/global_template_finder.rb +++ b/lib/gitlab/template/finders/global_template_finder.rb @@ -1,4 +1,4 @@ -# Searches and reads file present on Gitlab installation directory +# Searches and reads file present on GitLab installation directory module Gitlab module Template module Finders diff --git a/lib/gitlab/template/finders/repo_template_finder.rb b/lib/gitlab/template/finders/repo_template_finder.rb index 29bc2393ff9..9140ace879f 100644 --- a/lib/gitlab/template/finders/repo_template_finder.rb +++ b/lib/gitlab/template/finders/repo_template_finder.rb @@ -1,4 +1,4 @@ -# Searches and reads files present on each Gitlab project repository +# Searches and reads files present on each GitLab project repository module Gitlab module Template module Finders diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb index fd040148a1e..deae53cc61b 100644 --- a/lib/gitlab/template/gitlab_ci_yml_template.rb +++ b/lib/gitlab/template/gitlab_ci_yml_template.rb @@ -20,7 +20,7 @@ module Gitlab end def base_dir - Rails.root.join('vendor/gitlab-ci-yml') + Rails.root.join('lib/gitlab/ci/templates') end def finder(project = nil) diff --git a/lib/gitlab/temporarily_allow.rb b/lib/gitlab/temporarily_allow.rb index 880e55f71df..8d7dacc6c54 100644 --- a/lib/gitlab/temporarily_allow.rb +++ b/lib/gitlab/temporarily_allow.rb @@ -10,7 +10,7 @@ module Gitlab end def temporarily_allowed?(key) - if RequestStore.active? + if Gitlab::SafeRequestStore.active? temporarily_allow_request_store[key] > 0 else TEMPORARILY_ALLOW_MUTEX.synchronize do @@ -26,11 +26,11 @@ module Gitlab end def temporarily_allow_request_store - RequestStore[:temporarily_allow] ||= Hash.new(0) + Gitlab::SafeRequestStore[:temporarily_allow] ||= Hash.new(0) end def temporarily_allow_add(key, value) - if RequestStore.active? + if Gitlab::SafeRequestStore.active? temporarily_allow_request_store[key] += value else TEMPORARILY_ALLOW_MUTEX.synchronize do diff --git a/lib/gitlab/testing/request_inspector_middleware.rb b/lib/gitlab/testing/request_inspector_middleware.rb index e387667480d..c251e78f5c5 100644 --- a/lib/gitlab/testing/request_inspector_middleware.rb +++ b/lib/gitlab/testing/request_inspector_middleware.rb @@ -35,11 +35,15 @@ module Gitlab request_headers = env_http_headers(env) status, headers, body = @app.call(env) + full_body = '' + body.each { |b| full_body << b } + request = OpenStruct.new( url: url, status_code: status, request_headers: request_headers, - response_headers: headers + response_headers: headers, + body: full_body ) log_request request diff --git a/lib/quality/helm_client.rb b/lib/quality/helm_client.rb new file mode 100644 index 00000000000..49d953da681 --- /dev/null +++ b/lib/quality/helm_client.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'time' +require_relative '../gitlab/popen' unless defined?(Gitlab::Popen) + +module Quality + class HelmClient + attr_reader :namespace + + Release = Struct.new(:name, :revision, :last_update, :status, :chart, :namespace) do + def revision + @revision ||= self[:revision].to_i + end + + def last_update + @last_update ||= Time.parse(self[:last_update]) + end + end + + def initialize(namespace: ENV['KUBE_NAMESPACE']) + @namespace = namespace + end + + def releases(args: []) + command = ['list', %(--namespace "#{namespace}"), *args] + + run_command(command) + .stdout + .lines + .select { |line| line.include?(namespace) } + .map { |line| Release.new(*line.split(/\t/).map(&:strip)) } + end + + def delete(release_name:) + run_command(['delete', '--purge', release_name]) + end + + private + + def run_command(command) + final_command = ['helm', *command].join(' ') + puts "Running command: `#{final_command}`" # rubocop:disable Rails/Output + + Gitlab::Popen.popen_with_detail([final_command]) + end + end +end diff --git a/lib/quality/kubernetes_client.rb b/lib/quality/kubernetes_client.rb new file mode 100644 index 00000000000..e366a688e3e --- /dev/null +++ b/lib/quality/kubernetes_client.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require_relative '../gitlab/popen' unless defined?(Gitlab::Popen) + +module Quality + class KubernetesClient + attr_reader :namespace + + def initialize(namespace: ENV['KUBE_NAMESPACE']) + @namespace = namespace + end + + def cleanup(release_name:) + command = ['kubectl'] + command << %(-n "#{namespace}" get ingress,svc,pdb,hpa,deploy,statefulset,job,pod,secret,configmap,pvc,secret,clusterrole,clusterrolebinding,role,rolebinding,sa 2>&1) + command << '|' << %(grep "#{release_name}") + command << '|' << "awk '{print $1}'" + command << '|' << %(xargs kubectl -n "#{namespace}" delete) + command << '||' << 'true' + + run_command(command) + end + + private + + def run_command(command) + puts "Running command: `#{command.join(' ')}`" # rubocop:disable Rails/Output + + Gitlab::Popen.popen_with_detail(command) + end + end +end diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 72eb8adcce2..fc984d737d5 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -17,7 +17,7 @@ ## See installation.md#using-https for additional HTTPS configuration details. upstream gitlab-workhorse { - # Gitlab socket file, + # GitLab socket file, # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0; } @@ -112,7 +112,7 @@ server { error_page 502 /502.html; error_page 503 /503.html; location ~ ^/(404|422|500|502|503)\.html$ { - # Location to the Gitlab's public directory, + # Location to the GitLab's public directory, # for Omnibus this would be: /opt/gitlab/embedded/service/gitlab-rails/public. root /home/git/gitlab/public; internal; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 2e3799d5e1b..ba01e250bbb 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -21,7 +21,7 @@ ## See installation.md#using-https for additional HTTPS configuration details. upstream gitlab-workhorse { - # Gitlab socket file, + # GitLab socket file, # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0; } @@ -162,7 +162,7 @@ server { error_page 502 /502.html; error_page 503 /503.html; location ~ ^/(404|422|500|502|503)\.html$ { - # Location to the Gitlab's public directory, + # Location to the GitLab's public directory, # for Omnibus this would be: /opt/gitlab/embedded/service/gitlab-rails/public root /home/git/gitlab/public; internal; diff --git a/lib/tasks/gitlab/artifacts/migrate.rake b/lib/tasks/gitlab/artifacts/migrate.rake index bfca4bfb3f7..e7634d2ed4f 100644 --- a/lib/tasks/gitlab/artifacts/migrate.rake +++ b/lib/tasks/gitlab/artifacts/migrate.rake @@ -15,7 +15,7 @@ namespace :gitlab do build.artifacts_file.migrate!(ObjectStorage::Store::REMOTE) build.artifacts_metadata.migrate!(ObjectStorage::Store::REMOTE) - logger.info("Transferred artifacts of #{build.id} of #{build.artifacts_size} to object storage") + logger.info("Transferred artifact ID #{build.id} with size #{build.artifacts_size} to object storage") rescue => e logger.error("Failed to transfer artifacts of #{build.id} with error: #{e.message}") end diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake index 4fcbbbf8c9d..0ebc6f00793 100644 --- a/lib/tasks/gitlab/shell.rake +++ b/lib/tasks/gitlab/shell.rake @@ -92,9 +92,11 @@ namespace :gitlab do def setup warn_user_is_not_gitlab + ensure_write_to_authorized_keys_is_enabled + unless ENV['force'] == 'yes' - puts "This will rebuild an authorized_keys file." - puts "You will lose any data stored in authorized_keys file." + puts "This task will now rebuild the authorized_keys file." + puts "You will lose any data stored in the authorized_keys file." ask_to_continue puts "" end @@ -118,4 +120,44 @@ namespace :gitlab do puts "Quitting...".color(:red) exit 1 end + + def ensure_write_to_authorized_keys_is_enabled + return if Gitlab::CurrentSettings.current_application_settings.authorized_keys_enabled + + puts authorized_keys_is_disabled_warning + + unless ENV['force'] == 'yes' + puts 'Do you want to permanently enable the "Write to authorized_keys file" setting now?' + ask_to_continue + end + + puts 'Enabling the "Write to authorized_keys file" setting...' + Gitlab::CurrentSettings.current_application_settings.update!(authorized_keys_enabled: true) + + puts 'Successfully enabled "Write to authorized_keys file"!' + puts '' + end + + def authorized_keys_is_disabled_warning + <<-MSG.strip_heredoc + WARNING + + The "Write to authorized_keys file" setting is disabled, which prevents + the file from being rebuilt! + + It should be enabled for most GitLab installations. Large installations + may wish to disable it as part of speeding up SSH operations. + + See https://docs.gitlab.com/ee/administration/operations/fast_ssh_key_lookup.html + + If you did not intentionally disable this option in Admin Area > Settings, + then you may have been affected by the 9.3.0 bug in which the new setting + was disabled by default. + + https://gitlab.com/gitlab-org/gitlab-ee/issues/2738 + + It was reverted in 9.3.1 and fixed in 9.3.3, however, if Settings were + saved while the setting was unchecked, then it is still disabled. + MSG + end end diff --git a/lib/tasks/gitlab/site_statistics.rake b/lib/tasks/gitlab/site_statistics.rake index 7d24ec72a9d..d97f11b2ed5 100644 --- a/lib/tasks/gitlab/site_statistics.rake +++ b/lib/tasks/gitlab/site_statistics.rake @@ -10,14 +10,6 @@ namespace :gitlab do SiteStatistic.update_all('repositories_count = (SELECT COUNT(*) FROM projects)') end puts 'OK!'.color(:green) - - print '* Wikis... ' - SiteStatistic.transaction do - # see https://gitlab.com/gitlab-org/gitlab-ce/issues/48967 - ActiveRecord::Base.connection.execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? - SiteStatistic.update_all('wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)') - end - puts 'OK!'.color(:green) puts end end diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index ef6a32d6730..abe10f5580e 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -100,10 +100,6 @@ namespace :gitlab do /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ ), Template.new( - "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", - /(\.{1,2}|LICENSE|CONTRIBUTING.md|Pages|autodeploy|\.gitlab-ci.yml)\z/ - ), - Template.new( "https://gitlab.com/gitlab-org/Dockerfile.git", /(\.{1,2}|LICENSE|CONTRIBUTING.md|\.Dockerfile)\z/ ) diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po index dc4d2618ab7..c33fa2084a6 100644 --- a/locale/bg/gitlab.po +++ b/locale/bg/gitlab.po @@ -7109,7 +7109,7 @@ msgid "The tabs below will be removed in a future version" msgstr "" msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running." -msgstr "Етапът на тестване показва времето, което е нужно на „Gitlab CI“ да изпълни всяка схема от задачи за свързаната заявка за сливане. Данните ще бъдат добавени автоматично след като приключи изпълнението на първата Ви схема." +msgstr "Етапът на тестване показва времето, което е нужно на „GitLab CI“ да изпълни всяка схема от задачи за свързаната заявка за сливане. Данните ще бъдат добавени автоматично след като приключи изпълнението на първата Ви схема." msgid "The time in seconds GitLab will keep failure information. When no failures occur during this time, information about the mount is reset." msgstr "" diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po index 71e6504e306..25a041c94f4 100644 --- a/locale/de/gitlab.po +++ b/locale/de/gitlab.po @@ -3571,7 +3571,7 @@ msgid "Git revision" msgstr "" msgid "Git storage health information has been reset" -msgstr "Informationen über den Speicherzustand von Gitlab wurden zurückgesetzt." +msgstr "Informationen über den Speicherzustand von GitLab wurden zurückgesetzt." msgid "Git strategy for pipelines" msgstr "" diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po index eba59fdd3d8..648b323bed0 100644 --- a/locale/es/gitlab.po +++ b/locale/es/gitlab.po @@ -2130,7 +2130,7 @@ msgid "ContainerRegistry|First log in to GitLab’s Container Registry using msgstr "" msgid "ContainerRegistry|GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:" -msgstr "Gitlab soporta hasta 3 niveles para nombres de imágenes. Los siguientes ejemplos de imágenes son válidos para tu proyecto:" +msgstr "GitLab soporta hasta 3 niveles para nombres de imágenes. Los siguientes ejemplos de imágenes son válidos para tu proyecto:" msgid "ContainerRegistry|How to use the Container Registry" msgstr "" diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po index c0ce98832de..463c30cccfb 100644 --- a/locale/fr/gitlab.po +++ b/locale/fr/gitlab.po @@ -546,7 +546,7 @@ msgid "An application called %{link_to_client} is requesting access to your GitL msgstr "Une application appelée %{link_to_client} demande l’accès à votre compte GitLab." msgid "An empty GitLab User field will add the FogBugz user's full name (e.g. \"By John Smith\") in the description of all issues and comments. It will also associate and/or assign these issues and comments with the project creator." -msgstr "Un champ utilisateur Gitlab vide ajoutera le nom complet de l’utilisateur FogBugz (p. ex., « Par John Smith ») dans la description de tous les tickets et commentaires. Il associera ou assignera ces tickets et commentaires au créateur du projet." +msgstr "Un champ utilisateur GitLab vide ajoutera le nom complet de l’utilisateur FogBugz (p. ex., « Par John Smith ») dans la description de tous les tickets et commentaires. Il associera ou assignera ces tickets et commentaires au créateur du projet." msgid "An error accured whilst committing your changes." msgstr "Une erreur est survenue lors du commit de vos modifications." @@ -4020,7 +4020,7 @@ msgid "ImportButtons|Connect repositories from" msgstr "Connecter des dépôts provenant de" msgid "Improve Issue boards with GitLab Enterprise Edition." -msgstr "Améliorez le tableau des tickets avec Gitlab Entreprise Edition." +msgstr "Améliorez le tableau des tickets avec GitLab Entreprise Edition." msgid "Improve issues management with Issue weight and GitLab Enterprise Edition." msgstr "Améliorez la gestion des tickets grâce à la pondération disponible dans la version Entreprise Edition de GitLab." @@ -7004,7 +7004,7 @@ msgid "Thanks! Don't show me this again" msgstr "Merci ! Ne plus afficher ce message" msgid "The Advanced Global Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project." -msgstr "La recherche globale avancée de Gitlab est un outil puissant qui vous fait gagner du temps. Au lieu de perdre du temps à recréer du code existant, vous pouvez maintenant faire des recherches dans le code d’autres équipes afin de vous aider sur votre projet." +msgstr "La recherche globale avancée de GitLab est un outil puissant qui vous fait gagner du temps. Au lieu de perdre du temps à recréer du code existant, vous pouvez maintenant faire des recherches dans le code d’autres équipes afin de vous aider sur votre projet." msgid "The Git LFS objects will <strong>not</strong> be synced." msgstr "" diff --git a/locale/gitlab.pot b/locale/gitlab.pot index dc8fc1e53a0..a9c5e45f9fa 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -107,6 +107,9 @@ msgstr "" msgid "%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects." msgstr "" +msgid "%{issuableType} will be removed! Are you sure?" +msgstr "" + msgid "%{loadingIcon} Started" msgstr "" @@ -355,6 +358,9 @@ msgstr "" msgid "Add users to group" msgstr "" +msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission" +msgstr "" + msgid "Admin Area" msgstr "" @@ -784,9 +790,6 @@ msgstr "" msgid "Background color" msgstr "" -msgid "Background jobs" -msgstr "" - msgid "Badges" msgstr "" @@ -1050,6 +1053,9 @@ msgstr "" msgid "CI / CD Settings" msgstr "" +msgid "CI/CD" +msgstr "" + msgid "CI/CD configuration" msgstr "" @@ -1732,6 +1738,9 @@ msgstr "" msgid "CommitMessage|Add %{file_name}" msgstr "" +msgid "CommitWidget|authored" +msgstr "" + msgid "Commits" msgstr "" @@ -1804,9 +1813,6 @@ msgstr "" msgid "Configure Gitaly timeouts." msgstr "" -msgid "Configure Sidekiq job throttling." -msgstr "" - msgid "Configure automatic git checks and housekeeping on repositories." msgstr "" @@ -2553,6 +2559,9 @@ msgstr "" msgid "Environments|You don't have any environments right now." msgstr "" +msgid "Epic" +msgstr "" + msgid "Error" msgstr "" @@ -2841,6 +2850,9 @@ msgstr "" msgid "Generate a default set of labels" msgstr "" +msgid "Geo" +msgstr "" + msgid "Git" msgstr "" @@ -3293,6 +3305,9 @@ msgstr "" msgid "Invite" msgstr "" +msgid "Issue" +msgstr "" + msgid "Issue Boards" msgstr "" @@ -3323,9 +3338,6 @@ msgstr "" msgid "Jobs" msgstr "" -msgid "Job|Are you sure you want to erase this job?" -msgstr "" - msgid "Job|Browse" msgstr "" @@ -3362,7 +3374,7 @@ msgstr "" msgid "Job|The artifacts were removed" msgstr "" -msgid "Job|The artifacts will be removed" +msgid "Job|The artifacts will be removed in" msgstr "" msgid "Job|This job is stuck, because the project doesn't have any runners online assigned to it." @@ -3681,9 +3693,6 @@ msgstr "" msgid "MergeRequests|Toggle comments for this file" msgstr "" -msgid "MergeRequests|Updating discussions failed" -msgstr "" - msgid "MergeRequests|View file @ %{commitId}" msgstr "" @@ -3708,6 +3717,9 @@ msgstr "" msgid "Metrics - Prometheus" msgstr "" +msgid "Metrics and profiling" +msgstr "" + msgid "Metrics|Check out the CI/CD documentation on deploying to an environment" msgstr "" @@ -4995,6 +5007,9 @@ msgstr "" msgid "Reply to this email directly or %{view_it_on_gitlab}." msgstr "" +msgid "Reporting" +msgstr "" + msgid "Reports|%{failedString} and %{resolvedString}" msgstr "" @@ -5536,6 +5551,9 @@ msgstr "" msgid "SortOptions|Most popular" msgstr "" +msgid "SortOptions|Most stars" +msgstr "" + msgid "SortOptions|Name" msgstr "" @@ -5796,6 +5814,9 @@ msgstr "" msgid "Template" msgstr "" +msgid "Templates" +msgstr "" + msgid "Terms of Service Agreement and Privacy Policy" msgstr "" @@ -6334,6 +6355,9 @@ msgstr "" msgid "Toggle Sidebar" msgstr "" +msgid "Toggle commit description" +msgstr "" + msgid "Toggle discussion" msgstr "" diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po index a4e20f4fe65..8d7bc9aff91 100644 --- a/locale/it/gitlab.po +++ b/locale/it/gitlab.po @@ -143,7 +143,7 @@ msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will allow msgstr "%{number_of_failures} di %{maximum_failures} fallimenti. GitLab consentirà l'accesso al prossimo tentativo." msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will not retry automatically. Reset storage information when the problem is resolved." -msgstr "%{number_of_failures} di %{maximum_failures} fallimenti. Gitlab non ritenterà automaticamente. Ripristina l'informazioni d'archiviazione quando il problema è risolto." +msgstr "%{number_of_failures} di %{maximum_failures} fallimenti. GitLab non ritenterà automaticamente. Ripristina l'informazioni d'archiviazione quando il problema è risolto." msgid "%{openOrClose} %{noteable}" msgstr "" @@ -1091,7 +1091,7 @@ msgstr[0] "" msgstr[1] "" msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}" -msgstr "La branch <strong>%{branch_name}</strong> è stata creata. Per impostare un rilascio automatico scegli un template CI di Gitlab e committa le tue modifiche %{link_to_autodeploy_doc}" +msgstr "La branch <strong>%{branch_name}</strong> è stata creata. Per impostare un rilascio automatico scegli un template CI di GitLab e committa le tue modifiche %{link_to_autodeploy_doc}" msgid "Branch has changed" msgstr "La branche è cambiata" @@ -1661,7 +1661,7 @@ msgid "ClusterIntegration|GitLab Integration" msgstr "" msgid "ClusterIntegration|GitLab Runner" -msgstr "Gitlab Runner" +msgstr "GitLab Runner" msgid "ClusterIntegration|GitLab Runner connects to this project's repository and executes CI/CD jobs, pushing results back and deploying, applications to production." msgstr "" @@ -2163,7 +2163,7 @@ msgid "ContainerRegistry|Use different image names" msgstr "Utilizza nomi d'immagine differenti" msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images." -msgstr "Con il Docker Container Registry integrato in Gitlab, ogni progetto può avere il suo spazio d'archiviazione sulle immagini Docker." +msgstr "Con il Docker Container Registry integrato in GitLab, ogni progetto può avere il suo spazio d'archiviazione sulle immagini Docker." msgid "ContainerRegistry|You can also use a %{deploy_token} for read-only access to the registry images." msgstr "" @@ -3652,7 +3652,7 @@ msgid "Google Takeout" msgstr "" msgid "Google authentication is not %{link_to_documentation}. Ask your GitLab administrator if you want to use this service." -msgstr "L'autenticazione Google non è %{link_to_documentation}. Richiedi al tuo amministratore Gitlab se desideri utilizzare il servizio." +msgstr "L'autenticazione Google non è %{link_to_documentation}. Richiedi al tuo amministratore GitLab se desideri utilizzare il servizio." msgid "Got it!" msgstr "" diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po index a0e18f2be2f..516b85f0016 100644 --- a/locale/pt_BR/gitlab.po +++ b/locale/pt_BR/gitlab.po @@ -1646,7 +1646,7 @@ msgid "ClusterIntegration|Environment scope" msgstr "Escopo de ambiente" msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab's Google Kubernetes Engine Integration." -msgstr "Cada nova conta no Google Cloud Plataform (GCP) recebe US$300 em créditos por se %{sign_up_link}. Em parceria com o Google, o Gitlab pode oferecer um adicional de US$200 para novas contas do GCP para começar a usar a integração GKE do GitLab." +msgstr "Cada nova conta no Google Cloud Plataform (GCP) recebe US$300 em créditos por se %{sign_up_link}. Em parceria com o Google, o GitLab pode oferecer um adicional de US$200 para novas contas do GCP para começar a usar a integração GKE do GitLab." msgid "ClusterIntegration|Fetching machine types" msgstr "Recuperando tipos de máquina" @@ -1661,7 +1661,7 @@ msgid "ClusterIntegration|GitLab Integration" msgstr "Integração GitLab" msgid "ClusterIntegration|GitLab Runner" -msgstr "Gitlab Runner" +msgstr "GitLab Runner" msgid "ClusterIntegration|GitLab Runner connects to this project's repository and executes CI/CD jobs, pushing results back and deploying, applications to production." msgstr "" @@ -2127,10 +2127,10 @@ msgid "ContainerRegistry|Created" msgstr "Criado" msgid "ContainerRegistry|First log in to GitLab’s Container Registry using your GitLab username and password. If you have %{link_2fa} you need to use a %{link_token}:" -msgstr "Primeiro faça login no Container Registry do Gitlab usando seu nome de usuário e senha. Se você tiver %{link_2fa}, será necessário usar um %{link_token}:" +msgstr "Primeiro faça login no Container Registry do GitLab usando seu nome de usuário e senha. Se você tiver %{link_2fa}, será necessário usar um %{link_token}:" msgid "ContainerRegistry|GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:" -msgstr "Gitlab suporta até três níveis de nomes de imagens. Os exemplos a seguir são de imagens válidas para seu projeto:" +msgstr "GitLab suporta até três níveis de nomes de imagens. Os exemplos a seguir são de imagens válidas para seu projeto:" msgid "ContainerRegistry|How to use the Container Registry" msgstr "Como usar o Container Registry" @@ -2163,7 +2163,7 @@ msgid "ContainerRegistry|Use different image names" msgstr "Use nomes de imagem diferentes" msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images." -msgstr "Com o Container Registry do Docker integrado ao Gitlab, todo projeto pode ter seu próprio espaço para guardar suas imagens." +msgstr "Com o Container Registry do Docker integrado ao GitLab, todo projeto pode ter seu próprio espaço para guardar suas imagens." msgid "ContainerRegistry|You can also use a %{deploy_token} for read-only access to the registry images." msgstr "Você pode usar também um %{deploy_token} para acesso somente-leitura às imagens do registry." @@ -3652,7 +3652,7 @@ msgid "Google Takeout" msgstr "Google Takeout" msgid "Google authentication is not %{link_to_documentation}. Ask your GitLab administrator if you want to use this service." -msgstr "Autenticação do Google não está %{link_to_documentation}. Peça ao administrador do Gitlab se você deseja usar esse serviço." +msgstr "Autenticação do Google não está %{link_to_documentation}. Peça ao administrador do GitLab se você deseja usar esse serviço." msgid "Got it!" msgstr "Entendi!" @@ -5812,7 +5812,7 @@ msgid "PrometheusService|Automatically deploy and configure Prometheus on your c msgstr "Fazer deploy automático e configurar o Prometheus nos seus clusters para monitorar o ambiente do seu projeto" msgid "PrometheusService|By default, Prometheus listens on ‘http://localhost:9090’. It’s not recommended to change the default address and port as this might affect or conflict with other services running on the GitLab server." -msgstr "Por padrão, Prometheus escuta em 'http://localhost:9090'. Não é recomendado mudar o endereço padrão e sua porta, porque pode conflitar com outros serviços que estão executando no sevidor do Gitlab." +msgstr "Por padrão, Prometheus escuta em 'http://localhost:9090'. Não é recomendado mudar o endereço padrão e sua porta, porque pode conflitar com outros serviços que estão executando no sevidor do GitLab." msgid "PrometheusService|Common metrics" msgstr "Métricas comuns" diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po index 4b66d59bebd..75a291be637 100644 --- a/locale/ru/gitlab.po +++ b/locale/ru/gitlab.po @@ -6884,7 +6884,7 @@ msgid "Specify an e-mail address regex pattern to identify default internal user msgstr "" msgid "Specify the following URL during the Runner setup:" -msgstr "Укажите следующий URL во время настройки Gitlab Runner:" +msgstr "Укажите следующий URL во время настройки GitLab Runner:" msgid "Squash commits" msgstr "" diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po index c8f5cf5cae8..7757f421b1f 100644 --- a/locale/uk/gitlab.po +++ b/locale/uk/gitlab.po @@ -431,7 +431,7 @@ msgid "Access to failing storages has been temporarily disabled to allow the mou msgstr "Доступ до сховищ, що вийшли з ладу, тимчасово прибраний задля відновлення монтування. Після вирішення проблеми обнуліть інформацію сховища для відновлення доступу." msgid "Access your runner token, customize your pipeline configuration, and view your pipeline status and coverage report." -msgstr "Отримайте доступ до Gitlab Runner токену, налаштуйте конфігурацію конвеєра та перегляньте його статус, а також звіт про покриття." +msgstr "Отримайте доступ до GitLab Runner токену, налаштуйте конфігурацію конвеєра та перегляньте його статус, а також звіт про покриття." msgid "Account" msgstr "Обліковий запис" @@ -614,7 +614,7 @@ msgid "An application called %{link_to_client} is requesting access to your GitL msgstr "Додаток під назвою %{link_to_client} запитує доступ до вашого GitLab аккаунту." msgid "An empty GitLab User field will add the FogBugz user's full name (e.g. \"By John Smith\") in the description of all issues and comments. It will also associate and/or assign these issues and comments with the project creator." -msgstr "Порожнє поле Gitlab-користувача буде заповнено іменем користувача з FogBugz (наприклад \"John Smith\") в описі всіх проблем та коментарів. Крім того ці проблеми та коментарі будуть асоційовані з та/або призначені на автора проекту." +msgstr "Порожнє поле GitLab-користувача буде заповнено іменем користувача з FogBugz (наприклад \"John Smith\") в описі всіх проблем та коментарів. Крім того ці проблеми та коментарі будуть асоційовані з та/або призначені на автора проекту." msgid "An error accured whilst committing your changes." msgstr "Трапилася помилка при коміті ваших змін." @@ -3667,7 +3667,7 @@ msgid "GitLab Geo" msgstr "GitLab Geo" msgid "GitLab Group Runners can execute code for all the projects in this group." -msgstr "Групові Runner'и Gitlab можуть виконувати код для усіх проектів у цій групі." +msgstr "Групові Runner'и GitLab можуть виконувати код для усіх проектів у цій групі." msgid "GitLab Import" msgstr "Імпорт з GitLab" @@ -6541,7 +6541,7 @@ msgid "Select the custom project template source group." msgstr "" msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By <a href=\"#\">@johnsmith</a>\"). It will also associate and/or assign these issues and comments with the selected user." -msgstr "При виборі користувача Gitlab посилання на нього буде додане до опису проблем та коментарів (напр. \"<a href=\"#\"> @johnsmith</a>\"). Також це призведе до асоціації та/або призначення цих проблем та коментарів на вибраного користувача." +msgstr "При виборі користувача GitLab посилання на нього буде додане до опису проблем та коментарів (напр. \"<a href=\"#\"> @johnsmith</a>\"). Також це призведе до асоціації та/або призначення цих проблем та коментарів на вибраного користувача." msgid "Selective synchronization" msgstr "Вибіркова синхронізація" @@ -7149,7 +7149,7 @@ msgid "The number of attempts GitLab will make to access a storage." msgstr "Кількість спроб, які зробить GitLab для отримання доступу до сховища даних." msgid "The number of failures after which GitLab will completely prevent access to the storage. The number of failures can be reset in the admin interface: %{link_to_health_page} or using the %{api_documentation_link}." -msgstr "Кількість збоїв після чого Gitlab повністю заблокує доступ до сховища данних. Лічильник кількості збоїв може бути скинутий в інтерфейсі адміністратора %{link_to_health_page}, або через %{api_documentation_link}." +msgstr "Кількість збоїв після чого GitLab повністю заблокує доступ до сховища данних. Лічильник кількості збоїв може бути скинутий в інтерфейсі адміністратора %{link_to_health_page}, або через %{api_documentation_link}." msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest." msgstr "Пароль, який потрібен для дешифрування приватного ключа. Він є необов’язковим і зберігається у зашифрованому вигляді." @@ -7230,7 +7230,7 @@ msgid "The user map is a JSON document mapping the Google Code users that partic msgstr "Мапа користувачів — це JSON-документ, який задає як адреси електронної пошти та імена користувачів Google Code, що приймали участь у ваших проектах будуть імпортовані у GitLab. Ви можете змінити його шляхом зміни значень, що стоять справа від <code>:</code>. Не видаляйте лапки та інші знаки пунктуації, а також не змінюйте адреси електронної пошти чи імена користувачів зліва." msgid "The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames will be imported into GitLab. You can change this by populating the table below." -msgstr "Мапа користувачів — це правила імпортування користувачів FogBugz, які приймали участь у ваших проектах до Gitlab (зокрема їх імен та адрес електронної пошти). Ви можете вносити зміни шляхом заповнення таблиці нижче." +msgstr "Мапа користувачів — це правила імпортування користувачів FogBugz, які приймали участь у ваших проектах до GitLab (зокрема їх імен та адрес електронної пошти). Ви можете вносити зміни шляхом заповнення таблиці нижче." msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6." msgstr "Середнє значення в рядку. Приклад: між 3, 5, 9, середніми 5, між 3, 5, 7, 8, середніми (5 + 7) / 2 = 6." @@ -7625,7 +7625,7 @@ msgid "To connect GitHub repositories, you can use a %{personal_access_token_lin msgstr "Для підключення репозиторіїв з GitHub, ви можете використовувати %{personal_access_token_link}. Коли ви створюватимете ваш персональний токен доступу, вам потрібно буде вибрати область дії <code>repo</code>, щоб ми могли відобразити список ваших публічних та приватних репозиторіїв, доступних для підключення." msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories:" -msgstr "Для підключення репозиторіїв з GitHub, ви спочатку повинні дозволити Gitlab доступ до списку ваших репозиторіїв на GitHub:" +msgstr "Для підключення репозиторіїв з GitHub, ви спочатку повинні дозволити GitLab доступ до списку ваших репозиторіїв на GitHub:" msgid "To connect an SVN repository, check out %{svn_link}." msgstr "Для приєднання SVN-репозиторію, перегляньте %{svn_link}." @@ -7643,7 +7643,7 @@ msgid "To import GitHub repositories, you can use a %{personal_access_token_link msgstr "Для імпортування репозиторіїв з GitHub, ви можете використовувати %{personal_access_token_link}. Коли ви створюватимете ваш персональний токен доступу, вам потрібно буде вибрати область дії <code>repo</code>, щоб ми могли відобразити список ваших публічних та приватних репозиторіїв, доступних для підключення." msgid "To import GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories:" -msgstr "Для імпорту репозиторіїв з GitHub, ви спочатку повинні дозволити Gitlab доступ до списку ваших репозиторіїв на GitHub:" +msgstr "Для імпорту репозиторіїв з GitHub, ви спочатку повинні дозволити GitLab доступ до списку ваших репозиторіїв на GitHub:" msgid "To import an SVN repository, check out %{svn_link}." msgstr "Для імпортування SVN-репозиторію, перегляньте %{svn_link}." @@ -8177,7 +8177,7 @@ msgid "You are going to transfer %{project_full_name} to another owner. Are you msgstr "Ви збираєтеся передати проект %{project_full_name} іншому власнику. Ви АБСОЛЮТНО впевнені?" msgid "You are on a read-only GitLab instance." -msgstr "Ви знаходитеся на інстансі Gitlab \"тільки для читання\"." +msgstr "Ви знаходитеся на інстансі GitLab \"тільки для читання\"." msgid "You are on a secondary, <b>read-only</b> Geo node. If you want to make changes, you must visit this page on the %{primary_node}." msgstr "Ви знаходитесь на вторинному <b>лише для читання</b> Geo-вузлі. Якщо ви хочете внести будь-які зміни, ви повинні відвідати %{primary_node}." diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po index e93bfd7cfb8..5f72eee83d8 100644 --- a/locale/zh_CN/gitlab.po +++ b/locale/zh_CN/gitlab.po @@ -2078,7 +2078,7 @@ msgid "Connect repositories from GitHub" msgstr "从 Github 中导入代码仓库" msgid "Connect your external repositories, and CI/CD pipelines will run for new commits. A GitLab project will be created with only CI/CD features enabled." -msgstr "连接外部仓库后,新提交将会启动CI/CD流水线。仅启用CI/CD功能的Gitlab项目将会被创建。" +msgstr "连接外部仓库后,新提交将会启动CI/CD流水线。仅启用CI/CD功能的GitLab项目将会被创建。" msgid "Connecting..." msgstr "正在连接..." @@ -3550,7 +3550,7 @@ msgid "GitLab Geo" msgstr "GitLab Geo" msgid "GitLab Group Runners can execute code for all the projects in this group." -msgstr "Gitlab群组Runner可以用来运行群组内所有项目的代码。" +msgstr "GitLab群组Runner可以用来运行群组内所有项目的代码。" msgid "GitLab Import" msgstr "GitLab导入" diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po index 5c9746ad6b4..534e1f64ea1 100644 --- a/locale/zh_TW/gitlab.po +++ b/locale/zh_TW/gitlab.po @@ -1626,7 +1626,7 @@ msgid "ClusterIntegration|GitLab Integration" msgstr "GitLab 整合" msgid "ClusterIntegration|GitLab Runner" -msgstr "Gitlab Runner" +msgstr "GitLab Runner" msgid "ClusterIntegration|GitLab Runner connects to this project's repository and executes CI/CD jobs, pushing results back and deploying, applications to production." msgstr "" @@ -2090,7 +2090,7 @@ msgid "ContainerRegistry|Created" msgstr "已建立" msgid "ContainerRegistry|First log in to GitLab’s Container Registry using your GitLab username and password. If you have %{link_2fa} you need to use a %{link_token}:" -msgstr "請先使用你的 Gitlab 帳號來登入 Gitlab 的 Container Registry。如果你有 %{link_2fa} ,你必須使用 %{link_token}:" +msgstr "請先使用你的 GitLab 帳號來登入 GitLab 的 Container Registry。如果你有 %{link_2fa} ,你必須使用 %{link_token}:" msgid "ContainerRegistry|GitLab supports up to 3 levels of image names. The following examples of images are valid for your project:" msgstr "GitLab 支援多達 3 級的映像檔名稱。以下映像檔範例對您的專案有幫助:" @@ -6897,7 +6897,7 @@ msgid "TagsPage|Optionally, add a message to the tag." msgstr "增加標籤的說明(可選)" msgid "TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page." -msgstr "增加標籤的發佈說明,這將會被儲存在Gitlab資料庫中,並顯示於標籤頁。(可選)" +msgstr "增加標籤的發佈說明,這將會被儲存在GitLab資料庫中,並顯示於標籤頁。(可選)" msgid "TagsPage|Release notes" msgstr "發佈說明" diff --git a/package.json b/package.json index 4a479b6fb2a..714bdb285fe 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@gitlab-org/gitlab-svgs": "^1.29.0", - "@gitlab-org/gitlab-ui": "^1.5.0", + "@gitlab-org/gitlab-ui": "^1.7.1", "autosize": "^4.0.0", "axios": "^0.17.1", "babel-core": "^6.26.3", @@ -35,7 +35,7 @@ "classlist-polyfill": "^1.2.0", "clipboard": "^1.7.1", "codesandbox-api": "^0.0.18", - "compression-webpack-plugin": "^1.1.11", + "compression-webpack-plugin": "^2.0.0", "core-js": "^2.4.1", "cropper": "^2.3.0", "css-loader": "^1.0.0", @@ -55,7 +55,7 @@ "dropzone": "^4.2.0", "emoji-unicode-version": "^0.2.1", "exports-loader": "^0.7.0", - "file-loader": "^1.1.11", + "file-loader": "^2.0.0", "formdata-polyfill": "^3.0.11", "fuzzaldrin-plus": "^0.5.0", "glob": "^7.1.2", @@ -70,7 +70,7 @@ "katex": "^0.9.0", "marked": "^0.3.12", "monaco-editor": "^0.14.3", - "monaco-editor-webpack-plugin": "^1.5.2", + "monaco-editor-webpack-plugin": "^1.5.4", "mousetrap": "^1.4.6", "pikaday": "^1.6.1", "popper.js": "^1.14.3", @@ -85,47 +85,47 @@ "sortablejs": "^1.7.0", "sql.js": "^0.4.0", "stickyfilljs": "^2.0.5", - "style-loader": "^0.21.0", + "style-loader": "^0.23.0", "svg4everybody": "2.1.9", "three": "^0.84.0", "three-orbit-controls": "^82.1.0", "three-stl-loader": "^1.0.4", "timeago.js": "^3.0.2", "underscore": "^1.9.0", - "url-loader": "^1.0.1", + "url-loader": "^1.1.1", "visibilityjs": "^1.2.4", - "vue": "^2.5.16", - "vue-loader": "^15.2.4", + "vue": "^2.5.17", + "vue-loader": "^15.4.2", "vue-resource": "^1.5.0", "vue-router": "^3.0.1", - "vue-template-compiler": "^2.5.16", + "vue-template-compiler": "^2.5.17", "vue-virtual-scroll-list": "^1.2.5", "vuex": "^3.0.1", - "webpack": "^4.16.0", - "webpack-bundle-analyzer": "^2.13.1", - "webpack-cli": "^3.0.8", + "webpack": "^4.19.1", + "webpack-bundle-analyzer": "^3.0.2", + "webpack-cli": "^3.1.0", "webpack-stats-plugin": "^0.2.1", "worker-loader": "^2.0.0", "xterm": "^3.5.0" }, "devDependencies": { "axios-mock-adapter": "^1.15.0", - "babel-eslint": "^8.2.3", - "babel-plugin-istanbul": "^4.1.6", - "babel-plugin-rewire": "^1.1.0", + "babel-eslint": "^9.0.0", + "babel-plugin-istanbul": "^5.0.1", + "babel-plugin-rewire": "^1.2.0", "babel-template": "^6.26.0", "babel-types": "^6.26.0", "chalk": "^2.4.1", - "commander": "^2.15.1", - "eslint": "~4.12.1", - "eslint-config-airbnb-base": "^12.1.0", - "eslint-import-resolver-webpack": "^0.10.0", - "eslint-plugin-filenames": "^1.2.0", - "eslint-plugin-html": "4.0.3", - "eslint-plugin-import": "^2.12.0", - "eslint-plugin-jasmine": "^2.1.0", - "eslint-plugin-promise": "^3.8.0", - "eslint-plugin-vue": "^4.5.0", + "commander": "^2.18.0", + "eslint": "~5.6.0", + "eslint-config-airbnb-base": "^13.1.0", + "eslint-import-resolver-webpack": "^0.10.1", + "eslint-plugin-filenames": "^1.3.2", + "eslint-plugin-html": "4.0.5", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-jasmine": "^2.10.1", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-vue": "^5.0.0-beta.3", "gettext-extractor": "^3.3.2", "gettext-extractor-vue": "^4.0.1", "ignore": "^3.3.7", @@ -141,8 +141,8 @@ "karma-mocha-reporter": "^2.2.5", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^4.0.0-beta.0", - "nodemon": "^1.18.2", + "nodemon": "^1.18.4", "prettier": "1.12.1", - "webpack-dev-server": "^3.1.4" + "webpack-dev-server": "^3.1.8" } } diff --git a/qa/qa/factory/resource/fork.rb b/qa/qa/factory/resource/fork.rb index 01969c31438..92050eaba2a 100644 --- a/qa/qa/factory/resource/fork.rb +++ b/qa/qa/factory/resource/fork.rb @@ -13,8 +13,43 @@ module QA product(:user) { |factory| factory.user } + def visit_project_with_retry + # The user intermittently fails to stay signed in after visiting the + # project page. The new user is registered and then signs in and a + # screenshot shows that signing in was successful. Then the project + # page is visited but a screenshot shows the user is no longer signed + # in. It's difficult to reproduce locally but GDK logs don't seem to + # show anything unexpected. This method attempts to work around the + # problem and capture data to help troubleshoot. + + Capybara::Screenshot.screenshot_and_save_page + + start = Time.now + + while Time.now - start < 20 + push.project.visit! + + puts "Visited project page" + Capybara::Screenshot.screenshot_and_save_page + + return if Page::Menu::Main.act { has_personal_area?(wait: 0) } + + puts "Not signed in. Attempting to sign in again." + Capybara::Screenshot.screenshot_and_save_page + + Page::Menu::Main.act { sign_out } + + Page::Main::Login.perform do |login| + login.sign_in_using_credentials(user) + end + end + + raise "Failed to load project page and stay logged in" + end + def fabricate! - push.project.visit! + visit_project_with_retry + Page::Project::Show.act { fork_project } Page::Project::Fork::New.perform do |fork_new| diff --git a/qa/qa/factory/resource/user.rb b/qa/qa/factory/resource/user.rb index eac2a873bd5..34b52223b2d 100644 --- a/qa/qa/factory/resource/user.rb +++ b/qa/qa/factory/resource/user.rb @@ -37,7 +37,10 @@ module QA product(:password) { |factory| factory.password } def fabricate! - Page::Menu::Main.perform { |main| main.sign_out } + # Don't try to log-out if we're not logged-in + if Page::Menu::Main.act { has_personal_area?(wait: 0) } + Page::Menu::Main.perform { |main| main.sign_out } + end if credentials_given? Page::Main::Login.perform do |login| diff --git a/qa/qa/page/admin/settings/main.rb b/qa/qa/page/admin/settings/main.rb index db3387b4557..73034ffe0d8 100644 --- a/qa/qa/page/admin/settings/main.rb +++ b/qa/qa/page/admin/settings/main.rb @@ -6,11 +6,11 @@ module QA include QA::Page::Settings::Common view 'app/views/admin/application_settings/show.html.haml' do - element :repository_storage_settings + element :terms_settings end def expand_repository_storage(&block) - expand_section(:repository_storage_settings) do + expand_section(:terms_settings) do RepositoryStorage.perform(&block) end end diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index 30e35bf7abb..a87536671c6 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -76,6 +76,10 @@ module QA find_element(name).set(content) end + def has_element?(name) + has_css?(element_selector_css(name)) + end + def within_element(name) page.within(element_selector_css(name)) do yield diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb index 6747f7f10b6..74d20df76ba 100644 --- a/qa/qa/page/group/show.rb +++ b/qa/qa/page/group/show.rb @@ -5,14 +5,11 @@ module QA include Page::Component::GroupsFilter view 'app/views/groups/show.html.haml' do - element :new_project_or_subgroup_dropdown, '.new-project-subgroup' - element :new_project_or_subgroup_dropdown_toggle, '.dropdown-toggle' - element :new_project_option, /%li.*data:.*value: "new-project"/ - element :new_project_button, /%input.*data:.*action: "new-project"/ - element :new_subgroup_option, /%li.*data:.*value: "new-subgroup"/ - - # data-value and data-action get modified by JS for subgroup - element :new_subgroup_button, /%input.*\.js-new-group-child/ + element :new_project_or_subgroup_dropdown + element :new_project_or_subgroup_dropdown_toggle + element :new_project_option + element :new_subgroup_option + element :new_in_group_button end view 'app/assets/javascripts/groups/constants.js' do @@ -24,7 +21,7 @@ module QA end def has_new_project_or_subgroup_dropdown? - page.has_css?(element_selector_css(:new_project_or_subgroup_dropdown)) + has_element?(:new_project_or_subgroup_dropdown) end def has_subgroup?(name) @@ -36,31 +33,29 @@ module QA end def go_to_new_subgroup - click_new('subgroup') + select_kind :new_subgroup_option - find("input[data-action='new-subgroup']").click + click_element :new_in_group_button end def go_to_new_project - click_new('project') + select_kind :new_project_option - find("input[data-action='new-project']").click + click_element :new_in_group_button end private - def click_new(kind) - within '.new-project-subgroup' do - css = "li[data-value='new-#{kind}']" - + def select_kind(kind) + within_element(:new_project_or_subgroup_dropdown) do # May need to click again because it is possible to click the button quicker than the JS is bound wait(reload: false) do - find('.dropdown-toggle').click + click_element :new_project_or_subgroup_dropdown_toggle - page.has_css?(css) + has_element?(kind) end - find(css).click + click_element kind end end end diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index e9e49964e63..9b3183ba328 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -23,6 +23,7 @@ module QA view 'app/views/devise/shared/_tabs_ldap.html.haml' do element :ldap_tab element :standard_tab + element :register_tab end view 'app/views/devise/shared/_tabs_normal.html.haml' do @@ -35,7 +36,7 @@ module QA # we need to wait for the instance to start. That said, in some cases # we are already logged-in so we check both cases here. wait(max: 500) do - page.has_css?('.login-page') || + has_css?('.login-page') || Page::Menu::Main.act { has_personal_area?(wait: 0) } end end @@ -78,12 +79,28 @@ module QA '/users/sign_in' end + def has_sign_in_tab? + has_element?(:sign_in_tab) + end + + def has_ldap_tab? + has_element?(:ldap_tab) + end + + def has_standard_tab? + has_element?(:standard_tab) + end + def sign_in_tab? - page.has_button?('Sign in') + has_css?(".active", text: 'Sign in') end def ldap_tab? - page.has_link?('LDAP') + has_css?(".active", text: 'LDAP') + end + + def standard_tab? + has_css?(".active", text: 'Standard') end def switch_to_sign_in_tab @@ -91,6 +108,7 @@ module QA end def switch_to_register_tab + set_initial_password_if_present click_element :register_tab end @@ -113,8 +131,8 @@ module QA end def sign_in_using_gitlab_credentials(user) - switch_to_sign_in_tab unless sign_in_tab? - switch_to_standard_tab if ldap_tab? + switch_to_sign_in_tab if has_sign_in_tab? + switch_to_standard_tab if has_standard_tab? fill_element :login_field, user.username fill_element :password_field, user.password @@ -122,7 +140,7 @@ module QA end def set_initial_password_if_present - return unless page.has_content?('Change your password') + return unless has_content?('Change your password') fill_element :password_field, Runtime::User.password fill_element :password_confirmation, Runtime::User.password diff --git a/qa/qa/page/main/sign_up.rb b/qa/qa/page/main/sign_up.rb index 33ab56236f4..64cd395de78 100644 --- a/qa/qa/page/main/sign_up.rb +++ b/qa/qa/page/main/sign_up.rb @@ -19,7 +19,7 @@ module QA fill_in :new_user_password, with: user.password click_button 'Register' - Page::Menu::Main.act { has_personal_area? } + Page::Menu::Main.act { assert_has_personal_area } end end end diff --git a/qa/qa/page/menu/main.rb b/qa/qa/page/menu/main.rb index 36e7285f7b7..2ae86bbc7dc 100644 --- a/qa/qa/page/menu/main.rb +++ b/qa/qa/page/menu/main.rb @@ -61,8 +61,13 @@ module QA end def has_personal_area?(wait: Capybara.default_max_wait_time) - # No need to wait, either we're logged-in, or not. - using_wait_time(wait) { page.has_selector?('.qa-user-avatar') } + using_wait_time(wait) do + page.has_selector?(element_selector_css(:user_avatar)) + end + end + + def assert_has_personal_area + raise "Failed to sign in" unless has_personal_area? end private diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index c200f14f4fb..d9254d89541 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -5,6 +5,9 @@ module QA view 'app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue' do element :merge_button element :fast_forward_message, 'Fast-forward merge without a merge commit' + element :merge_moment_dropdown + element :merge_when_pipeline_succeeds_option + element :merge_immediately_option end view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do @@ -16,7 +19,7 @@ module QA element :no_fast_forward_message, 'Fast-forward merge is not possible' end - view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue' do + view 'app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue' do element :squash_checkbox end @@ -27,7 +30,20 @@ module QA def has_merge_button? refresh - has_selector?('.accept-merge-request') + has_css?(element_selector_css(:merge_button)) + end + + def has_merge_options? + has_css?(element_selector_css(:merge_moment_dropdown)) + end + + def merge_immediately + if has_merge_options? + click_element :merge_moment_dropdown + click_element :merge_immediately_option + else + click_element :merge_button + end end def rebase! @@ -59,7 +75,7 @@ module QA !first(element_selector_css(:merge_button)).disabled? end - click_element :merge_button + merge_immediately wait(reload: false) do has_text?('The changes were merged into') diff --git a/qa/qa/page/project/activity.rb b/qa/qa/page/project/activity.rb index 0196922c889..a0500b4d31a 100644 --- a/qa/qa/page/project/activity.rb +++ b/qa/qa/page/project/activity.rb @@ -3,7 +3,7 @@ module QA module Project class Activity < Page::Base view 'app/views/shared/_event_filter.html.haml' do - element :push_events, "event_filter_link EventFilter.push, _('Push events')" + element :push_events, "event_filter_link EventFilter::PUSH, _('Push events')" end def go_to_push_events diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb new file mode 100644 index 00000000000..478a5cb9c4c --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module QA + shared_examples 'registration and login' do + it 'user registers and logs in' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + + Factory::Resource::User.fabricate! + + # 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 + + context :manage do + describe 'standard' do + it_behaves_like 'registration and login' + end + end + + context :manage, :orchestrated, :ldap do + describe 'while LDAP is enabled' do + it_behaves_like 'registration and login' + end + end +end diff --git a/qa/qa/specs/features/sanity/framework_spec.rb b/qa/qa/specs/features/sanity/framework_spec.rb index ee9d068eb3a..aae0f0ade71 100644 --- a/qa/qa/specs/features/sanity/framework_spec.rb +++ b/qa/qa/specs/features/sanity/framework_spec.rb @@ -6,9 +6,7 @@ module QA it 'succeeds' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform do |main_login| - expect(main_login.sign_in_tab?).to be(true) - end + expect(page).to have_text('Open source software to collaborate on code') end end diff --git a/rubocop/cop/avoid_route_redirect_leading_slash.rb b/rubocop/cop/avoid_route_redirect_leading_slash.rb new file mode 100644 index 00000000000..7ac1c881269 --- /dev/null +++ b/rubocop/cop/avoid_route_redirect_leading_slash.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Checks for a leading '/' in route redirects + # For more information see: https://gitlab.com/gitlab-org/gitlab-ce/issues/50645 + # + # @example + # # bad + # root to: redirect('/-/instance/statistics/conversational_development_index') + # + # # good + # root to: redirect('-/instance/statistics/conversational_development_index') + # + + class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Cop + MSG = 'Do not use a leading "/" in route redirects' + + def_node_matcher :leading_slash_in_redirect?, <<~PATTERN + (send nil? :redirect (str #has_leading_slash?)) + PATTERN + + def on_send(node) + return unless in_routes?(node) + return unless leading_slash_in_redirect?(node) + + add_offense(node) + end + + def has_leading_slash?(str) + str.start_with?("/") + end + + def in_routes?(node) + path = node.location.expression.source_buffer.name + dirname = File.dirname(path) + filename = File.basename(path) + dirname.end_with?('config/routes') || filename.end_with?('routes.rb') + end + + def autocorrect(node) + lambda do |corrector| + corrector.replace(node.loc.expression, remove_leading_slash(node)) + end + end + + def remove_leading_slash(node) + node.source.sub('/', '') + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index 9d6cc73fc3b..ff929c7b6ce 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -7,6 +7,7 @@ require_relative 'cop/gitlab/union' require_relative 'cop/include_sidekiq_worker' require_relative 'cop/avoid_return_from_blocks' require_relative 'cop/avoid_break_from_strong_memoize' +require_relative 'cop/avoid_route_redirect_leading_slash' require_relative 'cop/line_break_around_conditional_block' require_relative 'cop/prefer_class_methods_over_module' require_relative 'cop/migration/add_column' diff --git a/scripts/review_apps/automated_cleanup.rb b/scripts/review_apps/automated_cleanup.rb new file mode 100755 index 00000000000..ea53f89c844 --- /dev/null +++ b/scripts/review_apps/automated_cleanup.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require 'gitlab' +require_relative File.expand_path('../../lib/quality/helm_client.rb', __dir__) +require_relative File.expand_path('../../lib/quality/kubernetes_client.rb', __dir__) + +class AutomatedCleanup + attr_reader :project_path, :gitlab_token, :cleaned_up_releases + + def initialize(project_path: ENV['CI_PROJECT_PATH'], gitlab_token: ENV['GITLAB_BOT_REVIEW_APPS_CLEANUP_TOKEN']) + @project_path = project_path + @gitlab_token = gitlab_token + @cleaned_up_releases = [] + end + + def gitlab + @gitlab ||= begin + Gitlab.configure do |config| + config.endpoint = 'https://gitlab.com/api/v4' + # gitlab-bot's token "GitLab review apps cleanup" + config.private_token = gitlab_token + end + + Gitlab + end + end + + def helm + @helm ||= Quality::HelmClient.new + end + + def kubernetes + @kubernetes ||= Quality::KubernetesClient.new + end + + def perform_gitlab_environment_cleanup!(days_for_stop:, days_for_delete:) + puts "Checking for review apps not updated in the last #{days_for_stop} days..." + + checked_environments = [] + delete_threshold = threshold_time(days: days_for_delete) + stop_threshold = threshold_time(days: days_for_stop) + gitlab.deployments(project_path, per_page: 50).auto_paginate do |deployment| + next unless deployment.environment.name.start_with?('review/') + next if checked_environments.include?(deployment.environment.slug) + + puts + + checked_environments << deployment.environment.slug + deployed_at = Time.parse(deployment.created_at) + + if deployed_at < delete_threshold + print_release_state(subject: 'Review app', release_name: deployment.environment.slug, release_date: deployment.created_at, action: 'deleting') + gitlab.delete_environment(project_path, deployment.environment.id) + cleaned_up_releases << deployment.environment.slug + elsif deployed_at < stop_threshold + print_release_state(subject: 'Review app', release_name: deployment.environment.slug, release_date: deployment.created_at, action: 'stopping') + gitlab.stop_environment(project_path, deployment.environment.id) + cleaned_up_releases << deployment.environment.slug + else + print_release_state(subject: 'Review app', release_name: deployment.environment.slug, release_date: deployment.created_at, action: 'leaving') + end + end + end + + def perform_helm_releases_cleanup!(days:) + puts "Checking for Helm releases not updated in the last #{days} days..." + + threshold_day = threshold_time(days: days) + helm.releases(args: ['--deployed', '--failed', '--date', '--reverse', '--max 25']).each do |release| + next if cleaned_up_releases.include?(release.name) + + if release.last_update < threshold_day + print_release_state(subject: 'Release', release_name: release.name, release_date: release.last_update, action: 'cleaning') + helm.delete(release_name: release.name) + kubernetes.cleanup(release_name: release.name) + else + print_release_state(subject: 'Release', release_name: release.name, release_date: release.last_update, action: 'leaving') + end + end + end + + def threshold_time(days:) + Time.now - days * 24 * 3600 + end + + def print_release_state(subject:, release_name:, release_date:, action:) + puts "\n#{subject} '#{release_name}' was last deployed on #{release_date}: #{action} it." + end +end + +def timed(task) + start = Time.now + yield(self) + puts "#{task} finished in #{Time.now - start} seconds.\n" +end + +automated_cleanup = AutomatedCleanup.new + +timed('Review apps cleanup') do + automated_cleanup.perform_gitlab_environment_cleanup!(days_for_stop: 5, days_for_delete: 6) +end + +puts + +timed('Helm releases cleanup') do + automated_cleanup.perform_helm_releases_cleanup!(days: 7) +end + +exit(0) diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh new file mode 100755 index 00000000000..78293464265 --- /dev/null +++ b/scripts/review_apps/review-apps.sh @@ -0,0 +1,184 @@ +[[ "$TRACE" ]] && set -x +export TILLER_NAMESPACE="$KUBE_NAMESPACE" + +function check_kube_domain() { + if [ -z ${REVIEW_APPS_DOMAIN+x} ]; then + echo "In order to deploy or use Review Apps, REVIEW_APPS_DOMAIN variable must be set" + echo "You can do it in Auto DevOps project settings or defining a variable at group or project level" + echo "You can also manually add it in .gitlab-ci.yml" + false + else + true + fi +} + +function download_gitlab_chart() { + curl -o gitlab.tar.bz2 https://gitlab.com/charts/gitlab/-/archive/$GITLAB_HELM_CHART_REF/gitlab-$GITLAB_HELM_CHART_REF.tar.bz2 + tar -xjf gitlab.tar.bz2 + cd gitlab-$GITLAB_HELM_CHART_REF + + helm init --client-only + helm repo add gitlab https://charts.gitlab.io + helm dependency update + helm dependency build +} + +function ensure_namespace() { + kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE" +} + +function install_tiller() { + echo "Checking Tiller..." + helm init --upgrade + kubectl rollout status -n "$TILLER_NAMESPACE" -w "deployment/tiller-deploy" + if ! helm version --debug; then + echo "Failed to init Tiller." + return 1 + fi + echo "" +} + +function create_secret() { + echo "Create secret..." + + kubectl create secret generic -n "$KUBE_NAMESPACE" \ + $CI_ENVIRONMENT_SLUG-gitlab-initial-root-password \ + --from-literal=password=$REVIEW_APPS_ROOT_PASSWORD \ + --dry-run -o json | kubectl apply -f - +} + +function previousDeployFailed() { + set +e + echo "Checking for previous deployment of $CI_ENVIRONMENT_SLUG" + deployment_status=$(helm status $CI_ENVIRONMENT_SLUG >/dev/null 2>&1) + status=$? + # if `status` is `0`, deployment exists, has a status + if [ $status -eq 0 ]; then + echo "Previous deployment found, checking status" + deployment_status=$(helm status $CI_ENVIRONMENT_SLUG | grep ^STATUS | cut -d' ' -f2) + echo "Previous deployment state: $deployment_status" + if [[ "$deployment_status" == "FAILED" || "$deployment_status" == "PENDING_UPGRADE" || "$deployment_status" == "PENDING_INSTALL" ]]; then + status=0; + else + status=1; + fi + else + echo "Previous deployment NOT found." + fi + set -e + return $status +} + +function deploy() { + track="${1-stable}" + name="$CI_ENVIRONMENT_SLUG" + + if [[ "$track" != "stable" ]]; then + name="$name-$track" + fi + + replicas="1" + service_enabled="false" + postgres_enabled="$POSTGRES_ENABLED" + gitlab_migrations_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-rails-ce" + gitlab_sidekiq_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-sidekiq-ce" + gitlab_unicorn_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-unicorn-ce" + gitlab_gitaly_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitaly" + gitlab_shell_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-shell" + gitlab_workhorse_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-workhorse-ce" + + if [[ "$CI_PROJECT_NAME" == "gitlab-ee" ]]; then + gitlab_migrations_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-rails-ee" + gitlab_sidekiq_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-sidekiq-ee" + gitlab_unicorn_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-unicorn-ee" + gitlab_workhorse_image_repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-workhorse-ee" + fi + + # canary uses stable db + [[ "$track" == "canary" ]] && postgres_enabled="false" + + env_track=$( echo $track | tr -s '[:lower:]' '[:upper:]' ) + env_slug=$( echo ${CI_ENVIRONMENT_SLUG//-/_} | tr -s '[:lower:]' '[:upper:]' ) + + if [[ "$track" == "stable" ]]; then + # for stable track get number of replicas from `PRODUCTION_REPLICAS` + eval new_replicas=\$${env_slug}_REPLICAS + service_enabled="true" + else + # for all tracks get number of replicas from `CANARY_PRODUCTION_REPLICAS` + eval new_replicas=\$${env_track}_${env_slug}_REPLICAS + fi + if [[ -n "$new_replicas" ]]; then + replicas="$new_replicas" + fi + + # Cleanup and previous installs, as FAILED and PENDING_UPGRADE will cause errors with `upgrade` + if [ "$CI_ENVIRONMENT_SLUG" != "production" ] && previousDeployFailed ; then + echo "Deployment in bad state, cleaning up $CI_ENVIRONMENT_SLUG" + delete + cleanup + fi + helm repo add gitlab https://charts.gitlab.io/ + helm dep update . + +HELM_CMD=$(cat << EOF + helm upgrade --install \ + --wait \ + --timeout 600 \ + --set releaseOverride="$CI_ENVIRONMENT_SLUG" \ + --set global.hosts.hostSuffix="$HOST_SUFFIX" \ + --set global.hosts.domain="$REVIEW_APPS_DOMAIN" \ + --set certmanager.install=false \ + --set global.ingress.configureCertmanager=false \ + --set global.ingress.tls.secretName=tls-cert \ + --set global.ingress.annotations."external-dns\.alpha\.kubernetes\.io/ttl"="10" + --set gitlab.unicorn.resources.requests.cpu=200m \ + --set gitlab.sidekiq.resources.requests.cpu=100m \ + --set gitlab.gitlab-shell.resources.requests.cpu=100m \ + --set redis.resources.requests.cpu=100m \ + --set minio.resources.requests.cpu=100m \ + --set gitlab.migrations.image.repository="$gitlab_migrations_image_repository" \ + --set gitlab.migrations.image.tag="$CI_COMMIT_REF_NAME" \ + --set gitlab.sidekiq.image.repository="$gitlab_sidekiq_image_repository" \ + --set gitlab.sidekiq.image.tag="$CI_COMMIT_REF_NAME" \ + --set gitlab.unicorn.image.repository="$gitlab_unicorn_image_repository" \ + --set gitlab.unicorn.image.tag="$CI_COMMIT_REF_NAME" \ + --set gitlab.gitaly.image.repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitaly" \ + --set gitlab.gitaly.image.tag="v$GITALY_VERSION" \ + --set gitlab.gitlab-shell.image.repository="registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-shell" \ + --set gitlab.gitlab-shell.image.tag="v$GITLAB_SHELL_VERSION" \ + --set gitlab.unicorn.workhorse.image="$gitlab_workhorse_image_repository" \ + --set gitlab.unicorn.workhorse.tag="$CI_COMMIT_REF_NAME" \ + --namespace="$KUBE_NAMESPACE" \ + --version="$CI_PIPELINE_ID-$CI_JOB_ID" \ + "$name" \ + . +EOF +) + + echo "Deploying with:" + echo $HELM_CMD + + eval $HELM_CMD +} + +function delete() { + track="${1-stable}" + name="$CI_ENVIRONMENT_SLUG" + + if [[ "$track" != "stable" ]]; then + name="$name-$track" + fi + + echo "Deleting release '$name'..." + helm delete --purge "$name" || true +} + +function cleanup() { + echo "Cleaning up $CI_ENVIRONMENT_SLUG..." + kubectl -n "$KUBE_NAMESPACE" get ingress,svc,pdb,hpa,deploy,statefulset,job,pod,secret,configmap,pvc,secret,clusterrole,clusterrolebinding,role,rolebinding,sa 2>&1 \ + | grep "$CI_ENVIRONMENT_SLUG" \ + | awk '{print $1}' \ + | xargs kubectl -n "$KUBE_NAMESPACE" delete \ + || true +} diff --git a/scripts/trigger-build b/scripts/trigger-build index 798bf1e82b7..0b5fd5995dd 100755 --- a/scripts/trigger-build +++ b/scripts/trigger-build @@ -1,122 +1,144 @@ #!/usr/bin/env ruby -require 'net/http' -require 'json' -require 'cgi' +require 'gitlab' + +# +# Configure credentials to be used with gitlab gem +# +Gitlab.configure do |config| + config.endpoint = 'https://gitlab.com/api/v4' + config.private_token = ENV['GITLAB_QA_ACCESS_TOKEN'] # gitlab-qa bot access token +end module Trigger - OMNIBUS_PROJECT_PATH = 'gitlab-org/omnibus-gitlab'.freeze - CNG_PROJECT_PATH = 'gitlab-org/build/CNG'.freeze TOKEN = ENV['BUILD_TRIGGER_TOKEN'] def self.ee? ENV['CI_PROJECT_NAME'] == 'gitlab-ee' || File.exist?('CHANGELOG-EE.md') end - class Omnibus - def initialize - @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(Trigger::OMNIBUS_PROJECT_PATH)}/trigger/pipeline") - @params = env_params.merge(file_params).merge(token: Trigger::TOKEN) + class Base + def initialize(api_token) + Gitlab.private_token = api_token end - def invoke! - res = Net::HTTP.post_form(@uri, @params) - id = JSON.parse(res.body)['id'] - project = Trigger::OMNIBUS_PROJECT_PATH + def invoke!(post_comment: false) + pipeline = Gitlab.run_trigger( + downstream_project_path, + Trigger::TOKEN, + ref, + variables) - if id - puts "Triggered https://gitlab.com/#{project}/pipelines/#{id}" - puts "Waiting for downstream pipeline status" - else - raise "Trigger failed! The response from the trigger is: #{res.body}" - end + puts "Triggered #{pipeline.web_url}" + puts "Waiting for downstream pipeline status" - Trigger::Pipeline.new(project, id) + begin + Trigger::CommitComment.post!(downstream_project_path, pipeline) if post_comment + rescue Gitlab::Error::Error => error + puts "Ignoring the following error: #{error}" + end + Trigger::Pipeline.new(downstream_project_path, pipeline.id) end private - def env_params + # Must be overriden + def downstream_project_path + raise NotImplementedError + end + + # Must be overriden + def ref + raise NotImplementedError + end + + # Can be overriden + def extra_variables + {} + end + + # Can be overriden + def version_param_value(version_file) + File.read(version_file).strip + end + + def variables + base_variables.merge(extra_variables).merge(version_file_variables) + end + + def base_variables { - "ref" => ENV["OMNIBUS_BRANCH"] || "master", - "variables[GITLAB_VERSION]" => ENV["CI_COMMIT_SHA"], - "variables[ALTERNATIVE_SOURCES]" => true, - "variables[ee]" => Trigger.ee? ? 'true' : 'false', - "variables[TRIGGERED_USER]" => ENV["GITLAB_USER_NAME"], - "variables[TRIGGER_SOURCE]" => "https://gitlab.com/gitlab-org/#{ENV['CI_PROJECT_NAME']}/-/jobs/#{ENV['CI_JOB_ID']}" + 'TRIGGERED_USER' => ENV['GITLAB_USER_NAME'], + 'TRIGGER_SOURCE' => ENV['CI_JOB_URL'] } end - def file_params - Hash.new.tap do |params| - Dir.glob("*_VERSION").each do |version_file| - params["variables[#{version_file}]"] = File.read(version_file).strip - end + # Read version files from all components + def version_file_variables + Dir.glob("*_VERSION").each_with_object({}) do |version_file, params| + params[version_file] = version_param_value(version_file) end end end - class CNG - def initialize - @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(Trigger::CNG_PROJECT_PATH)}/trigger/pipeline") - @ref_name = ENV['CI_COMMIT_REF_NAME'] - @username = ENV['GITLAB_USER_NAME'] - @project_name = ENV['CI_PROJECT_NAME'] - @job_id = ENV['CI_JOB_ID'] - @params = env_params.merge(file_params).merge(token: Trigger::TOKEN) - end - - # - # Trigger a pipeline - # - def invoke! - res = Net::HTTP.post_form(@uri, @params) - id = JSON.parse(res.body)['id'] - project = Trigger::CNG_PROJECT_PATH - - if id - puts "Triggered https://gitlab.com/#{project}/pipelines/#{id}" - puts "Waiting for downstream pipeline status" - else - raise "Trigger failed! The response from the trigger is: #{res.body}" - end + class Omnibus < Base + private - Trigger::Pipeline.new(project, id) + def downstream_project_path + 'gitlab-org/omnibus-gitlab'.freeze end + def ref + ENV['OMNIBUS_BRANCH'] || 'master' + end + + def extra_variables + { + 'GITLAB_VERSION' => ENV['CI_COMMIT_SHA'], + 'ALTERNATIVE_SOURCES' => 'true', + 'ee' => Trigger.ee? ? 'true' : 'false' + } + end + end + + class CNG < Base private - def env_params - params = { - "ref" => ENV["CNG_BRANCH"] || "master", - "variables[TRIGGERED_USER]" => @username, - "variables[TRIGGER_SOURCE]" => "https://gitlab.com/gitlab-org/#{@project_name}/-/jobs/#{@job_id}" + def downstream_project_path + ENV['CNG_PROJECT_PATH'] || 'gitlab-org/build/CNG-mirror' + end + + def ref + ENV['CNG_BRANCH'] || 'master' + end + + def extra_variables + edition = Trigger.ee? ? 'EE' : 'CE' + + { + "GITLAB_#{edition}_VERSION" => ENV['CI_COMMIT_REF_NAME'], + "#{edition}_PIPELINE" => 'true' } + end - if Trigger.ee? - params["variables[GITLAB_EE_VERSION]"] = @ref_name - params["variables[EE_PIPELINE]"] = 'true' + def version_param_value(_version_file) + raw_version = super + + # if the version matches semver format, treat it as a tag and prepend `v` + if raw_version =~ Regexp.compile(/^\d+\.\d+\.\d+(-rc\d+)?(-ee)?$/) + "v#{raw_version}" else - params["variables[GITLAB_CE_VERSION]"] = @ref_name - params["variables[CE_PIPELINE]"] = 'true' + raw_version end - - params end + end - # Read version files from all components - def file_params - Dir.glob("*_VERSION").each_with_object({}) do |version_file, params| - raw_version = File.read(version_file).strip - # if the version matches semver format, treat it as a tag and prepend `v` - version = if raw_version =~ Regexp.compile(/^\d+\.\d+\.\d+(-rc\d+)?(-ee)?$/) - "v#{raw_version}" - else - raw_version - end - - params["variables[#{version_file}]"] = version - end + class CommitComment + def self.post!(downstream_project_path, downstream_pipeline) + Gitlab.create_commit_comment( + ENV['CI_PROJECT_PATH'], + ENV['CI_COMMIT_SHA'], + "The [`#{ENV['CI_JOB_NAME']}`](#{ENV['CI_JOB_URL']}) job from pipeline #{ENV['CI_PIPELINE_URL']} triggered #{downstream_pipeline.web_url} downstream.") end end @@ -124,9 +146,15 @@ module Trigger INTERVAL = 60 # seconds MAX_DURATION = 3600 * 3 # 3 hours + attr_reader :project, :id + def initialize(project, id) + @project = project + @id = id @start = Time.now.to_i - @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(project)}/pipelines/#{id}") + + # gitlab-bot's token "GitLab multi-project pipeline polling" + Gitlab.private_token = ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN'] end def wait! @@ -157,15 +185,9 @@ module Trigger end def status - req = Net::HTTP::Get.new(@uri) - req['PRIVATE-TOKEN'] = ENV['GITLAB_QA_ACCESS_TOKEN'] - - res = Net::HTTP.start(@uri.hostname, @uri.port, use_ssl: true) do |http| - http.request(req) - end - - JSON.parse(res.body)['status'].to_s.to_sym - rescue JSON::ParserError + Gitlab.pipeline(project, id).status.to_sym + rescue Gitlab::Error::Error => error + puts "Ignoring the following error: #{error}" # Ignore GitLab API hiccups. If GitLab is really down, we'll hit the job # timeout anyway. :running @@ -175,9 +197,9 @@ end case ARGV[0] when 'omnibus' - Trigger::Omnibus.new.invoke!.wait! + Trigger::Omnibus.new(ENV['GITLAB_QA_ACCESS_TOKEN']).invoke!(post_comment: true).wait! when 'cng' - Trigger::CNG.new.invoke!.wait! + Trigger::CNG.new(ENV['GITLAB_QA_ACCESS_TOKEN']).invoke!.wait! else puts "Please provide a valid option: omnibus - Triggers a pipeline that builds the omnibus-gitlab package diff --git a/scripts/trigger-build-docs b/scripts/trigger-build-docs index 9ee35684509..dfc8ee6050a 100755 --- a/scripts/trigger-build-docs +++ b/scripts/trigger-build-docs @@ -6,8 +6,8 @@ require 'gitlab' # Configure credentials to be used with gitlab gem # Gitlab.configure do |config| - config.endpoint = 'https://gitlab.com/api/v4' - config.private_token = ENV["DOCS_API_TOKEN"] # GitLab Docs bot access token with Developer access to gitlab-docs + config.endpoint = 'https://gitlab.com/api/v4' + config.private_token = ENV["DOCS_API_TOKEN"] # GitLab Docs bot access token with Developer access to gitlab-docs end # @@ -99,7 +99,7 @@ def trigger_pipeline puts "=> Follow the status of the triggered pipeline:" puts "" - puts "https://gitlab.com/gitlab-com/gitlab-docs/pipelines/#{pipeline.id}" + puts pipeline.web_url puts "" puts "=> In a few minutes, you will be able to preview your changes under the following URL:" puts "" diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index fbf116e533b..7202cee04ea 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -694,4 +694,38 @@ describe ApplicationController do expect(response).to have_gitlab_http_status(403) end end + + context 'when invalid UTF-8 parameters are received' do + controller(described_class) do + def index + params[:text].split(' ') + + render json: :ok + end + end + + before do + sign_in user + end + + context 'html' do + it 'renders 412' do + get :index, text: "hi \255" + + expect(response).to have_gitlab_http_status(412) + expect(response).to render_template :precondition_failed + end + end + + context 'js' do + it 'renders 412' do + get :index, text: "hi \255", format: :js + + json_response = JSON.parse(response.body) + + expect(response).to have_gitlab_http_status(412) + expect(json_response['error']).to eq('Invalid UTF-8') + end + end + end end diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index 1195f44f37d..ace8a954e92 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -15,14 +15,44 @@ describe Oauth::ApplicationsController do expect(response).to have_gitlab_http_status(200) end - it 'redirects back to profile page if OAuth applications are disabled' do - allow(Gitlab::CurrentSettings.current_application_settings).to receive(:user_oauth_applications?).and_return(false) + it 'shows list of applications' do + disable_user_oauth get :index + expect(response).to have_gitlab_http_status(200) + end + end + + describe 'POST #create' do + it 'creates an application' do + post :create, oauth_params + + expect(response).to have_gitlab_http_status(302) + expect(response).to redirect_to(oauth_application_path(Doorkeeper::Application.last)) + end + + it 'redirects back to profile page if OAuth applications are disabled' do + disable_user_oauth + + post :create, oauth_params + expect(response).to have_gitlab_http_status(302) expect(response).to redirect_to(profile_path) end end end + + def disable_user_oauth + allow(Gitlab::CurrentSettings.current_application_settings).to receive(:user_oauth_applications?).and_return(false) + end + + def oauth_params + { + doorkeeper_application: { + name: 'foo', + redirect_uri: 'http://example.org' + } + } + end end diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index c82c85970dc..fd11cb31a2a 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -337,6 +337,22 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end end end + + context 'when no trace is available' do + it 'has_trace is false' do + expect(response).to match_response_schema('job/job_details') + expect(json_response['has_trace']).to be false + end + end + + context 'when job has trace' do + let(:job) { create(:ci_build, :running, :trace_live, pipeline: pipeline) } + + it "has_trace is true" do + expect(response).to match_response_schema('job/job_details') + expect(json_response['has_trace']).to be true + end + end end context 'when requesting JSON job is triggered' do diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 81badaac76b..e48c9dea976 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -207,6 +207,14 @@ describe Projects::NotesController do expect(response).to have_gitlab_http_status(200) end + it 'returns discussion JSON when the return_discussion param is set' do + post :create, request_params.merge(format: :json, return_discussion: 'true') + + expect(response).to have_gitlab_http_status(200) + expect(json_response).to have_key 'discussion' + expect(json_response['discussion']['notes'][0]['note']).to eq(request_params[:note][:note]) + end + context 'when merge_request_diff_head_sha present' do before do service_params = { diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 0d49033c691..5c7415a318d 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -90,6 +90,11 @@ describe Projects::PipelinesController do context 'when performing gitaly calls', :request_store do it 'limits the Gitaly requests' do + # Isolate from test preparation (Repository#exists? is also cached in RequestStore) + RequestStore.end! + RequestStore.clear! + RequestStore.begin! + expect { get_pipelines_index_json } .to change { Gitlab::GitalyClient.get_request_count }.by(2) end diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb index f028803ca74..ee79f0ae5fd 100644 --- a/spec/factories/ci/job_artifacts.rb +++ b/spec/factories/ci/job_artifacts.rb @@ -14,6 +14,33 @@ FactoryBot.define do artifact.project ||= artifact.job.project end + trait :raw do + file_format :raw + + after(:build) do |artifact, _| + artifact.file = fixture_file_upload( + Rails.root.join('spec/fixtures/trace/sample_trace'), 'text/plain') + end + end + + trait :zip do + file_format :zip + + after(:build) do |artifact, _| + artifact.file = fixture_file_upload( + Rails.root.join('spec/fixtures/ci_build_artifacts.zip'), 'application/zip') + end + end + + trait :gzip do + file_format :gzip + + after(:build) do |artifact, _| + artifact.file = fixture_file_upload( + Rails.root.join('spec/fixtures/ci_build_artifacts_metadata.gz'), 'application/x-gzip') + end + end + trait :archive do file_type :archive file_format :zip diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 5798b81ecad..bf8411b1894 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -24,7 +24,7 @@ FactoryBot.define do factory :push_event, class: PushEvent do project factory: :project_empty_repo - author factory: :user + author(factory: :user) { project.creator } action Event::PUSHED end diff --git a/spec/factories/site_statistics.rb b/spec/factories/site_statistics.rb index dd8c795515a..2533d0eecc2 100644 --- a/spec/factories/site_statistics.rb +++ b/spec/factories/site_statistics.rb @@ -2,6 +2,5 @@ FactoryBot.define do factory :site_statistics, class: 'SiteStatistic' do id 1 repositories_count 999 - wikis_count 555 end end diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index a6ab6a5696a..ed9c0ea9ac0 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -73,24 +73,72 @@ describe "Admin Runners" do expect(page).to have_text 'No runners found' end + + it 'shows correct runner when status is selected and search term is entered' do + create(:ci_runner, description: 'runner-a-1', active: true) + create(:ci_runner, description: 'runner-a-2', active: false) + create(:ci_runner, description: 'runner-b-1', active: true) + + visit admin_runners_path + + input_filtered_search_keys('status:active') + expect(page).to have_content 'runner-a-1' + expect(page).to have_content 'runner-b-1' + expect(page).not_to have_content 'runner-a-2' + + input_filtered_search_keys('status:active runner-a') + expect(page).to have_content 'runner-a-1' + expect(page).not_to have_content 'runner-b-1' + expect(page).not_to have_content 'runner-a-2' + end end - it 'shows correct runner when status is selected and search term is entered', :js do - create(:ci_runner, description: 'runner-a-1', active: true) - create(:ci_runner, description: 'runner-a-2', active: false) - create(:ci_runner, description: 'runner-b-1', active: true) + describe 'filter by type', :js do + it 'shows correct runner when type matches' do + create :ci_runner, :project, description: 'runner-project' + create :ci_runner, :group, description: 'runner-group' - visit admin_runners_path + visit admin_runners_path + + expect(page).to have_content 'runner-project' + expect(page).to have_content 'runner-group' - input_filtered_search_keys('status:active') - expect(page).to have_content 'runner-a-1' - expect(page).to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + input_filtered_search_keys('type:project_type') + expect(page).to have_content 'runner-project' + expect(page).not_to have_content 'runner-group' + end + + it 'shows no runner when type does not match' do + create :ci_runner, :project, description: 'runner-project' + create :ci_runner, :group, description: 'runner-group' - input_filtered_search_keys('status:active runner-a') - expect(page).to have_content 'runner-a-1' - expect(page).not_to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + visit admin_runners_path + + input_filtered_search_keys('type:instance_type') + + expect(page).not_to have_content 'runner-project' + expect(page).not_to have_content 'runner-group' + + expect(page).to have_text 'No runners found' + end + + it 'shows correct runner when type is selected and search term is entered' do + create :ci_runner, :project, description: 'runner-a-1' + create :ci_runner, :instance, description: 'runner-a-2' + create :ci_runner, :project, description: 'runner-b-1' + + visit admin_runners_path + + input_filtered_search_keys('type:project_type') + expect(page).to have_content 'runner-a-1' + expect(page).to have_content 'runner-b-1' + expect(page).not_to have_content 'runner-a-2' + + input_filtered_search_keys('type:project_type runner-a') + expect(page).to have_content 'runner-a-1' + expect(page).not_to have_content 'runner-b-1' + expect(page).not_to have_content 'runner-a-2' + end end it 'sorts by last contact date', :js do diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 3c65b5898b4..0a69a26eb3e 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -9,340 +9,365 @@ describe 'Admin updates settings' do before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) - visit admin_application_settings_path end - it 'Change visibility settings' do - page.within('.as-visibility-access') do - choose "application_setting_default_project_visibility_20" - click_button 'Save changes' + context 'General page' do + before do + visit admin_application_settings_path end - expect(page).to have_content "Application settings saved successfully" - end + it 'Change visibility settings' do + page.within('.as-visibility-access') do + choose "application_setting_default_project_visibility_20" + click_button 'Save changes' + end - it 'Uncheck all restricted visibility levels' do - page.within('.as-visibility-access') do - find('#application_setting_visibility_level_0').set(false) - find('#application_setting_visibility_level_10').set(false) - find('#application_setting_visibility_level_20').set(false) - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" end - expect(page).to have_content "Application settings saved successfully" - expect(find('#application_setting_visibility_level_0')).not_to be_checked - expect(find('#application_setting_visibility_level_10')).not_to be_checked - expect(find('#application_setting_visibility_level_20')).not_to be_checked - end + it 'Uncheck all restricted visibility levels' do + page.within('.as-visibility-access') do + find('#application_setting_visibility_level_0').set(false) + find('#application_setting_visibility_level_10').set(false) + find('#application_setting_visibility_level_20').set(false) + click_button 'Save changes' + end - it 'Modify import sources' do - expect(Gitlab::CurrentSettings.import_sources).not_to be_empty + expect(page).to have_content "Application settings saved successfully" + expect(find('#application_setting_visibility_level_0')).not_to be_checked + expect(find('#application_setting_visibility_level_10')).not_to be_checked + expect(find('#application_setting_visibility_level_20')).not_to be_checked + end - page.within('.as-visibility-access') do - Gitlab::ImportSources.options.map do |name, _| - uncheck name + it 'Modify import sources' do + expect(Gitlab::CurrentSettings.import_sources).not_to be_empty + + page.within('.as-visibility-access') do + Gitlab::ImportSources.options.map do |name, _| + uncheck name + end + + click_button 'Save changes' end - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.import_sources).to be_empty + + page.within('.as-visibility-access') do + check "Repo by URL" + click_button 'Save changes' + end + + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.import_sources).to eq(['git']) end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.import_sources).to be_empty + it 'Change Visibility and Access Controls' do + page.within('.as-visibility-access') do + uncheck 'Project export enabled' + click_button 'Save changes' + end - page.within('.as-visibility-access') do - check "Repo by URL" - click_button 'Save changes' + expect(Gitlab::CurrentSettings.project_export_enabled).to be_falsey + expect(page).to have_content "Application settings saved successfully" end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.import_sources).to eq(['git']) - end + it 'Change Keys settings' do + page.within('.as-visibility-access') do + select 'Are forbidden', from: 'RSA SSH keys' + select 'Are allowed', from: 'DSA SSH keys' + select 'Must be at least 384 bits', from: 'ECDSA SSH keys' + select 'Are forbidden', from: 'ED25519 SSH keys' + click_on 'Save changes' + end - it 'Change Visibility and Access Controls' do - page.within('.as-visibility-access') do - uncheck 'Project export enabled' - click_button 'Save changes' + forbidden = ApplicationSetting::FORBIDDEN_KEY_VALUE.to_s + + expect(page).to have_content 'Application settings saved successfully' + expect(find_field('RSA SSH keys').value).to eq(forbidden) + expect(find_field('DSA SSH keys').value).to eq('0') + expect(find_field('ECDSA SSH keys').value).to eq('384') + expect(find_field('ED25519 SSH keys').value).to eq(forbidden) end - expect(Gitlab::CurrentSettings.project_export_enabled).to be_falsey - expect(page).to have_content "Application settings saved successfully" - end + it 'Change Account and Limit Settings' do + page.within('.as-account-limit') do + uncheck 'Gravatar enabled' + click_button 'Save changes' + end - it 'Change Account and Limit Settings' do - page.within('.as-account-limit') do - uncheck 'Gravatar enabled' - click_button 'Save changes' + expect(Gitlab::CurrentSettings.gravatar_enabled).to be_falsey + expect(page).to have_content "Application settings saved successfully" end - expect(Gitlab::CurrentSettings.gravatar_enabled).to be_falsey - expect(page).to have_content "Application settings saved successfully" - end + it 'Change New users set to external', :js do + user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all) - it 'Change New users set to external', :js do - user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all) + expect(user_internal_regex).to be_readonly + expect(user_internal_regex['placeholder']).to eq 'To define internal users, first enable new users set to external' - expect(user_internal_regex).to be_readonly - expect(user_internal_regex['placeholder']).to eq 'To define internal users, first enable new users set to external' + check 'application_setting_user_default_external' - check 'application_setting_user_default_external' + expect(user_internal_regex).not_to be_readonly + expect(user_internal_regex['placeholder']).to eq 'Regex pattern' + end - expect(user_internal_regex).not_to be_readonly - expect(user_internal_regex['placeholder']).to eq 'Regex pattern' - end + it 'Change Sign-in restrictions' do + page.within('.as-signin') do + fill_in 'Home page URL', with: 'https://about.gitlab.com/' + click_button 'Save changes' + end - it 'Change Sign-in restrictions' do - page.within('.as-signin') do - fill_in 'Home page URL', with: 'https://about.gitlab.com/' - click_button 'Save changes' + expect(Gitlab::CurrentSettings.home_page_url).to eq "https://about.gitlab.com/" + expect(page).to have_content "Application settings saved successfully" end - expect(Gitlab::CurrentSettings.home_page_url).to eq "https://about.gitlab.com/" - expect(page).to have_content "Application settings saved successfully" - end + it 'Terms of Service' do + # Already have the admin accept terms, so they don't need to accept in this spec. + _existing_terms = create(:term) + accept_terms(admin) - it 'Terms of Service' do - # Already have the admin accept terms, so they don't need to accept in this spec. - _existing_terms = create(:term) - accept_terms(admin) + page.within('.as-terms') do + check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.' + fill_in 'Terms of Service Agreement', with: 'Be nice!' + click_button 'Save changes' + end - page.within('.as-terms') do - check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.' - fill_in 'Terms of Service Agreement', with: 'Be nice!' - click_button 'Save changes' + expect(Gitlab::CurrentSettings.enforce_terms).to be(true) + expect(Gitlab::CurrentSettings.terms).to eq 'Be nice!' + expect(page).to have_content 'Application settings saved successfully' end - expect(Gitlab::CurrentSettings.enforce_terms).to be(true) - expect(Gitlab::CurrentSettings.terms).to eq 'Be nice!' - expect(page).to have_content 'Application settings saved successfully' - end + it 'Modify oauth providers' do + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty - it 'Modify oauth providers' do - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty + page.within('.as-signin') do + uncheck 'Google' + click_button 'Save changes' + end - page.within('.as-signin') do - uncheck 'Google' - click_button 'Save changes' - end + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') + page.within('.as-signin') do + check "Google" + click_button 'Save changes' + end - page.within('.as-signin') do - check "Google" - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2') end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2') - end + it 'Oauth providers do not raise validation errors when saving unrelated changes' do + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty - it 'Oauth providers do not raise validation errors when saving unrelated changes' do - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty + page.within('.as-signin') do + uncheck 'Google' + click_button 'Save changes' + end - page.within('.as-signin') do - uncheck 'Google' - click_button 'Save changes' - end + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') + # Remove google_oauth2 from the Omniauth strategies + allow(Devise).to receive(:omniauth_providers).and_return([]) - # Remove google_oauth2 from the Omniauth strategies - allow(Devise).to receive(:omniauth_providers).and_return([]) + # Save an unrelated setting + page.within('.as-terms') do + click_button 'Save changes' + end - # Save an unrelated setting - page.within('.as-ci-cd') do - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2') - end + it 'Configure web terminal' do + page.within('.as-terminal') do + fill_in 'Max session time', with: 15 + click_button 'Save changes' + end - it 'Change Help page' do - page.within('.as-help-page') do - fill_in 'Help page text', with: 'Example text' - check 'Hide marketing-related entries from help' - fill_in 'Support page URL', with: 'http://example.com/help' - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.terminal_max_session_time).to eq(15) end - - expect(Gitlab::CurrentSettings.help_page_text).to eq "Example text" - expect(Gitlab::CurrentSettings.help_page_hide_commercial_content).to be_truthy - expect(Gitlab::CurrentSettings.help_page_support_url).to eq "http://example.com/help" - expect(page).to have_content "Application settings saved successfully" end - it 'Change Pages settings' do - page.within('.as-pages') do - fill_in 'Maximum size of pages (MB)', with: 15 - check 'Require users to prove ownership of custom domains' - click_button 'Save changes' + context 'Integrations page' do + before do + visit integrations_admin_application_settings_path end - expect(Gitlab::CurrentSettings.max_pages_size).to eq 15 - expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy - expect(page).to have_content "Application settings saved successfully" - end + it 'Enable hiding third party offers' do + page.within('.as-third-party-offers') do + check 'Do not display offers from third parties within GitLab' + click_button 'Save changes' + end - it 'Change CI/CD settings' do - page.within('.as-ci-cd') do - check 'Default to Auto DevOps pipeline for all projects' - fill_in 'Auto devops domain', with: 'domain.com' - click_button 'Save changes' + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.hide_third_party_offers).to be true end - expect(Gitlab::CurrentSettings.auto_devops_enabled?).to be true - expect(Gitlab::CurrentSettings.auto_devops_domain).to eq('domain.com') - expect(page).to have_content "Application settings saved successfully" - end + it 'Change Slack Notifications Service template settings' do + first(:link, 'Service Templates').click + click_link 'Slack notifications' + fill_in 'Webhook', with: 'http://localhost' + fill_in 'Username', with: 'test_user' + fill_in 'service_push_channel', with: '#test_channel' + page.check('Notify only broken pipelines') + page.check('Notify only default branch') - it 'Change Influx settings' do - page.within('.as-influx') do - check 'Enable InfluxDB Metrics' - click_button 'Save changes' - end + check_all_events + click_on 'Save' - expect(Gitlab::CurrentSettings.metrics_enabled?).to be true - expect(page).to have_content "Application settings saved successfully" - end + expect(page).to have_content 'Application settings saved successfully' - it 'Change Prometheus settings' do - page.within('.as-prometheus') do - check 'Enable Prometheus Metrics' - click_button 'Save changes' - end + click_link 'Slack notifications' - expect(Gitlab::CurrentSettings.prometheus_metrics_enabled?).to be true - expect(page).to have_content "Application settings saved successfully" + page.all('input[type=checkbox]').each do |checkbox| + expect(checkbox).to be_checked + end + expect(find_field('Webhook').value).to eq 'http://localhost' + expect(find_field('Username').value).to eq 'test_user' + expect(find('#service_push_channel').value).to eq '#test_channel' + end end - it 'Change Performance bar settings' do - group = create(:group) + context 'CI/CD page' do + it 'Change CI/CD settings' do + visit ci_cd_admin_application_settings_path + + page.within('.as-ci-cd') do + check 'Default to Auto DevOps pipeline for all projects' + fill_in 'Auto devops domain', with: 'domain.com' + click_button 'Save changes' + end - page.within('.as-performance-bar') do - check 'Enable the Performance Bar' - fill_in 'Allowed group', with: group.path - click_on 'Save changes' + expect(Gitlab::CurrentSettings.auto_devops_enabled?).to be true + expect(Gitlab::CurrentSettings.auto_devops_domain).to eq('domain.com') + expect(page).to have_content "Application settings saved successfully" end + end - expect(page).to have_content "Application settings saved successfully" - expect(find_field('Enable the Performance Bar')).to be_checked - expect(find_field('Allowed group').value).to eq group.path + context 'Reporting page' do + it 'Change Spam settings' do + visit reporting_admin_application_settings_path - page.within('.as-performance-bar') do - uncheck 'Enable the Performance Bar' - click_on 'Save changes' - end + page.within('.as-spam') do + check 'Enable reCAPTCHA' + fill_in 'reCAPTCHA Site Key', with: 'key' + fill_in 'reCAPTCHA Private Key', with: 'key' + fill_in 'IPs per user', with: 15 + click_button 'Save changes' + end - expect(page).to have_content 'Application settings saved successfully' - expect(find_field('Enable the Performance Bar')).not_to be_checked - expect(find_field('Allowed group').value).to be_nil + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.recaptcha_enabled).to be true + expect(Gitlab::CurrentSettings.unique_ips_limit_per_user).to eq(15) + end end - it 'Change Background jobs settings' do - page.within('.as-background') do - fill_in 'Throttling Factor', with: 1 - click_button 'Save changes' + context 'Metrics and profiling page' do + before do + visit metrics_and_profiling_admin_application_settings_path end - expect(Gitlab::CurrentSettings.sidekiq_throttling_factor).to eq(1) - expect(page).to have_content "Application settings saved successfully" - end + it 'Change Influx settings' do + page.within('.as-influx') do + check 'Enable InfluxDB Metrics' + click_button 'Save changes' + end - it 'Change Spam settings' do - page.within('.as-spam') do - check 'Enable reCAPTCHA' - fill_in 'reCAPTCHA Site Key', with: 'key' - fill_in 'reCAPTCHA Private Key', with: 'key' - fill_in 'IPs per user', with: 15 - click_button 'Save changes' + expect(Gitlab::CurrentSettings.metrics_enabled?).to be true + expect(page).to have_content "Application settings saved successfully" end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.recaptcha_enabled).to be true - expect(Gitlab::CurrentSettings.unique_ips_limit_per_user).to eq(15) - end + it 'Change Prometheus settings' do + page.within('.as-prometheus') do + check 'Enable Prometheus Metrics' + click_button 'Save changes' + end - it 'Configure web terminal' do - page.within('.as-terminal') do - fill_in 'Max session time', with: 15 - click_button 'Save changes' + expect(Gitlab::CurrentSettings.prometheus_metrics_enabled?).to be true + expect(page).to have_content "Application settings saved successfully" end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.terminal_max_session_time).to eq(15) - end + it 'Change Performance bar settings' do + group = create(:group) - it 'Enable outbound requests' do - page.within('.as-outbound') do - check 'Allow requests to the local network from hooks and services' - click_button 'Save changes' - end + page.within('.as-performance-bar') do + check 'Enable the Performance Bar' + fill_in 'Allowed group', with: group.path + click_on 'Save changes' + end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true - end + expect(page).to have_content "Application settings saved successfully" + expect(find_field('Enable the Performance Bar')).to be_checked + expect(find_field('Allowed group').value).to eq group.path - it 'Enable hiding third party offers' do - page.within('.as-third-party-offers') do - check 'Do not display offers from third parties within GitLab' - click_button 'Save changes' + page.within('.as-performance-bar') do + uncheck 'Enable the Performance Bar' + click_on 'Save changes' + end + + expect(page).to have_content 'Application settings saved successfully' + expect(find_field('Enable the Performance Bar')).not_to be_checked + expect(find_field('Allowed group').value).to be_nil end - expect(page).to have_content "Application settings saved successfully" - expect(Gitlab::CurrentSettings.hide_third_party_offers).to be true - end + it 'loads usage ping payload on click', :js do + expect(page).to have_button 'Preview payload' - it 'Change Slack Notifications Service template settings' do - first(:link, 'Service Templates').click - click_link 'Slack notifications' - fill_in 'Webhook', with: 'http://localhost' - fill_in 'Username', with: 'test_user' - fill_in 'service_push_channel', with: '#test_channel' - page.check('Notify only broken pipelines') - page.check('Notify only default branch') + find('.js-usage-ping-payload-trigger').click - check_all_events - click_on 'Save' + expect(page).to have_selector '.js-usage-ping-payload' + expect(page).to have_button 'Hide payload' + end + end - expect(page).to have_content 'Application settings saved successfully' + context 'Network page' do + it 'Enable outbound requests' do + visit network_admin_application_settings_path - click_link 'Slack notifications' + page.within('.as-outbound') do + check 'Allow requests to the local network from hooks and services' + click_button 'Save changes' + end - page.all('input[type=checkbox]').each do |checkbox| - expect(checkbox).to be_checked + expect(page).to have_content "Application settings saved successfully" + expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true end - expect(find_field('Webhook').value).to eq 'http://localhost' - expect(find_field('Username').value).to eq 'test_user' - expect(find('#service_push_channel').value).to eq '#test_channel' end - it 'Change Keys settings' do - page.within('.as-visibility-access') do - select 'Are forbidden', from: 'RSA SSH keys' - select 'Are allowed', from: 'DSA SSH keys' - select 'Must be at least 384 bits', from: 'ECDSA SSH keys' - select 'Are forbidden', from: 'ED25519 SSH keys' - click_on 'Save changes' + context 'Preferences page' do + before do + visit preferences_admin_application_settings_path end - forbidden = ApplicationSetting::FORBIDDEN_KEY_VALUE.to_s - - expect(page).to have_content 'Application settings saved successfully' - expect(find_field('RSA SSH keys').value).to eq(forbidden) - expect(find_field('DSA SSH keys').value).to eq('0') - expect(find_field('ECDSA SSH keys').value).to eq('384') - expect(find_field('ED25519 SSH keys').value).to eq(forbidden) - end + it 'Change Help page' do + page.within('.as-help-page') do + fill_in 'Help page text', with: 'Example text' + check 'Hide marketing-related entries from help' + fill_in 'Support page URL', with: 'http://example.com/help' + click_button 'Save changes' + end - it 'loads usage ping payload on click', :js do - expect(page).to have_button 'Preview payload' + expect(Gitlab::CurrentSettings.help_page_text).to eq "Example text" + expect(Gitlab::CurrentSettings.help_page_hide_commercial_content).to be_truthy + expect(Gitlab::CurrentSettings.help_page_support_url).to eq "http://example.com/help" + expect(page).to have_content "Application settings saved successfully" + end - find('.js-usage-ping-payload-trigger').click + it 'Change Pages settings' do + page.within('.as-pages') do + fill_in 'Maximum size of pages (MB)', with: 15 + check 'Require users to prove ownership of custom domains' + click_button 'Save changes' + end - expect(page).to have_selector '.js-usage-ping-payload' - expect(page).to have_button 'Hide payload' + expect(Gitlab::CurrentSettings.max_pages_size).to eq 15 + expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy + expect(page).to have_content "Application settings saved successfully" + end end def check_all_events diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index e658f1b6738..d04bb9acd9e 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -33,7 +33,7 @@ describe 'Admin uses repository checks' do end it 'to clear all repository checks', :js do - visit admin_application_settings_path + visit repository_admin_application_settings_path expect(RepositoryCheck::ClearWorker).to receive(:perform_async) diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 4daacc61d85..975b7944741 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -103,6 +103,14 @@ describe 'Dashboard Projects' do expect(page).not_to have_content(project.name) expect(page).to have_content(project3.name) end + + it 'sorts projects by most stars when sorting by most stars' do + project_with_most_stars = create(:project, namespace: user.namespace, star_count: 10) + + visit dashboard_projects_path(sort: :stars_desc) + + expect(first('.project-row')).to have_content(project_with_most_stars.title) + end end context 'when on Starred projects tab' do diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index d4949de3f27..35d57b3896d 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -265,7 +265,7 @@ describe 'Filter issues', :js do context 'issue label clicked' do it 'filters and displays in search bar' do - find('.issues-list .issue .issue-main-info .issuable-info a .badge', text: multiple_words_label.title).click + find('.issues-list .issue .issuable-main-info .issuable-info a .badge', text: multiple_words_label.title).click expect_issues_list_count(1) expect_tokens([label_token("\"#{multiple_words_label.title}\"")]) diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb index 2d268ecab58..8a16c011067 100644 --- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb +++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb @@ -139,44 +139,64 @@ describe 'Merge request > User resolves diff notes and discussions', :js do expect(find('.diffs .diff-file .notes_holder')).to be_visible end end - end - it 'allows user to resolve from reply form without a comment' do - page.within '.diff-content' do - click_button 'Reply...' + describe 'reply form' do + before do + click_button 'Toggle discussion' - click_button 'Resolve discussion' - end + page.within '.diff-content' do + click_button 'Reply...' + end + end - page.within '.line-resolve-all-container' do - expect(page).to have_content('1/1 discussion resolved') - expect(page).to have_selector('.line-resolve-btn.is-active') - end - end + it 'allows user to comment' do + page.within '.diff-content' do + find('.js-note-text').set 'testing' - it 'allows user to unresolve from reply form without a comment' do - page.within '.diff-content' do - click_button 'Resolve discussion' - sleep 1 + click_button 'Comment' - click_button 'Reply...' + wait_for_requests + end - click_button 'Unresolve discussion' - end + page.within '.line-resolve-all-container' do + expect(page).to have_content('1/1 discussion resolved') + end + end - page.within '.line-resolve-all-container' do - expect(page).to have_content('0/1 discussion resolved') - expect(page).not_to have_selector('.line-resolve-btn.is-active') + it 'allows user to unresolve from reply form without a comment' do + page.within '.diff-content' do + click_button 'Unresolve discussion' + + wait_for_requests + end + + page.within '.line-resolve-all-container' do + expect(page).to have_content('0/1 discussion resolved') + expect(page).not_to have_selector('.line-resolve-btn.is-active') + end + end + + it 'allows user to comment & unresolve discussion' do + page.within '.diff-content' do + find('.js-note-text').set 'testing' + + click_button 'Comment & unresolve discussion' + + wait_for_requests + end + + page.within '.line-resolve-all-container' do + expect(page).to have_content('0/1 discussion resolved') + end + end end end - it 'allows user to comment & resolve discussion' do + it 'allows user to resolve from reply form without a comment' do page.within '.diff-content' do click_button 'Reply...' - find('.js-note-text').set 'testing' - - click_button 'Comment & resolve discussion' + click_button 'Resolve discussion' end page.within '.line-resolve-all-container' do @@ -185,19 +205,18 @@ describe 'Merge request > User resolves diff notes and discussions', :js do end end - it 'allows user to comment & unresolve discussion' do + it 'allows user to comment & resolve discussion' do page.within '.diff-content' do - click_button 'Resolve discussion' - click_button 'Reply...' find('.js-note-text').set 'testing' - click_button 'Comment & unresolve discussion' + click_button 'Comment & resolve discussion' end page.within '.line-resolve-all-container' do - expect(page).to have_content('0/1 discussion resolved') + expect(page).to have_content('1/1 discussion resolved') + expect(page).to have_selector('.line-resolve-btn.is-active') end end diff --git a/spec/features/projects/activity/user_sees_activity_spec.rb b/spec/features/projects/activity/user_sees_activity_spec.rb index e0248911b5f..ebaa137772d 100644 --- a/spec/features/projects/activity/user_sees_activity_spec.rb +++ b/spec/features/projects/activity/user_sees_activity_spec.rb @@ -3,8 +3,10 @@ require 'spec_helper' describe 'Projects > Activity > User sees activity' do let(:project) { create(:project, :repository, :public) } let(:user) { project.creator } + let(:issue) { create(:issue, project: project) } before do + create(:event, :created, project: project, target: issue, author: user) event = create(:push_event, project: project, author: user) create(:push_event_payload, event: event, @@ -12,10 +14,18 @@ describe 'Projects > Activity > User sees activity' do commit_to: '6d394385cf567f80a8fd85055db1ab4c5295806f', ref: 'fix', commit_count: 1) - visit activity_project_path(project) end it 'shows the last push in the activity page', :js do + visit activity_project_path(project) + expect(page).to have_content "#{user.name} pushed new branch fix" end + + it 'allows to filter event with the "event_filter=issue" URL param', :js do + visit activity_project_path(project, event_filter: 'issue') + + expect(page).not_to have_content "#{user.name} pushed new branch fix" + expect(page).to have_content "#{user.name} opened issue #{issue.to_reference}" + end end diff --git a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb index 67ed2f18d76..554f0b49052 100644 --- a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb +++ b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb @@ -20,23 +20,13 @@ describe "User downloads artifacts" do end context "via job id" do - set(:url) { download_project_job_artifacts_path(project, job) } + let(:url) { download_project_job_artifacts_path(project, job) } it_behaves_like "downloading" end context "via branch name and job name" do - set(:url) { latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name) } - - it_behaves_like "downloading" - end - - context "via clicking the `Download` button" do - set(:url) { project_job_path(project, job) } - - before do - click_link("Download") - end + let(:url) { latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name) } it_behaves_like "downloading" end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 83293c0ca7d..d0bf4975b81 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -5,7 +5,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do let(:user) { create(:user) } let(:user_access_level) { :developer } let(:project) { create(:project, :repository) } - let(:pipeline) { create(:ci_pipeline, project: project) } + let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) } let(:job) { create(:ci_build, :trace_live, pipeline: pipeline) } let(:job2) { create(:ci_build) } @@ -20,7 +20,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end describe "GET /:project/jobs" do - let!(:job) { create(:ci_build, pipeline: pipeline) } + let!(:job) { create(:ci_build, pipeline: pipeline) } context "Pending scope" do before do @@ -115,22 +115,28 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do context "Job from project" do let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline) } - before do + it 'shows status name', :js do visit project_job_path(project, job) - end - it 'shows status name', :js do + wait_for_requests + expect(page).to have_css('.ci-status.ci-success', text: 'passed') end - it 'shows commit`s data' do - expect(page.status_code).to eq(200) + it 'shows commit`s data', :js do + requests = inspect_requests() do + visit project_job_path(project, job) + end + + wait_for_requests + expect(requests.first.status_code).to eq(200) expect(page).to have_content pipeline.sha[0..7] - expect(page).to have_content pipeline.git_commit_message - expect(page).to have_content pipeline.git_author_name + expect(page).to have_content pipeline.commit.title end it 'shows active job' do + visit project_job_path(project, job) + expect(page).to have_selector('.build-job.active') end end @@ -199,7 +205,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do it { expect(page.status_code).to eq(404) } end - context "Download artifacts" do + context "Download artifacts", :js do before do job.update(legacy_artifacts_file: artifacts_file) visit project_job_path(project, job) @@ -208,9 +214,22 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do it 'has button to download artifacts' do expect(page).to have_content 'Download' end + + it 'downloads the zip file when user clicks the download button' do + requests = inspect_requests() do + click_link 'Download' + end + + artifact_request = requests.find { |req| req.url.match(%r{artifacts/download}) } + + expect(artifact_request.response_headers["Content-Disposition"]).to eq(%Q{attachment; filename="#{job.artifacts_file.filename}"}) + expect(artifact_request.response_headers['Content-Transfer-Encoding']).to eq("binary") + expect(artifact_request.response_headers['Content-Type']).to eq("image/gif") + expect(artifact_request.body).to eq(job.artifacts_file.file.read.b) + end end - context 'Artifacts expire date' do + context 'Artifacts expire date', :js do before do job.update(legacy_artifacts_file: artifacts_file, artifacts_expire_at: expire_at) @@ -231,12 +250,12 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do context 'when user has ability to update job' do it 'keeps artifacts when keep button is clicked' do - expect(page).to have_content 'The artifacts will be removed' + expect(page).to have_content 'The artifacts will be removed in' click_link 'Keep' expect(page).to have_no_link 'Keep' - expect(page).to have_no_content 'The artifacts will be removed' + expect(page).to have_no_content 'The artifacts will be removed in' end end @@ -314,6 +333,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do shared_examples 'expected variables behavior' do it 'shows variable key and value after click', :js do + expect(page).to have_content('Token') expect(page).to have_css('.js-reveal-variables') expect(page).not_to have_css('.js-build-variable') expect(page).not_to have_css('.js-build-value') @@ -542,20 +562,26 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - describe "GET /:project/jobs/:id/download" do + describe "GET /:project/jobs/:id/download", :js do before do job.update(legacy_artifacts_file: artifacts_file) visit project_job_path(project, job) + click_link 'Download' end context "Build from other project" do before do job2.update(legacy_artifacts_file: artifacts_file) - visit download_project_job_artifacts_path(project, job2) end - it { expect(page.status_code).to eq(404) } + it do + requests = inspect_requests() do + visit download_project_job_artifacts_path(project, job2) + end + + expect(requests.first.status_code).to eq(404) + end end end diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb index 57b4b1287fa..9357215ae6f 100644 --- a/spec/features/projects/settings/user_tags_project_spec.rb +++ b/spec/features/projects/settings/user_tags_project_spec.rb @@ -9,15 +9,13 @@ describe 'Projects > Settings > User tags a project' do visit edit_project_path(project) end - context 'when a project is archived' do - it 'unarchives a project' do - fill_in 'Tags', with: 'tag1, tag2' + it 'sets project tags' do + fill_in 'Tags', with: 'tag1, tag2' - page.within '.general-settings' do - click_button 'Save changes' - end - - expect(find_field('Tags').value).to eq 'tag1, tag2' + page.within '.general-settings' do + click_button 'Save changes' end + + expect(find_field('Tags').value).to eq 'tag1, tag2' end end diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb index 9e58280b868..2cb2a23b7be 100644 --- a/spec/features/projects/tree/create_directory_spec.rb +++ b/spec/features/projects/tree/create_directory_spec.rb @@ -43,7 +43,7 @@ describe 'Multi-file editor new directory', :js do find('.js-ide-commit-mode').click find('.multi-file-commit-list-item').hover - first('.multi-file-discard-btn .btn').click + click_button 'Stage' fill_in('commit-message', with: 'commit message ide') diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb index a04d3566a7e..9f5524da8e9 100644 --- a/spec/features/projects/tree/create_file_spec.rb +++ b/spec/features/projects/tree/create_file_spec.rb @@ -35,7 +35,7 @@ describe 'Multi-file editor new file', :js do find('.js-ide-commit-mode').click find('.multi-file-commit-list-item').hover - first('.multi-file-discard-btn .btn').click + click_button 'Stage' fill_in('commit-message', with: 'commit message ide') diff --git a/spec/features/snippets/user_sees_breadcrumb_links.rb b/spec/features/snippets/user_sees_breadcrumb_links.rb new file mode 100644 index 00000000000..696f2b93390 --- /dev/null +++ b/spec/features/snippets/user_sees_breadcrumb_links.rb @@ -0,0 +1,17 @@ +require 'rails_helper' + +describe 'New user snippet breadcrumbs' do + let(:user) { create(:user) } + + before do + sign_in(user) + visit new_snippet_path + end + + it 'display a link to user snippets and new user snippet pages' do + page.within '.breadcrumbs' do + expect(find_link('Snippets')[:href]).to end_with(dashboard_snippets_path) + expect(find_link('New')[:href]).to end_with(new_snippet_path) + end + end +end diff --git a/spec/finders/admin/runners_finder_spec.rb b/spec/finders/admin/runners_finder_spec.rb index 1e9793a5e0a..0b2325cc7ca 100644 --- a/spec/finders/admin/runners_finder_spec.rb +++ b/spec/finders/admin/runners_finder_spec.rb @@ -29,6 +29,14 @@ describe Admin::RunnersFinder do end end + context 'filter by runner type' do + it 'calls the corresponding scope on Ci::Runner' do + expect(Ci::Runner).to receive(:project_type).and_call_original + + described_class.new(params: { type_type: 'project_type' }).execute + end + end + context 'sort' do context 'without sort param' do it 'sorts by created_at' do diff --git a/spec/finders/group_labels_finder_spec.rb b/spec/finders/group_labels_finder_spec.rb new file mode 100644 index 00000000000..ef68fc105e4 --- /dev/null +++ b/spec/finders/group_labels_finder_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe GroupLabelsFinder, '#execute' do + let!(:group) { create(:group) } + let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) } + let!(:label2) { create(:group_label, title: 'Bar', description: 'Fusce consequat', group: group) } + + it 'returns all group labels sorted by name if no params' do + result = described_class.new(group).execute + + expect(result.to_a).to match_array([label2, label1]) + end + + it 'returns all group labels sorted by name desc' do + result = described_class.new(group, sort: 'name_desc').execute + + expect(result.to_a).to match_array([label2, label1]) + end + + it 'returns group labels that march search' do + result = described_class.new(group, search: 'Foo').execute + + expect(result.to_a).to match_array([label1]) + end + + it 'returns second page of labels' do + result = described_class.new(group, page: '2').execute + + expect(result.to_a).to match_array([]) + end +end diff --git a/spec/fixtures/api/schemas/job/job_details.json b/spec/fixtures/api/schemas/job/job_details.json index cd67d3e4160..07e674216fa 100644 --- a/spec/fixtures/api/schemas/job/job_details.json +++ b/spec/fixtures/api/schemas/job/job_details.json @@ -3,12 +3,19 @@ { "$ref": "job.json" } ], "description": "An extension of job.json with more detailed information", + "required": [ + "artifact", + "runner", + "runners", + "has_trace" + ], "properties": { "artifact": { "$ref": "artifact.json" }, "terminal_path": { "type": "string" }, "trigger": { "$ref": "trigger.json" }, "deployment_status": { "$ref": "deployment_status.json" }, "runner": { "$ref": "runner.json" }, - "runners": { "type": "runners.json" } + "runners": { "$ref": "runners.json" }, + "has_trace": { "type": "boolean" } } } diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index 4b6c7c33e5b..9c0e55739d6 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -37,7 +37,7 @@ describe CommitsHelper do .not_to include('onmouseover="alert(1)"') end - it 'escapes the commiter name' do + it 'escapes the committer name' do user = build_stubbed(:user, name: 'Foo <script>alert("XSS")</script>') commit = double(committer: user, committer_name: '', committer_email: '') diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml index 5525c9f5bd0..9b2c84ce9f5 100644 --- a/spec/javascripts/.eslintrc.yml +++ b/spec/javascripts/.eslintrc.yml @@ -35,3 +35,9 @@ rules: - error - ignore: - 'fixtures/blob' + # Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine + jasmine/new-line-before-expect: off + jasmine/new-line-between-declarations: off + jasmine/no-promise-without-done-fail: off + jasmine/prefer-jasmine-matcher: off + jasmine/prefer-toHaveBeenCalledWith: off diff --git a/spec/javascripts/close_reopen_report_toggle_spec.js b/spec/javascripts/close_reopen_report_toggle_spec.js index 925e959c85a..412abe2cbf8 100644 --- a/spec/javascripts/close_reopen_report_toggle_spec.js +++ b/spec/javascripts/close_reopen_report_toggle_spec.js @@ -1,3 +1,5 @@ +/* eslint-disable jasmine/no-unsafe-spy */ + import CloseReopenReportToggle from '~/close_reopen_report_toggle'; import DropLab from '~/droplab/drop_lab'; diff --git a/spec/javascripts/diffs/components/app_spec.js b/spec/javascripts/diffs/components/app_spec.js index 7be44a26ded..cf7d8df5405 100644 --- a/spec/javascripts/diffs/components/app_spec.js +++ b/spec/javascripts/diffs/components/app_spec.js @@ -3,6 +3,7 @@ import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper import { TEST_HOST } from 'spec/test_constants'; import App from '~/diffs/components/app.vue'; import createDiffsStore from '../create_diffs_store'; +import getDiffWithCommit from '../mock_data/diff_with_commit'; describe('diffs/components/app', () => { const oldMrTabs = window.mrTabs; @@ -36,12 +37,17 @@ describe('diffs/components/app', () => { vm.$destroy(); }); + it('does not show commit info', () => { + expect(vm.$el).not.toContainElement('.blob-commit-info'); + }); + it('shows comments message, with commit', done => { - vm.$store.state.diffs.commit = {}; + vm.$store.state.diffs.commit = getDiffWithCommit().commit; vm.$nextTick() .then(() => { expect(vm.$el).toContainText('Only comments from the following commit are shown below'); + expect(vm.$el).toContainElement('.blob-commit-info'); }) .then(done) .catch(done.fail); diff --git a/spec/javascripts/diffs/components/commit_item_spec.js b/spec/javascripts/diffs/components/commit_item_spec.js new file mode 100644 index 00000000000..627fb8c490a --- /dev/null +++ b/spec/javascripts/diffs/components/commit_item_spec.js @@ -0,0 +1,128 @@ +import Vue from 'vue'; +import { TEST_HOST } from 'spec/test_constants'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import { trimText } from 'spec/helpers/vue_component_helper'; +import { getTimeago } from '~/lib/utils/datetime_utility'; +import CommitItem from '~/diffs/components/commit_item.vue'; +import getDiffWithCommit from '../mock_data/diff_with_commit'; + +const TEST_AUTHOR_NAME = 'test'; +const TEST_AUTHOR_EMAIL = 'test+test@gitlab.com'; +const TEST_AUTHOR_GRAVATAR = `${TEST_HOST}/avatar/test?s=36`; + +const getTitleElement = vm => vm.$el.querySelector('.commit-row-message.item-title'); +const getDescElement = vm => vm.$el.querySelector('pre.commit-row-description'); +const getDescExpandElement = vm => vm.$el.querySelector('.commit-content .text-expander.js-toggle-button'); +const getShaElement = vm => vm.$el.querySelector('.commit-sha-group'); +const getAvatarElement = vm => vm.$el.querySelector('.user-avatar-link'); +const getCommitterElement = vm => vm.$el.querySelector('.commiter'); + +describe('diffs/components/commit_widget', () => { + const Component = Vue.extend(CommitItem); + const timeago = getTimeago(); + const { commit } = getDiffWithCommit(); + + let vm; + + beforeEach(() => { + vm = mountComponent(Component, { + commit: getDiffWithCommit().commit, + }); + }); + + it('renders commit title', () => { + const titleElement = getTitleElement(vm); + + expect(titleElement).toHaveAttr('href', commit.commitUrl); + expect(titleElement).toHaveText(commit.titleHtml); + }); + + it('renders commit description', () => { + const descElement = getDescElement(vm); + const descExpandElement = getDescExpandElement(vm); + + const expected = commit.descriptionHtml.replace(/
/g, ''); + + expect(trimText(descElement.innerHTML)).toEqual(trimText(expected)); + expect(descExpandElement).not.toBeNull(); + }); + + it('renders commit sha', () => { + const shaElement = getShaElement(vm); + const labelElement = shaElement.querySelector('.label'); + const buttonElement = shaElement.querySelector('button'); + + expect(labelElement.textContent).toEqual(commit.shortId); + expect(buttonElement).toHaveData('clipboard-text', commit.id); + }); + + it('renders author avatar', () => { + const avatarElement = getAvatarElement(vm); + const imgElement = avatarElement.querySelector('img'); + + expect(avatarElement).toHaveAttr('href', commit.author.webUrl); + expect(imgElement).toHaveClass('s36'); + expect(imgElement).toHaveAttr('alt', commit.author.name); + expect(imgElement).toHaveAttr('src', commit.author.avatarUrl); + }); + + it('renders committer text', () => { + const committerElement = getCommitterElement(vm); + const nameElement = committerElement.querySelector('a'); + + const expectTimeText = timeago.format(commit.authoredDate); + const expectedText = `${commit.author.name} authored ${expectTimeText}`; + + expect(trimText(committerElement.textContent)).toEqual(expectedText); + expect(nameElement).toHaveAttr('href', commit.author.webUrl); + expect(nameElement).toHaveText(commit.author.name); + }); + + describe('without commit description', () => { + beforeEach(done => { + vm.commit.descriptionHtml = ''; + + vm.$nextTick() + .then(done) + .catch(done.fail); + }); + + it('hides description', () => { + const descElement = getDescElement(vm); + const descExpandElement = getDescExpandElement(vm); + + expect(descElement).toBeNull(); + expect(descExpandElement).toBeNull(); + }); + }); + + describe('with no matching user', () => { + beforeEach(done => { + vm.commit.author = null; + vm.commit.authorEmail = TEST_AUTHOR_EMAIL; + vm.commit.authorName = TEST_AUTHOR_NAME; + vm.commit.authorGravatarUrl = TEST_AUTHOR_GRAVATAR; + + vm.$nextTick() + .then(done) + .catch(done.fail); + }); + + it('renders author avatar', () => { + const avatarElement = getAvatarElement(vm); + const imgElement = avatarElement.querySelector('img'); + + expect(avatarElement).toHaveAttr('href', `mailto:${TEST_AUTHOR_EMAIL}`); + expect(imgElement).toHaveAttr('alt', TEST_AUTHOR_NAME); + expect(imgElement).toHaveAttr('src', TEST_AUTHOR_GRAVATAR); + }); + + it('renders committer text', () => { + const committerElement = getCommitterElement(vm); + const nameElement = committerElement.querySelector('a'); + + expect(nameElement).toHaveAttr('href', `mailto:${TEST_AUTHOR_EMAIL}`); + expect(nameElement).toHaveText(TEST_AUTHOR_NAME); + }); + }); +}); diff --git a/spec/javascripts/diffs/components/commit_widget_spec.js b/spec/javascripts/diffs/components/commit_widget_spec.js new file mode 100644 index 00000000000..951eb57255d --- /dev/null +++ b/spec/javascripts/diffs/components/commit_widget_spec.js @@ -0,0 +1,24 @@ +import Vue from 'vue'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import CommitWidget from '~/diffs/components/commit_widget.vue'; +import getDiffWithCommit from '../mock_data/diff_with_commit'; + +describe('diffs/components/commit_widget', () => { + const Component = Vue.extend(CommitWidget); + const { commit } = getDiffWithCommit(); + + let vm; + + beforeEach(() => { + vm = mountComponent(Component, { + commit: getDiffWithCommit().commit, + }); + }); + + it('renders commit item', () => { + const commitElement = vm.$el.querySelector('li.commit'); + + expect(commitElement).not.toBeNull(); + expect(commitElement).toContainText(commit.shortId); + }); +}); diff --git a/spec/javascripts/diffs/components/diff_line_note_form_spec.js b/spec/javascripts/diffs/components/diff_line_note_form_spec.js index 6fe5fdaf7f9..f31fc1f0e2b 100644 --- a/spec/javascripts/diffs/components/diff_line_note_form_spec.js +++ b/spec/javascripts/diffs/components/diff_line_note_form_spec.js @@ -69,22 +69,21 @@ describe('DiffLineNoteForm', () => { describe('saveNoteForm', () => { it('should call saveNote action with proper params', done => { - let isPromiseCalled = false; - const formDataSpy = spyOnDependency(DiffLineNoteForm, 'getNoteFormData').and.returnValue({ - postData: 1, - }); - const saveNoteSpy = spyOn(component, 'saveNote').and.returnValue( - new Promise(() => { - isPromiseCalled = true; - done(); - }), + const saveDiffDiscussionSpy = spyOn(component, 'saveDiffDiscussion').and.returnValue( + Promise.resolve(), ); - - component.handleSaveNote('note body'); - - expect(formDataSpy).toHaveBeenCalled(); - expect(saveNoteSpy).toHaveBeenCalled(); - expect(isPromiseCalled).toEqual(true); + spyOnProperty(component, 'formData').and.returnValue('formData'); + + component + .handleSaveNote('note body') + .then(() => { + expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({ + note: 'note body', + formData: 'formData', + }); + }) + .then(done) + .catch(done.fail); }); }); }); diff --git a/spec/javascripts/diffs/mock_data/diff_with_commit.js b/spec/javascripts/diffs/mock_data/diff_with_commit.js new file mode 100644 index 00000000000..98393a20583 --- /dev/null +++ b/spec/javascripts/diffs/mock_data/diff_with_commit.js @@ -0,0 +1,12 @@ +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; + +const FIXTURE = 'merge_request_diffs/with_commit.json'; + +preloadFixtures(FIXTURE); + +export default function getDiffWithCommit() { + return convertObjectPropsToCamelCase( + getJSONFixture(FIXTURE), + { deep: true }, + ); +} diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js index 4c662fac231..05b39bad6ea 100644 --- a/spec/javascripts/diffs/store/actions_spec.js +++ b/spec/javascripts/diffs/store/actions_spec.js @@ -21,6 +21,7 @@ import actions, { loadCollapsedDiff, expandAllFiles, toggleFileDiscussions, + saveDiffDiscussion, } from '~/diffs/store/actions'; import * as types from '~/diffs/store/mutation_types'; import { reduceDiscussionsToLineCodes } from '~/notes/stores/utils'; @@ -245,7 +246,7 @@ describe('DiffsStoreActions', () => { }); describe('startRenderDiffsQueue', () => { - it('should set all files to RENDER_FILE', done => { + it('should set all files to RENDER_FILE', () => { const state = { diffFiles: [ { @@ -268,16 +269,10 @@ describe('DiffsStoreActions', () => { }); }; - startRenderDiffsQueue({ state, commit: pseudoCommit }) - .then(() => { - expect(state.diffFiles[0].renderIt).toBeTruthy(); - expect(state.diffFiles[1].renderIt).toBeTruthy(); + startRenderDiffsQueue({ state, commit: pseudoCommit }); - done(); - }) - .catch(() => { - done.fail(); - }); + expect(state.diffFiles[0].renderIt).toBe(true); + expect(state.diffFiles[1].renderIt).toBe(true); }); }); @@ -582,4 +577,35 @@ describe('DiffsStoreActions', () => { expect(handleLocationHashSpy).toHaveBeenCalledTimes(1); }); }); + + describe('saveDiffDiscussion', () => { + beforeEach(() => { + spyOnDependency(actions, 'getNoteFormData').and.returnValue('testData'); + spyOnDependency(actions, 'reduceDiscussionsToLineCodes').and.returnValue('discussions'); + }); + + it('dispatches actions', done => { + const dispatch = jasmine.createSpy('dispatch').and.callFake(name => { + switch (name) { + case 'saveNote': + return Promise.resolve({ + discussion: 'test', + }); + case 'updateDiscussion': + return Promise.resolve('discussion'); + default: + return Promise.resolve({}); + } + }); + + saveDiffDiscussion({ dispatch }, { note: {}, formData: {} }) + .then(() => { + expect(dispatch.calls.argsFor(0)).toEqual(['saveNote', 'testData', { root: true }]); + expect(dispatch.calls.argsFor(1)).toEqual(['updateDiscussion', 'test', { root: true }]); + expect(dispatch.calls.argsFor(2)).toEqual(['assignDiscussionsToDiff', 'discussions']); + }) + .then(done) + .catch(done.fail); + }); + }); }); diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js index 6138b9701f4..897cd1483aa 100644 --- a/spec/javascripts/diffs/store/utils_spec.js +++ b/spec/javascripts/diffs/store/utils_spec.js @@ -136,6 +136,7 @@ describe('DiffsStoreUtils', () => { note_project_id: '', target_type: options.noteableType, target_id: options.noteableData.id, + return_discussion: true, note: { noteable_type: options.noteableType, noteable_id: options.noteableData.id, @@ -194,6 +195,7 @@ describe('DiffsStoreUtils', () => { note_project_id: '', target_type: options.noteableType, target_id: options.noteableData.id, + return_discussion: true, note: { noteable_type: options.noteableType, noteable_id: options.noteableData.id, diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/javascripts/fixtures/merge_requests_diffs.rb index ddce00bc0fe..afe34b834b0 100644 --- a/spec/javascripts/fixtures/merge_requests_diffs.rb +++ b/spec/javascripts/fixtures/merge_requests_diffs.rb @@ -9,6 +9,7 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type let(:project) { create(:project, :repository, namespace: namespace, path: 'merge-requests-project') } let(:merge_request) { create(:merge_request, :with_diffs, source_project: project, target_project: project, description: '- [ ] Task List Item') } let(:path) { "files/ruby/popen.rb" } + let(:selected_commit) { merge_request.all_commits[0] } let(:position) do Gitlab::Diff::Position.new( old_path: path, @@ -33,6 +34,14 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type remove_repository(project) end + it 'merge_request_diffs/with_commit.json' do |example| + # Create a user that matches the selected commit author + # This is so that the "author" information will be populated + create(:user, email: selected_commit.author_email, name: selected_commit.author_name) + + render_merge_request(example.description, merge_request, commit_id: selected_commit.sha) + end + it 'merge_request_diffs/inline_changes_tab_with_comments.json' do |example| create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request) create(:note_on_merge_request, author: admin, project: project, noteable: merge_request) @@ -47,13 +56,14 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type private - def render_merge_request(fixture_file_name, merge_request, view: 'inline') + def render_merge_request(fixture_file_name, merge_request, view: 'inline', **extra_params) get :show, namespace_id: project.namespace.to_param, project_id: project, id: merge_request.to_param, format: :json, - view: view + view: view, + **extra_params expect(response).to be_success store_frontend_fixture(response, fixture_file_name) diff --git a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js index b45ae5bbb0f..bf48d7bfdad 100644 --- a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js @@ -33,10 +33,6 @@ describe('Multi-file editor commit sidebar list item', () => { expect(vm.$el.querySelector('.multi-file-commit-list-path').textContent).toContain(f.path); }); - it('renders actionn button', () => { - expect(vm.$el.querySelector('.multi-file-discard-btn')).not.toBeNull(); - }); - it('opens a closed file in the editor when clicking the file path', done => { spyOn(vm, 'openPendingTab').and.callThrough(); spyOn(router, 'push'); diff --git a/spec/javascripts/ide/components/repo_commit_section_spec.js b/spec/javascripts/ide/components/repo_commit_section_spec.js index d09ccd7ac34..6c726c1e154 100644 --- a/spec/javascripts/ide/components/repo_commit_section_spec.js +++ b/spec/javascripts/ide/components/repo_commit_section_spec.js @@ -103,65 +103,6 @@ describe('RepoCommitSection', () => { }); }); - it('adds changed files into staged files', done => { - vm.$el.querySelector('.multi-file-discard-btn .btn').click(); - vm - .$nextTick() - .then(() => vm.$el.querySelector('.multi-file-discard-btn .btn').click()) - .then(vm.$nextTick) - .then(() => { - expect(vm.$el.querySelector('.ide-commit-list-container').textContent).toContain( - 'There are no unstaged changes', - ); - }) - .then(done) - .catch(done.fail); - }); - - it('stages a single file', done => { - vm.$el.querySelector('.multi-file-discard-btn .btn').click(); - - Vue.nextTick(() => { - expect( - vm.$el - .querySelector('.ide-commit-list-container') - .querySelectorAll('.multi-file-commit-list > li').length, - ).toBe(1); - - done(); - }); - }); - - it('discards a single file', done => { - vm.$el.querySelector('.multi-file-commit-list li:first-child .js-modal-primary-action').click(); - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.ide-commit-list-container').textContent).not.toContain('file1'); - expect( - vm.$el - .querySelector('.ide-commit-list-container') - .querySelectorAll('.multi-file-commit-list > li').length, - ).toBe(1); - - done(); - }); - }); - - it('unstages a single file', done => { - vm.$el - .querySelectorAll('.multi-file-discard-btn')[2] - .querySelector('.btn') - .click(); - - Vue.nextTick(() => { - expect( - vm.$el.querySelectorAll('.ide-commit-list-container')[1].querySelectorAll('li').length, - ).toBe(1); - - done(); - }); - }); - describe('mounted', () => { it('opens last opened file', () => { expect(store.state.openFiles.length).toBe(1); diff --git a/spec/javascripts/ide/components/repo_loading_file_spec.js b/spec/javascripts/ide/components/repo_loading_file_spec.js deleted file mode 100644 index 7c20b8302f9..00000000000 --- a/spec/javascripts/ide/components/repo_loading_file_spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoLoadingFile from '~/ide/components/repo_loading_file.vue'; -import { resetStore } from '../helpers'; - -describe('RepoLoadingFile', () => { - let vm; - - function createComponent() { - const RepoLoadingFile = Vue.extend(repoLoadingFile); - - return new RepoLoadingFile({ - store, - }).$mount(); - } - - function assertLines(lines) { - lines.forEach((line, n) => { - const index = n + 1; - expect(line.classList.contains(`skeleton-line-${index}`)).toBeTruthy(); - }); - } - - function assertColumns(columns) { - columns.forEach(column => { - const container = column.querySelector('.animation-container'); - const lines = [...container.querySelectorAll(':scope > div')]; - - expect(container).toBeTruthy(); - expect(lines.length).toEqual(3); - assertLines(lines); - }); - } - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders 3 columns of animated LoC', () => { - vm = createComponent(); - const columns = [...vm.$el.querySelectorAll('td')]; - - expect(columns.length).toEqual(3); - assertColumns(columns); - }); - - it('renders 1 column of animated LoC if isMini', done => { - vm = createComponent(); - vm.$store.state.leftPanelCollapsed = true; - vm.$store.state.openFiles.push('test'); - - vm.$nextTick(() => { - const columns = [...vm.$el.querySelectorAll('td')]; - - expect(columns.length).toEqual(1); - assertColumns(columns); - - done(); - }); - }); -}); diff --git a/spec/javascripts/issue_show/components/edit_actions_spec.js b/spec/javascripts/issue_show/components/edit_actions_spec.js index a3772285527..004621f488a 100644 --- a/spec/javascripts/issue_show/components/edit_actions_spec.js +++ b/spec/javascripts/issue_show/components/edit_actions_spec.js @@ -21,6 +21,7 @@ describe('Edit Actions components', () => { propsData: { canDestroy: true, formState: store.formState, + issuableType: 'issue', }, }).$mount(); diff --git a/spec/javascripts/issue_show/components/form_spec.js b/spec/javascripts/issue_show/components/form_spec.js index 50ce019c32a..eaac1e3536d 100644 --- a/spec/javascripts/issue_show/components/form_spec.js +++ b/spec/javascripts/issue_show/components/form_spec.js @@ -15,6 +15,7 @@ describe('Inline edit form component', () => { description: 'a', lockedWarningVisible: false, }, + issuableType: 'issue', markdownPreviewPath: '/', markdownDocsPath: '/', projectPath: '/', diff --git a/spec/javascripts/jobs/components/artifacts_block_spec.js b/spec/javascripts/jobs/components/artifacts_block_spec.js index a06d287b3fa..2fa7ff653fe 100644 --- a/spec/javascripts/jobs/components/artifacts_block_spec.js +++ b/spec/javascripts/jobs/components/artifacts_block_spec.js @@ -11,6 +11,19 @@ describe('Artifacts block', () => { const timeago = getTimeago(); const formatedDate = timeago.format(expireAt); + const expiredArtifact = { + expire_at: expireAt, + expired: true, + }; + + const nonExpiredArtifact = { + download_path: '/gitlab-org/gitlab-ce/-/jobs/98314558/artifacts/download', + browse_path: '/gitlab-org/gitlab-ce/-/jobs/98314558/artifacts/browse', + keep_path: '/gitlab-org/gitlab-ce/-/jobs/98314558/artifacts/keep', + expire_at: expireAt, + expired: false, + }; + afterEach(() => { vm.$destroy(); }); @@ -18,100 +31,87 @@ describe('Artifacts block', () => { describe('with expired artifacts', () => { it('renders expired artifact date and info', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, + artifact: expiredArtifact, }); expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull(); expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull(); expect(vm.$el.textContent).toContain(formatedDate); + expect(vm.$el.querySelector('.js-artifacts-removed').textContent.trim()).toEqual( + 'The artifacts were removed', + ); }); }); describe('with artifacts that will expire', () => { it('renders will expire artifact date and info', () => { vm = mountComponent(Component, { - haveArtifactsExpired: false, - willArtifactsExpire: true, - expireAt, + artifact: nonExpiredArtifact, }); expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull(); expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull(); expect(vm.$el.textContent).toContain(formatedDate); + expect(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent.trim()).toEqual( + 'The artifacts will be removed in', + ); }); }); - describe('when the user can keep the artifacts', () => { + describe('with keep path', () => { it('renders the keep button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, - keepArtifactsPath: '/keep', + artifact: nonExpiredArtifact, }); expect(vm.$el.querySelector('.js-keep-artifacts')).not.toBeNull(); }); }); - describe('when the user can not keep the artifacts', () => { + describe('without keep path', () => { it('does not render the keep button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, + artifact: expiredArtifact, }); expect(vm.$el.querySelector('.js-keep-artifacts')).toBeNull(); }); }); - describe('when the user can download the artifacts', () => { + describe('with download path', () => { it('renders the download button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, - downloadArtifactsPath: '/download', + artifact: nonExpiredArtifact, }); expect(vm.$el.querySelector('.js-download-artifacts')).not.toBeNull(); }); }); - describe('when the user can not download the artifacts', () => { + describe('without download path', () => { it('does not render the keep button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, + artifact: expiredArtifact, }); expect(vm.$el.querySelector('.js-download-artifacts')).toBeNull(); }); }); - describe('when the user can browse the artifacts', () => { + describe('with browse path', () => { it('does not render the browse button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, - browseArtifactsPath: '/browse', + artifact: nonExpiredArtifact, }); expect(vm.$el.querySelector('.js-browse-artifacts')).not.toBeNull(); }); }); - describe('when the user can not browse the artifacts', () => { + describe('without browse path', () => { it('does not render the browse button', () => { vm = mountComponent(Component, { - haveArtifactsExpired: true, - willArtifactsExpire: false, - expireAt, + artifact: expiredArtifact, }); expect(vm.$el.querySelector('.js-browse-artifacts')).toBeNull(); diff --git a/spec/javascripts/jobs/components/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js index e21fa9c2874..61ee993f46a 100644 --- a/spec/javascripts/jobs/components/commit_block_spec.js +++ b/spec/javascripts/jobs/components/commit_block_spec.js @@ -7,11 +7,16 @@ describe('Commit block', () => { let vm; const props = { - pipelineShortSha: '1f0fb84f', - pipelineShaPath: 'commit/1f0fb84fb6770d74d97eee58118fd3909cd4f48c', - mergeRequestReference: '!21244', - mergeRequestPath: 'merge_requests/21244', - gitCommitTitlte: 'Regenerate pot files', + commit: { + short_id: '1f0fb84f', + commit_path: 'commit/1f0fb84fb6770d74d97eee58118fd3909cd4f48c', + title: 'Update README.md', + }, + mergeRequest: { + iid: '!21244', + path: 'merge_requests/21244', + }, + isLastBlock: true, }; afterEach(() => { @@ -26,12 +31,18 @@ describe('Commit block', () => { }); it('renders pipeline short sha link', () => { - expect(vm.$el.querySelector('.js-commit-sha').getAttribute('href')).toEqual(props.pipelineShaPath); - expect(vm.$el.querySelector('.js-commit-sha').textContent.trim()).toEqual(props.pipelineShortSha); + expect(vm.$el.querySelector('.js-commit-sha').getAttribute('href')).toEqual( + props.commit.commit_path, + ); + expect(vm.$el.querySelector('.js-commit-sha').textContent.trim()).toEqual( + props.commit.short_id, + ); }); it('renders clipboard button', () => { - expect(vm.$el.querySelector('button').getAttribute('data-clipboard-text')).toEqual(props.pipelineShortSha); + expect(vm.$el.querySelector('button').getAttribute('data-clipboard-text')).toEqual( + props.commit.short_id, + ); }); }); @@ -41,17 +52,19 @@ describe('Commit block', () => { ...props, }); - expect(vm.$el.querySelector('.js-link-commit').getAttribute('href')).toEqual(props.mergeRequestPath); - expect(vm.$el.querySelector('.js-link-commit').textContent.trim()).toEqual(props.mergeRequestReference); - + expect(vm.$el.querySelector('.js-link-commit').getAttribute('href')).toEqual( + props.mergeRequest.path, + ); + expect(vm.$el.querySelector('.js-link-commit').textContent.trim()).toEqual( + props.mergeRequest.iid, + ); }); }); describe('without merge request', () => { it('does not render merge request', () => { const copyProps = Object.assign({}, props); - delete copyProps.mergeRequestPath; - delete copyProps.mergeRequestReference; + delete copyProps.mergeRequest; vm = mountComponent(Component, { ...copyProps, @@ -67,7 +80,7 @@ describe('Commit block', () => { ...props, }); - expect(vm.$el.textContent).toContain(props.gitCommitTitlte); + expect(vm.$el.textContent).toContain(props.commit.title); }); }); }); diff --git a/spec/javascripts/jobs/components/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js index dcc2b3d8a20..872cc1e3864 100644 --- a/spec/javascripts/jobs/components/empty_state_spec.js +++ b/spec/javascripts/jobs/components/empty_state_spec.js @@ -66,7 +66,7 @@ describe('Empty State', () => { ...props, content, action: { - link: 'runner', + path: 'runner', title: 'Check runner', method: 'post', }, diff --git a/spec/javascripts/jobs/components/erased_block_spec.js b/spec/javascripts/jobs/components/erased_block_spec.js index a4ae0c7c81e..8e0433d3fb7 100644 --- a/spec/javascripts/jobs/components/erased_block_spec.js +++ b/spec/javascripts/jobs/components/erased_block_spec.js @@ -18,9 +18,10 @@ describe('Erased block', () => { describe('with job erased by user', () => { beforeEach(() => { vm = mountComponent(Component, { - erasedByUser: true, - username: 'root', - linkToUser: 'gitlab.com/root', + user: { + username: 'root', + web_url: 'gitlab.com/root', + }, erasedAt, }); }); @@ -40,7 +41,6 @@ describe('Erased block', () => { describe('with erased job', () => { beforeEach(() => { vm = mountComponent(Component, { - erasedByUser: false, erasedAt, }); }); diff --git a/spec/javascripts/jobs/components/job_details_mediator_spec.js b/spec/javascripts/jobs/components/job_details_mediator_spec.js deleted file mode 100644 index 3e2fb7bfbbb..00000000000 --- a/spec/javascripts/jobs/components/job_details_mediator_spec.js +++ /dev/null @@ -1,39 +0,0 @@ -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'; - -describe('JobMediator', () => { - let mediator; - let mock; - - beforeEach(() => { - mediator = new JobMediator({ endpoint: 'jobs/40291672.json' }); - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - - it('should set defaults', () => { - expect(mediator.store).toBeDefined(); - expect(mediator.service).toBeDefined(); - expect(mediator.options).toEqual({ endpoint: 'jobs/40291672.json' }); - expect(mediator.state.isLoading).toEqual(false); - }); - - describe('request and store data', () => { - beforeEach(() => { - mock.onGet().reply(200, job, {}); - }); - - it('should store received data', (done) => { - mediator.fetchJob(); - setTimeout(() => { - expect(mediator.store.state.job).toEqual(job); - done(); - }, 0); - }); - }); -}); diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/javascripts/jobs/components/job_log_controllers_spec.js index 416dfab8a48..099aca602c4 100644 --- a/spec/javascripts/jobs/components/job_log_controllers_spec.js +++ b/spec/javascripts/jobs/components/job_log_controllers_spec.js @@ -10,50 +10,51 @@ describe('Job log controllers', () => { vm.$destroy(); }); - describe('Truncate information', () => { + const props = { + rawPath: '/raw', + erasePath: '/erase', + size: 511952, + isScrollTopDisabled: false, + isScrollBottomDisabled: false, + isScrollingDown: true, + isTraceSizeVisible: true, + }; - beforeEach(() => { - vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, - size: 511952, - canScrollToTop: true, - canScrollToBottom: true, + describe('Truncate information', () => { + describe('with isTraceSizeVisible', () => { + beforeEach(() => { + vm = mountComponent(Component, props); + }); + it('renders size information', () => { + expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB'); }); - }); - - it('renders size information', () => { - expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB'); - }); - it('renders link to raw trace', () => { - expect(vm.$el.querySelector('.js-raw-link').getAttribute('href')).toEqual('/raw'); + it('renders link to raw trace', () => { + expect(vm.$el.querySelector('.js-raw-link').getAttribute('href')).toEqual('/raw'); + }); }); - }); describe('links section', () => { describe('with raw trace path', () => { it('renders raw trace link', () => { - vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, - size: 511952, - canScrollToTop: true, - canScrollToBottom: true, - }); + vm = mountComponent(Component, props); - expect(vm.$el.querySelector('.js-raw-link-controller').getAttribute('href')).toEqual('/raw'); + expect(vm.$el.querySelector('.js-raw-link-controller').getAttribute('href')).toEqual( + '/raw', + ); }); }); describe('without raw trace path', () => { it('does not render raw trace link', () => { vm = mountComponent(Component, { - canEraseJob: true, + erasePath: '/erase', size: 511952, - canScrollToTop: true, - canScrollToBottom: true, + isScrollTopDisabled: true, + isScrollBottomDisabled: true, + isScrollingDown: false, + isTraceSizeVisible: true, }); expect(vm.$el.querySelector('.js-raw-link-controller')).toBeNull(); @@ -62,52 +63,23 @@ describe('Job log controllers', () => { describe('when is erasable', () => { beforeEach(() => { - vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, - size: 511952, - canScrollToTop: true, - canScrollToBottom: true, - }); + vm = mountComponent(Component, props); }); - it('renders erase job button', () => { + it('renders erase job link', () => { expect(vm.$el.querySelector('.js-erase-link')).not.toBeNull(); }); - - describe('on click', () => { - describe('when user confirms action', () => { - it('emits eraseJob event', () => { - spyOn(window, 'confirm').and.returnValue(true); - spyOn(vm, '$emit'); - - vm.$el.querySelector('.js-erase-link').click(); - - expect(vm.$emit).toHaveBeenCalledWith('eraseJob'); - }); - }); - - describe('when user does not confirm action', () => { - it('does not emit eraseJob event', () => { - spyOn(window, 'confirm').and.returnValue(false); - spyOn(vm, '$emit'); - - vm.$el.querySelector('.js-erase-link').click(); - - expect(vm.$emit).not.toHaveBeenCalledWith('eraseJob'); - }); - }); - }); }); describe('when it is not erasable', () => { it('does not render erase button', () => { vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: false, + rawPath: '/raw', size: 511952, - canScrollToTop: true, - canScrollToBottom: true, + isScrollTopDisabled: true, + isScrollBottomDisabled: true, + isScrollingDown: false, + isTraceSizeVisible: true, }); expect(vm.$el.querySelector('.js-erase-link')).toBeNull(); @@ -119,13 +91,7 @@ describe('Job log controllers', () => { describe('scroll top button', () => { describe('when user can scroll top', () => { beforeEach(() => { - vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, - size: 511952, - canScrollToTop: true, - canScrollToBottom: true, - }); + vm = mountComponent(Component, props); }); it('renders enabled scroll top button', () => { @@ -143,16 +109,20 @@ describe('Job log controllers', () => { describe('when user can not scroll top', () => { beforeEach(() => { vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, + rawPath: '/raw', + erasePath: '/erase', size: 511952, - canScrollToTop: false, - canScrollToBottom: true, + isScrollTopDisabled: true, + isScrollBottomDisabled: false, + isScrollingDown: false, + isTraceSizeVisible: true, }); }); it('renders disabled scroll top button', () => { - expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toEqual('disabled'); + expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toEqual( + 'disabled', + ); }); it('does not emit scrollJobLogTop event on click', () => { @@ -167,13 +137,7 @@ describe('Job log controllers', () => { describe('scroll bottom button', () => { describe('when user can scroll bottom', () => { beforeEach(() => { - vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, - size: 511952, - canScrollToTop: true, - canScrollToBottom: true, - }); + vm = mountComponent(Component, props); }); it('renders enabled scroll bottom button', () => { @@ -191,17 +155,20 @@ describe('Job log controllers', () => { describe('when user can not scroll bottom', () => { beforeEach(() => { vm = mountComponent(Component, { - rawTracePath: '/raw', - canEraseJob: true, + rawPath: '/raw', + erasePath: '/erase', size: 511952, - canScrollToTop: true, - canScrollToBottom: false, + isScrollTopDisabled: false, + isScrollBottomDisabled: true, + isScrollingDown: false, + isTraceSizeVisible: true, }); }); it('renders disabled scroll bottom button', () => { - expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toEqual('disabled'); - + expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toEqual( + 'disabled', + ); }); it('does not emit scrollJobLogBottom event on click', () => { @@ -211,7 +178,29 @@ describe('Job log controllers', () => { expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogBottom'); }); }); + + describe('while isScrollingDown is true', () => { + it('renders animate class for the scroll down button', () => { + vm = mountComponent(Component, props); + + expect(vm.$el.querySelector('.js-scroll-bottom').className).toContain('animate'); + }); + }); + + describe('while isScrollingDown is false', () => { + it('does not render animate class for the scroll down button', () => { + vm = mountComponent(Component, { + rawPath: '/raw', + erasePath: '/erase', + size: 511952, + isScrollTopDisabled: true, + isScrollBottomDisabled: false, + isScrollingDown: false, + isTraceSizeVisible: true, + }); + expect(vm.$el.querySelector('.js-scroll-bottom').className).not.toContain('animate'); + }); + }); }); }); }); - diff --git a/spec/javascripts/jobs/components/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js index 6a5b375a26c..1011512360d 100644 --- a/spec/javascripts/jobs/components/job_log_spec.js +++ b/spec/javascripts/jobs/components/job_log_spec.js @@ -15,7 +15,7 @@ describe('Job Log', () => { it('renders provided trace', () => { vm = mountComponent(Component, { trace, - isReceivingBuildTrace: true, + isComplete: true, }); expect(vm.$el.querySelector('code').textContent).toContain('Running with gitlab-runner 11.1.0 (081978aa)'); @@ -25,7 +25,7 @@ describe('Job Log', () => { it('renders animation', () => { vm = mountComponent(Component, { trace, - isReceivingBuildTrace: true, + isComplete: true, }); expect(vm.$el.querySelector('.js-log-animation')).not.toBeNull(); @@ -36,7 +36,7 @@ describe('Job Log', () => { it('does not render animation', () => { vm = mountComponent(Component, { trace, - isReceivingBuildTrace: false, + isComplete: false, }); expect(vm.$el.querySelector('.js-log-animation')).toBeNull(); diff --git a/spec/javascripts/jobs/components/job_store_spec.js b/spec/javascripts/jobs/components/job_store_spec.js deleted file mode 100644 index 0dad5111b32..00000000000 --- a/spec/javascripts/jobs/components/job_store_spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import JobStore from '~/jobs/stores/job_store'; -import job from '../mock_data'; - -describe('Job Store', () => { - let store; - - beforeEach(() => { - store = new JobStore(); - }); - - it('should set defaults', () => { - expect(store.state.job).toEqual({}); - }); - - describe('storeJob', () => { - it('should store empty object if none is provided', () => { - store.storeJob(); - expect(store.state.job).toEqual({}); - }); - - it('should store provided argument', () => { - store.storeJob(job); - expect(store.state.job).toEqual(job); - }); - }); -}); diff --git a/spec/javascripts/jobs/components/trigger_value_spec.js b/spec/javascripts/jobs/components/trigger_block_spec.js index 3d41a3cfac1..e1b9898393e 100644 --- a/spec/javascripts/jobs/components/trigger_value_spec.js +++ b/spec/javascripts/jobs/components/trigger_block_spec.js @@ -13,7 +13,9 @@ describe('Trigger block', () => { describe('with short token', () => { it('renders short token', () => { vm = mountComponent(Component, { - shortToken: '0a666b2', + trigger: { + short_token: '0a666b2', + }, }); expect(vm.$el.querySelector('.js-short-token').textContent).toContain('0a666b2'); @@ -22,7 +24,7 @@ describe('Trigger block', () => { describe('without short token', () => { it('does not render short token', () => { - vm = mountComponent(Component, {}); + vm = mountComponent(Component, { trigger: {} }); expect(vm.$el.querySelector('.js-short-token')).toBeNull(); }); @@ -32,9 +34,12 @@ describe('Trigger block', () => { describe('reveal variables', () => { it('reveals variables on click', done => { vm = mountComponent(Component, { - variables: { - key: 'value', - variable: 'foo', + trigger: { + short_token: 'bd7e', + variables: [ + { key: 'UPLOAD_TO_GCS', value: 'false', public: false }, + { key: 'UPLOAD_TO_S3', value: 'true', public: false }, + ], }, }); @@ -44,10 +49,10 @@ describe('Trigger block', () => { .$nextTick() .then(() => { expect(vm.$el.querySelector('.js-build-variables')).not.toBeNull(); - expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('key'); - expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('value'); - expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('variable'); - expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('foo'); + expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('UPLOAD_TO_GCS'); + expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('false'); + expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('UPLOAD_TO_S3'); + expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('true'); }) .then(done) .catch(done.fail); @@ -57,7 +62,7 @@ describe('Trigger block', () => { describe('without variables', () => { it('does not render variables', () => { - vm = mountComponent(Component); + vm = mountComponent(Component, { trigger: {} }); expect(vm.$el.querySelector('.js-reveal-variables')).toBeNull(); expect(vm.$el.querySelector('.js-build-variables')).toBeNull(); diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js index 6900b2e5602..9ba543d32a8 100644 --- a/spec/javascripts/jobs/store/mutations_spec.js +++ b/spec/javascripts/jobs/store/mutations_spec.js @@ -12,6 +12,13 @@ describe('Jobs Store Mutations', () => { stateCopy = state(); }); + describe('SET_JOB_ENDPOINT', () => { + it('should set jobEndpoint', () => { + mutations[types.SET_JOB_ENDPOINT](stateCopy, 'job/21312321.json'); + expect(stateCopy.jobEndpoint).toEqual('job/21312321.json'); + }); + }); + describe('REQUEST_STATUS_FAVICON', () => { it('should set fetchingStatusFavicon to true', () => { mutations[types.REQUEST_STATUS_FAVICON](stateCopy); diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js index 523f4997bc0..b28a052902e 100644 --- a/spec/javascripts/lib/utils/poll_spec.js +++ b/spec/javascripts/lib/utils/poll_spec.js @@ -1,3 +1,5 @@ +/* eslint-disable jasmine/no-unsafe-spy */ + import Poll from '~/lib/utils/poll'; import { successCodes } from '~/lib/utils/http_status'; diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js index 997163c7602..f0d53b2d8d7 100644 --- a/spec/javascripts/monitoring/dashboard_spec.js +++ b/spec/javascripts/monitoring/dashboard_spec.js @@ -25,7 +25,10 @@ describe('Dashboard', () => { }; beforeEach(() => { - setFixtures('<div class="prometheus-graphs"></div>'); + setFixtures(` + <div class="prometheus-graphs"></div> + <div class="nav-sidebar"></div> + `); DashboardComponent = Vue.extend(Dashboard); }); @@ -127,4 +130,41 @@ describe('Dashboard', () => { }); }); }); + + describe('when the window resizes', () => { + let mock; + beforeEach(() => { + mock = new MockAdapter(axios); + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + jasmine.clock().install(); + }); + + afterEach(() => { + mock.restore(); + jasmine.clock().uninstall(); + }); + + it('rerenders the dashboard when the sidebar is resized', done => { + const component = new DashboardComponent({ + el: document.querySelector('.prometheus-graphs'), + propsData: { ...propsData, hasMetrics: true, showPanels: false }, + }); + + expect(component.forceRedraw).toEqual(0); + + const navSidebarEl = document.querySelector('.nav-sidebar'); + navSidebarEl.classList.add('nav-sidebar-collapsed'); + + Vue.nextTick() + .then(() => { + jasmine.clock().tick(1000); + return Vue.nextTick(); + }) + .then(() => { + expect(component.forceRedraw).toEqual(component.elWidth); + done(); + }) + .catch(done.fail); + }); + }); }); diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js index 990619b4109..99180e4d303 100644 --- a/spec/javascripts/monitoring/graph_spec.js +++ b/spec/javascripts/monitoring/graph_spec.js @@ -1,7 +1,6 @@ import Vue from 'vue'; import Graph from '~/monitoring/components/graph.vue'; import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins'; -import eventHub from '~/monitoring/event_hub'; import { deploymentData, convertDatesMultipleSeries, @@ -69,23 +68,6 @@ describe('Graph', () => { }); }); - it('sends an event to the eventhub when it has finished resizing', done => { - const component = createComponent({ - graphData: convertedMetrics[1], - updateAspectRatio: false, - deploymentData, - tagsPath, - projectPath, - }); - spyOn(eventHub, '$emit'); - - component.updateAspectRatio = true; - Vue.nextTick(() => { - expect(eventHub.$emit).toHaveBeenCalled(); - done(); - }); - }); - it('has a title for the y-axis and the chart legend that comes from the backend', () => { const component = createComponent({ graphData: convertedMetrics[1], diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js index 6b7f61468d5..1ecfe914859 100644 --- a/spec/javascripts/notes/stores/mutation_spec.js +++ b/spec/javascripts/notes/stores/mutation_spec.js @@ -156,6 +156,41 @@ describe('Notes Store mutations', () => { expect(state.discussions[2].notes[0].note).toBe(legacyNote.notes[1].note); expect(state.discussions.length).toEqual(3); }); + + it('adds truncated_diff_lines if discussion is a diffFile', () => { + const state = { + discussions: [], + }; + + mutations.SET_INITIAL_DISCUSSIONS(state, [ + { + ...note, + diff_file: { + file_hash: 'a', + }, + truncated_diff_lines: ['a'], + }, + ]); + + expect(state.discussions[0].truncated_diff_lines).toEqual(['a']); + }); + + it('adds empty truncated_diff_lines when not in discussion', () => { + const state = { + discussions: [], + }; + + mutations.SET_INITIAL_DISCUSSIONS(state, [ + { + ...note, + diff_file: { + file_hash: 'a', + }, + }, + ]); + + expect(state.discussions[0].truncated_diff_lines).toEqual([]); + }); }); describe('SET_LAST_FETCHED_AT', () => { diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js index 6d49536a712..c7190ea9960 100644 --- a/spec/javascripts/right_sidebar_spec.js +++ b/spec/javascripts/right_sidebar_spec.js @@ -1,4 +1,4 @@ -/* eslint-disable no-var, one-var, one-var-declaration-per-line, no-return-assign, vars-on-top, max-len */ +/* eslint-disable no-var, one-var, one-var-declaration-per-line, no-return-assign, vars-on-top, jasmine/no-unsafe-spy, max-len */ import $ from 'jquery'; import MockAdapter from 'axios-mock-adapter'; diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 6342ea00436..6ac7138743b 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -27,6 +27,10 @@ describe('mrWidgetOptions', () => { }); }); + afterEach(() => { + vm.$destroy(); + }); + describe('data', () => { it('should instantiate Store and Service', () => { expect(vm.mr).toBeDefined(); diff --git a/spec/javascripts/vue_shared/components/skeleton_loading_container_spec.js b/spec/javascripts/vue_shared/components/skeleton_loading_container_spec.js deleted file mode 100644 index 34487885cf0..00000000000 --- a/spec/javascripts/vue_shared/components/skeleton_loading_container_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import Vue from 'vue'; -import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; - -describe('Skeleton loading container', () => { - let vm; - - beforeEach(() => { - const component = Vue.extend(skeletonLoadingContainer); - vm = mountComponent(component); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders 3 skeleton lines by default', () => { - expect(vm.$el.querySelector('.skeleton-line-3')).not.toBeNull(); - }); - - it('renders in full mode by default', () => { - expect(vm.$el.classList.contains('animation-container-small')).toBeFalsy(); - }); - - describe('small', () => { - beforeEach((done) => { - vm.small = true; - - Vue.nextTick(done); - }); - - it('renders in small mode', () => { - expect(vm.$el.classList.contains('animation-container-small')).toBeTruthy(); - }); - }); - - describe('lines', () => { - beforeEach((done) => { - vm.lines = 5; - - Vue.nextTick(done); - }); - - it('renders 5 lines', () => { - expect(vm.$el.querySelector('.skeleton-line-5')).not.toBeNull(); - expect(vm.$el.querySelector('.skeleton-line-6')).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js index c36b607a34e..d193667210b 100644 --- a/spec/javascripts/vue_shared/components/table_pagination_spec.js +++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js @@ -5,13 +5,13 @@ describe('Pagination component', () => { let component; let PaginationComponent; let spy; - let mountComponet; + let mountComponent; beforeEach(() => { spy = jasmine.createSpy('spy'); PaginationComponent = Vue.extend(paginationComp); - mountComponet = function (props) { + mountComponent = function (props) { return new PaginationComponent({ propsData: props, }).$mount(); @@ -20,7 +20,7 @@ describe('Pagination component', () => { describe('render', () => { it('should not render anything', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 1, page: 1, @@ -37,7 +37,7 @@ describe('Pagination component', () => { describe('prev button', () => { it('should be disabled and non clickable', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 2, page: 1, @@ -59,7 +59,7 @@ describe('Pagination component', () => { }); it('should be enabled and clickable', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 3, page: 2, @@ -78,7 +78,7 @@ describe('Pagination component', () => { describe('first button', () => { it('should call the change callback with the first page', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 3, page: 2, @@ -102,7 +102,7 @@ describe('Pagination component', () => { describe('last button', () => { it('should call the change callback with the last page', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 3, page: 2, @@ -126,7 +126,7 @@ describe('Pagination component', () => { describe('next button', () => { it('should be disabled and non clickable', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 5, page: 5, @@ -148,7 +148,7 @@ describe('Pagination component', () => { }); it('should be enabled and clickable', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 4, page: 3, @@ -168,7 +168,7 @@ describe('Pagination component', () => { describe('numbered buttons', () => { it('should render 5 pages', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 4, page: 3, @@ -185,7 +185,7 @@ describe('Pagination component', () => { }); it('should render the spread operator', () => { - component = mountComponet({ + component = mountComponent({ pageInfo: { nextPage: 4, page: 3, diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index d9018a7e4fe..0d0554a2259 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -79,13 +79,9 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do expect(link).to eq helper.url_for_issue(issue_id, project, only_path: true) end - context 'with RequestStore enabled' do + context 'with RequestStore enabled', :request_store do let(:reference_filter) { HTML::Pipeline.new([described_class]) } - before do - allow(RequestStore).to receive(:active?).and_return(true) - end - it 'queries the collection on the first call' do expect_any_instance_of(Project).to receive(:default_issues_tracker?).once.and_call_original expect_any_instance_of(Project).to receive(:external_issue_reference_pattern).once.and_call_original diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb index 4e6e8eca38a..c6e9fc414a1 100644 --- a/spec/lib/banzai/reference_parser/base_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -263,11 +263,10 @@ describe Banzai::ReferenceParser::BaseParser do end end - context 'with RequestStore enabled' do + context 'with RequestStore enabled', :request_store do before do cache = Hash.new { |hash, key| hash[key] = {} } - allow(RequestStore).to receive(:active?).and_return(true) allow(subject).to receive(:collection_cache).and_return(cache) end diff --git a/spec/lib/event_filter_spec.rb b/spec/lib/event_filter_spec.rb index 87ae6b6cf01..30016da6828 100644 --- a/spec/lib/event_filter_spec.rb +++ b/spec/lib/event_filter_spec.rb @@ -1,58 +1,119 @@ require 'spec_helper' describe EventFilter do + describe 'FILTERS' do + it 'returns a definite list of filters' do + expect(described_class::FILTERS).to eq(%w[all push merged issue comments team]) + end + end + + describe '#filter' do + it 'returns "all" if given filter is nil' do + expect(described_class.new(nil).filter).to eq(described_class::ALL) + end + + it 'returns "all" if given filter is ""' do + expect(described_class.new('').filter).to eq(described_class::ALL) + end + + it 'returns "all" if given filter is "foo"' do + expect(described_class.new('foo').filter).to eq('all') + end + end + describe '#apply_filter' do - let(:source_user) { create(:user) } - let!(:public_project) { create(:project, :public) } + set(:public_project) { create(:project, :public) } + + set(:push_event) { create(:push_event, project: public_project) } + set(:merged_event) { create(:event, :merged, project: public_project, target: public_project) } + set(:created_event) { create(:event, :created, project: public_project, target: public_project) } + set(:updated_event) { create(:event, :updated, project: public_project, target: public_project) } + set(:closed_event) { create(:event, :closed, project: public_project, target: public_project) } + set(:reopened_event) { create(:event, :reopened, project: public_project, target: public_project) } + set(:comments_event) { create(:event, :commented, project: public_project, target: public_project) } + set(:joined_event) { create(:event, :joined, project: public_project, target: public_project) } + set(:left_event) { create(:event, :left, project: public_project, target: public_project) } - let!(:push_event) { create(:push_event, project: public_project, author: source_user) } - let!(:merged_event) { create(:event, :merged, project: public_project, target: public_project, author: source_user) } - let!(:created_event) { create(:event, :created, project: public_project, target: public_project, author: source_user) } - let!(:updated_event) { create(:event, :updated, project: public_project, target: public_project, author: source_user) } - let!(:closed_event) { create(:event, :closed, project: public_project, target: public_project, author: source_user) } - let!(:reopened_event) { create(:event, :reopened, project: public_project, target: public_project, author: source_user) } - let!(:comments_event) { create(:event, :commented, project: public_project, target: public_project, author: source_user) } - let!(:joined_event) { create(:event, :joined, project: public_project, target: public_project, author: source_user) } - let!(:left_event) { create(:event, :left, project: public_project, target: public_project, author: source_user) } + let(:filtered_events) { described_class.new(filter).apply_filter(Event.all) } - it 'applies push filter' do - events = described_class.new(described_class.push).apply_filter(Event.all) - expect(events).to contain_exactly(push_event) + context 'with the "push" filter' do + let(:filter) { described_class::PUSH } + + it 'filters push events only' do + expect(filtered_events).to contain_exactly(push_event) + end end - it 'applies merged filter' do - events = described_class.new(described_class.merged).apply_filter(Event.all) - expect(events).to contain_exactly(merged_event) + context 'with the "merged" filter' do + let(:filter) { described_class::MERGED } + + it 'filters merged events only' do + expect(filtered_events).to contain_exactly(merged_event) + end end - it 'applies issue filter' do - events = described_class.new(described_class.issue).apply_filter(Event.all) - expect(events).to contain_exactly(created_event, updated_event, closed_event, reopened_event) + context 'with the "issue" filter' do + let(:filter) { described_class::ISSUE } + + it 'filters issue events only' do + expect(filtered_events).to contain_exactly(created_event, updated_event, closed_event, reopened_event) + end end - it 'applies comments filter' do - events = described_class.new(described_class.comments).apply_filter(Event.all) - expect(events).to contain_exactly(comments_event) + context 'with the "comments" filter' do + let(:filter) { described_class::COMMENTS } + + it 'filters comment events only' do + expect(filtered_events).to contain_exactly(comments_event) + end end - it 'applies team filter' do - events = described_class.new(described_class.team).apply_filter(Event.all) - expect(events).to contain_exactly(joined_event, left_event) + context 'with the "team" filter' do + let(:filter) { described_class::TEAM } + + it 'filters team events only' do + expect(filtered_events).to contain_exactly(joined_event, left_event) + end end - it 'applies all filter' do - events = described_class.new(described_class.all).apply_filter(Event.all) - expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event) + context 'with the "all" filter' do + let(:filter) { described_class::ALL } + + it 'returns all events' do + expect(filtered_events).to eq(Event.all) + end + end + + context 'with an unknown filter' do + let(:filter) { 'foo' } + + it 'returns all events' do + expect(filtered_events).to eq(Event.all) + end + end + + context 'with a nil filter' do + let(:filter) { nil } + + it 'returns all events' do + expect(filtered_events).to eq(Event.all) + end + end + end + + describe '#active?' do + let(:event_filter) { described_class.new(described_class::TEAM) } + + it 'returns false if filter does not include the given key' do + expect(event_filter.active?('foo')).to eq(false) end - it 'applies no filter' do - events = described_class.new(nil).apply_filter(Event.all) - expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event) + it 'returns false if the given key is nil' do + expect(event_filter.active?(nil)).to eq(false) end - it 'applies unknown filter' do - events = described_class.new('').apply_filter(Event.all) - expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event) + it 'returns true if filter does not include the given key' do + expect(event_filter.active?(described_class::TEAM)).to eq(true) end end end diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb index 48c0ba8a653..9d56c62ae57 100644 --- a/spec/lib/feature_spec.rb +++ b/spec/lib/feature_spec.rb @@ -91,7 +91,11 @@ describe Feature do end describe '.flipper' do - shared_examples 'a memoized Flipper instance' do + before do + described_class.instance_variable_set(:@flipper, nil) + end + + context 'when request store is inactive' do it 'memoizes the Flipper instance' do expect(Flipper).to receive(:new).once.and_call_original @@ -101,16 +105,14 @@ describe Feature do end end - context 'when request store is inactive' do - before do + context 'when request store is active', :request_store do + it 'memoizes the Flipper instance' do + expect(Flipper).to receive(:new).once.and_call_original + + described_class.flipper described_class.instance_variable_set(:@flipper, nil) + described_class.flipper end - - it_behaves_like 'a memoized Flipper instance' - end - - context 'when request store is inactive', :request_store do - it_behaves_like 'a memoized Flipper instance' end end diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb index 7800c543cdb..662f899180b 100644 --- a/spec/lib/gitlab/auth/ldap/access_spec.rb +++ b/spec/lib/gitlab/auth/ldap/access_spec.rb @@ -48,7 +48,7 @@ describe Gitlab::Auth::LDAP::Access do 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})" + "blocking GitLab user \"#{user.name}\" (#{user.email})" ) access.allowed? @@ -79,7 +79,7 @@ describe Gitlab::Auth::LDAP::Access do 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})" + "blocking GitLab user \"#{user.name}\" (#{user.email})" ) access.allowed? @@ -123,7 +123,7 @@ describe Gitlab::Auth::LDAP::Access do 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})" + "unblocking GitLab user \"#{user.name}\" (#{user.email})" ) access.allowed? @@ -161,7 +161,7 @@ describe Gitlab::Auth::LDAP::Access do 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})" + "blocking GitLab user \"#{user.name}\" (#{user.email})" ) access.allowed? @@ -183,7 +183,7 @@ describe Gitlab::Auth::LDAP::Access do 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})" + "unblocking GitLab user \"#{user.name}\" (#{user.email})" ) access.allowed? diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb index b3a3a6bee1d..e5fc36b5d7a 100644 --- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb @@ -3,27 +3,53 @@ require 'spec_helper' describe Gitlab::Ci::Config::Entry::Reports do let(:entry) { described_class.new(config) } + describe 'validates ALLOWED_KEYS' do + let(:artifact_file_types) { Ci::JobArtifact.file_types } + + described_class::ALLOWED_KEYS.each do |keyword, _| + it "expects #{keyword} to be an artifact file_type" do + expect(artifact_file_types).to include(keyword) + end + end + end + describe 'validation' do context 'when entry config value is correct' do - let(:config) { { junit: %w[junit.xml] } } + using RSpec::Parameterized::TableSyntax - describe '#value' do - it 'returns artifacs configuration' do - expect(entry.value).to eq config + shared_examples 'a valid entry' do |keyword, file| + describe '#value' do + it 'returns artifacs configuration' do + expect(entry.value).to eq({ "#{keyword}": [file] } ) + end end - end - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end end end - context 'when value is not array' do - let(:config) { { junit: 'junit.xml' } } + where(:keyword, :file) do + :junit | 'junit.xml' + :sast | 'gl-sast-report.json' + :dependency_scanning | 'gl-dependency-scanning-report.json' + :container_scanning | 'gl-container-scanning-report.json' + :dast | 'gl-dast-report.json' + end + + with_them do + context 'when value is an array' do + let(:config) { { "#{keyword}": [file] } } - it 'converts to array' do - expect(entry.value).to eq({ junit: ['junit.xml'] } ) + it_behaves_like 'a valid entry', params[:keyword], params[:file] + end + + context 'when value is not array' do + let(:config) { { "#{keyword}": file } } + + it_behaves_like 'a valid entry', params[:keyword], params[:file] end end end @@ -31,11 +57,13 @@ describe Gitlab::Ci::Config::Entry::Reports do context 'when entry value is not correct' do describe '#errors' do context 'when value of attribute is invalid' do - let(:config) { { junit: 10 } } + where(key: described_class::ALLOWED_KEYS) do + let(:config) { { "#{key}": 10 } } - it 'reports error' do - expect(entry.errors) - .to include 'reports junit should be an array of strings or a string' + it 'reports error' do + expect(entry.errors) + .to include "reports #{key} should be an array of strings or a string" + end end end diff --git a/spec/lib/gitlab/ci/external/file/local_spec.rb b/spec/lib/gitlab/ci/external/file/local_spec.rb index 3f32d81a827..73bb4ccf468 100644 --- a/spec/lib/gitlab/ci/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/external/file/local_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::Ci::External::File::Local do describe '#valid?' do context 'when is a valid local path' do - let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' } + let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' } before do allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("image: 'ruby2:2'") @@ -20,7 +20,7 @@ describe Gitlab::Ci::External::File::Local do end context 'when is not a valid local path' do - let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' } + let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' } it 'should return false' do expect(local_file.valid?).to be_falsy @@ -48,7 +48,7 @@ describe Gitlab::Ci::External::File::Local do - bundle install --jobs $(nproc) "${FLAGS[@]}" HEREDOC end - let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' } + let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' } before do allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return(local_file_content) @@ -60,7 +60,7 @@ describe Gitlab::Ci::External::File::Local do end context 'with an invalid file' do - let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' } + let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' } it 'should be nil' do expect(local_file.content).to be_nil @@ -69,7 +69,7 @@ describe Gitlab::Ci::External::File::Local do end describe '#error_message' do - let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' } + let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' } it 'should return an error message' do expect(local_file.error_message).to eq("Local file '#{location}' is not valid.") diff --git a/spec/lib/gitlab/ci/external/mapper_spec.rb b/spec/lib/gitlab/ci/external/mapper_spec.rb index 6270d27a36d..d925d6af73d 100644 --- a/spec/lib/gitlab/ci/external/mapper_spec.rb +++ b/spec/lib/gitlab/ci/external/mapper_spec.rb @@ -17,7 +17,7 @@ describe Gitlab::Ci::External::Mapper do context 'when the string is a local file' do let(:values) do { - include: '/vendor/gitlab-ci-yml/non-existent-file.yml', + include: '/lib/gitlab/ci/templates/non-existent-file.yml', image: 'ruby:2.2' } end @@ -61,7 +61,7 @@ describe Gitlab::Ci::External::Mapper do include: [ remote_url, - '/vendor/gitlab-ci-yml/template.yml' + '/lib/gitlab/ci/templates/template.yml' ], image: 'ruby:2.2' } diff --git a/spec/lib/gitlab/ci/external/processor_spec.rb b/spec/lib/gitlab/ci/external/processor_spec.rb index 688c2b3c8aa..3c7394f53d2 100644 --- a/spec/lib/gitlab/ci/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/external/processor_spec.rb @@ -16,12 +16,12 @@ describe Gitlab::Ci::External::Processor do end context 'when an invalid local file is defined' do - let(:values) { { include: '/vendor/gitlab-ci-yml/non-existent-file.yml', image: 'ruby:2.2' } } + let(:values) { { include: '/lib/gitlab/ci/templates/non-existent-file.yml', image: 'ruby:2.2' } } it 'should raise an error' do expect { processor.perform }.to raise_error( described_class::FileError, - "Local file '/vendor/gitlab-ci-yml/non-existent-file.yml' is not valid." + "Local file '/lib/gitlab/ci/templates/non-existent-file.yml' is not valid." ) end end @@ -79,7 +79,7 @@ describe Gitlab::Ci::External::Processor do end context 'with a valid local external file is defined' do - let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } } + let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } } let(:local_file_content) do <<-HEREDOC before_script: @@ -145,7 +145,7 @@ describe Gitlab::Ci::External::Processor do end context 'when external files are defined but not valid' do - let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } } + let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } } let(:local_file_content) { 'invalid content file ////' } diff --git a/spec/lib/gitlab/ci/parsers/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb index 47497f06229..a49402c7398 100644 --- a/spec/lib/gitlab/ci/parsers/junit_spec.rb +++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb @@ -1,6 +1,6 @@ require 'fast_spec_helper' -describe Gitlab::Ci::Parsers::Junit do +describe Gitlab::Ci::Parsers::Test::Junit do describe '#parse!' do subject { described_class.new.parse!(junit, test_suite) } diff --git a/spec/lib/gitlab/ci/parsers_spec.rb b/spec/lib/gitlab/ci/parsers/test_spec.rb index 2fa83c4abae..0b85b432677 100644 --- a/spec/lib/gitlab/ci/parsers_spec.rb +++ b/spec/lib/gitlab/ci/parsers/test_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Ci::Parsers do +describe Gitlab::Ci::Parsers::Test do describe '.fabricate!' do subject { described_class.fabricate!(file_type) } @@ -16,7 +16,7 @@ describe Gitlab::Ci::Parsers do let(:file_type) { 'undefined' } it 'raises an error' do - expect { subject }.to raise_error(NameError) + expect { subject }.to raise_error(Gitlab::Ci::Parsers::Test::ParserNotFoundError) end end end diff --git a/spec/lib/gitlab/ci/templates/templates_spec.rb b/spec/lib/gitlab/ci/templates/templates_spec.rb new file mode 100644 index 00000000000..0dd74399a47 --- /dev/null +++ b/spec/lib/gitlab/ci/templates/templates_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe "CI YML Templates" do + Gitlab::Template::GitlabCiYmlTemplate.all.each do |template| + it "#{template.name} should be valid" do + expect { Gitlab::Ci::YamlProcessor.new(template.content) }.not_to raise_error + end + end +end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index fcbdf71a4e9..a2d429fa859 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -1371,18 +1371,6 @@ module Gitlab end end - describe "Validate configuration templates" do - templates = Dir.glob("#{Rails.root.join('vendor/gitlab-ci-yml')}/**/*.gitlab-ci.yml") - - templates.each do |file| - it "does not return errors for #{file}" do - file = File.read(file) - - expect { Gitlab::Ci::YamlProcessor.new(file) }.not_to raise_error - end - end - end - describe "#validation_message" do subject { Gitlab::Ci::YamlProcessor.validation_message(content) } diff --git a/spec/lib/gitlab/database/subquery_spec.rb b/spec/lib/gitlab/database/subquery_spec.rb new file mode 100644 index 00000000000..70380e02f16 --- /dev/null +++ b/spec/lib/gitlab/database/subquery_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::Subquery do + describe '.self_join' do + set(:project) { create(:project) } + + it 'allows you to delete_all rows with WHERE and LIMIT' do + events = create_list(:event, 8, project: project) + + expect do + described_class.self_join(Event.where('id < ?', events[5]).recent.limit(2)).delete_all + end.to change { Event.count }.by(-2) + end + end +end diff --git a/spec/lib/gitlab/git/hook_env_spec.rb b/spec/lib/gitlab/git/hook_env_spec.rb index e6aa5ad8c90..5e49ea6da7a 100644 --- a/spec/lib/gitlab/git/hook_env_spec.rb +++ b/spec/lib/gitlab/git/hook_env_spec.rb @@ -4,11 +4,7 @@ describe Gitlab::Git::HookEnv do let(:gl_repository) { 'project-123' } describe ".set" do - context 'with RequestStore.store disabled' do - before do - allow(RequestStore).to receive(:active?).and_return(false) - end - + context 'with RequestStore disabled' do it 'does not store anything' do described_class.set(gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'foo') @@ -16,11 +12,7 @@ describe Gitlab::Git::HookEnv do end end - context 'with RequestStore.store enabled' do - before do - allow(RequestStore).to receive(:active?).and_return(true) - end - + context 'with RequestStore enabled', :request_store do it 'whitelist some `GIT_*` variables and stores them using RequestStore' do described_class.set( gl_repository, @@ -41,9 +33,8 @@ describe Gitlab::Git::HookEnv do end describe ".all" do - context 'with RequestStore.store enabled' do + context 'with RequestStore enabled', :request_store do before do - allow(RequestStore).to receive(:active?).and_return(true) described_class.set( gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'foo', @@ -60,7 +51,7 @@ describe Gitlab::Git::HookEnv do end describe ".to_env_hash" do - context 'with RequestStore.store enabled' do + context 'with RequestStore enabled', :request_store do using RSpec::Parameterized::TableSyntax let(:key) { 'GIT_OBJECT_DIRECTORY_RELATIVE' } @@ -76,7 +67,6 @@ describe Gitlab::Git::HookEnv do with_them do before do - allow(RequestStore).to receive(:active?).and_return(true) described_class.set(gl_repository, key.to_sym => input) end @@ -92,7 +82,7 @@ describe Gitlab::Git::HookEnv do end describe 'thread-safety' do - context 'with RequestStore.store enabled' do + context 'with RequestStore enabled', :request_store do before do allow(RequestStore).to receive(:active?).and_return(true) described_class.set(gl_repository, GIT_OBJECT_DIRECTORY_RELATIVE: 'foo') diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index eefd00e7383..3f2281f213f 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -6143,7 +6143,7 @@ "id": 36, "project_id": 5, "ref": "master", - "sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "sha": "sha-notes", "before_sha": null, "push_data": null, "created_at": "2016-03-22T15:20:35.755Z", @@ -6154,6 +6154,7 @@ "status": "failed", "started_at": null, "finished_at": null, + "user_id": 9999, "duration": null, "notes": [ { @@ -6353,6 +6354,7 @@ }, { "id": 38, + "iid": 1, "project_id": 5, "ref": "master", "sha": "5f923865dde3436854e9ceb9cdb7815618d4e849", diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index 3ff6be595a8..7ebfc61f5e7 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -59,7 +59,11 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do end it 'creates a valid pipeline note' do - expect(Ci::Pipeline.first.notes).not_to be_empty + expect(Ci::Pipeline.find_by_sha('sha-notes').notes).not_to be_empty + end + + it 'pipeline has the correct user ID' do + expect(Ci::Pipeline.find_by_sha('sha-notes').user_id).to eq(@user.id) end it 'restores pipelines with missing ref' do diff --git a/spec/lib/gitlab/middleware/read_only_spec.rb b/spec/lib/gitlab/middleware/read_only_spec.rb index 8fbeaa065fa..ac3bc6b2dfe 100644 --- a/spec/lib/gitlab/middleware/read_only_spec.rb +++ b/spec/lib/gitlab/middleware/read_only_spec.rb @@ -34,7 +34,7 @@ describe Gitlab::Middleware::ReadOnly do end end - context 'normal requests to a read-only Gitlab instance' do + context 'normal requests to a read-only GitLab instance' do let(:fake_app) { lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ['OK']] } } before do diff --git a/spec/lib/gitlab/null_request_store_spec.rb b/spec/lib/gitlab/null_request_store_spec.rb new file mode 100644 index 00000000000..c023dac53ad --- /dev/null +++ b/spec/lib/gitlab/null_request_store_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::NullRequestStore do + let(:null_store) { described_class.new } + + describe '#store' do + it 'returns an empty hash' do + expect(null_store.store).to eq({}) + end + end + + describe '#active?' do + it 'returns falsey' do + expect(null_store.active?).to be_falsey + end + end + + describe '#read' do + it 'returns nil' do + expect(null_store.read('foo')).to be nil + end + end + + describe '#[]' do + it 'returns nil' do + expect(null_store['foo']).to be nil + end + end + + describe '#write' do + it 'returns the same value' do + expect(null_store.write('key', 'value')).to eq('value') + end + end + + describe '#[]=' do + it 'returns the same value' do + expect(null_store['key'] = 'value').to eq('value') + end + end + + describe '#exist?' do + it 'returns falsey' do + expect(null_store.exist?('foo')).to be_falsey + end + end + + describe '#fetch' do + it 'returns the block result' do + expect(null_store.fetch('key') { 'block result' }).to eq('block result') + end + end + + describe '#delete' do + context 'when a block is given' do + it 'yields the key to the block' do + expect do |b| + null_store.delete('foo', &b) + end.to yield_with_args('foo') + end + + it 'returns the block result' do + expect(null_store.delete('foo') { |key| 'block result' }).to eq('block result') + end + end + + context 'when a block is not given' do + it 'returns nil' do + expect(null_store.delete('foo')).to be nil + end + end + end +end diff --git a/spec/lib/gitlab/repository_cache_adapter_spec.rb b/spec/lib/gitlab/repository_cache_adapter_spec.rb index 5bd4d6c6a48..0295138fc3a 100644 --- a/spec/lib/gitlab/repository_cache_adapter_spec.rb +++ b/spec/lib/gitlab/repository_cache_adapter_spec.rb @@ -65,6 +65,144 @@ describe Gitlab::RepositoryCacheAdapter do end end + describe '#cache_method_output_asymmetrically', :use_clean_rails_memory_store_caching, :request_store do + let(:request_store_cache) { repository.send(:request_store_cache) } + + context 'with a non-existing repository' do + let(:project) { create(:project) } # No repository + let(:object) { double } + + subject do + repository.cache_method_output_asymmetrically(:cats) do + object.cats_call_stub + end + end + + it 'returns the output of the original method' do + expect(object).to receive(:cats_call_stub).and_return('output') + + expect(subject).to eq('output') + end + end + + context 'with a method throwing a non-existing-repository error' do + subject do + repository.cache_method_output_asymmetrically(:cats) do + raise Gitlab::Git::Repository::NoRepository + end + end + + it 'returns nil' do + expect(subject).to eq(nil) + end + + it 'does not cache the data' do + subject + + expect(repository.instance_variable_defined?(:@cats)).to eq(false) + expect(cache.exist?(:cats)).to eq(false) + end + end + + context 'with an existing repository' do + let(:object) { double } + + context 'when it returns truthy' do + before do + expect(object).to receive(:cats).once.and_return('truthy output') + end + + it 'caches the output in RequestStore' do + expect do + repository.cache_method_output_asymmetrically(:cats) { object.cats } + end.to change { request_store_cache.read(:cats) }.from(nil).to('truthy output') + end + + it 'caches the output in RepositoryCache' do + expect do + repository.cache_method_output_asymmetrically(:cats) { object.cats } + end.to change { cache.read(:cats) }.from(nil).to('truthy output') + end + end + + context 'when it returns false' do + before do + expect(object).to receive(:cats).once.and_return(false) + end + + it 'caches the output in RequestStore' do + expect do + repository.cache_method_output_asymmetrically(:cats) { object.cats } + end.to change { request_store_cache.read(:cats) }.from(nil).to(false) + end + + it 'does NOT cache the output in RepositoryCache' do + expect do + repository.cache_method_output_asymmetrically(:cats) { object.cats } + end.not_to change { cache.read(:cats) }.from(nil) + end + end + end + end + + describe '#memoize_method_output' do + let(:fallback) { 10 } + + context 'with a non-existing repository' do + let(:project) { create(:project) } # No repository + + subject do + repository.memoize_method_output(:cats, fallback: fallback) do + repository.cats_call_stub + end + end + + it 'returns the fallback value' do + expect(subject).to eq(fallback) + end + + it 'avoids calling the original method' do + expect(repository).not_to receive(:cats_call_stub) + + subject + end + + it 'does not set the instance variable' do + subject + + expect(repository.instance_variable_defined?(:@cats)).to eq(false) + end + end + + context 'with a method throwing a non-existing-repository error' do + subject do + repository.memoize_method_output(:cats, fallback: fallback) do + raise Gitlab::Git::Repository::NoRepository + end + end + + it 'returns the fallback value' do + expect(subject).to eq(fallback) + end + + it 'does not set the instance variable' do + subject + + expect(repository.instance_variable_defined?(:@cats)).to eq(false) + end + end + + context 'with an existing repository' do + it 'sets the instance variable' do + repository.memoize_method_output(:cats, fallback: fallback) do + 'block output' + end + + expect(repository.instance_variable_get(:@cats)).to eq('block output') + end + end + end + describe '#expire_method_caches' do it 'expires the caches of the given methods' do expect(cache).to receive(:expire).with(:rendered_readme) diff --git a/spec/lib/gitlab/repository_cache_spec.rb b/spec/lib/gitlab/repository_cache_spec.rb index fc259cf1208..741ee12633f 100644 --- a/spec/lib/gitlab/repository_cache_spec.rb +++ b/spec/lib/gitlab/repository_cache_spec.rb @@ -47,4 +47,89 @@ describe Gitlab::RepositoryCache do expect(backend).to have_received(:fetch).with("baz:#{namespace}", &p) end end + + describe '#fetch_without_caching_false', :use_clean_rails_memory_store_caching do + let(:key) { :foo } + let(:backend) { Rails.cache } + + it 'requires a block' do + expect do + cache.fetch_without_caching_false(key) + end.to raise_error(LocalJumpError) + end + + context 'when the key does not exist in the cache' do + context 'when the result of the block is truthy' do + it 'returns the result of the block' do + result = cache.fetch_without_caching_false(key) { true } + + expect(result).to be true + end + + it 'caches the value' do + expect(backend).to receive(:write).with("#{key}:#{namespace}", true) + + cache.fetch_without_caching_false(key) { true } + end + end + + context 'when the result of the block is falsey' do + let(:p) { -> { false } } + + it 'returns the result of the block' do + result = cache.fetch_without_caching_false(key, &p) + + expect(result).to be false + end + + it 'does not cache the value' do + expect(backend).not_to receive(:write).with("#{key}:#{namespace}", true) + + cache.fetch_without_caching_false(key, &p) + end + end + end + + context 'when the cached value is truthy' do + before do + backend.write("#{key}:#{namespace}", true) + end + + it 'returns the cached value' do + result = cache.fetch_without_caching_false(key) { 'block result' } + + expect(result).to be true + end + + it 'does not execute the block' do + expect do |b| + cache.fetch_without_caching_false(key, &b) + end.not_to yield_control + end + + it 'does not write to the cache' do + expect(backend).not_to receive(:write) + + cache.fetch_without_caching_false(key) { 'block result' } + end + end + + context 'when the cached value is falsey' do + before do + backend.write("#{key}:#{namespace}", false) + end + + it 'returns the result of the block' do + result = cache.fetch_without_caching_false(key) { 'block result' } + + expect(result).to eq 'block result' + end + + it 'writes the truthy value to the cache' do + expect(backend).to receive(:write).with("#{key}:#{namespace}", 'block result') + + cache.fetch_without_caching_false(key) { 'block result' } + end + end + end end diff --git a/spec/lib/gitlab/safe_request_store_spec.rb b/spec/lib/gitlab/safe_request_store_spec.rb new file mode 100644 index 00000000000..c797171dbe2 --- /dev/null +++ b/spec/lib/gitlab/safe_request_store_spec.rb @@ -0,0 +1,245 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::SafeRequestStore do + describe '.store' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect(described_class.store).to eq(RequestStore) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect(described_class.store).to be_a(Gitlab::NullRequestStore) + end + end + end + + describe '.begin!' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect(RequestStore).to receive(:begin!) + + described_class.begin! + end + end + + context 'when RequestStore is NOT active' do + it 'uses RequestStore' do + expect(RequestStore).to receive(:begin!) + + described_class.begin! + end + end + end + + describe '.clear!' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect(RequestStore).to receive(:clear!).twice.and_call_original + + described_class.clear! + end + end + + context 'when RequestStore is NOT active' do + it 'uses RequestStore' do + expect(RequestStore).to receive(:clear!).and_call_original + + described_class.clear! + end + end + end + + describe '.end!' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect(RequestStore).to receive(:end!).twice.and_call_original + + described_class.end! + end + end + + context 'when RequestStore is NOT active' do + it 'uses RequestStore' do + expect(RequestStore).to receive(:end!).and_call_original + + described_class.end! + end + end + end + + describe '.write' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + described_class.write('foo', true) + end.to change { described_class.read('foo') }.from(nil).to(true) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect do + described_class.write('foo', true) + end.not_to change { described_class.read('foo') }.from(nil) + end + end + end + + describe '.[]=' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + described_class['foo'] = true + end.to change { described_class.read('foo') }.from(nil).to(true) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect do + described_class['foo'] = true + end.not_to change { described_class.read('foo') }.from(nil) + end + end + end + + describe '.read' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + RequestStore.write('foo', true) + end.to change { described_class.read('foo') }.from(nil).to(true) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect do + RequestStore.write('foo', true) + end.not_to change { described_class.read('foo') }.from(nil) + + RequestStore.clear! # Clean up + end + end + end + + describe '.[]' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + RequestStore.write('foo', true) + end.to change { described_class['foo'] }.from(nil).to(true) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect do + RequestStore.write('foo', true) + end.not_to change { described_class['foo'] }.from(nil) + + RequestStore.clear! # Clean up + end + end + end + + describe '.exist?' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + RequestStore.write('foo', 'not nil') + end.to change { described_class.exist?('foo') }.from(false).to(true) + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + expect do + RequestStore.write('foo', 'not nil') + end.not_to change { described_class.exist?('foo') }.from(false) + + RequestStore.clear! # Clean up + end + end + end + + describe '.fetch' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + expect do + described_class.fetch('foo') { 'block result' } + end.to change { described_class.read('foo') }.from(nil).to('block result') + end + end + + context 'when RequestStore is NOT active' do + it 'does not use RequestStore' do + RequestStore.clear! # Ensure clean + + expect do + described_class.fetch('foo') { 'block result' } + end.not_to change { described_class.read('foo') }.from(nil) + + RequestStore.clear! # Clean up + end + end + end + + describe '.delete' do + context 'when RequestStore is active', :request_store do + it 'uses RequestStore' do + described_class.write('foo', true) + + expect do + described_class.delete('foo') + end.to change { described_class.read('foo') }.from(true).to(nil) + end + + context 'when given a block and the key exists' do + it 'does not execute the block' do + described_class.write('foo', true) + + expect do |b| + described_class.delete('foo', &b) + end.not_to yield_control + end + end + + context 'when given a block and the key does not exist' do + it 'yields the key and returns the block result' do + result = described_class.delete('foo') { |key| "#{key} block result" } + + expect(result).to eq('foo block result') + end + end + end + + context 'when RequestStore is NOT active' do + before do + RequestStore.write('foo', true) + end + + after do + RequestStore.clear! # Clean up + end + + it 'does not use RequestStore' do + expect do + described_class.delete('foo') + end.not_to change { RequestStore.read('foo') }.from(true) + end + + context 'when given a block' do + it 'yields the key and returns the block result' do + result = described_class.delete('foo') { |key| "#{key} block result" } + + expect(result).to eq('foo block result') + end + end + end + end +end diff --git a/spec/lib/gitlab/sidekiq_throttler_spec.rb b/spec/lib/gitlab/sidekiq_throttler_spec.rb deleted file mode 100644 index 2dbb7bb7c34..00000000000 --- a/spec/lib/gitlab/sidekiq_throttler_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' - -describe Gitlab::SidekiqThrottler do - describe '#execute!' do - context 'when job throttling is enabled' do - before do - Sidekiq.options[:concurrency] = 35 - - stub_application_setting( - sidekiq_throttling_enabled: true, - sidekiq_throttling_factor: 0.1, - sidekiq_throttling_queues: %w[build project_cache] - ) - end - - it 'requires sidekiq-limit_fetch' do - expect(described_class).to receive(:require).with('sidekiq-limit_fetch').and_call_original - - described_class.execute! - end - - it 'sets limits on the selected queues' do - described_class.execute! - - expect(Sidekiq::Queue['build'].limit).to eq 4 - expect(Sidekiq::Queue['project_cache'].limit).to eq 4 - end - - it 'does not set limits on other queues' do - described_class.execute! - - expect(Sidekiq::Queue['merge'].limit).to be_nil - end - end - - context 'when job throttling is disabled' do - it 'does not require sidekiq-limit_fetch' do - expect(described_class).not_to receive(:require).with('sidekiq-limit_fetch') - - described_class.execute! - end - end - end -end diff --git a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb index e2fa76522bc..fe46c67a920 100644 --- a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb +++ b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb @@ -40,7 +40,7 @@ describe Gitlab::Template::GitlabCiYmlTemplate do describe '#content' do it 'loads the full file' do - gitignore = subject.new(Rails.root.join('vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml')) + gitignore = subject.new(Rails.root.join('lib/gitlab/ci/templates/Ruby.gitlab-ci.yml')) expect(gitignore.name).to eq 'Ruby' expect(gitignore.content).to start_with('#') diff --git a/spec/lib/quality/helm_client_spec.rb b/spec/lib/quality/helm_client_spec.rb new file mode 100644 index 00000000000..553cd8719de --- /dev/null +++ b/spec/lib/quality/helm_client_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Quality::HelmClient do + let(:namespace) { 'review-apps-ee' } + let(:release_name) { 'my-release' } + let(:raw_helm_list_result) do + <<~OUTPUT + NAME REVISION UPDATED STATUS CHART NAMESPACE + review-improve-re-2dsd9d 1 Tue Jul 31 15:53:17 2018 FAILED gitlab-0.3.4 #{namespace} + review-11-1-stabl-3r2fso 1 Mon Jul 30 22:44:14 2018 FAILED gitlab-0.3.3 #{namespace} + review-49375-css-fk664j 1 Thu Jul 19 11:01:30 2018 FAILED gitlab-0.2.4 #{namespace} + OUTPUT + end + + subject { described_class.new(namespace: namespace) } + + describe '#releases' do + it 'calls helm list with default arguments' do + expect(Gitlab::Popen).to receive(:popen_with_detail) + .with([%(helm list --namespace "#{namespace}")]) + .and_return(Gitlab::Popen::Result.new([], '')) + + subject.releases + end + + it 'calls helm list with given arguments' do + expect(Gitlab::Popen).to receive(:popen_with_detail) + .with([%(helm list --namespace "#{namespace}" --deployed)]) + .and_return(Gitlab::Popen::Result.new([], '')) + + subject.releases(args: ['--deployed']) + end + + it 'returns a list of Release objects' do + expect(Gitlab::Popen).to receive(:popen_with_detail) + .with([%(helm list --namespace "#{namespace}" --deployed)]) + .and_return(Gitlab::Popen::Result.new([], raw_helm_list_result)) + + releases = subject.releases(args: ['--deployed']) + + expect(releases.size).to eq(3) + expect(releases[0].name).to eq('review-improve-re-2dsd9d') + expect(releases[0].revision).to eq(1) + expect(releases[0].last_update).to eq(Time.parse('Tue Jul 31 15:53:17 2018')) + expect(releases[0].status).to eq('FAILED') + expect(releases[0].chart).to eq('gitlab-0.3.4') + expect(releases[0].namespace).to eq(namespace) + end + end + + describe '#delete' do + it 'calls helm delete with default arguments' do + expect(Gitlab::Popen).to receive(:popen_with_detail) + .with(["helm delete --purge #{release_name}"]) + .and_return(Gitlab::Popen::Result.new([], '', '', 0)) + + expect(subject.delete(release_name: release_name).status).to eq(0) + end + end +end diff --git a/spec/lib/quality/kubernetes_client_spec.rb b/spec/lib/quality/kubernetes_client_spec.rb new file mode 100644 index 00000000000..3c0c0d0977a --- /dev/null +++ b/spec/lib/quality/kubernetes_client_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Quality::KubernetesClient do + subject { described_class.new(namespace: 'review-apps-ee') } + + describe '#cleanup' do + it 'calls kubectl with the correct arguments' do + # popen_with_detail will receive an array with a bunch of arguments; we're + # only concerned with it having the correct namespace and release name + expect(Gitlab::Popen).to receive(:popen_with_detail) do |args| + expect(args) + .to satisfy_one { |arg| arg.start_with?('-n "review-apps-ee" get') } + expect(args) + .to satisfy_one { |arg| arg == 'grep "my-release"' } + expect(args) + .to satisfy_one { |arg| arg.end_with?('-n "review-apps-ee" delete') } + end + + # We're not verifying the output here, just silencing it + expect { subject.cleanup(release_name: 'my-release') }.to output.to_stdout + end + end +end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index dbebda20ce0..e82d93d5935 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -176,9 +176,7 @@ describe Ci::Build do it 'does not execute a query for selecting job artifact one by one' do recorded = ActiveRecord::QueryRecorder.new do subject.each do |build| - Ci::JobArtifact::TEST_REPORT_FILE_TYPES.each do |file_type| - build.public_send("job_artifacts_#{file_type}").file.exists? - end + build.job_artifacts.map { |a| a.file.exists? } end end @@ -550,44 +548,22 @@ describe Ci::Build do end end - describe '#has_test_reports?' do - subject { build.has_test_reports? } + describe '#has_job_artifacts?' do + subject { build.has_job_artifacts? } - context 'when build has a test report' do - let(:build) { create(:ci_build, :test_reports) } + context 'when build has a job artifact' do + let(:build) { create(:ci_build, :artifacts) } it { is_expected.to be_truthy } end - context 'when build does not have test reports' do - let(:build) { create(:ci_build, :artifacts) } + context 'when build does not have job artifacts' do + let(:build) { create(:ci_build, :legacy_artifacts) } it { is_expected.to be_falsy } end end - describe '#erase_test_reports!' do - subject { build.erase_test_reports! } - - context 'when build has a test report' do - let!(:build) { create(:ci_build, :test_reports) } - - it 'removes a test report' do - subject - - expect(build.has_test_reports?).to be_falsy - end - end - - context 'when build does not have test reports' do - let!(:build) { create(:ci_build, :artifacts) } - - it 'does not erase anything' do - expect { subject }.not_to change { Ci::JobArtifact.count } - end - end - end - describe '#has_old_trace?' do subject { build.has_old_trace? } @@ -850,8 +826,8 @@ describe Ci::Build do expect(build.artifacts_metadata.exists?).to be_falsy end - it 'removes test reports' do - expect(build.job_artifacts.test_reports.count).to eq(0) + it 'removes all job_artifacts' do + expect(build.job_artifacts.count).to eq(0) end it 'erases build trace in trace file' do @@ -1022,6 +998,32 @@ describe Ci::Build do end end + describe '#erase_erasable_artifacts!' do + let!(:build) { create(:ci_build, :success) } + + subject { build.erase_erasable_artifacts! } + + before do + Ci::JobArtifact.file_types.keys.each do |file_type| + create(:ci_job_artifact, job: build, file_type: file_type, file_format: Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS[file_type.to_sym]) + end + end + + it "erases erasable artifacts" do + subject + + expect(build.job_artifacts.erasable).to be_empty + end + + it "keeps non erasable artifacts" do + subject + + Ci::JobArtifact::NON_ERASABLE_FILE_TYPES.each do |file_type| + expect(build.send("job_artifacts_#{file_type}")).not_to be_nil + end + end + end + describe '#first_pending' do let!(:first) { create(:ci_build, pipeline: pipeline, status: 'pending', created_at: Date.yesterday) } let!(:second) { create(:ci_build, pipeline: pipeline, status: 'pending') } @@ -2844,16 +2846,10 @@ describe Ci::Build do end it 'raises an error' do - expect { subject }.to raise_error(Gitlab::Ci::Parsers::Junit::JunitParserError) + expect { subject }.to raise_error(Gitlab::Ci::Parsers::Test::Junit::JunitParserError) end end end - - context 'when build does not have test reports' do - it 'raises an error' do - expect { subject }.to raise_error(NoMethodError) - end - end end describe '#artifacts_metadata_entry' do diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb index 1bf338f4c70..2f449d617be 100644 --- a/spec/models/ci/job_artifact_spec.rb +++ b/spec/models/ci/job_artifact_spec.rb @@ -31,6 +31,22 @@ describe Ci::JobArtifact do end end + describe '.erasable' do + subject { described_class.erasable } + + context 'when there is am erasable artifact' do + let!(:artifact) { create(:ci_job_artifact, :junit) } + + it { is_expected.to eq([artifact]) } + end + + context 'when there are no erasable artifacts' do + let!(:artifact) { create(:ci_job_artifact, :trace) } + + it { is_expected.to be_empty } + end + end + describe 'callbacks' do subject { create(:ci_job_artifact, :archive) } @@ -106,34 +122,46 @@ describe Ci::JobArtifact do describe 'validates file format' do subject { artifact } - context 'when archive type with zip format' do - let(:artifact) { build(:ci_job_artifact, :archive, file_format: :zip) } + described_class::TYPE_AND_FORMAT_PAIRS.except(:trace).each do |file_type, file_format| + context "when #{file_type} type with #{file_format} format" do + let(:artifact) { build(:ci_job_artifact, file_type: file_type, file_format: file_format) } - it { is_expected.to be_valid } - end + it { is_expected.to be_valid } + end - context 'when archive type with gzip format' do - let(:artifact) { build(:ci_job_artifact, :archive, file_format: :gzip) } + context "when #{file_type} type without format specification" do + let(:artifact) { build(:ci_job_artifact, file_type: file_type, file_format: nil) } - it { is_expected.not_to be_valid } - end + it { is_expected.not_to be_valid } + end - context 'when archive type without format specification' do - let(:artifact) { build(:ci_job_artifact, :archive, file_format: nil) } + context "when #{file_type} type with other formats" do + described_class.file_formats.except(file_format).values.each do |other_format| + let(:artifact) { build(:ci_job_artifact, file_type: file_type, file_format: other_format) } - it { is_expected.not_to be_valid } + it { is_expected.not_to be_valid } + end + end end + end - context 'when junit type with zip format' do - let(:artifact) { build(:ci_job_artifact, :junit, file_format: :zip) } + describe 'validates DEFAULT_FILE_NAMES' do + subject { described_class::DEFAULT_FILE_NAMES } - it { is_expected.not_to be_valid } + described_class.file_types.each do |file_type, _| + it "expects #{file_type} to be included" do + is_expected.to include(file_type.to_sym) + end end + end - context 'when junit type with gzip format' do - let(:artifact) { build(:ci_job_artifact, :junit, file_format: :gzip) } + describe 'validates TYPE_AND_FORMAT_PAIRS' do + subject { described_class::TYPE_AND_FORMAT_PAIRS } - it { is_expected.to be_valid } + described_class.file_types.each do |file_type, _| + it "expects #{file_type} to be included" do + expect(described_class.file_formats).to include(subject[file_type.to_sym]) + end end end diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb index 591a01d78a9..9c4396731eb 100644 --- a/spec/models/clusters/applications/jupyter_spec.rb +++ b/spec/models/clusters/applications/jupyter_spec.rb @@ -108,8 +108,15 @@ describe Clusters::Applications::Jupyter do expect(values).to include('rbac') expect(values).to include('proxy') expect(values).to include('auth') + expect(values).to include('singleuser') expect(values).to match(/clientId: '?#{application.oauth_application.uid}/) expect(values).to match(/callbackUrl: '?#{application.callback_url}/) end + + context 'when cluster belongs to a project' do + it 'sets GitLab project id' do + expect(values).to match(/GITLAB_CLUSTER_ID: '?#{application.cluster.id}/) + end + end end end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index d5f88e930d4..ed41ff7a0fa 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -65,7 +65,7 @@ describe Commit do key = "Commit:author:#{commit.author_email.downcase}" - expect(RequestStore.store[key]).to eq(user) + expect(Gitlab::SafeRequestStore[key]).to eq(user) expect(commit.author).to eq(user) end @@ -270,11 +270,11 @@ eos let(:issue) { create :issue, project: project } let(:other_project) { create(:project, :public) } let(:other_issue) { create :issue, project: other_project } - let(:commiter) { create :user } + let(:committer) { create :user } before do - project.add_developer(commiter) - other_project.add_developer(commiter) + project.add_developer(committer) + other_project.add_developer(committer) end it 'detects issues that this commit is marked as closing' do @@ -282,7 +282,7 @@ eos allow(commit).to receive_messages( safe_message: "Fixes ##{issue.iid} and #{ext_ref}", - committer_email: commiter.email + committer_email: committer.email ) expect(commit.closes_issues).to include(issue) diff --git a/spec/models/event_collection_spec.rb b/spec/models/event_collection_spec.rb index e0a87c18cc7..6078f429bdc 100644 --- a/spec/models/event_collection_spec.rb +++ b/spec/models/event_collection_spec.rb @@ -41,7 +41,7 @@ describe EventCollection do end it 'allows filtering of events using an EventFilter' do - filter = EventFilter.new(EventFilter.issue) + filter = EventFilter.new(EventFilter::ISSUE) events = described_class.new(projects, filter: filter).to_a expect(events.length).to eq(1) diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb index 8548fff5c76..34db94920f3 100644 --- a/spec/models/instance_configuration_spec.rb +++ b/spec/models/instance_configuration_spec.rb @@ -52,7 +52,7 @@ RSpec.describe InstanceConfiguration do expect(gitlab_pages).to eq(Settings.pages.symbolize_keys) end - it 'returns the Gitlab\'s pages host ip address' do + it 'returns the GitLab\'s pages host ip address' do expect(gitlab_pages.keys).to include(:ip_address) end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index c21d85fb2a4..19bc2713ef5 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -84,15 +84,32 @@ describe Issue do end end - describe '#closed_at' do - it 'sets closed_at to Time.now when issue is closed' do - issue = create(:issue, state: 'opened') + describe '#close' do + subject(:issue) { create(:issue, state: 'opened') } - expect(issue.closed_at).to be_nil + it 'sets closed_at to Time.now when an issue is closed' do + expect { issue.close }.to change { issue.closed_at }.from(nil) + end - issue.close + it 'changes the state to closed' do + expect { issue.close }.to change { issue.state }.from('opened').to('closed') + end + end + + describe '#reopen' do + let(:user) { create(:user) } + let(:issue) { create(:issue, state: 'closed', closed_at: Time.now, closed_by: user) } + + it 'sets closed_at to nil when an issue is reopend' do + expect { issue.reopen }.to change { issue.closed_at }.to(nil) + end + + it 'sets closed_by to nil when an issue is reopend' do + expect { issue.reopen }.to change { issue.closed_by }.from(user).to(nil) + end - expect(issue.closed_at).to be_present + it 'changes the state to opened' do + expect { issue.reopen }.to change { issue.state }.from('closed').to('opened') end end diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb index 10617edec0f..cd7f77024da 100644 --- a/spec/models/project_feature_spec.rb +++ b/spec/models/project_feature_spec.rb @@ -119,46 +119,4 @@ describe ProjectFeature do end end end - - context 'Site Statistics' do - set(:project_with_wiki) { create(:project, :wiki_enabled) } - set(:project_without_wiki) { create(:project, :wiki_disabled) } - - context 'when creating a project' do - it 'tracks wiki availability when wikis are enabled by default' do - expect { create(:project) }.to change { SiteStatistic.fetch.wikis_count }.by(1) - end - - it 'does not track wiki availability when wikis are disabled by default' do - expect { create(:project, :wiki_disabled) }.not_to change { SiteStatistic.fetch.wikis_count } - end - end - - context 'when updating a project_feature' do - it 'untracks wiki availability when disabling wiki access' do - expect { project_with_wiki.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED) } - .to change { SiteStatistic.fetch.wikis_count }.by(-1) - end - - it 'tracks again wiki availability when re-enabling wiki access as public' do - expect { project_without_wiki.project_feature.update_attribute(:wiki_access_level, ProjectFeature::ENABLED) } - .to change { SiteStatistic.fetch.wikis_count }.by(1) - end - - it 'tracks again wiki availability when re-enabling wiki access as private' do - expect { project_without_wiki.project_feature.update_attribute(:wiki_access_level, ProjectFeature::PRIVATE) } - .to change { SiteStatistic.fetch.wikis_count }.by(1) - end - end - - context 'when removing a project' do - it 'untracks wiki availability when removing a project with previous wiki access' do - expect { project_with_wiki.destroy }.to change { SiteStatistic.fetch.wikis_count }.by(-1) - end - - it 'does not untrack wiki availability when removing a project without wiki access' do - expect { project_without_wiki.destroy }.not_to change { SiteStatistic.fetch.wikis_count } - end - end - end end diff --git a/spec/models/project_services/chat_message/merge_message_spec.rb b/spec/models/project_services/chat_message/merge_message_spec.rb index 96496295825..7997b5bb6b9 100644 --- a/spec/models/project_services/chat_message/merge_message_spec.rb +++ b/spec/models/project_services/chat_message/merge_message_spec.rb @@ -27,6 +27,23 @@ describe ChatMessage::MergeMessage do } end + # Integration point in EE + context 'when state is overridden' do + it 'respects the overridden state' do + allow(subject).to receive(:state_or_action_text) { 'devoured' } + + aggregate_failures do + expect(subject.summary).not_to include('opened') + expect(subject.summary).to include('devoured') + + activity_title = subject.activity[:title] + + expect(activity_title).not_to include('opened') + expect(activity_title).to include('devoured') + end + end + end + context 'without markdown' do let(:color) { '#345' } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 909012b7789..afc9ea1917e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1072,6 +1072,18 @@ describe Project do it { expect(project.builds_enabled?).to be_truthy } end + describe '.sort_by_attribute' do + it 'reorders the input relation by start count desc' do + project1 = create(:project, star_count: 2) + project2 = create(:project, star_count: 1) + project3 = create(:project) + + projects = described_class.sort_by_attribute(:stars_desc) + + expect(projects).to eq([project1, project2, project3]) + end + end + describe '.with_shared_runners' do subject { described_class.with_shared_runners } @@ -3983,40 +3995,6 @@ describe Project do end end - describe '#update_root_ref' do - let(:project) { create(:project, :repository) } - - it 'updates the default branch when HEAD has changed' do - stub_find_remote_root_ref(project, ref: 'feature') - - expect { project.update_root_ref('origin') } - .to change { project.default_branch } - .from('master') - .to('feature') - end - - it 'does not update the default branch when HEAD does not change' do - stub_find_remote_root_ref(project, ref: 'master') - - expect { project.update_root_ref('origin') } - .not_to change { project.default_branch } - end - - it 'does not update the default branch when HEAD does not exist' do - stub_find_remote_root_ref(project, ref: 'foo') - - expect { project.update_root_ref('origin') } - .not_to change { project.default_branch } - end - - def stub_find_remote_root_ref(project, ref:) - allow(project.repository) - .to receive(:find_remote_root_ref) - .with('origin') - .and_return(ref) - end - end - def rugged_config Gitlab::GitalyClient::StorageSettings.allow_disk_access do project.repository.rugged.config diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index dffac05152b..7e1b7c35517 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1044,6 +1044,47 @@ describe Repository do expect_to_raise_storage_error { broken_repository.exists? } end end + + context 'asymmetric caching', :use_clean_rails_memory_store_caching, :request_store do + let(:cache) { repository.send(:cache) } + let(:request_store_cache) { repository.send(:request_store_cache) } + + context 'when it returns true' do + before do + expect(repository.raw_repository).to receive(:exists?).once.and_return(true) + end + + it 'caches the output in RequestStore' do + expect do + repository.exists? + end.to change { request_store_cache.read(:exists?) }.from(nil).to(true) + end + + it 'caches the output in RepositoryCache' do + expect do + repository.exists? + end.to change { cache.read(:exists?) }.from(nil).to(true) + end + end + + context 'when it returns false' do + before do + expect(repository.raw_repository).to receive(:exists?).once.and_return(false) + end + + it 'caches the output in RequestStore' do + expect do + repository.exists? + end.to change { request_store_cache.read(:exists?) }.from(nil).to(false) + end + + it 'does NOT cache the output in RepositoryCache' do + expect do + repository.exists? + end.not_to change { cache.read(:exists?) }.from(nil) + end + end + end end describe '#has_visible_content?' do @@ -1716,12 +1757,19 @@ describe Repository do describe '#expire_exists_cache' do let(:cache) { repository.send(:cache) } + let(:request_store_cache) { repository.send(:request_store_cache) } it 'expires the cache' do expect(cache).to receive(:expire).with(:exists?) repository.expire_exists_cache end + + it 'expires the request store cache', :request_store do + expect(request_store_cache).to receive(:expire).with(:exists?) + + repository.expire_exists_cache + end end describe '#xcode_project?' do @@ -1892,7 +1940,7 @@ describe Repository do match[1].to_sym if match end.compact - expect(methods).to match_array(Repository::CACHED_METHODS + Repository::MEMOIZED_CACHED_METHODS) + expect(Repository::CACHED_METHODS + Repository::MEMOIZED_CACHED_METHODS).to include(*methods) end end diff --git a/spec/models/site_statistic_spec.rb b/spec/models/site_statistic_spec.rb index 9b056fbf332..0e739900065 100644 --- a/spec/models/site_statistic_spec.rb +++ b/spec/models/site_statistic_spec.rb @@ -25,7 +25,6 @@ describe SiteStatistic do it 'increases the attribute counter' do expect { described_class.track('repositories_count') }.to change { statistics.reload.repositories_count }.by(1) - expect { described_class.track('wikis_count') }.to change { statistics.reload.wikis_count }.by(1) end it 'doesnt increase the attribute counter when an exception happens during transaction' do @@ -56,7 +55,6 @@ describe SiteStatistic do it 'decreases the attribute counter' do expect { described_class.untrack('repositories_count') }.to change { statistics.reload.repositories_count }.by(-1) - expect { described_class.untrack('wikis_count') }.to change { statistics.reload.wikis_count }.by(-1) end it 'doesnt decrease the attribute counter when an exception happens during transaction' do diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb index e7019b990dd..a42d1f3d399 100644 --- a/spec/presenters/ci/build_runner_presenter_spec.rb +++ b/spec/presenters/ci/build_runner_presenter_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' describe Ci::BuildRunnerPresenter do let(:presenter) { described_class.new(build) } let(:archive) { { paths: ['sample.txt'] } } - let(:junit) { { junit: ['junit.xml'] } } let(:archive_expectation) do { @@ -14,16 +13,6 @@ describe Ci::BuildRunnerPresenter do } end - let(:junit_expectation) do - { - name: 'junit.xml', - artifact_type: :junit, - artifact_format: :gzip, - paths: ['junit.xml'], - when: 'always' - } - end - describe '#artifacts' do context "when option contains archive-type artifacts" do let(:build) { create(:ci_build, options: { artifacts: archive } ) } @@ -49,20 +38,44 @@ describe Ci::BuildRunnerPresenter do end end - context "when option has 'junit' keyword" do - let(:build) { create(:ci_build, options: { artifacts: { reports: junit } } ) } + context "with reports" do + Ci::JobArtifact::DEFAULT_FILE_NAMES.each do |file_type, filename| + let(:report) { { "#{file_type}": [filename] } } + let(:build) { create(:ci_build, options: { artifacts: { reports: report } } ) } + + let(:report_expectation) do + { + name: filename, + artifact_type: :"#{file_type}", + artifact_format: :gzip, + paths: [filename], + when: 'always' + } + end - it 'presents correct hash' do - expect(presenter.artifacts.first).to include(junit_expectation) + it 'presents correct hash' do + expect(presenter.artifacts.first).to include(report_expectation) + end end end context "when option has both archive and reports specification" do - let(:build) { create(:ci_build, options: { script: 'echo', artifacts: { **archive, reports: junit } } ) } + let(:report) { { junit: ['junit.xml'] } } + let(:build) { create(:ci_build, options: { script: 'echo', artifacts: { **archive, reports: report } } ) } + + let(:report_expectation) do + { + name: 'junit.xml', + artifact_type: :junit, + artifact_format: :gzip, + paths: ['junit.xml'], + when: 'always' + } + end it 'presents correct hash' do expect(presenter.artifacts.first).to include(archive_expectation) - expect(presenter.artifacts.second).to include(junit_expectation) + expect(presenter.artifacts.second).to include(report_expectation) end context "when archive specifies 'expire_in' keyword" do @@ -70,7 +83,7 @@ describe Ci::BuildRunnerPresenter do it 'inherits expire_in from archive' do expect(presenter.artifacts.first).to include({ **archive_expectation, expire_in: '3 mins 4 sec' }) - expect(presenter.artifacts.second).to include({ **junit_expectation, expire_in: '3 mins 4 sec' }) + expect(presenter.artifacts.second).to include({ **report_expectation, expire_in: '3 mins 4 sec' }) end end end diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index d5b31610dad..f3fb88474a4 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -238,7 +238,7 @@ describe API::Commits do describe 'create' do let(:message) { 'Created file' } - let!(:invalid_c_params) do + let(:invalid_c_params) do { branch: 'master', commit_message: message, @@ -251,7 +251,7 @@ describe API::Commits do ] } end - let!(:valid_c_params) do + let(:valid_c_params) do { branch: 'master', commit_message: message, @@ -264,7 +264,7 @@ describe API::Commits do ] } end - let!(:valid_utf8_c_params) do + let(:valid_utf8_c_params) do { branch: 'master', commit_message: message, @@ -315,7 +315,7 @@ describe API::Commits do describe 'delete' do let(:message) { 'Deleted file' } - let!(:invalid_d_params) do + let(:invalid_d_params) do { branch: 'markdown', commit_message: message, @@ -327,7 +327,7 @@ describe API::Commits do ] } end - let!(:valid_d_params) do + let(:valid_d_params) do { branch: 'markdown', commit_message: message, @@ -356,7 +356,7 @@ describe API::Commits do describe 'move' do let(:message) { 'Moved file' } - let!(:invalid_m_params) do + let(:invalid_m_params) do { branch: 'feature', commit_message: message, @@ -370,7 +370,7 @@ describe API::Commits do ] } end - let!(:valid_m_params) do + let(:valid_m_params) do { branch: 'feature', commit_message: message, @@ -401,7 +401,7 @@ describe API::Commits do describe 'update' do let(:message) { 'Updated file' } - let!(:invalid_u_params) do + let(:invalid_u_params) do { branch: 'master', commit_message: message, @@ -414,7 +414,7 @@ describe API::Commits do ] } end - let!(:valid_u_params) do + let(:valid_u_params) do { branch: 'master', commit_message: message, @@ -442,9 +442,57 @@ describe API::Commits do end end + describe 'chmod' do + let(:message) { 'Chmod +x file' } + let(:file_path) { 'files/ruby/popen.rb' } + let(:execute_filemode) { true } + let(:params) do + { + branch: 'master', + commit_message: message, + actions: [ + { + action: 'chmod', + file_path: file_path, + execute_filemode: execute_filemode + } + ] + } + end + + it 'responds with success' do + post api(url, user), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['title']).to eq(message) + end + + context 'when execute_filemode is false' do + let(:execute_filemode) { false } + + it 'responds with success' do + post api(url, user), params + + expect(response).to have_gitlab_http_status(201) + expect(json_response['title']).to eq(message) + end + end + + context "when the file doesn't exists" do + let(:file_path) { 'foo/bar.baz' } + + it "responds with 400" do + post api(url, user), params + + expect(response).to have_gitlab_http_status(400) + expect(json_response['message']).to eq("A file with this name doesn't exist") + end + end + end + describe 'multiple operations' do let(:message) { 'Multiple actions' } - let!(:invalid_mo_params) do + let(:invalid_mo_params) do { branch: 'master', commit_message: message, @@ -468,11 +516,16 @@ describe API::Commits do action: 'update', file_path: 'foo/bar.baz', content: 'puts 8' + }, + { + action: 'chmod', + file_path: 'files/ruby/popen.rb', + execute_filemode: true } ] } end - let!(:valid_mo_params) do + let(:valid_mo_params) do { branch: 'master', commit_message: message, @@ -496,6 +549,11 @@ describe API::Commits do action: 'update', file_path: 'files/ruby/popen.rb', content: 'puts 8' + }, + { + action: 'chmod', + file_path: 'files/ruby/popen.rb', + execute_filemode: true } ] } diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb index 6adbbb40489..8770365c893 100644 --- a/spec/requests/api/jobs_spec.rb +++ b/spec/requests/api/jobs_spec.rb @@ -721,7 +721,7 @@ describe API::Jobs do expect(job.trace.exist?).to be_falsy expect(job.artifacts_file.exists?).to be_falsy expect(job.artifacts_metadata.exists?).to be_falsy - expect(job.has_test_reports?).to be_falsy + expect(job.has_job_artifacts?).to be_falsy end it 'updates job' do diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 3ebdb54f71f..49a79d2ccf9 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -25,36 +25,71 @@ describe API::Runners do describe 'GET /runners' do context 'authorized user' do - it 'returns user available runners' do + it 'returns response status and headers' do get api('/runners', user) - shared = json_response.any? { |r| r['is_shared'] } - descriptions = json_response.map { |runner| runner['description'] } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers - expect(json_response).to be_an Array - expect(json_response[0]).to have_key('ip_address') - expect(descriptions).to contain_exactly( - 'Project runner', 'Two projects runner', 'Group runner' - ) - expect(shared).to be_falsey + end + + it 'returns user available runners' do + get api('/runners', user) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner'), + a_hash_including('description' => 'Group runner') + ] end it 'filters runners by scope' do - get api('/runners?scope=active', user) + create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) + + get api('/runners?scope=paused', user) - shared = json_response.any? { |r| r['is_shared'] } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers - expect(json_response).to be_an Array - expect(json_response[0]).to have_key('ip_address') - expect(shared).to be_falsey + + expect(json_response).to match_array [ + a_hash_including('description' => 'Inactive project runner') + ] end it 'avoids filtering if scope is invalid' do get api('/runners?scope=unknown', user) expect(response).to have_gitlab_http_status(400) end + + it 'filters runners by type' do + get api('/runners?type=project_type', user) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner') + ] + end + + it 'does not filter by invalid type' do + get api('/runners?type=bogus', user) + + expect(response).to have_gitlab_http_status(400) + end + + it 'filters runners by status' do + create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) + + get api('/runners?status=paused', user) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Inactive project runner') + ] + end + + it 'does not filter by invalid status' do + get api('/runners?status=bogus', user) + + expect(response).to have_gitlab_http_status(400) + end end context 'unauthorized user' do @@ -69,51 +104,91 @@ describe API::Runners do describe 'GET /runners/all' do context 'authorized user' do context 'with admin privileges' do + it 'returns response status and headers' do + get api('/runners/all', admin) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + end + it 'returns all runners' do get api('/runners/all', admin) - shared = json_response.any? { |r| r['is_shared'] } + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner'), + a_hash_including('description' => 'Group runner'), + a_hash_including('description' => 'Shared runner') + ] + end + + it 'filters runners by scope' do + get api('/runners/all?scope=shared', admin) + + shared = json_response.all? { |r| r['is_shared'] } expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response[0]).to have_key('ip_address') expect(shared).to be_truthy end - end - context 'without admin privileges' do - it 'does not return runners list' do - get api('/runners/all', user) + it 'filters runners by scope' do + get api('/runners/all?scope=specific', admin) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner'), + a_hash_including('description' => 'Group runner') + ] end - end - it 'filters runners by scope' do - get api('/runners/all?scope=shared', admin) + it 'avoids filtering if scope is invalid' do + get api('/runners/all?scope=unknown', admin) + expect(response).to have_gitlab_http_status(400) + end - shared = json_response.all? { |r| r['is_shared'] } - expect(response).to have_gitlab_http_status(200) - expect(response).to include_pagination_headers - expect(json_response).to be_an Array - expect(json_response[0]).to have_key('ip_address') - expect(shared).to be_truthy - end + it 'filters runners by type' do + get api('/runners/all?type=project_type', admin) - it 'filters runners by scope' do - get api('/runners/all?scope=specific', admin) + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner') + ] + end - shared = json_response.any? { |r| r['is_shared'] } - expect(response).to have_gitlab_http_status(200) - expect(response).to include_pagination_headers - expect(json_response).to be_an Array - expect(json_response[0]).to have_key('ip_address') - expect(shared).to be_falsey + it 'does not filter by invalid type' do + get api('/runners/all?type=bogus', admin) + + expect(response).to have_gitlab_http_status(400) + end + + it 'filters runners by status' do + create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) + + get api('/runners/all?status=paused', admin) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Inactive project runner') + ] + end + + it 'does not filter by invalid status' do + get api('/runners/all?status=bogus', admin) + + expect(response).to have_gitlab_http_status(400) + end end - it 'avoids filtering if scope is invalid' do - get api('/runners?scope=unknown', admin) - expect(response).to have_gitlab_http_status(400) + context 'without admin privileges' do + it 'does not return runners list' do + get api('/runners/all', user) + + expect(response).to have_gitlab_http_status(403) + end end end @@ -577,15 +652,69 @@ describe API::Runners do describe 'GET /projects/:id/runners' do context 'authorized user with maintainer privileges' do - it "returns project's runners" do + it 'returns response status and headers' do + get api('/runners/all', admin) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + end + + it 'returns all runners' do get api("/projects/#{project.id}/runners", user) - shared = json_response.any? { |r| r['is_shared'] } + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner'), + a_hash_including('description' => 'Shared runner') + ] + end + + it 'filters runners by scope' do + get api("/projects/#{project.id}/runners?scope=specific", user) + expect(response).to have_gitlab_http_status(200) expect(response).to include_pagination_headers - expect(json_response).to be_an Array - expect(json_response[0]).to have_key('ip_address') - expect(shared).to be_truthy + + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner') + ] + end + + it 'avoids filtering if scope is invalid' do + get api("/projects/#{project.id}/runners?scope=unknown", user) + expect(response).to have_gitlab_http_status(400) + end + + it 'filters runners by type' do + get api("/projects/#{project.id}/runners?type=project_type", user) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Project runner'), + a_hash_including('description' => 'Two projects runner') + ] + end + + it 'does not filter by invalid type' do + get api("/projects/#{project.id}/runners?type=bogus", user) + + expect(response).to have_gitlab_http_status(400) + end + + it 'filters runners by status' do + create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) + + get api("/projects/#{project.id}/runners?status=paused", user) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Inactive project runner') + ] + end + + it 'does not filter by invalid status' do + get api("/projects/#{project.id}/runners?status=bogus", user) + + expect(response).to have_gitlab_http_status(400) end end diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb index b14d4b8fb6e..b1cf7a531f4 100644 --- a/spec/requests/openid_connect_spec.rb +++ b/spec/requests/openid_connect_spec.rb @@ -121,7 +121,7 @@ describe 'OpenID Connect requests' do expect(@payload).to match(a_hash_including(id_token_claims)) end - it 'includes the Gitlab root URL' do + it 'includes the GitLab root URL' do expect(@payload['iss']).to eq Gitlab.config.gitlab.url end diff --git a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb new file mode 100644 index 00000000000..c9eb61ccc72 --- /dev/null +++ b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rubocop' +require_relative '../../../rubocop/cop/avoid_route_redirect_leading_slash' + +describe RuboCop::Cop::AvoidRouteRedirectLeadingSlash do + include CopHelper + + subject(:cop) { described_class.new } + + before do + allow(cop).to receive(:in_routes?).and_return(true) + end + + it 'registers an offense when redirect has a leading slash' do + expect_offense(<<~PATTERN.strip_indent) + root to: redirect("/-/route") + ^^^^^^^^^^^^^^^^^^^^ Do not use a leading "/" in route redirects + PATTERN + end + + it 'does not register an offense when redirect does not have a leading slash' do + expect_no_offenses(<<~PATTERN.strip_indent) + root to: redirect("-/route") + PATTERN + end + + it 'autocorrect `/-/route` to `-/route`' do + expect(autocorrect_source('redirect("/-/route")')).to eq('redirect("-/route")') + end +end diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 04247c78549..35215e06f5f 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -51,4 +51,37 @@ describe CommitEntity do it 'exposes gravatar url that belongs to author' do expect(subject.fetch(:author_gravatar_url)).to match /gravatar/ end + + context 'when type is not set' do + it 'does not expose extra properties' do + expect(subject).not_to include(:description_html) + expect(subject).not_to include(:title_html) + end + end + + context 'when type is "full"' do + let(:entity) do + described_class.new(commit, request: request, type: :full) + end + + it 'exposes extra properties' do + expect(subject).to include(:description_html) + expect(subject).to include(:title_html) + expect(subject.fetch(:description_html)).not_to be_nil + expect(subject.fetch(:title_html)).not_to be_nil + end + end + + context 'when commit_url_params is set' do + let(:entity) do + params = { merge_request_iid: 3 } + + described_class.new(commit, request: request, commit_url_params: params) + end + + it 'adds commit_url_params to url and path' do + expect(subject[:commit_path]).to include "?merge_request_iid=3" + expect(subject[:commit_url]).to include "?merge_request_iid=3" + end + end end diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb index c7f88e45c84..f2e9799452a 100644 --- a/spec/services/auth/container_registry_authentication_service_spec.rb +++ b/spec/services/auth/container_registry_authentication_service_spec.rb @@ -145,7 +145,7 @@ describe Auth::ContainerRegistryAuthenticationService do { scopes: ["registry:catalog:*"] } end - context 'disallow browsing for users without Gitlab admin rights' do + context 'disallow browsing for users without GitLab admin rights' do it_behaves_like 'an inaccessible' it_behaves_like 'not a container repository factory' end diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 18d52082399..951c0b16a68 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -24,7 +24,9 @@ describe Ci::RetryBuildService do artifacts_file artifacts_metadata artifacts_size created_at updated_at started_at finished_at queued_at erased_by erased_at auto_canceled_by job_artifacts job_artifacts_archive - job_artifacts_metadata job_artifacts_trace job_artifacts_junit].freeze + job_artifacts_metadata job_artifacts_trace job_artifacts_junit + job_artifacts_sast job_artifacts_dependency_scanning + job_artifacts_container_scanning job_artifacts_dast].freeze IGNORE_ACCESSORS = %i[type lock_version target_url base_tags trace_sections @@ -38,9 +40,8 @@ describe Ci::RetryBuildService do let(:another_pipeline) { create(:ci_empty_pipeline, project: project) } let(:build) do - create(:ci_build, :failed, :artifacts, :test_reports, :expired, :erased, - :queued, :coverage, :tags, :allowed_to_fail, :on_tag, - :triggered, :trace_artifact, :teardown_environment, + create(:ci_build, :failed, :expired, :erased, :queued, :coverage, :tags, + :allowed_to_fail, :on_tag, :triggered, :teardown_environment, description: 'my-job', stage: 'test', stage_id: stage.id, pipeline: pipeline, auto_canceled_by: another_pipeline) end @@ -50,6 +51,15 @@ describe Ci::RetryBuildService do # can reset one of the fields when assigning another. We plan to deprecate # and remove legacy `stage` column in the future. build.update(stage: 'test', stage_id: stage.id) + + # Make sure we have one instance for every possible job_artifact_X + # associations to check they are correctly rejected on build duplication. + Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.each do |file_type, file_format| + create(:ci_job_artifact, file_format, + file_type: file_type, job: build, expire_at: build.artifacts_expire_at) + end + + build.reload end describe 'clone accessors' do diff --git a/spec/services/files/multi_service_spec.rb b/spec/services/files/multi_service_spec.rb index 3bdedaf3770..5f3c8e82715 100644 --- a/spec/services/files/multi_service_spec.rb +++ b/spec/services/files/multi_service_spec.rb @@ -11,6 +11,7 @@ describe Files::MultiService do let(:new_file_path) { 'files/ruby/popen.rb' } let(:file_content) { 'New content' } let(:action) { 'update' } + let(:commit_message) { 'Update File' } let!(:original_commit_id) do Gitlab::Git::Commit.last_for_path(project.repository, branch_name, original_file_path).sha @@ -30,7 +31,7 @@ describe Files::MultiService do let(:commit_params) do { - commit_message: "Update File", + commit_message: commit_message, branch_name: branch_name, start_branch: branch_name, actions: actions @@ -84,6 +85,39 @@ describe Files::MultiService do end end + describe 'changing execute_filemode of a file' do + let(:commit_message) { 'Chmod +x file' } + let(:file_path) { original_file_path } + let(:default_action) do + { + action: 'chmod', + file_path: file_path, + execute_filemode: true + } + end + + it 'accepts the commit' do + results = subject.execute + + expect(results[:status]).to eq(:success) + end + + it 'updates the execute_filemode of the file' do + expect { subject.execute }.to change { repository.blob_at_branch(branch_name, file_path).mode }.from('100644').to('100755') + end + + context "when the file doesn't exists" do + let(:file_path) { 'files/wrong_path.rb' } + + it 'rejects the commit' do + results = subject.execute + + expect(results[:status]).to eq(:error) + expect(results[:message]).to eq("A file with this name doesn't exist") + end + end + end + context 'when moving a file' do let(:action) { 'move' } let(:new_file_path) { 'files/ruby/new_popen.rb' } diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb index 97a88b5d697..d80d0f5a8a8 100644 --- a/spec/services/groups/destroy_service_spec.rb +++ b/spec/services/groups/destroy_service_spec.rb @@ -35,14 +35,6 @@ 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/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb index 999677cfaaa..d71ccfb4334 100644 --- a/spec/services/groups/transfer_service_spec.rb +++ b/spec/services/groups/transfer_service_spec.rb @@ -22,7 +22,7 @@ describe Groups::TransferService, :postgresql do end end - context "when there's an exception on Gitlab shell directories" do + context "when there's an exception on GitLab shell directories" do let(:new_parent_group) { create(:group, :public) } before do diff --git a/spec/services/merge_requests/rebase_service_spec.rb b/spec/services/merge_requests/rebase_service_spec.rb index 2703da7ae44..427a2d63a88 100644 --- a/spec/services/merge_requests/rebase_service_spec.rb +++ b/spec/services/merge_requests/rebase_service_spec.rb @@ -87,7 +87,7 @@ describe MergeRequests::RebaseService do expect(merge_request.reload.rebase_commit_sha).to eq(head_sha) end - it 'logs correct author and commiter' do + it 'logs correct author and committer' do head_commit = merge_request.source_project.repository.commit(merge_request.source_branch) expect(head_commit.author_email).to eq('dmitriy.zaporozhets@gmail.com') diff --git a/spec/services/notes/build_service_spec.rb b/spec/services/notes/build_service_spec.rb index 6e1c1fe6c02..ff85c261cd4 100644 --- a/spec/services/notes/build_service_spec.rb +++ b/spec/services/notes/build_service_spec.rb @@ -4,6 +4,8 @@ describe Notes::BuildService do let(:note) { create(:discussion_note_on_issue) } let(:project) { note.project } let(:author) { note.author } + let(:merge_request) { create(:merge_request, source_project: project) } + let(:mr_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: author) } describe '#execute' do context 'when in_reply_to_discussion_id is specified' do @@ -12,6 +14,19 @@ describe Notes::BuildService do new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute expect(new_note).to be_valid expect(new_note.in_reply_to?(note)).to be_truthy + expect(new_note.resolved?).to be_falsey + end + + context 'when discussion is resolved' do + before do + mr_note.resolve!(author) + end + + it 'resolves the note' do + new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: mr_note.discussion_id).execute + expect(new_note).to be_valid + expect(new_note.resolved?).to be_truthy + 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 56a36432462..cd903bfe8a5 100644 --- a/spec/services/projects/update_remote_mirror_service_spec.rb +++ b/spec/services/projects/update_remote_mirror_service_spec.rb @@ -17,7 +17,6 @@ describe Projects::UpdateRemoteMirrorService do it "ensures the remote exists" do stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name) expect(remote_mirror).to receive(:ensure_remote!) @@ -25,8 +24,6 @@ describe Projects::UpdateRemoteMirrorService do end it "fetches the remote repository" do - stub_find_remote_root_ref(project, remote_name: remote_name) - expect(project.repository) .to receive(:fetch_remote) .with(remote_mirror.remote_name, no_tags: true) @@ -34,26 +31,8 @@ describe Projects::UpdateRemoteMirrorService do service.execute(remote_mirror) end - it "updates the default branch when HEAD has changed" do - stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name, ref: "existing-branch") - - expect { service.execute(remote_mirror) } - .to change { project.default_branch } - .from("master") - .to("existing-branch") - end - - it "does not update the default branch when HEAD does not change" do - stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name, ref: "master") - - expect { service.execute(remote_mirror) }.not_to change { project.default_branch } - end - it "returns success when updated succeeds" do stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name) result = service.execute(remote_mirror) @@ -63,7 +42,6 @@ describe Projects::UpdateRemoteMirrorService do context 'when syncing all branches' do it "push all the branches the first time" do stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name) expect(remote_mirror).to receive(:update_repository).with({}) @@ -74,7 +52,6 @@ describe Projects::UpdateRemoteMirrorService do context 'when only syncing protected branches' do it "sync updated protected branches" do stub_fetch_remote(project, remote_name: remote_name) - stub_find_remote_root_ref(project, remote_name: remote_name) protected_branch = create_protected_branch(project) remote_mirror.only_protected_branches = true @@ -92,13 +69,6 @@ describe Projects::UpdateRemoteMirrorService do end end - def stub_find_remote_root_ref(project, ref: 'master', remote_name:) - allow(project.repository) - .to receive(:find_remote_root_ref) - .with(remote_name) - .and_return(ref) - end - def stub_fetch_remote(project, remote_name:) allow(project.repository) .to receive(:fetch_remote) diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index 06cad9c00d2..ac0ca1f33a5 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe QuickActions::InterpretService do @@ -863,6 +865,13 @@ describe QuickActions::InterpretService do let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) } let(:content) { "/copy_metadata #{source_issuable.to_reference}" } + let(:issuable) { build(:issue, project: project) } + end + + it_behaves_like 'copy_metadata command' do + let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) } + + let(:content) { "/copy_metadata #{source_issuable.to_reference}" } let(:issuable) { issue } end diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb index 0bc235701eb..0c35764ed9a 100644 --- a/spec/support/helpers/migrations_helpers.rb +++ b/spec/support/helpers/migrations_helpers.rb @@ -3,6 +3,10 @@ module MigrationsHelpers Class.new(ActiveRecord::Base) do self.table_name = name self.inheritance_column = :_type_disabled + + def self.name + table_name.singularize.camelcase + end end end diff --git a/spec/tasks/gitlab/site_statistics_rake_spec.rb b/spec/tasks/gitlab/site_statistics_rake_spec.rb index 20f0df65e63..c43ce25a540 100644 --- a/spec/tasks/gitlab/site_statistics_rake_spec.rb +++ b/spec/tasks/gitlab/site_statistics_rake_spec.rb @@ -6,7 +6,7 @@ describe 'rake gitlab:refresh_site_statistics' do Rake.application.rake_require 'tasks/gitlab/site_statistics' create(:project) - SiteStatistic.fetch.update(repositories_count: 0, wikis_count: 0) + SiteStatistic.fetch.update(repositories_count: 0) end let(:task) { 'gitlab:refresh_site_statistics' } @@ -15,10 +15,9 @@ describe 'rake gitlab:refresh_site_statistics' do run_rake_task(task) expect(SiteStatistic.fetch.repositories_count).to eq(1) - expect(SiteStatistic.fetch.wikis_count).to eq(1) end it 'displays message listing counters' do - expect { run_rake_task(task) }.to output(/Updating Site Statistics counters:.* Repositories\.\.\. OK!.* Wikis\.\.\. OK!/m).to_stdout + expect { run_rake_task(task) }.to output(/Updating Site Statistics counters:.* Repositories\.\.\. OK!/m).to_stdout end end diff --git a/spec/views/projects/jobs/show.html.haml_spec.rb b/spec/views/projects/jobs/show.html.haml_spec.rb index c93152b88e3..496646dc623 100644 --- a/spec/views/projects/jobs/show.html.haml_spec.rb +++ b/spec/views/projects/jobs/show.html.haml_spec.rb @@ -188,40 +188,4 @@ describe 'projects/jobs/show' do expect(rendered).not_to have_link('New issue') end end - - context 'when incomplete trigger_request is used' do - before do - build.trigger_request = FactoryBot.build(:ci_trigger_request, trigger: nil) - end - - it 'test should not render token block' do - render - - expect(rendered).not_to have_content('Token') - end - end - - context 'when complete trigger_request is used' do - before do - build.trigger_request = FactoryBot.build(:ci_trigger_request) - end - - it 'should render token' do - render - - expect(rendered).to have_content('Token') - expect(rendered).to have_content(build.trigger_request.trigger.short_token) - end - end - - describe 'commit title in sidebar' do - let(:commit_title) { project.commit.title } - - it 'shows commit title and not show commit message' do - render - - expect(rendered).to have_css('p.build-light-text.append-bottom-0', - text: /\A\n#{Regexp.escape(commit_title)}\n\Z/) - end - end end diff --git a/vendor/gitlab-ci-yml/.gitlab-ci.yml b/vendor/gitlab-ci-yml/.gitlab-ci.yml deleted file mode 100644 index e2a55163682..00000000000 --- a/vendor/gitlab-ci-yml/.gitlab-ci.yml +++ /dev/null @@ -1,4 +0,0 @@ -image: ruby:2.4-alpine - -test: - script: ./verify_templates.rb diff --git a/vendor/gitlab-ci-yml/CONTRIBUTING.md b/vendor/gitlab-ci-yml/CONTRIBUTING.md deleted file mode 100644 index d33a1f06f26..00000000000 --- a/vendor/gitlab-ci-yml/CONTRIBUTING.md +++ /dev/null @@ -1,46 +0,0 @@ -## Developer Certificate of Origin + License - -By contributing to GitLab B.V., You accept and agree to the following terms and -conditions for Your present and future Contributions submitted to GitLab B.V. -Except for the license granted herein to GitLab B.V. and recipients of software -distributed by GitLab B.V., You reserve all right, title, and interest in and to -Your Contributions. All Contributions are subject to the following DCO + License -terms. - -[DCO + License](https://gitlab.com/gitlab-org/dco/blob/master/README.md) - -_This notice should stay as the first item in the CONTRIBUTING.md file._ - -## Code of conduct - -As contributors and maintainers of this project, we pledge to respect all people -who contribute through reporting issues, posting feature requests, updating -documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free -experience for everyone, regardless of level of experience, gender, gender -identity and expression, sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, or religion. - -Examples of unacceptable behavior by participants include the use of sexual -language or imagery, derogatory comments or personal attacks, trolling, public -or private harassment, insults, or other unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct. Project maintainers who do not follow the -Code of Conduct may be removed from the project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior can be -reported by emailing contact@gitlab.com. - -This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0, -available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/). - -[contributor-covenant]: http://contributor-covenant.org -[individual-agreement]: https://docs.gitlab.com/ee/legal/individual_contributor_license_agreement.html -[corporate-agreement]: https://docs.gitlab.com/ee/legal/corporate_contributor_license_agreement.html - diff --git a/vendor/gitlab-ci-yml/LICENSE b/vendor/gitlab-ci-yml/LICENSE deleted file mode 100644 index 27a215686e7..00000000000 --- a/vendor/gitlab-ci-yml/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2011-2017 GitLab B.V. - -With regard to the GitLab Software: - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. diff --git a/yarn.lock b/yarn.lock index fe4702f3a78..33849642705 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,89 +2,171 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" +"@babel/code-frame@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz#bd71d9b192af978df915829d39d4094456439a0c" dependencies: - "@babel/highlight" "7.0.0-beta.44" + "@babel/highlight" "7.0.0-beta.51" -"@babel/generator@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/generator@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.51.tgz#6c7575ffde761d07485e04baedc0392c6d9e30f6" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.51" jsesc "^2.5.1" - lodash "^4.2.0" + lodash "^4.17.5" source-map "^0.5.0" trim-right "^1.0.1" -"@babel/helper-function-name@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" +"@babel/generator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0.tgz#1efd58bffa951dc846449e58ce3a1d7f02d393aa" + dependencies: + "@babel/types" "^7.0.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-function-name@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz#21b4874a227cf99ecafcc30a90302da5a2640561" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz#3281b2d045af95c172ce91b20825d85ea4676411" + dependencies: + "@babel/types" "7.0.0-beta.51" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.44" - "@babel/template" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" + "@babel/types" "^7.0.0" -"@babel/helper-get-function-arity@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" +"@babel/helper-split-export-declaration@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz#8a6c3f66c4d265352fc077484f9f6e80a51ab978" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-split-export-declaration@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "^7.0.0" -"@babel/highlight@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" +"@babel/highlight@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.51.tgz#e8844ae25a1595ccfd42b89623b4376ca06d225d" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/template@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" - dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" - lodash "^4.2.0" - -"@babel/traverse@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" - dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/generator" "7.0.0-beta.44" - "@babel/helper-function-name" "7.0.0-beta.44" - "@babel/helper-split-export-declaration" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.51.tgz#27cec2df409df60af58270ed8f6aa55409ea86f6" + +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.0.tgz#a7cd42cb3c12aec52e24375189a47b39759b783e" + +"@babel/template@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.51.tgz#9602a40aebcf357ae9677e2532ef5fc810f5fbff" + dependencies: + "@babel/code-frame" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + lodash "^4.17.5" + +"@babel/template@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.0.tgz#58cc9572e1bfe24fe1537fdf99d839d53e517e22" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/traverse@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.51.tgz#981daf2cec347a6231d3aa1d9e1803b03aaaa4a8" + dependencies: + "@babel/code-frame" "7.0.0-beta.51" + "@babel/generator" "7.0.0-beta.51" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-split-export-declaration" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" debug "^3.1.0" globals "^11.1.0" invariant "^2.2.0" - lodash "^4.2.0" + lodash "^4.17.5" + +"@babel/traverse@^7.0.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + debug "^3.1.0" + globals "^11.1.0" + lodash "^4.17.10" -"@babel/types@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" +"@babel/types@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9" dependencies: esutils "^2.0.2" - lodash "^4.2.0" + lodash "^4.17.5" + to-fast-properties "^2.0.0" + +"@babel/types@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118" + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" to-fast-properties "^2.0.0" "@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.29.0": version "1.29.0" resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.29.0.tgz#03b65b513f9099bbda6ecf94d673a2952f8c6c70" -"@gitlab-org/gitlab-ui@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.5.0.tgz#320ba164ba8812ff64f94b1cae79a7b749f5bc03" +"@gitlab-org/gitlab-ui@^1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.7.1.tgz#e9cce86cb7e34311405e705c1de674276b453f17" dependencies: "@gitlab-org/gitlab-svgs" "^1.23.0" bootstrap-vue "^2.0.0-rc.11" @@ -122,9 +204,9 @@ version "5.0.0" resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.0.tgz#9ae2106efc443d7c1e26570aa8247828c9c80f11" -"@vue/component-compiler-utils@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-1.2.1.tgz#3d543baa75cfe5dab96e29415b78366450156ef6" +"@vue/component-compiler-utils@^2.0.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.2.0.tgz#bbbb7ed38a9a8a7c93abe7ef2e54a90a04b631b4" dependencies: consolidate "^0.15.1" hash-sum "^1.0.2" @@ -132,155 +214,156 @@ merge-source-map "^1.1.0" postcss "^6.0.20" postcss-selector-parser "^3.1.1" - prettier "^1.11.1" + prettier "1.13.7" source-map "^0.5.6" vue-template-es2015-compiler "^1.6.0" -"@webassemblyjs/ast@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" +"@webassemblyjs/ast@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.6.tgz#3ef8c45b3e5e943a153a05281317474fef63e21e" dependencies: - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - debug "^3.1.0" + "@webassemblyjs/helper-module-context" "1.7.6" + "@webassemblyjs/helper-wasm-bytecode" "1.7.6" + "@webassemblyjs/wast-parser" "1.7.6" mamacro "^0.0.3" -"@webassemblyjs/floating-point-hex-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" +"@webassemblyjs/floating-point-hex-parser@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.6.tgz#7cb37d51a05c3fe09b464ae7e711d1ab3837801f" -"@webassemblyjs/helper-api-error@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" +"@webassemblyjs/helper-api-error@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.6.tgz#99b7e30e66f550a2638299a109dda84a622070ef" -"@webassemblyjs/helper-buffer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" - dependencies: - debug "^3.1.0" +"@webassemblyjs/helper-buffer@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.6.tgz#ba0648be12bbe560c25c997e175c2018df39ca3e" -"@webassemblyjs/helper-code-frame@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" +"@webassemblyjs/helper-code-frame@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.6.tgz#5a94d21b0057b69a7403fca0c253c3aaca95b1a5" dependencies: - "@webassemblyjs/wast-printer" "1.5.13" + "@webassemblyjs/wast-printer" "1.7.6" -"@webassemblyjs/helper-fsm@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" +"@webassemblyjs/helper-fsm@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.6.tgz#ae1741c6f6121213c7a0b587fb964fac492d3e49" -"@webassemblyjs/helper-module-context@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" +"@webassemblyjs/helper-module-context@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.6.tgz#116d19a51a6cebc8900ad53ca34ff8269c668c23" dependencies: - debug "^3.1.0" mamacro "^0.0.3" -"@webassemblyjs/helper-wasm-bytecode@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" - -"@webassemblyjs/helper-wasm-section@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/ieee754@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" - dependencies: - ieee754 "^1.1.11" - -"@webassemblyjs/leb128@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" - dependencies: - long "4.0.0" - -"@webassemblyjs/utf8@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" - -"@webassemblyjs/wasm-edit@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/helper-wasm-section" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - "@webassemblyjs/wast-printer" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/wasm-gen@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" +"@webassemblyjs/helper-wasm-bytecode@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.6.tgz#98e515eaee611aa6834eb5f6a7f8f5b29fefb6f1" + +"@webassemblyjs/helper-wasm-section@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.6.tgz#783835867bdd686df7a95377ab64f51a275e8333" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-buffer" "1.7.6" + "@webassemblyjs/helper-wasm-bytecode" "1.7.6" + "@webassemblyjs/wasm-gen" "1.7.6" + +"@webassemblyjs/ieee754@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.6.tgz#c34fc058f2f831fae0632a8bb9803cf2d3462eb1" + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.6.tgz#197f75376a29f6ed6ace15898a310d871d92f03b" + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.6.tgz#eb62c66f906af2be70de0302e29055d25188797d" + +"@webassemblyjs/wasm-edit@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.6.tgz#fa41929160cd7d676d4c28ecef420eed5b3733c5" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-buffer" "1.7.6" + "@webassemblyjs/helper-wasm-bytecode" "1.7.6" + "@webassemblyjs/helper-wasm-section" "1.7.6" + "@webassemblyjs/wasm-gen" "1.7.6" + "@webassemblyjs/wasm-opt" "1.7.6" + "@webassemblyjs/wasm-parser" "1.7.6" + "@webassemblyjs/wast-printer" "1.7.6" + +"@webassemblyjs/wasm-gen@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.6.tgz#695ac38861ab3d72bf763c8c75e5f087ffabc322" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-wasm-bytecode" "1.7.6" + "@webassemblyjs/ieee754" "1.7.6" + "@webassemblyjs/leb128" "1.7.6" + "@webassemblyjs/utf8" "1.7.6" + +"@webassemblyjs/wasm-opt@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.6.tgz#fbafa78e27e1a75ab759a4b658ff3d50b4636c21" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-buffer" "1.7.6" + "@webassemblyjs/wasm-gen" "1.7.6" + "@webassemblyjs/wasm-parser" "1.7.6" + +"@webassemblyjs/wasm-parser@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.6.tgz#84eafeeff405ad6f4c4b5777d6a28ae54eed51fe" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-api-error" "1.7.6" + "@webassemblyjs/helper-wasm-bytecode" "1.7.6" + "@webassemblyjs/ieee754" "1.7.6" + "@webassemblyjs/leb128" "1.7.6" + "@webassemblyjs/utf8" "1.7.6" + +"@webassemblyjs/wast-parser@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.6.tgz#ca4d20b1516e017c91981773bd7e819d6bd9c6a7" + dependencies: + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/floating-point-hex-parser" "1.7.6" + "@webassemblyjs/helper-api-error" "1.7.6" + "@webassemblyjs/helper-code-frame" "1.7.6" + "@webassemblyjs/helper-fsm" "1.7.6" + "@xtuc/long" "4.2.1" + mamacro "^0.0.3" -"@webassemblyjs/wasm-opt@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" +"@webassemblyjs/wast-printer@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.6.tgz#a6002c526ac5fa230fe2c6d2f1bdbf4aead43a5e" dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - debug "^3.1.0" + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/wast-parser" "1.7.6" + "@xtuc/long" "4.2.1" -"@webassemblyjs/wasm-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" - -"@webassemblyjs/wast-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/floating-point-hex-parser" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-code-frame" "1.5.13" - "@webassemblyjs/helper-fsm" "1.5.13" - long "^3.2.0" - mamacro "^0.0.3" +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" -"@webassemblyjs/wast-printer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - long "^3.2.0" +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" abbrev@1, abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" -accepts@~1.3.3, accepts@~1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" +accepts@~1.3.3, accepts@~1.3.4, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" dependencies: - mime-types "~2.1.16" + mime-types "~2.1.18" negotiator "0.6.1" acorn-dynamic-import@^3.0.0: @@ -289,56 +372,36 @@ acorn-dynamic-import@^3.0.0: dependencies: acorn "^5.0.0" -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" +acorn-jsx@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" dependencies: - acorn "^3.0.4" + acorn "^5.0.3" -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^5.0.0, acorn@^5.3.0, acorn@^5.5.0, acorn@^5.6.2: - version "5.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" +acorn@^5.0.0, acorn@^5.0.3, acorn@^5.6.0, acorn@^5.6.2, acorn@^5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - -ajv-keywords@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" +ajv-errors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" -ajv@^5.2.3, ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" +ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" -ajv@^6.1.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.1.1.tgz#978d597fbc2b7d0e5a5c3ddeb149a682f2abfa0e" +ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" dependencies: - fast-deep-equal "^1.0.0" + fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" amdefine@>=0.0.4: version "1.0.1" @@ -350,6 +413,10 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-colors@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.0.5.tgz#cb9dc64993b64fd6945485f797fc3853137d9a7b" + ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -405,8 +472,8 @@ are-we-there-yet@~1.1.2: readable-stream "^2.0.6" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" @@ -438,13 +505,6 @@ array-flatten@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" -array-includes@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.7.0" - array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" @@ -501,11 +561,11 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@1.x, async@^1.4.0, async@^1.5.2: +async@1.x, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.0.0, async@^2.1.4: +async@^2.0.0, async@^2.1.4, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" dependencies: @@ -532,7 +592,7 @@ axios@^0.17.1: follow-redirects "^1.2.5" is-buffer "^1.1.5" -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: +babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -564,20 +624,20 @@ babel-core@^6.26.0, babel-core@^6.26.3: slash "^1.0.0" source-map "^0.5.7" -babel-eslint@^8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.3.tgz#1a2e6681cc9bc4473c32899e59915e19cd6733cf" +babel-eslint@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/traverse" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" - eslint-scope "~3.7.1" + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" babel-generator@^6.18.0, babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" dependencies: babel-messages "^6.23.0" babel-runtime "^6.26.0" @@ -585,7 +645,7 @@ babel-generator@^6.18.0, babel-generator@^6.26.0: detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.17.4" - source-map "^0.5.6" + source-map "^0.5.7" trim-right "^1.0.1" babel-helper-bindify-decorators@^6.24.1: @@ -726,18 +786,17 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-istanbul@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" +babel-plugin-istanbul@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.0.1.tgz#2ce7bf211f0d9480ff7fd294bd05e2fa555e31ea" dependencies: - babel-plugin-syntax-object-rest-spread "^6.13.0" - find-up "^2.1.0" - istanbul-lib-instrument "^1.10.1" - test-exclude "^4.2.1" + find-up "^3.0.0" + istanbul-lib-instrument "^2.2.0" + test-exclude "^5.0.0" -babel-plugin-rewire@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.1.0.tgz#a6b966d9d8c06c03d95dcda2eec4e2521519549b" +babel-plugin-rewire@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -763,7 +822,7 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: +babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -1098,7 +1157,7 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: @@ -1138,10 +1197,6 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26 lodash "^4.17.4" to-fast-properties "^1.0.3" -babylon@7.0.0-beta.44: - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" - babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1188,17 +1243,18 @@ better-assert@~1.0.0: dependencies: callsite "1.0.0" -bfj-node4@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.2.1.tgz#3a6aa2730cf6911ba2afb836c2f88f015d718f3f" +bfj@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48" dependencies: bluebird "^3.5.1" check-types "^7.3.0" + hoopy "^0.1.2" tryer "^1.0.0" big.js@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" binary-extensions@^1.0.0: version "1.11.0" @@ -1268,14 +1324,10 @@ bootstrap-vue@^2.0.0-rc.11: popper.js "^1.12.9" vue-functional-data-merge "^2.0.5" -bootstrap@4.1.1: +bootstrap@4.1.1, bootstrap@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.1.tgz#3aec85000fa619085da8d2e4983dfd67cf2114cb" -bootstrap@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.3.tgz#0eb371af2c8448e8c210411d0cb824a6409a12be" - boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" @@ -1410,7 +1462,7 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" -cacache@^10.0.1, cacache@^10.0.4: +cacache@^10.0.4: version "10.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" dependencies: @@ -1428,6 +1480,25 @@ cacache@^10.0.1, cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" +cacache@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.2.0.tgz#617bdc0b02844af56310e411c0878941d5739965" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -1477,21 +1548,6 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1500,13 +1556,6 @@ capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1517,7 +1566,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1624,14 +1673,6 @@ clipboard@^1.5.5, clipboard@^1.7.1: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - cliui@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" @@ -1646,10 +1687,6 @@ clone-response@1.0.2: dependencies: mimic-response "^1.0.0" -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1678,14 +1715,14 @@ collection-visit@^1.0.0: object-visit "^1.0.0" color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: - color-name "^1.1.1" + color-name "1.1.3" -color-name@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" colors@^1.1.0: version "1.1.2" @@ -1697,14 +1734,18 @@ combine-lists@^1.0.0: dependencies: lodash "^4.5.0" -commander@2, commander@^2.13.0, commander@^2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" +commander@2, commander@^2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1727,13 +1768,14 @@ compressible@~2.0.10: dependencies: mime-db ">= 1.29.0 < 2" -compression-webpack-plugin@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-1.1.11.tgz#8384c7a6ead1d2e2efb190bdfcdcf35878ed8266" +compression-webpack-plugin@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-2.0.0.tgz#46476350c1eb27f783dccc79ac2f709baa2cffbc" dependencies: - cacache "^10.0.1" - find-cache-dir "^1.0.0" + cacache "^11.2.0" + find-cache-dir "^2.0.0" neo-async "^2.5.0" + schema-utils "^1.0.0" serialize-javascript "^1.4.0" webpack-sources "^1.0.1" @@ -1753,7 +1795,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0, concat-stream@^1.6.0: +concat-stream@^1.5.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -1846,8 +1888,8 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" core-js@~2.3.0: version "2.3.0" @@ -1896,7 +1938,7 @@ cropper@^2.3.0: dependencies: jquery ">= 1.9.1" -cross-spawn@^5.0.1, cross-spawn@^5.1.0: +cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -1904,7 +1946,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" dependencies: @@ -2243,15 +2285,23 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6. dependencies: ms "2.0.0" -debug@^3.0.1, debug@^3.1.0, debug@~3.1.0: +debug@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + dependencies: + ms "^2.1.1" + +debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + dependencies: + xregexp "4.0.0" deckar01-task_list@^2.0.0: version "2.0.0" @@ -2279,6 +2329,13 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +default-gateway@^2.6.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f" + dependencies: + execa "^0.10.0" + ip-regex "^2.1.0" + default-require-extensions@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" @@ -2286,11 +2343,10 @@ default-require-extensions@^1.0.0: strip-bom "^2.0.0" define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" + object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" @@ -2346,6 +2402,10 @@ depd@1.1.1, depd@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -2411,7 +2471,7 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.2: +doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: @@ -2497,9 +2557,9 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@^2.5.7: - version "2.5.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.9.tgz#7ba254582a560d267437109a68354112475b0ce5" +ejs@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" elliptic@^6.0.0: version "6.4.0" @@ -2521,7 +2581,7 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" -encodeurl@~1.0.1: +encodeurl@~1.0.1, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2604,15 +2664,15 @@ errno@^0.1.3, errno@^0.1.4: dependencies: prr "~1.0.1" -error-ex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" dependencies: is-arrayish "^0.2.1" -es-abstract@^1.7.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" +es-abstract@^1.6.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -2651,11 +2711,13 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" -eslint-config-airbnb-base@^12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" +eslint-config-airbnb-base@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c" dependencies: eslint-restricted-globals "^0.1.1" + object.assign "^4.1.0" + object.entries "^1.0.4" eslint-import-resolver-node@^0.3.1: version "0.3.2" @@ -2664,9 +2726,9 @@ eslint-import-resolver-node@^0.3.1: debug "^2.6.9" resolve "^1.5.0" -eslint-import-resolver-webpack@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.10.0.tgz#b6f2468dc3e8b4ea076e5d75bece8da932789b07" +eslint-import-resolver-webpack@^0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.10.1.tgz#4cbceed2c0c43e488a74775c30861e58e00fb290" dependencies: array-find "^1.0.0" debug "^2.6.8" @@ -2686,24 +2748,24 @@ eslint-module-utils@^2.2.0: debug "^2.6.8" pkg-dir "^1.0.0" -eslint-plugin-filenames@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.2.0.tgz#aee9c1c90189c95d2e49902c160eceefecd99f53" +eslint-plugin-filenames@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz#7094f00d7aefdd6999e3ac19f72cea058e590cf7" dependencies: lodash.camelcase "4.3.0" lodash.kebabcase "4.1.1" lodash.snakecase "4.1.1" lodash.upperfirst "4.3.1" -eslint-plugin-html@4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.3.tgz#97d52dcf9e22724505d02719fbd02754013c8a17" +eslint-plugin-html@4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.5.tgz#e8ec7e16485124460f3bff312016feb0a54d9659" dependencies: htmlparser2 "^3.8.2" -eslint-plugin-import@^2.12.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.12.0.tgz#dad31781292d6664b25317fd049d2e2b2f02205d" +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" dependencies: contains-path "^0.1.0" debug "^2.6.8" @@ -2716,93 +2778,105 @@ eslint-plugin-import@^2.12.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-jasmine@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.2.0.tgz#7135879383c39a667c721d302b9f20f0389543de" +eslint-plugin-jasmine@^2.10.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.10.1.tgz#5733b709e751f4bc40e31e1c16989bd2cdfbec97" -eslint-plugin-promise@^3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621" +eslint-plugin-promise@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" -eslint-plugin-vue@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-4.5.0.tgz#09d6597f4849e31a3846c2c395fccf17685b69c3" +eslint-plugin-vue@^5.0.0-beta.3: + version "5.0.0-beta.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-5.0.0-beta.3.tgz#f3fa9f109b76e20fc1e45a71ce7c6d567118924e" dependencies: - vue-eslint-parser "^2.0.3" + vue-eslint-parser "^3.2.1" eslint-restricted-globals@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" -eslint-scope@^3.7.1, eslint-scope@~3.7.1: +eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@~4.12.1: - version "4.12.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.1.tgz#5ec1973822b4a066b353770c3c6d69a2a188e880" +eslint@~5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.6.0.tgz#b6f7806041af01f71b3f1895cbb20971ea4b6223" dependencies: - ajv "^5.3.0" - babel-code-frame "^6.22.0" + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" chalk "^2.1.0" - concat-stream "^1.6.0" - cross-spawn "^5.1.0" - debug "^3.0.1" - doctrine "^2.0.2" - eslint-scope "^3.7.1" - espree "^3.5.2" - esquery "^1.0.0" - estraverse "^4.2.0" + cross-spawn "^6.0.5" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^2.0.0" functional-red-black-tree "^1.0.1" glob "^7.1.2" - globals "^11.0.1" - ignore "^3.3.3" + globals "^11.7.0" + ignore "^4.0.6" imurmurhash "^0.1.4" - inquirer "^3.0.6" - is-resolvable "^1.0.0" - js-yaml "^3.9.1" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" + lodash "^4.17.5" + minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" pluralize "^7.0.0" progress "^2.0.0" + regexpp "^2.0.0" require-uncached "^1.0.3" - semver "^5.3.0" + semver "^5.5.1" strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "^4.0.1" - text-table "~0.2.0" + strip-json-comments "^2.0.1" + table "^4.0.3" + text-table "^0.2.0" -espree@^3.5.2: - version "3.5.4" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" +espree@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634" dependencies: - acorn "^5.5.0" - acorn-jsx "^3.0.0" + acorn "^5.6.0" + acorn-jsx "^4.1.1" esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" -esquery@^1.0.0: +esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" dependencies: @@ -2818,7 +2892,7 @@ estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -2867,6 +2941,18 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -2913,11 +2999,11 @@ exports-loader@^0.7.0: loader-utils "^1.1.0" source-map "0.5.0" -express@^4.16.2: - version "4.16.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" +express@^4.16.2, express@^4.16.3: + version "4.16.3" + resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" dependencies: - accepts "~1.3.4" + accepts "~1.3.5" array-flatten "1.1.1" body-parser "1.18.2" content-disposition "0.5.2" @@ -2925,26 +3011,26 @@ express@^4.16.2: cookie "0.3.1" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.1" - encodeurl "~1.0.1" + depd "~1.1.2" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.1.0" + finalhandler "1.1.1" fresh "0.5.2" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" parseurl "~1.3.2" path-to-regexp "0.1.7" - proxy-addr "~2.0.2" + proxy-addr "~2.0.3" qs "6.5.1" range-parser "~1.2.0" safe-buffer "5.1.1" - send "0.16.1" - serve-static "1.13.1" + send "0.16.2" + serve-static "1.13.2" setprototypeof "1.1.0" - statuses "~1.3.1" - type-is "~1.6.15" + statuses "~1.4.0" + type-is "~1.6.16" utils-merge "1.0.1" vary "~1.1.2" @@ -2965,7 +3051,7 @@ extend@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.1, external-editor@^2.0.4: +external-editor@^2.0.1: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: @@ -2994,9 +3080,9 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" fast-json-stable-stringify@^2.0.0: version "2.0.0" @@ -3022,6 +3108,10 @@ faye-websocket@~0.11.0: dependencies: websocket-driver ">=0.5.1" +figgy-pudding@^3.1.0, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3035,12 +3125,12 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -file-loader@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" +file-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde" dependencies: loader-utils "^1.0.2" - schema-utils "^0.4.5" + schema-utils "^1.0.0" fileset@^2.0.2: version "2.0.3" @@ -3049,9 +3139,9 @@ fileset@^2.0.2: glob "^7.0.3" minimatch "^3.0.3" -filesize@^3.5.11: - version "3.6.0" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.0.tgz#22d079615624bb6fd3c04026120628a41b3f4efa" +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" fill-range@^4.0.0: version "4.0.0" @@ -3074,6 +3164,18 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -3082,6 +3184,14 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" @@ -3099,6 +3209,12 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + dependencies: + locate-path "^3.0.0" + flat-cache@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" @@ -3125,10 +3241,6 @@ for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - formdata-polyfill@^3.0.11: version "3.0.11" resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-3.0.11.tgz#c82b4b4bea3356c0a6752219e54ce1edb2a7fb5b" @@ -3190,7 +3302,7 @@ fsevents@^1.2.2: nan "^2.9.2" node-pre-gyp "^0.10.0" -function-bind@^1.0.2, function-bind@^1.1.1: +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3219,10 +3331,6 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -3259,8 +3367,8 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" "glob@5 - 7", glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3289,9 +3397,9 @@ global-modules-path@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.1.0.tgz#923ec524e8726bb0c1a4ed4b8e21e1ff80c88bbb" -globals@^11.0.1, globals@^11.1.0: - version "11.5.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" +globals@^11.1.0, globals@^11.7.0: + version "11.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" globals@^9.18.0: version "9.18.0" @@ -3372,9 +3480,9 @@ graphlib@^2.1.1: dependencies: lodash "^4.11.1" -gzip-size@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" +gzip-size@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" dependencies: duplexer "^0.1.1" pify "^3.0.0" @@ -3384,14 +3492,14 @@ handle-thing@^1.2.5: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" handlebars@^4.0.1, handlebars@^4.0.3: - version "4.0.6" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7" + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" dependencies: - async "^1.4.0" + async "^2.5.0" optimist "^0.6.1" - source-map "^0.4.4" + source-map "^0.6.1" optionalDependencies: - uglify-js "^2.6" + uglify-js "^3.1.4" has-ansi@^2.0.0: version "2.0.0" @@ -3421,6 +3529,10 @@ has-symbol-support-x@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.3.0.tgz#588bd6927eaa0e296afae24160659167fc2be4f8" +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + has-to-string-tag-x@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.3.0.tgz#78e3d98c3c0ec9413e970eb8d766249a1e13058f" @@ -3507,6 +3619,10 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +hoopy@^0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + hosted-git-info@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" @@ -3592,7 +3708,7 @@ icss-utils@^2.1.0: dependencies: postcss "^6.0.1" -ieee754@^1.1.11, ieee754@^1.1.4: +ieee754@^1.1.4: version "1.1.11" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455" @@ -3610,10 +3726,14 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.3.3, ignore@^3.3.7: +ignore@^3.3.7: version "3.3.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b" +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -3629,6 +3749,13 @@ import-local@^1.0.0: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + imports-loader@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.8.0.tgz#030ea51b8ca05977c40a3abfd9b4088fe0be9a69" @@ -3640,12 +3767,6 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" @@ -3691,28 +3812,9 @@ inquirer@3.0.6: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -inquirer@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8" +inquirer@^6.0.0, inquirer@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -3720,7 +3822,7 @@ inquirer@^6.0.0: cli-width "^2.0.0" external-editor "^3.0.0" figures "^2.0.0" - lodash "^4.3.0" + lodash "^4.17.10" mute-stream "0.0.7" run-async "^2.2.0" rxjs "^6.1.0" @@ -3728,11 +3830,12 @@ inquirer@^6.0.0: strip-ansi "^4.0.0" through "^2.3.6" -internal-ip@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" +internal-ip@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27" dependencies: - meow "^3.3.0" + default-gateway "^2.6.0" + ipaddr.js "^1.5.2" interpret@^1.0.0, interpret@^1.1.0: version "1.1.0" @@ -3746,22 +3849,26 @@ into-stream@^3.1.0: p-is-promise "^1.1.0" invariant@^2.2.0, invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" dependencies: loose-envify "^1.0.0" -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" -ipaddr.js@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" +ipaddr.js@1.8.0, ipaddr.js@^1.5.2: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -3796,8 +3903,8 @@ is-builtin-module@^1.0.0: builtin-modules "^1.0.0" is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" is-data-descriptor@^0.1.4: version "0.1.4" @@ -3952,11 +4059,9 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-resolvable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" - dependencies: - tryit "^1.0.1" +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" @@ -3967,8 +4072,10 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + dependencies: + has-symbols "^1.0.0" is-utf8@^0.2.0: version "0.2.1" @@ -4008,66 +4115,82 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" -istanbul-api@^1.1.14: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620" +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" dependencies: async "^2.1.4" fileset "^2.0.2" - istanbul-lib-coverage "^1.1.1" - istanbul-lib-hook "^1.1.0" - istanbul-lib-instrument "^1.9.1" - istanbul-lib-report "^1.1.2" - istanbul-lib-source-maps "^1.2.2" - istanbul-reports "^1.1.3" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" js-yaml "^3.7.0" mkdirp "^0.5.1" once "^1.4.0" -istanbul-lib-coverage@^1.1.1, istanbul-lib-coverage@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" +istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" -istanbul-lib-hook@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.9.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" +istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" babylon "^6.18.0" - istanbul-lib-coverage "^1.2.0" + istanbul-lib-coverage "^1.2.1" semver "^5.3.0" -istanbul-lib-report@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" +istanbul-lib-instrument@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-2.3.2.tgz#b287cbae2b5f65f3567b05e2e29b275eaf92d25e" + dependencies: + "@babel/generator" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" dependencies: - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.2.1" mkdirp "^0.5.1" path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" +istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" dependencies: debug "^3.1.0" - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.2.1" mkdirp "^0.5.1" rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" dependencies: handlebars "^4.0.3" @@ -4145,9 +4268,13 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@3.x, js-yaml@^3.7.0, js-yaml@^3.9.1: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.7.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4168,13 +4295,13 @@ json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -4210,10 +4337,10 @@ karma-chrome-launcher@^2.2.0: which "^1.2.1" karma-coverage-istanbul-reporter@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.2.tgz#a8d0c8815c7d6f6cea15a394a7c4b39ef151a939" + version "1.4.3" + resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.3.tgz#3b5dff4664fa5b8d5196b9889e3f61c1fa2b80d9" dependencies: - istanbul-api "^1.1.14" + istanbul-api "^1.3.1" minimatch "^3.0.4" karma-jasmine@^1.1.2: @@ -4242,15 +4369,14 @@ karma-sourcemap-loader@^0.3.7: graceful-fs "^4.1.2" karma-webpack@^4.0.0-beta.0: - version "4.0.0-beta.0" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-4.0.0-beta.0.tgz#2b386df6c364f588f896ffbdae57c2e51513d1ba" + version "4.0.0-rc.2" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-4.0.0-rc.2.tgz#4c194e94789842af7f0ffa0de77ee7715739c7c1" dependencies: async "^2.0.0" - babel-runtime "^6.0.0" - loader-utils "^1.0.0" - lodash "^4.0.0" + loader-utils "^1.1.0" + lodash "^4.17.10" source-map "^0.5.6" - webpack-dev-middleware "^3.0.1" + webpack-dev-middleware "^3.2.0" karma@^3.0.0: version "3.0.0" @@ -4326,21 +4452,17 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - lazy-cache@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" dependencies: set-getter "^0.1.0" -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" dependencies: - invert-kv "^1.0.0" + invert-kv "^2.0.0" levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -4355,16 +4477,6 @@ lie@~3.1.0: dependencies: immediate "~3.0.5" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -4374,6 +4486,15 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -4393,6 +4514,13 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.camelcase@4.3.0, lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -4441,9 +4569,9 @@ lodash@4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@^4.0.0, lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" +lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.5.0: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" log-symbols@^2.1.0: version "2.2.0" @@ -4465,29 +4593,13 @@ loglevel@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.4.1.tgz#95b383f91a3c2756fd4ab093667e4309161f2bcd" -loglevelnext@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.3.tgz#0f69277e73bbbf2cd61b94d82313216bf87ac66e" - -long@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - -long@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" dependencies: - js-tokens "^3.0.0" + js-tokens "^3.0.0 || ^4.0.0" -loud-rejection@^1.0.0, loud-rejection@^1.6.0: +loud-rejection@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" dependencies: @@ -4502,7 +4614,7 @@ lru-cache@2.2.x: version "2.2.4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" -lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2: +lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" dependencies: @@ -4523,14 +4635,16 @@ mamacro@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" +map-age-cleaner@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74" + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - map-stream@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" @@ -4560,11 +4674,13 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" dependencies: + map-age-cleaner "^0.1.1" mimic-fn "^1.0.0" + p-is-promise "^1.1.0" memory-fs@^0.2.0: version "0.2.0" @@ -4577,21 +4693,6 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -4635,7 +4736,7 @@ miller-rabin@^4.0.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.18: +mime-types@~2.1.15, mime-types@~2.1.18: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: @@ -4645,7 +4746,7 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -mime@^2.0.3, mime@^2.1.0, mime@^2.3.1: +mime@^2.0.3, mime@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" @@ -4673,15 +4774,15 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: minimist@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: +minimist@1.2.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" minimist@~0.0.1: version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" minipass@^2.2.1, minipass@^2.3.3: version "2.3.3" @@ -4711,6 +4812,21 @@ mississippi@^2.0.0: stream-each "^1.1.0" through2 "^2.0.0" +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -4720,7 +4836,7 @@ mixin-deep@^1.2.0: mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" @@ -4728,9 +4844,9 @@ moment@2.x, moment@^2.18.1: version "2.19.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.2.tgz#8a7f774c95a64550b4c7ebd496683908f9419dbe" -monaco-editor-webpack-plugin@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.5.2.tgz#e113fa1d5759ede6fd776eb620cdd5930203b55a" +monaco-editor-webpack-plugin@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.5.4.tgz#6781a130e3e1379bb8f4cd190132f4af6dcd2c16" monaco-editor@^0.14.3: version "0.14.3" @@ -4755,6 +4871,10 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -4869,9 +4989,9 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -nodemon@^1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.2.tgz#36b89c790da70c4f270e2cc0718723131bc04abb" +nodemon@^1.18.4: + version "1.18.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" dependencies: chokidar "^2.0.2" debug "^3.1.0" @@ -4903,7 +5023,7 @@ nopt@~1.0.10: dependencies: abbrev "1" -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: @@ -4976,9 +5096,9 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" object-visit@^1.0.0: version "1.0.1" @@ -4986,6 +5106,24 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.entries@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -5029,9 +5167,9 @@ opencollective@^1.0.3: node-fetch "1.6.3" opn "4.0.2" -opener@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" opn@4.0.2: version "4.0.2" @@ -5078,13 +5216,13 @@ os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" @@ -5101,6 +5239,10 @@ p-cancelable@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -5115,12 +5257,24 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + p-map@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a" @@ -5135,6 +5289,10 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -5172,6 +5330,13 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse5@^5: version "5.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.0.0.tgz#4d02710d44f3c3846197a11e205d4ef17842b81a" @@ -5227,27 +5392,25 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -5300,6 +5463,12 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + dependencies: + find-up "^3.0.0" + pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -5383,10 +5552,14 @@ prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" -prettier@1.12.1, prettier@^1.11.1: +prettier@1.12.1: version "1.12.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" +prettier@1.13.7: + version "1.13.7" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" + prismjs@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.6.0.tgz#118d95fb7a66dba2272e343b345f5236659db365" @@ -5417,12 +5590,12 @@ promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" -proxy-addr@~2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" +proxy-addr@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" dependencies: forwarded "~0.1.2" - ipaddr.js "1.6.0" + ipaddr.js "1.8.0" prr@~1.0.1: version "1.0.1" @@ -5461,6 +5634,13 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" @@ -5473,6 +5653,10 @@ punycode@1.3.2, punycode@^1.2.4: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + qjobs@^1.1.4: version "1.2.0" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" @@ -5554,13 +5738,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -5568,13 +5745,12 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" + find-up "^3.0.0" + read-pkg "^3.0.0" read-pkg@^2.0.0: version "2.0.0" @@ -5584,6 +5760,14 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -5616,13 +5800,6 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" @@ -5632,8 +5809,8 @@ regenerator-runtime@^0.10.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" regenerator-transform@^0.10.0: version "0.10.1" @@ -5650,6 +5827,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365" + regexpu-core@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" @@ -5701,7 +5882,7 @@ repeat-string@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" @@ -5779,12 +5960,6 @@ rfdc@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.2.tgz#e6e72d74f5dc39de8f538f65e00c36c18018e349" -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" @@ -5814,16 +5989,6 @@ rw@1: version "1.3.3" resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" @@ -5868,13 +6033,21 @@ sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.3, schema-utils@^0.4.4, schema-utils@^0.4.5: +schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" dependencies: ajv "^6.1.0" ajv-keywords "^3.1.0" +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -5899,18 +6072,18 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" -send@0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" dependencies: debug "2.6.9" - depd "~1.1.1" + depd "~1.1.2" destroy "~1.0.4" - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" @@ -5919,7 +6092,7 @@ send@0.16.1: ms "2.0.0" on-finished "~2.3.0" range-parser "~1.2.0" - statuses "~1.3.1" + statuses "~1.4.0" serialize-javascript@^1.4.0: version "1.4.0" @@ -5937,14 +6110,14 @@ serve-index@^1.7.2: mime-types "~2.1.15" parseurl "~1.3.1" -serve-static@1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" dependencies: - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.2" - send "0.16.1" + send "0.16.2" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -6105,9 +6278,9 @@ socket.io@2.1.1: socket.io-client "2.1.1" socket.io-parser "~3.2.0" -sockjs-client@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" +sockjs-client@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.5.tgz#1bb7c0f7222c40f42adf14f4442cbd1269771a83" dependencies: debug "^2.6.6" eventsource "0.1.6" @@ -6161,13 +6334,7 @@ source-map@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.0.tgz#0fe96503ac86a5adb5de63f4e412ae4872cdbe86" -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -6251,6 +6418,12 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" +ssri@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + dependencies: + figgy-pudding "^3.5.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -6258,7 +6431,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2", statuses@~1.3.1: +"statuses@>= 1.3.1 < 2", statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" @@ -6364,19 +6541,13 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -style-loader@^0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.21.0.tgz#68c52e5eb2afc9ca92b6274be277ee59aea3a852" +style-loader@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.0.tgz#8377fefab68416a2e05f1cabd8c3a3acfcce74f1" dependencies: loader-utils "^1.1.0" schema-utils "^0.4.5" @@ -6392,8 +6563,8 @@ supports-color@^3.1.0, supports-color@^3.1.2: has-flag "^1.0.0" supports-color@^5.1.0, supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" dependencies: has-flag "^3.0.0" @@ -6401,12 +6572,12 @@ svg4everybody@2.1.9: version "2.1.9" resolved "https://registry.yarnpkg.com/svg4everybody/-/svg4everybody-2.1.9.tgz#5bd9f6defc133859a044646d4743fabc28db7e2d" -table@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" +table@^4.0.3: + version "4.0.3" + resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" dependencies: - ajv "^5.2.3" - ajv-keywords "^2.1.0" + ajv "^6.0.1" + ajv-keywords "^3.0.0" chalk "^2.1.0" lodash "^4.17.4" slice-ansi "1.0.0" @@ -6416,9 +6587,9 @@ tapable@^0.1.8: version "0.1.10" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" -tapable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" tar@^4: version "4.4.4" @@ -6438,17 +6609,16 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -test-exclude@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" +test-exclude@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" dependencies: arrify "^1.0.1" - micromatch "^3.1.8" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" require-main-filename "^1.0.1" -text-table@~0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -6557,10 +6727,6 @@ traverse@0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -6569,10 +6735,6 @@ tryer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" -tryit@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" - tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -6587,7 +6749,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-is@~1.6.15: +type-is@~1.6.15, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: @@ -6609,18 +6771,12 @@ uglify-es@^3.3.4: commander "~2.13.0" source-map "~0.6.1" -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + commander "~2.17.1" + source-map "~0.6.1" uglifyjs-webpack-plugin@^1.2.4: version "1.2.5" @@ -6713,6 +6869,12 @@ update-notifier@^2.3.0: semver-diff "^2.0.0" xdg-basedir "^3.0.0" +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -6721,13 +6883,13 @@ url-join@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a" -url-loader@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.0.1.tgz#61bc53f1f184d7343da2728a1289ef8722ea45ee" +url-loader@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.1.tgz#4d1f3b4f90dde89f02c008e662d604d7511167c1" dependencies: loader-utils "^1.1.0" mime "^2.0.3" - schema-utils "^0.4.3" + schema-utils "^1.0.0" url-parse-lax@^1.0.0: version "1.0.0" @@ -6795,7 +6957,7 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid@^3.0.1, uuid@^3.1.0: +uuid@^3.0.1, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -6828,16 +6990,16 @@ void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" -vue-eslint-parser@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1" +vue-eslint-parser@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-3.2.2.tgz#47c971ee4c39b0ee7d7f5e154cb621beb22f7a34" dependencies: debug "^3.1.0" - eslint-scope "^3.7.1" + eslint-scope "^4.0.0" eslint-visitor-keys "^1.0.0" - espree "^3.5.2" - esquery "^1.0.0" - lodash "^4.17.4" + espree "^4.0.0" + esquery "^1.0.1" + lodash "^4.17.10" vue-functional-data-merge@^2.0.5: version "2.0.6" @@ -6847,11 +7009,11 @@ vue-hot-reload-api@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926" -vue-loader@^15.2.4: - version "15.2.4" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.2.4.tgz#a7b923123d3cf87230a8ff54a1c16d31a6c5dbb4" +vue-loader@^15.4.2: + version "15.4.2" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.4.2.tgz#812bb26e447dd3b84c485eb634190d914ce125e2" dependencies: - "@vue/component-compiler-utils" "^1.2.1" + "@vue/component-compiler-utils" "^2.0.0" hash-sum "^1.0.2" loader-utils "^1.1.0" vue-hot-reload-api "^2.3.0" @@ -6874,9 +7036,9 @@ vue-style-loader@^4.1.0: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.5.0, vue-template-compiler@^2.5.16: - version "2.5.16" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb" +vue-template-compiler@^2.5.0, vue-template-compiler@^2.5.17: + version "2.5.17" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.17.tgz#52a4a078c327deb937482a509ae85c06f346c3cb" dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -6889,9 +7051,9 @@ vue-virtual-scroll-list@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.2.5.tgz#bcbd010f7cdb035eba8958ebf807c6214d9a167a" -vue@^2.5.16: - version "2.5.16" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085" +vue@^2.5.16, vue@^2.5.17: + version "2.5.17" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada" vuex@^3.0.1: version "3.0.1" @@ -6911,26 +7073,26 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" -webpack-bundle-analyzer@^2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz#07d2176c6e86c3cdce4c23e56fae2a7b6b4ad526" +webpack-bundle-analyzer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.2.tgz#22f19ea6d1b5a15fd7a90baae0bc0f39bd1e4d48" dependencies: - acorn "^5.3.0" - bfj-node4 "^5.2.0" - chalk "^2.3.0" - commander "^2.13.0" - ejs "^2.5.7" - express "^4.16.2" - filesize "^3.5.11" - gzip-size "^4.1.0" - lodash "^4.17.4" + acorn "^5.7.3" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.10" mkdirp "^0.5.1" - opener "^1.4.3" - ws "^4.0.0" + opener "^1.5.1" + ws "^6.0.0" -webpack-cli@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.0.8.tgz#90eddcf04a4bfc31aa8c0edc4c76785bc4f1ccd9" +webpack-cli@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994" dependencies: chalk "^2.4.1" cross-spawn "^6.0.5" @@ -6942,26 +7104,25 @@ webpack-cli@^3.0.8: loader-utils "^1.1.0" supports-color "^5.4.0" v8-compile-cache "^2.0.0" - yargs "^11.1.0" + yargs "^12.0.1" -webpack-dev-middleware@3.1.3, webpack-dev-middleware@^3.0.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz#8b32aa43da9ae79368c1bf1183f2b6cf5e1f39ed" +webpack-dev-middleware@3.2.0, webpack-dev-middleware@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.2.0.tgz#a20ceef194873710052da678f3c6ee0aeed92552" dependencies: loud-rejection "^1.6.0" memory-fs "~0.4.1" - mime "^2.1.0" + mime "^2.3.1" path-is-absolute "^1.0.0" range-parser "^1.0.3" url-join "^4.0.0" - webpack-log "^1.0.1" + webpack-log "^2.0.0" -webpack-dev-server@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz#9a08d13c4addd1e3b6d8ace116e86715094ad5b4" +webpack-dev-server@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.8.tgz#eb7a95945d1108170f902604fb3b939533d9daeb" dependencies: ansi-html "0.0.7" - array-includes "^3.0.3" bonjour "^3.5.0" chokidar "^2.0.0" compression "^1.5.2" @@ -6971,36 +7132,35 @@ webpack-dev-server@^3.1.4: express "^4.16.2" html-entities "^1.2.0" http-proxy-middleware "~0.18.0" - import-local "^1.0.0" - internal-ip "1.2.0" + import-local "^2.0.0" + internal-ip "^3.0.1" ip "^1.1.5" killable "^1.0.0" loglevel "^1.4.1" opn "^5.1.0" portfinder "^1.0.9" + schema-utils "^1.0.0" selfsigned "^1.9.1" serve-index "^1.7.2" sockjs "0.3.19" - sockjs-client "1.1.4" + sockjs-client "1.1.5" spdy "^3.4.1" strip-ansi "^3.0.0" supports-color "^5.1.0" - webpack-dev-middleware "3.1.3" - webpack-log "^1.1.2" - yargs "11.0.0" + webpack-dev-middleware "3.2.0" + webpack-log "^2.0.0" + yargs "12.0.2" -webpack-log@^1.0.1, webpack-log@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" dependencies: - chalk "^2.1.0" - log-symbols "^2.1.0" - loglevelnext "^1.0.1" - uuid "^3.1.0" + ansi-colors "^3.0.0" + uuid "^3.3.2" -webpack-sources@^1.0.1, webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" +webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" @@ -7009,22 +7169,21 @@ webpack-stats-plugin@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/webpack-stats-plugin/-/webpack-stats-plugin-0.2.1.tgz#1f5bac13fc25d62cbb5fd0ff646757dc802b8595" -webpack@^4.16.0: - version "4.16.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.0.tgz#660dae90890e55b8ed17c6f9d17bebb01dab5b4c" +webpack@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.19.1.tgz#096674bc3b573f8756c762754366e5b333d6576f" dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/wasm-edit" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" + "@webassemblyjs/ast" "1.7.6" + "@webassemblyjs/helper-module-context" "1.7.6" + "@webassemblyjs/wasm-edit" "1.7.6" + "@webassemblyjs/wasm-parser" "1.7.6" acorn "^5.6.2" acorn-dynamic-import "^3.0.0" ajv "^6.1.0" ajv-keywords "^3.1.0" chrome-trace-event "^1.0.0" enhanced-resolve "^4.1.0" - eslint-scope "^3.7.1" + eslint-scope "^4.0.0" json-parse-better-errors "^1.0.2" loader-runner "^2.3.0" loader-utils "^1.1.0" @@ -7034,10 +7193,10 @@ webpack@^4.16.0: neo-async "^2.5.0" node-libs-browser "^2.0.0" schema-utils "^0.4.4" - tapable "^1.0.0" + tapable "^1.1.0" uglifyjs-webpack-plugin "^1.2.4" watchpack "^1.5.0" - webpack-sources "^1.0.1" + webpack-sources "^1.2.0" websocket-driver@>=0.5.1: version "0.6.5" @@ -7071,14 +7230,6 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -7126,13 +7277,11 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-4.0.0.tgz#bfe1da4c08eeb9780b986e0e4d10eccd7345999f" +ws@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.0.0.tgz#eaa494aded00ac4289d455bac8d84c7c651cef35" dependencies: async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" ws@~3.3.1: version "3.3.3" @@ -7158,6 +7307,10 @@ xmlhttprequest@1: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -7166,11 +7319,7 @@ xterm@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.5.0.tgz#ba3f464bc5730c9d259ebe62131862224db9ddcc" -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -y18n@^4.0.0: +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -7182,54 +7331,28 @@ yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" -yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" dependencies: camelcase "^4.1.0" -yargs@11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b" - dependencies: - cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^9.0.2" - -yargs@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" +yargs@12.0.2, yargs@^12.0.1: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" dependencies: cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" + decamelize "^2.0.0" + find-up "^3.0.0" get-caller-file "^1.0.1" - os-locale "^2.0.0" + os-locale "^3.0.0" require-directory "^2.1.1" require-main-filename "^1.0.1" set-blocking "^2.0.0" string-width "^2.0.0" which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^9.0.2" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" yeast@0.1.2: version "0.1.2" |
