Commit 332dad45 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce_upstream' into 'master'

CE upstream

Closes gitlab-ce#29554

See merge request !1475
parents 28baca8a 87b81fa6
...@@ -376,7 +376,8 @@ trigger_docs: ...@@ -376,7 +376,8 @@ trigger_docs:
cache: {} cache: {}
artifacts: {} artifacts: {}
script: script:
- "curl -X POST -F token=${DOCS_TRIGGER_TOKEN} -F ref=master -F variables[PROJECT]=ee https://gitlab.com/api/v3/projects/1794617/trigger/builds" - "HTTP_STATUS=$(curl -X POST -F token=${DOCS_TRIGGER_TOKEN} -F ref=master -F variables[PROJECT]=${CI_PROJECT_NAME} --silent --output curl.log --write-out '%{http_code}' https://gitlab.com/api/v3/projects/1794617/trigger/builds)"
- if [ "${HTTP_STATUS}" -ne "201" ]; then echo "Error ${HTTP_STATUS}"; cat curl.log; echo; exit 1; fi
only: only:
- master@gitlab-org/gitlab-ee - master@gitlab-org/gitlab-ee
......
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
## 9.0.0 (2017-03-22)
- Geo: Replicate repository creation in Geo secondary node. !952
- Make approval system notes lowercase. !1125
- Issues can be exported as CSV, via email. !1126
- Try to update mirrors again after 15 minutes if the previous update failed. !1183
- Adds abitlity to render deploy boards in the frontend side. !1233
- Add filtered search to MR page. !1243
- Update project list API returns with approvals_before_merge attribute. !1245 (Geoff Webster)
- Catch Net::LDAP::DN exceptions in EE::Gitlab::LDAP::Group. !1260
- API: Use `post ":id/#{type}/:subscribable_id/subscribe"` to subscribe and `post ":id/#{type}/:subscribable_id/unsubscribe"` to unsubscribe from a resource. !1274 (Robert Schilling)
- API: Remove deprecated fields Notes#upvotes and Notes#downvotes. !1275 (Robert Schilling)
- Deploy board backend. !1278
- API: Remove the ProjectGitHook API. !1301 (Robert Schilling)
- Expose elasticsearch client params for AWS signing and HTTPS. !1305 (Matt Gresko)
- Fix LDAP DN case-mismatch bug in LDAP group sync. !1337
- Remove es6 file extension from JavaScript files. !1344 (winniehell)
- Geo: Don't load dependent models when fetching an existing GeoNode from the database. !1348
- Parallelise the gitlab:elastic:index_database Rake task. !1361
- Robustify reading attributes for elasticsearch. !1365
- Introduce one additional thread into bin/elastic_repo_indexer. !1372
- Show hook errors for fast-forward merges. !1375
- Allow all parameters of group webhooks to be set through the UI. !1376
- Fix Elasticsearch queries when a group_id is specified. !1423
- Check the right index mapping based on Rails environment for rake gitlab:elastic:add_feature_visiblity_levels_to_project. !1473
- Fix issues with another milestone that has a matching list label could not be added to a board.
- Only admins or group owners can set LDAP overrides.
- Add support for load balancing database queries.
- Only replace non-approval mr-widget-footer on getMergeStatus.
- Remove repository_storage from V4 "/application/settings" settings API.
- Added headers to protected branches access dropdowns.
- Remove support for Git Annex.
- Repositioned multiple issue boards selector.
- Added back weight in issue rows on issue list.
- Add basic support for GitLab Geo file transfers over HTTP.
- Added weight slash command.
- Set deployment status invalid when the environments does not match a k8s label.
- Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called Repository.
- Rebase - fix commiter email & name.
- Adds a EE specific dev favicon.
- Elastic security fix: Respect feature visibility level.
- Update Elasticsearch to 5.1.
- [Elasticsearch] More efficient search.
- Get Geo secondaries nodes statuses over AJAX.
## 8.17.4 (2017-03-19) ## 8.17.4 (2017-03-19)
- Elastic security fix: Respect feature visibility level. - Elastic security fix: Respect feature visibility level.
...@@ -954,51 +999,6 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -954,51 +999,6 @@ Please view this file on the master branch, on stable branches it's out of date.
- Add documentation for "Share project with group" API call - Add documentation for "Share project with group" API call
- Ability to disable 'Share with Group' feature (via UI and API) - Ability to disable 'Share with Group' feature (via UI and API)
## 9.0.0 (2017-03-22)
- Geo: Replicate repository creation in Geo secondary node. !952
- Make approval system notes lowercase. !1125
- Issues can be exported as CSV, via email. !1126
- Try to update mirrors again after 15 minutes if the previous update failed. !1183
- Adds abitlity to render deploy boards in the frontend side. !1233
- Add filtered search to MR page. !1243
- Update project list API returns with approvals_before_merge attribute. !1245 (Geoff Webster)
- Catch Net::LDAP::DN exceptions in EE::Gitlab::LDAP::Group. !1260
- API: Use `post ":id/#{type}/:subscribable_id/subscribe"` to subscribe and `post ":id/#{type}/:subscribable_id/unsubscribe"` to unsubscribe from a resource. !1274 (Robert Schilling)
- API: Remove deprecated fields Notes#upvotes and Notes#downvotes. !1275 (Robert Schilling)
- Deploy board backend. !1278
- API: Remove the ProjectGitHook API. !1301 (Robert Schilling)
- Expose elasticsearch client params for AWS signing and HTTPS. !1305 (Matt Gresko)
- Fix LDAP DN case-mismatch bug in LDAP group sync. !1337
- Remove es6 file extension from JavaScript files. !1344 (winniehell)
- Geo: Don't load dependent models when fetching an existing GeoNode from the database. !1348
- Parallelise the gitlab:elastic:index_database Rake task. !1361
- Robustify reading attributes for elasticsearch. !1365
- Introduce one additional thread into bin/elastic_repo_indexer. !1372
- Show hook errors for fast-forward merges. !1375
- Allow all parameters of group webhooks to be set through the UI. !1376
- Fix Elasticsearch queries when a group_id is specified. !1423
- Check the right index mapping based on Rails environment for rake gitlab:elastic:add_feature_visiblity_levels_to_project. !1473
- Fix issues with another milestone that has a matching list label could not be added to a board.
- Only admins or group owners can set LDAP overrides.
- Add support for load balancing database queries.
- Only replace non-approval mr-widget-footer on getMergeStatus.
- Remove repository_storage from V4 "/application/settings" settings API.
- Added headers to protected branches access dropdowns.
- Remove support for Git Annex.
- Repositioned multiple issue boards selector.
- Added back weight in issue rows on issue list.
- Add basic support for GitLab Geo file transfers over HTTP.
- Added weight slash command.
- Set deployment status invalid when the environments does not match a k8s label.
- Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called Repository.
- Rebase - fix commiter email & name.
- Adds a EE specific dev favicon.
- Elastic security fix: Respect feature visibility level.
- Update Elasticsearch to 5.1.
- [Elasticsearch] More efficient search.
- Get Geo secondaries nodes statuses over AJAX.
## 8.0.6 ## 8.0.6
- No EE-specific changes - No EE-specific changes
......
...@@ -2,13 +2,296 @@ ...@@ -2,13 +2,296 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 8.17.4 (2017-03-19) ## 9.0.0 (2017-03-22)
- Remove the newrelic gem. !1335 (Robert Schilling)
- Fix inconsistent naming for services that delete things. !5803 (dixpac)
- UI: Allow a project variable to be set to an empty value. !6044 (Lukáš Nový)
- Align task list checkboxes. !6487 (Jared Deckard <jared.deckard@gmail.com>)
- SanitizationFilter allows html5 details and summary tags. !6568
- on branch deletion show loading icon and disabled the button. !6761 (wendy0402)
- Use an entity for RepoBranch commits and enhance RepoCommit. !7138 (Ben Boeckel)
- Deleting a user doesn't delete issues they've created/are assigned to. !7393
- Fix position of counter in milestone panels. !7842 (Andrew Smith (EspadaV8))
- Added a feature to create a 'directly addressed' Todo when mentioned in the beginning of a line. !7926 (Ershad Kunnakkadan)
- Implement OpenID Connect identity provider. !8018 (Markus Koller)
- Show directory hierarchy when listing wiki pages. !8133 (Alex Braha Stoll)
- Migrate SlackService and MattermostService from build_events to pipeline_events, and migrate BuildsEmailService to PipelinesEmailService. Update Hipchat to use pipeline events rather than build events. !8196
- Execute web hooks for WikiPage delete operation. !8198
- Added external environment link to web terminal view. !8303
- Responsive title in diffs inline, side by side, with and without sidebar. !8475
- Bypass email domain validation when a user is created by an admin. !8575 (Reza Mohammadi @remohammadi)
- API: Paginate all endpoints that return an array. !8606 (Robert Schilling)
- pass in current_user in MergeRequest and MergeRequestsHelper. !8624 (Dongqing Hu)
- Add user & build links in Slack Notifications. !8641 (Poornima M)
- Todo done clicking is kind of unusable. !8691 (Jacopo Beschi @jacopo-beschi)
- Filter todos by manual add. !8691 (Jacopo Beschi @jacopo-beschi)
- Add runner version to /admin/runners view. !8733 (Jonathon Reinhart)
- API: remove `public` param for projects. !8736
- Allow creating nested groups via UI. !8786
- API: Add environment stop action. !8808
- Add discussion events to contributions calendar. !8821
- Unify issues search behavior by always filtering when ALL labels matches. !8849
- V3 deprecated templates endpoints removal. !8853
- Expose pipelines as PipelineBasic `api/v3/projects/:id/pipelines`. !8875
- Alphabetically sort tags on runner list. !8922 (blackst0ne)
- Added documentation for permalinks to most recent build artifacts. !8934 (Christian Godenschwager)
- Standardize branch name params as branch on V4 API. !8936
- Move /projects/fork/:id to /projects/:id/fork. !8940
- Fix small height of activity header page. !8952 (Pavel Sorokin)
- Optionally make users created via the API set their password. !8957 (Joost Rijneveld)
- GitHub Importer - Find users based on GitHub email address. !8958
- API: Consolidate /projects endpoint. !8962
- Add filtered search visual tokens. !8969
- Store group and project full name and full path in routes table. !8979
- Add internal API to notify Gitaly of post receive. !8983
- Remove inactive default email services. !8987
- Option to prevent signing in from multiple ips. !8998
- Download snippets with LF line-endings by default. !8999
- Fixes dropdown width in admin project page. !9002
- fixes issue number alignment problem in MR and issue list. !9020
- Fix CI/CD pipeline retry and take stages order into account. !9021
- Make stuck builds detection more performant. !9025
- Filter by projects in the end of search. !9030
- Add nested groups to the API. !9034
- Use ETag to improve performance of issue notes polling. !9036
- Add the oauth2_generic OmniAuth strategy. !9048 (Joe Marty)
- Brand header logo for pipeline emails. !9049 (Alexis Reigel)
- replace npm with yarn and add yarn.lock. !9055
- Fix displaying error messages for create label dropdown. !9058 (Tom Koole)
- Set dropdown height fixed to 250px and make it scrollable. !9063
- Update API docs for new namespace format. !9073 (Markus Koller)
- Replace static fixture for behaviors/quick_submit_spec.js. !9086 (winniehell)
- Use iids as filter parameter. !9096
- Manage user personal access tokens through api and add impersonation tokens. !9099 (Simon Vocella)
- Added the ability to copy a branch name to the clipboard. !9103 (Glenn Sayers)
- Rename Files::DeleteService to Files::DestroyService. !9110 (dixpac)
- Fixes FE Doc broken link. !9120
- Add git version to gitlab:env:info. !9128 (Semyon Pupkov)
- Replace static fixture for new_branch_spec.js. !9131 (winniehell)
- Reintroduce coverage report for JavaScript. !9133 (winniehell)
- Fix MR widget jump. !9146
- Avoid calling Build#trace_with_state for performance. !9149 (Takuya Noguchi)
- fix background color for labels mention in todo. !9155 (mhasbini)
- Replace static fixture for behaviors/requires_input_spec.js. !9162 (winniehell)
- Added AsciiDoc Snippet to CI/CD Badges. !9164 (Jan Christophersen)
- Make Karma output look nicer for CI. !9165 (winniehell)
- show 99+ for large count in todos notification bell. !9171 (mhasbini)
- Replace static fixture for header_spec.js. !9174 (winniehell)
- Replace static fixture for project_title_spec.js. !9175 (winniehell)
- Fixes markdown in activity-feed is gray. !9179
- Show notifications settings dropdown even if repository feature is disabled. !9180
- Fixes job dropdown action throws error in js console. !9182
- Set maximum width for mini pipeline graph text so it is not truncated to early. !9188
- Added 'Most Recent Activity' header to the User Profile page. !9189 (Jan Christophersen)
- Show Issues mentioned / being closed from a Merge Requests title below the 'Accept Merge Request' button. !9194 (Jan Christophersen)
- Stop linking to deleted Branches in Activity tabs. !9203 (Jan Christophersen)
- Make it possible to pass coverage value to commit status API. !9214 (wendy0402)
- Add admin setting for default artifacts expiration. !9219
- add :iids param to IssuableFinder (resolve technical dept). !9222 (mhasbini)
- Add Links to Branches in Calendar Activity. !9224 (Jan Christophersen)
- Fix pipeline retry and cancel buttons on pipeline details page. !9225
- Remove es6 file extension from JavaScript files. !9241 (winniehell)
- Add Runner's registration/deletion v4 API. !9246
- Add merge request count to each issue on issues list. !9252 (blackst0ne)
- Fix error in MR widget after /merge slash command. !9259
- Clean-up Project navigation order. !9272
- Add Runner's jobs v4 API. !9273
- Add pipeline trigger API with user permissions. !9277
- Enhanced filter issues layout for better mobile experiance. !9280 (Pratik Borsadiya)
- Move babel config for instanbul to karma config. !9286 (winniehell)
- Document U2F limitations with multiple URLs. !9300
- Wrap long Project and Group titles. !9301
- Clean-up Groups navigation order. !9309
- Truncate long Todo titles for non-mobile screens. !9311
- add rake tasks to handle yarn dependencies and update documentation. !9316
- API: - Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. !9325 (Robert Schilling)
- API: Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar`. !9328 (Robert Schilling)
- API: Use `visibility` as string parameter everywhere. !9337
- Add the Username to the HTTP(S) clone URL of a Repository. !9347 (Jan Christophersen)
- Add spec for todo with target_type Commit. !9351 (George Andrinopoulos)
- Fixes includes line number during unfold copy n paste in parallel diff view. !9365
- API: Remove `DELETE projects/:id/deploy_keys/:key_id/disable`. !9365 (Robert Schilling)
- API: Use POST to (un)block a user. !9371 (Robert Schilling)
- Remove markup that was showing in tooltip for renamed files. !9374
- Drop unused ci_projects table and some unused project_id columns, then rename gl_project_id to project_id. Stop exporting job trace when exporting projects. !9378 (David Wagner)
- Adds remote logout functionality to the Authentiq OAuth provider. !9381 (Alexandros Keramidas)
- Introduce /award slash command; Allow posting of just an emoji in comment. !9382 (mhasbini)
- API: Remove deprecated fields Notes#upvotes and Notes#downvotes. !9384 (Robert Schilling)
- Redo internals of Incoming Mail Support. !9385
- update Vue to v2.1.10. !9386
- Add button to create issue for failing build. !9391 (Alex Sanford)
- test compiling production assets and generate webpack bundle report in CI. !9396
- API: Return 204 for all delete endpoints. !9397 (Robert Schilling)
- Add KUBE_CA_PEM_FILE, deprecate KUBE_CA_PEM. !9398
- API: Use POST requests to mark todos as done. !9410 (Robert Schilling)
- API project create: Make name or path required. !9416
- Add housekeeping endpoint for Projects API. !9421
- Fixes delimiter removes when todo marked as done. !9435
- Document when current coverage configuration option was introduced. !9443
- Uploaded files which content can change now require revalidation on each page load. !9453
- Only add a newline in the Markdown Editor if the current line is not empty. !9455 (Jan Christophersen)
- Rename builds to job for the v4 API. !9463
- API: Remove /groups/owned endpoint. !9505 (Robert Schilling)
- API: Return 400 for all validation erros in the mebers API. !9523 (Robert Schilling)
- Fixes large file name tooltip cutoff in diff header. !9529
- Keep consistent in handling indexOf results. !9531 (Takuya Noguchi)
- Make documentation of list repository tree API call more detailed. !9532 (Marius Kleiner)
- Fix Sort dropdown reflow issue. !9533 (Jarkko Tuunanen)
- Improve grammar in GitLab flow documentation. !9552 (infogrind)
- Change default project view for user from readme to files view. !9584
- Make it possible to configure blocking manual actions. !9585
- Show public RSS feeds to anonymous users. !9596 (Michael Kozono)
- Update storage settings to allow extra values per repository storage. !9597
- Enable filtering milestones by search criteria in the API. !9606
- Ensure archive download is only one directory deep. !9616
- Fix updaing commit status when using optional attributes. !9618
- Add filter and sorting to dashboard groups page. !9619
- Remove deprecated build status badge and related services. !9620
- Rename table ci_commits to ci_pipelines. !9638
- Remove various unused CI tables and columns. !9639
- Use webpack CommonsChunkPlugin to place common javascript libraries in their own bundles. !9647
- CORS: Whitelist pagination headers. !9651 (Robert Schilling)
- Remove "subscribed" field from API responses returning list of issues or merge requests. !9661
- Highlight line number if specified on diff pages when page loads. !9664
- Set default cache key to "default" for jobs. !9666
- Set max height to screen height for Zen mode. !9667
- GET 'projects/:id/repository/commits' endpoint improvements. !9679 (George Andrinopoulos, Jordan Ryan Reuter)
- 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 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
- Use gitlab-workhorse 1.4.0. !9724
- Add GET /projects/:id/pipelines/:pipeline_id/jobs endpoint. !9727
- Restrict nested group names to prevent ambiguous routes. !9738
- Rename job environment variables to new terminology. !9756
- Deprecate usage of `types` configuration entry to describe CI/CD stages. !9766
- Moved project settings from the gear drop-down menu to a tab. !9786
- Fix "passed with warnings" stage status on MySQL installations. !9802
- Fix for creating a project through API when import_url is nil. !9841
- Use GitLab Pages v0.4.0. !9896
- Reserve few project and nested group paths that have wildcard routes associated. !9898
- Speed up project dashboard by caching pipeline status and eager loading routes. !9903
- Fixes n+1 query for tags and branches index page. !9905
- Hide ancestor groups in the share group dropdown list. !9965
- Allow creating merge request even if target branch is not specified in query params. !9968
- Removed d3 from the main application.js bundle. !10062
- Return 404 in project issues API endpoint when project cannot be found. !10093
- Add frequently used emojis back to awards menu.
- Add filtered search to MR page.
- Re-add the New Project button in nav bar.
- Show members of parent groups on project members page.
- Set Auto-Submitted header to mails. (Semyon Pupkov)
- Return 202 with JSON body on async removals on V4 API.
- Stop setting Strict-Transport-Securty header from within the app.
- Use "branch_name" instead "branch" on V3 branch creation API.
- Adds paginationd and folders view to environments table.
- Fix archive prefix bug for refs containing dots.
- ensure MR widget dropdown is same color as button.
- hide loading spinners for server-rendered sidebar fields.
- Decrease tanuki logo size.
- Add filter param for project membership for current_user in API v4.
- Add limit to the number of events showed in cycle analytics.
- Remove help link from right dropdown.
- Fix jobs table header height.
- Update account view to display new username.
- Narrow environment payload by using basic project details resource.
- Make a default namespace of Kubernetes service to contain project ID.
- Fix issues mentioned but not closed for external issue trackers.
- fix milestone does not automatically assign when create issue from milestone.
- Present GitLab version for each V3 to V4 API change on v3_to_v4.md.
- Format timeago date to short format.
- Fix errors in slash commands matcher, add simple test coverage. (YarNayar)
- Re-add Assign to me link to Merge Request and Issues.
- Added option to update to owner for group members.
- Add badges to global dropdown.
- Introduce Pipeline Triggers that are user-aware.
- Fixed loading spinner position on issue template toggle.
- Removed duplicate "Visibility Level" label on New Project page. (Robert Marcano)
- Fix 'New Tag' layout on Tags page. (Robert Marcano)
- Update API endpoints for raw files.
- Fix issuable stale object error handler for js when updating tasklists.
- Gather issuable metadata to avoid n+1 queries on index view.
- Remove JIRA closed status icon.
- Changed coverage reg expression placeholder text to be more like a placeholder.
- Make Git history follow renames again by performing the --skip in Ruby.
- Fixed long file names overflowing under action buttons.
- Fix grammer issue in admin/runners.
- Add Mock CI service/integration for development.
- Move tag services to Tags namespace. (dixpac)
- Removes label when moving issue to another list that it is currently in.
- Improved diff comment button UX.
- Allow slashes in slash command arguments.
- Only create unmergeable todos once when MR fails to merge.
- Only yield valid references in ReferenceFilter.references_in.
- Adds API endpoint to fetch all merge request for a single milestone. (Joren De Groof)
- Add member: Always return 409 when a member exists.
- Change development tanuki favicon colors to match logo color order.
- API issues - support filtering by iids.
- Rename priority sorting option to label priority.
- Added headers to protected branch access dropdowns.
- Remove plus icon from MR button on compare view.
- removed unused parameter 'status_only: true'.
- Fix positioning of `Scroll to top` button.
- Hide issue info when project issues are disabled. (George Andrinopoulos)
- Replaced jQuery UI datepicker.
- Removed jQuery UI highlight & autocomplete.
- Replaced jQuery UI sortable.
- Only run timeago loops after rendering timeago components.
- Remove readme-only project view preference.
- Remove tooltips from label subscription buttons.
- Increase right side of file header to button stays on same line.
- Centers loading icon vertically and horizontally in pipelines table in commit view.
- Rename retry failed button on pipeline page to just retry.
- Align bulk update issues button to the right.
- Remove remnants of git annex support.
- Pick up option from GDK to disable webpack dev server livereload.
- Fix z index issues with sidebar.
- Change project count limit from 10 to 100000.
- Remove repeated routes.path check for postgresql database. (mhasbini)
- Fixed RSS button alignment on activity pages.
- Seed abuse reports for development.
- Only show public emails in atom feeds. - Only show public emails in atom feeds.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443. - Bump Hashie to 3.5.5 and omniauth to 1.4.2 to eliminate warning noise.
- Add user deletion permission check in `Users::DestroyService`.
## 8.17.3 (2017-03-07) - Fix snippets search result spacing.
- Sort builds in stage dropdown.
- SSH key field updates title after pasting key.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
- Remove fixed positioning from top nav.
- Deduplicate markdown task lists.
- Default to subtle MR mege button until CI status is available.
- Update code editor (ACE) to 1.2.6, to fix input problems with compose key.
- update issue count when closing/reopening an issue.
- Use redis channel to post notifications.
- Removed top border from user contribution calendar.
- Added user callouts to the projects dashboard and user profile.
- Left align logo.
- Dispatch needed JS when creating a new MR in diff view.
- Specify in the documentation that only projects owners can transfer projects.
- Improves a11y in sidebar by adding aria-hidden attributes in i tags and by fixing two broken aria-hidden attributes.
- Clear ActiveRecord connections before starting Sidekiq.
- Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called Repository.
- Use native unicode emojis.
- Add storage class configuration option for Amazon S3 remote backups. (Jon Keys)
- Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist.
- Dashboard project search keeps selected sort & filters.
- Add all available statuses to scope filter for project builds endpoint. (George Andrinopoulos)
- Visually show expanded diff lines cant have comments.
- Use full group name in GFM group reference title.
- Adds Pending and Finished tabs to pipelines page.
- don't animate logo when downloading files.
## 8.17.4 (2017-03-19)
- Only show public emails in atom feeds.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
## 8.17.3 (2017-03-07)
- Fix the redirect to custom home page URL. !9518 - Fix the redirect to custom home page URL. !9518
- Fix broken migration when upgrading straight to 8.17.1. !9613 - Fix broken migration when upgrading straight to 8.17.1. !9613
- Make projects dropdown only show projects you are a member of. !9614 - Make projects dropdown only show projects you are a member of. !9614
...@@ -218,9 +501,6 @@ entry. ...@@ -218,9 +501,6 @@ entry.
## 8.16.8 (2017-03-19) ## 8.16.8 (2017-03-19)
- No changes.
- No changes.
- No changes.
- Only show public emails in atom feeds. - Only show public emails in atom feeds.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443. - To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
...@@ -425,8 +705,6 @@ entry. ...@@ -425,8 +705,6 @@ entry.
## 8.15.8 (2017-03-19) ## 8.15.8 (2017-03-19)
- No changes.
- No changes.
- Read true-up info from license and validate it. !1159 - Read true-up info from license and validate it. !1159
- Only show public emails in atom feeds. - Only show public emails in atom feeds.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443. - To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
...@@ -3567,289 +3845,6 @@ entry. ...@@ -3567,289 +3845,6 @@ entry.
- Fix padding of outdated discussion item. - Fix padding of outdated discussion item.
- Animate the logo on hover - Animate the logo on hover
## 9.0.0 (2017-03-22)
- Remove the newrelic gem. !1335 (Robert Schilling)
- Fix inconsistent naming for services that delete things. !5803 (dixpac)
- UI: Allow a project variable to be set to an empty value. !6044 (Lukáš Nový)
- Align task list checkboxes. !6487 (Jared Deckard <jared.deckard@gmail.com>)
- SanitizationFilter allows html5 details and summary tags. !6568
- on branch deletion show loading icon and disabled the button. !6761 (wendy0402)
- Use an entity for RepoBranch commits and enhance RepoCommit. !7138 (Ben Boeckel)
- Deleting a user doesn't delete issues they've created/are assigned to. !7393
- Fix position of counter in milestone panels. !7842 (Andrew Smith (EspadaV8))
- Added a feature to create a 'directly addressed' Todo when mentioned in the beginning of a line. !7926 (Ershad Kunnakkadan)
- Implement OpenID Connect identity provider. !8018 (Markus Koller)
- Show directory hierarchy when listing wiki pages. !8133 (Alex Braha Stoll)
- Migrate SlackService and MattermostService from build_events to pipeline_events, and migrate BuildsEmailService to PipelinesEmailService. Update Hipchat to use pipeline events rather than build events. !8196
- Execute web hooks for WikiPage delete operation. !8198
- Added external environment link to web terminal view. !8303
- Responsive title in diffs inline, side by side, with and without sidebar. !8475
- Bypass email domain validation when a user is created by an admin. !8575 (Reza Mohammadi @remohammadi)
- API: Paginate all endpoints that return an array. !8606 (Robert Schilling)
- pass in current_user in MergeRequest and MergeRequestsHelper. !8624 (Dongqing Hu)
- Add user & build links in Slack Notifications. !8641 (Poornima M)
- Todo done clicking is kind of unusable. !8691 (Jacopo Beschi @jacopo-beschi)
- Filter todos by manual add. !8691 (Jacopo Beschi @jacopo-beschi)
- Add runner version to /admin/runners view. !8733 (Jonathon Reinhart)
- API: remove `public` param for projects. !8736
- Allow creating nested groups via UI. !8786
- API: Add environment stop action. !8808
- Add discussion events to contributions calendar. !8821
- Unify issues search behavior by always filtering when ALL labels matches. !8849
- V3 deprecated templates endpoints removal. !8853
- Expose pipelines as PipelineBasic `api/v3/projects/:id/pipelines`. !8875
- Alphabetically sort tags on runner list. !8922 (blackst0ne)
- Added documentation for permalinks to most recent build artifacts. !8934 (Christian Godenschwager)
- Standardize branch name params as branch on V4 API. !8936
- Move /projects/fork/:id to /projects/:id/fork. !8940
- Fix small height of activity header page. !8952 (Pavel Sorokin)
- Optionally make users created via the API set their password. !8957 (Joost Rijneveld)
- GitHub Importer - Find users based on GitHub email address. !8958
- API: Consolidate /projects endpoint. !8962
- Add filtered search visual tokens. !8969
- Store group and project full name and full path in routes table. !8979
- Add internal API to notify Gitaly of post receive. !8983
- Remove inactive default email services. !8987
- Option to prevent signing in from multiple ips. !8998
- Download snippets with LF line-endings by default. !8999
- Fixes dropdown width in admin project page. !9002
- fixes issue number alignment problem in MR and issue list. !9020
- Fix CI/CD pipeline retry and take stages order into account. !9021
- Make stuck builds detection more performant. !9025
- Filter by projects in the end of search. !9030
- Add nested groups to the API. !9034
- Use ETag to improve performance of issue notes polling. !9036
- Add the oauth2_generic OmniAuth strategy. !9048 (Joe Marty)
- Brand header logo for pipeline emails. !9049 (Alexis Reigel)
- replace npm with yarn and add yarn.lock. !9055
- Fix displaying error messages for create label dropdown. !9058 (Tom Koole)
- Set dropdown height fixed to 250px and make it scrollable. !9063
- Update API docs for new namespace format. !9073 (Markus Koller)
- Replace static fixture for behaviors/quick_submit_spec.js. !9086 (winniehell)
- Use iids as filter parameter. !9096
- Manage user personal access tokens through api and add impersonation tokens. !9099 (Simon Vocella)
- Added the ability to copy a branch name to the clipboard. !9103 (Glenn Sayers)
- Rename Files::DeleteService to Files::DestroyService. !9110 (dixpac)
- Fixes FE Doc broken link. !9120
- Add git version to gitlab:env:info. !9128 (Semyon Pupkov)
- Replace static fixture for new_branch_spec.js. !9131 (winniehell)
- Reintroduce coverage report for JavaScript. !9133 (winniehell)
- Fix MR widget jump. !9146
- Avoid calling Build#trace_with_state for performance. !9149 (Takuya Noguchi)
- fix background color for labels mention in todo. !9155 (mhasbini)
- Replace static fixture for behaviors/requires_input_spec.js. !9162 (winniehell)
- Added AsciiDoc Snippet to CI/CD Badges. !9164 (Jan Christophersen)
- Make Karma output look nicer for CI. !9165 (winniehell)
- show 99+ for large count in todos notification bell. !9171 (mhasbini)
- Replace static fixture for header_spec.js. !9174 (winniehell)
- Replace static fixture for project_title_spec.js. !9175 (winniehell)
- Fixes markdown in activity-feed is gray. !9179
- Show notifications settings dropdown even if repository feature is disabled. !9180
- Fixes job dropdown action throws error in js console. !9182
- Set maximum width for mini pipeline graph text so it is not truncated to early. !9188
- Added 'Most Recent Activity' header to the User Profile page. !9189 (Jan Christophersen)
- Show Issues mentioned / being closed from a Merge Requests title below the 'Accept Merge Request' button. !9194 (Jan Christophersen)
- Stop linking to deleted Branches in Activity tabs. !9203 (Jan Christophersen)
- Make it possible to pass coverage value to commit status API. !9214 (wendy0402)
- Add admin setting for default artifacts expiration. !9219
- add :iids param to IssuableFinder (resolve technical dept). !9222 (mhasbini)
- Add Links to Branches in Calendar Activity. !9224 (Jan Christophersen)
- Fix pipeline retry and cancel buttons on pipeline details page. !9225
- Remove es6 file extension from JavaScript files. !9241 (winniehell)
- Add Runner's registration/deletion v4 API. !9246
- Add merge request count to each issue on issues list. !9252 (blackst0ne)
- Fix error in MR widget after /merge slash command. !9259
- Clean-up Project navigation order. !9272
- Add Runner's jobs v4 API. !9273
- Add pipeline trigger API with user permissions. !9277
- Enhanced filter issues layout for better mobile experiance. !9280 (Pratik Borsadiya)
- Move babel config for instanbul to karma config. !9286 (winniehell)
- Document U2F limitations with multiple URLs. !9300
- Wrap long Project and Group titles. !9301
- Clean-up Groups navigation order. !9309
- Truncate long Todo titles for non-mobile screens. !9311
- add rake tasks to handle yarn dependencies and update documentation. !9316
- API: - Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. !9325 (Robert Schilling)
- API: Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar`. !9328 (Robert Schilling)
- API: Use `visibility` as string parameter everywhere. !9337
- Add the Username to the HTTP(S) clone URL of a Repository. !9347 (Jan Christophersen)
- Add spec for todo with target_type Commit. !9351 (George Andrinopoulos)
- Fixes includes line number during unfold copy n paste in parallel diff view. !9365
- API: Remove `DELETE projects/:id/deploy_keys/:key_id/disable`. !9365 (Robert Schilling)
- API: Use POST to (un)block a user. !9371 (Robert Schilling)
- Remove markup that was showing in tooltip for renamed files. !9374
- Drop unused ci_projects table and some unused project_id columns, then rename gl_project_id to project_id. Stop exporting job trace when exporting projects. !9378 (David Wagner)
- Adds remote logout functionality to the Authentiq OAuth provider. !9381 (Alexandros Keramidas)
- Introduce /award slash command; Allow posting of just an emoji in comment. !9382 (mhasbini)
- API: Remove deprecated fields Notes#upvotes and Notes#downvotes. !9384 (Robert Schilling)
- Redo internals of Incoming Mail Support. !9385
- update Vue to v2.1.10. !9386
- Add button to create issue for failing build. !9391 (Alex Sanford)
- test compiling production assets and generate webpack bundle report in CI. !9396
- API: Return 204 for all delete endpoints. !9397 (Robert Schilling)
- Add KUBE_CA_PEM_FILE, deprecate KUBE_CA_PEM. !9398
- API: Use POST requests to mark todos as done. !9410 (Robert Schilling)
- API project create: Make name or path required. !9416
- Add housekeeping endpoint for Projects API. !9421
- Fixes delimiter removes when todo marked as done. !9435
- Document when current coverage configuration option was introduced. !9443
- Uploaded files which content can change now require revalidation on each page load. !9453
- Only add a newline in the Markdown Editor if the current line is not empty. !9455 (Jan Christophersen)
- Rename builds to job for the v4 API. !9463
- API: Remove /groups/owned endpoint. !9505 (Robert Schilling)
- API: Return 400 for all validation erros in the mebers API. !9523 (Robert Schilling)
- Fixes large file name tooltip cutoff in diff header. !9529
- Keep consistent in handling indexOf results. !9531 (Takuya Noguchi)
- Make documentation of list repository tree API call more detailed. !9532 (Marius Kleiner)
- Fix Sort dropdown reflow issue. !9533 (Jarkko Tuunanen)
- Improve grammar in GitLab flow documentation. !9552 (infogrind)
- Change default project view for user from readme to files view. !9584
- Make it possible to configure blocking manual actions. !9585
- Show public RSS feeds to anonymous users. !9596 (Michael Kozono)
- Update storage settings to allow extra values per repository storage. !9597
- Enable filtering milestones by search criteria in the API. !9606
- Ensure archive download is only one directory deep. !9616
- Fix updaing commit status when using optional attributes. !9618
- Add filter and sorting to dashboard groups page. !9619
- Remove deprecated build status badge and related services. !9620
- Rename table ci_commits to ci_pipelines. !9638
- Remove various unused CI tables and columns. !9639
- Use webpack CommonsChunkPlugin to place common javascript libraries in their own bundles. !9647
- CORS: Whitelist pagination headers. !9651 (Robert Schilling)
- Remove "subscribed" field from API responses returning list of issues or merge requests. !9661
- Highlight line number if specified on diff pages when page loads. !9664
- Set default cache key to "default" for jobs. !9666
- Set max height to screen height for Zen mode. !9667
- GET 'projects/:id/repository/commits' endpoint improvements. !9679 (George Andrinopoulos, Jordan Ryan Reuter)
- 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 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
- Use gitlab-workhorse 1.4.0. !9724
- Add GET /projects/:id/pipelines/:pipeline_id/jobs endpoint. !9727
- Restrict nested group names to prevent ambiguous routes. !9738
- Rename job environment variables to new terminology. !9756
- Deprecate usage of `types` configuration entry to describe CI/CD stages. !9766
- Moved project settings from the gear drop-down menu to a tab. !9786
- Fix "passed with warnings" stage status on MySQL installations. !9802
- Fix for creating a project through API when import_url is nil. !9841
- Use GitLab Pages v0.4.0. !9896
- Reserve few project and nested group paths that have wildcard routes associated. !9898
- Speed up project dashboard by caching pipeline status and eager loading routes. !9903
- Fixes n+1 query for tags and branches index page. !9905
- Hide ancestor groups in the share group dropdown list. !9965
- Allow creating merge request even if target branch is not specified in query params. !9968
- Removed d3 from the main application.js bundle. !10062
- Return 404 in project issues API endpoint when project cannot be found. !10093
- Add frequently used emojis back to awards menu.
- Add filtered search to MR page.
- Re-add the New Project button in nav bar.
- Show members of parent groups on project members page.
- Set Auto-Submitted header to mails. (Semyon Pupkov)
- Return 202 with JSON body on async removals on V4 API.
- Stop setting Strict-Transport-Securty header from within the app.
- Use "branch_name" instead "branch" on V3 branch creation API.
- Adds paginationd and folders view to environments table.
- Fix archive prefix bug for refs containing dots.
- ensure MR widget dropdown is same color as button.
- hide loading spinners for server-rendered sidebar fields.
- Decrease tanuki logo size.
- Add filter param for project membership for current_user in API v4.
- Add limit to the number of events showed in cycle analytics.
- Remove help link from right dropdown.
- Fix jobs table header height.
- Update account view to display new username.
- Narrow environment payload by using basic project details resource.
- Make a default namespace of Kubernetes service to contain project ID.
- Fix issues mentioned but not closed for external issue trackers.
- fix milestone does not automatically assign when create issue from milestone.
- Present GitLab version for each V3 to V4 API change on v3_to_v4.md.
- Format timeago date to short format.
- Fix errors in slash commands matcher, add simple test coverage. (YarNayar)
- Re-add Assign to me link to Merge Request and Issues.
- Added option to update to owner for group members.
- Add badges to global dropdown.
- Introduce Pipeline Triggers that are user-aware.
- Fixed loading spinner position on issue template toggle.
- Removed duplicate "Visibility Level" label on New Project page. (Robert Marcano)
- Fix 'New Tag' layout on Tags page. (Robert Marcano)
- Update API endpoints for raw files.
- Fix issuable stale object error handler for js when updating tasklists.
- Gather issuable metadata to avoid n+1 queries on index view.
- Remove JIRA closed status icon.
- Changed coverage reg expression placeholder text to be more like a placeholder.
- Make Git history follow renames again by performing the --skip in Ruby.
- Fixed long file names overflowing under action buttons.
- Fix grammer issue in admin/runners.
- Add Mock CI service/integration for development.
- Move tag services to Tags namespace. (dixpac)
- Removes label when moving issue to another list that it is currently in.
- Improved diff comment button UX.
- Allow slashes in slash command arguments.
- Only create unmergeable todos once when MR fails to merge.
- Only yield valid references in ReferenceFilter.references_in.
- Adds API endpoint to fetch all merge request for a single milestone. (Joren De Groof)
- Add member: Always return 409 when a member exists.
- Change development tanuki favicon colors to match logo color order.
- API issues - support filtering by iids.
- Rename priority sorting option to label priority.
- Added headers to protected branch access dropdowns.
- Remove plus icon from MR button on compare view.
- removed unused parameter 'status_only: true'.
- Fix positioning of `Scroll to top` button.
- Hide issue info when project issues are disabled. (George Andrinopoulos)
- Replaced jQuery UI datepicker.
- Removed jQuery UI highlight & autocomplete.
- Replaced jQuery UI sortable.
- Only run timeago loops after rendering timeago components.
- Remove readme-only project view preference.
- Remove tooltips from label subscription buttons.
- Increase right side of file header to button stays on same line.
- Centers loading icon vertically and horizontally in pipelines table in commit view.
- Rename retry failed button on pipeline page to just retry.
- Align bulk update issues button to the right.
- Remove remnants of git annex support.
- Pick up option from GDK to disable webpack dev server livereload.
- Fix z index issues with sidebar.
- Change project count limit from 10 to 100000.
- Remove repeated routes.path check for postgresql database. (mhasbini)
- Fixed RSS button alignment on activity pages.
- Seed abuse reports for development.
- Only show public emails in atom feeds.
- Bump Hashie to 3.5.5 and omniauth to 1.4.2 to eliminate warning noise.
- Add user deletion permission check in `Users::DestroyService`.
- Fix snippets search result spacing.
- Sort builds in stage dropdown.
- SSH key field updates title after pasting key.
- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
- Remove fixed positioning from top nav.
- Deduplicate markdown task lists.
- Default to subtle MR mege button until CI status is available.
- Update code editor (ACE) to 1.2.6, to fix input problems with compose key.
- update issue count when closing/reopening an issue.
- Use redis channel to post notifications.
- Removed top border from user contribution calendar.
- Added user callouts to the projects dashboard and user profile.
- Left align logo.
- Dispatch needed JS when creating a new MR in diff view.
- Specify in the documentation that only projects owners can transfer projects.
- Improves a11y in sidebar by adding aria-hidden attributes in i tags and by fixing two broken aria-hidden attributes.
- Clear ActiveRecord connections before starting Sidekiq.
- Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called Repository.
- Use native unicode emojis.
- Add storage class configuration option for Amazon S3 remote backups. (Jon Keys)
- Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist.
- Dashboard project search keeps selected sort & filters.
- Add all available statuses to scope filter for project builds endpoint. (George Andrinopoulos)
- Visually show expanded diff lines cant have comments.
- Use full group name in GFM group reference title.
- Adds Pending and Finished tabs to pipelines page.
- don't animate logo when downloading files.
## 8.0.5 ## 8.0.5
- Correct lookup-by-email for LDAP logins - Correct lookup-by-email for LDAP logins
......
...@@ -65,6 +65,7 @@ require('./empty_state'); ...@@ -65,6 +65,7 @@ require('./empty_state');
}, },
filter: { filter: {
handler() { handler() {
this.page = 1;
this.loadIssues(true); this.loadIssues(true);
}, },
deep: true, deep: true,
...@@ -116,6 +117,9 @@ require('./empty_state'); ...@@ -116,6 +117,9 @@ require('./empty_state');
return this.activeTab === 'selected' && this.selectedIssues.length === 0; return this.activeTab === 'selected' && this.selectedIssues.length === 0;
}, },
}, },
created() {
this.page = 1;
},
components: { components: {
'modal-header': gl.issueBoards.ModalHeader, 'modal-header': gl.issueBoards.ModalHeader,
'modal-list': gl.issueBoards.ModalList, 'modal-list': gl.issueBoards.ModalList,
......
import PrometheusGraph from './monitoring/prometheus_graph'; // TODO: Maybe Make this a bundle
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */
/* global UsernameValidator */ /* global UsernameValidator */
/* global ActiveTabMemoizer */ /* global ActiveTabMemoizer */
...@@ -341,8 +340,6 @@ const UserCallout = require('./user_callout'); ...@@ -341,8 +340,6 @@ const UserCallout = require('./user_callout');
case 'ci:lints:show': case 'ci:lints:show':
new gl.CILintEditor(); new gl.CILintEditor();
break; break;
case 'projects:environments:metrics':
new PrometheusGraph();
case 'users:show': case 'users:show':
new UserCallout(); new UserCallout();
break; break;
......
...@@ -14,6 +14,7 @@ export default { ...@@ -14,6 +14,7 @@ export default {
class="btn external_url" class="btn external_url"
:href="externalUrl" :href="externalUrl"
target="_blank" target="_blank"
rel="noopener noreferrer"
title="Environment external URL"> title="Environment external URL">
<i class="fa fa-external-link" aria-hidden="true"></i> <i class="fa fa-external-link" aria-hidden="true"></i>
</a> </a>
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
gl.FilteredSearchDropdownManager.addWordToInput(this.filter, value, true); gl.FilteredSearchDropdownManager.addWordToInput(this.filter, value, true);
} }
this.resetFilters();
this.dismissDropdown(); this.dismissDropdown();
this.dispatchInputEvent(); this.dispatchInputEvent();
} }
...@@ -107,7 +108,7 @@ ...@@ -107,7 +108,7 @@
const hook = this.getCurrentHook(); const hook = this.getCurrentHook();
if (hook) { if (hook) {
const data = hook.list.data; const data = hook.list.data || [];
if (!data) return; if (!data) return;
......
...@@ -44,6 +44,8 @@ import FilteredSearchContainer from './container'; ...@@ -44,6 +44,8 @@ import FilteredSearchContainer from './container';
this.unselectEditTokensWrapper = this.unselectEditTokens.bind(this); this.unselectEditTokensWrapper = this.unselectEditTokens.bind(this);
this.editTokenWrapper = this.editToken.bind(this); this.editTokenWrapper = this.editToken.bind(this);
this.tokenChange = this.tokenChange.bind(this); this.tokenChange = this.tokenChange.bind(this);
this.addInputContainerFocusWrapper = this.addInputContainerFocus.bind(this);
this.removeInputContainerFocusWrapper = this.removeInputContainerFocus.bind(this);
this.filteredSearchInputForm = this.filteredSearchInput.form; this.filteredSearchInputForm = this.filteredSearchInput.form;
this.filteredSearchInputForm.addEventListener('submit', this.handleFormSubmit); this.filteredSearchInputForm.addEventListener('submit', this.handleFormSubmit);
...@@ -55,11 +57,13 @@ import FilteredSearchContainer from './container'; ...@@ -55,11 +57,13 @@ import FilteredSearchContainer from './container';
this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper); this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper);
this.filteredSearchInput.addEventListener('click', this.tokenChange); this.filteredSearchInput.addEventListener('click', this.tokenChange);
this.filteredSearchInput.addEventListener('keyup', this.tokenChange); this.filteredSearchInput.addEventListener('keyup', this.tokenChange);
this.filteredSearchInput.addEventListener('focus', this.addInputContainerFocusWrapper);
this.tokensContainer.addEventListener('click', FilteredSearchManager.selectToken); this.tokensContainer.addEventListener('click', FilteredSearchManager.selectToken);
this.tokensContainer.addEventListener('dblclick', this.editTokenWrapper); this.tokensContainer.addEventListener('dblclick', this.editTokenWrapper);
this.clearSearchButton.addEventListener('click', this.clearSearchWrapper); this.clearSearchButton.addEventListener('click', this.clearSearchWrapper);
document.addEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens); document.addEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens);
document.addEventListener('click', this.unselectEditTokensWrapper); document.addEventListener('click', this.unselectEditTokensWrapper);
document.addEventListener('click', this.removeInputContainerFocusWrapper);
document.addEventListener('keydown', this.removeSelectedTokenWrapper); document.addEventListener('keydown', this.removeSelectedTokenWrapper);
} }
...@@ -73,11 +77,13 @@ import FilteredSearchContainer from './container'; ...@@ -73,11 +77,13 @@ import FilteredSearchContainer from './container';
this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper); this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper);
this.filteredSearchInput.removeEventListener('click', this.tokenChange); this.filteredSearchInput.removeEventListener('click', this.tokenChange);
this.filteredSearchInput.removeEventListener('keyup', this.tokenChange); this.filteredSearchInput.removeEventListener('keyup', this.tokenChange);
this.filteredSearchInput.removeEventListener('focus', this.addInputContainerFocusWrapper);
this.tokensContainer.removeEventListener('click', FilteredSearchManager.selectToken); this.tokensContainer.removeEventListener('click', FilteredSearchManager.selectToken);
this.tokensContainer.removeEventListener('dblclick', this.editTokenWrapper); this.tokensContainer.removeEventListener('dblclick', this.editTokenWrapper);
this.clearSearchButton.removeEventListener('click', this.clearSearchWrapper); this.clearSearchButton.removeEventListener('click', this.clearSearchWrapper);
document.removeEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens); document.removeEventListener('click', gl.FilteredSearchVisualTokens.unselectTokens);
document.removeEventListener('click', this.unselectEditTokensWrapper); document.removeEventListener('click', this.unselectEditTokensWrapper);
document.removeEventListener('click', this.removeInputContainerFocusWrapper);
document.removeEventListener('keydown', this.removeSelectedTokenWrapper); document.removeEventListener('keydown', this.removeSelectedTokenWrapper);
} }
...@@ -130,6 +136,26 @@ import FilteredSearchContainer from './container'; ...@@ -130,6 +136,26 @@ import FilteredSearchContainer from './container';
} }
} }
addInputContainerFocus() {
const inputContainer = this.filteredSearchInput.closest('.filtered-search-input-container');
if (inputContainer) {
inputContainer.classList.add('focus');
}
}
removeInputContainerFocus(e) {
const inputContainer = this.filteredSearchInput.closest('.filtered-search-input-container');
const isElementInFilteredSearch = inputContainer && inputContainer.contains(e.target);
const isElementInDynamicFilterDropdown = e.target.closest('.filter-dropdown') !== null;
const isElementInStaticFilterDropdown = e.target.closest('ul[data-dropdown]') !== null;
if (!isElementInFilteredSearch && !isElementInDynamicFilterDropdown &&
!isElementInStaticFilterDropdown && inputContainer) {
inputContainer.classList.remove('focus');
}
}
static selectToken(e) { static selectToken(e) {
const button = e.target.closest('.selectable'); const button = e.target.closest('.selectable');
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* global Flash */ /* global Flash */
require('./flash'); require('./flash');
require('~/lib/utils/text_utility');
require('vendor/jquery.waitforimages'); require('vendor/jquery.waitforimages');
require('./task_list'); require('./task_list');
...@@ -50,20 +51,21 @@ class Issue { ...@@ -50,20 +51,21 @@ class Issue {
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
if ('id' in data) { if ('id' in data) {
$(document).trigger('issuable:change'); $(document).trigger('issuable:change');
const currentTotal = Number($('.issue_counter').text()); let total = Number($('.issue_counter').text().replace(/[^\d]/, ''));
if (isClose) { if (isClose) {
$('a.btn-close').addClass('hidden'); $('a.btn-close').addClass('hidden');
$('a.btn-reopen').removeClass('hidden'); $('a.btn-reopen').removeClass('hidden');
$('div.status-box-closed').removeClass('hidden'); $('div.status-box-closed').removeClass('hidden');
$('div.status-box-open').addClass('hidden'); $('div.status-box-open').addClass('hidden');
$('.issue_counter').text(currentTotal - 1); total -= 1;
} else { } else {
$('a.btn-reopen').addClass('hidden'); $('a.btn-reopen').addClass('hidden');
$('a.btn-close').removeClass('hidden'); $('a.btn-close').removeClass('hidden');
$('div.status-box-closed').addClass('hidden'); $('div.status-box-closed').addClass('hidden');
$('div.status-box-open').removeClass('hidden'); $('div.status-box-open').removeClass('hidden');
$('.issue_counter').text(currentTotal + 1); total += 1;
} }
$('.issue_counter').text(gl.text.addDelimiter(total));
} else { } else {
new Flash(issueFailMessage, 'alert'); new Flash(issueFailMessage, 'alert');
} }
......
...@@ -14,13 +14,13 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown'; ...@@ -14,13 +14,13 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
<%= ci_success_icon %> <%= ci_success_icon %>
<span> <span>
Deployed to Deployed to
<a href="<%- url %>" target="_blank" class="environment"> <a href="<%- url %>" target="_blank" rel="noopener noreferrer" class="environment">
<%- name %> <%- name %>
</a> </a>
<span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>"> <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>">
<%- deployed_at %> <%- deployed_at %>
</span> </span>
<a class="js-environment-link" href="<%- external_url %>" target="_blank"> <a class="js-environment-link" href="<%- external_url %>" target="_blank" rel="noopener noreferrer">
<i class="fa fa-external-link"></i> <i class="fa fa-external-link"></i>
View on <%- external_url_formatted %> View on <%- external_url_formatted %>
</a> </a>
......
import PrometheusGraph from './prometheus_graph';
document.addEventListener('DOMContentLoaded', function onLoad() {
document.removeEventListener('DOMContentLoaded', onLoad, false);
return new PrometheusGraph();
}, false);
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
/* global Flash */ /* global Flash */
import d3 from 'd3'; import d3 from 'd3';
import _ from 'underscore';
import statusCodes from '~/lib/utils/http_status'; import statusCodes from '~/lib/utils/http_status';
import '~/lib/utils/common_utils'; import '../lib/utils/common_utils';
import '~/flash'; import '../flash';
const prometheusGraphsContainer = '.prometheus-graph'; const prometheusGraphsContainer = '.prometheus-graph';
const metricsEndpoint = 'metrics.json'; const metricsEndpoint = 'metrics.json';
...@@ -31,22 +30,21 @@ class PrometheusGraph { ...@@ -31,22 +30,21 @@ class PrometheusGraph {
} }
createGraph() { createGraph() {
const self = this; Object.keys(this.data).forEach((key) => {
_.each(this.data, (value, key) => { const value = this.data[key];
if (value.length > 0 && (key === 'cpu_values' || key === 'memory_values')) { if (value.length > 0) {
self.plotValues(value, key); this.plotValues(value, key);
} }
}); });
} }
init() { init() {
const self = this;
this.getData().then((metricsResponse) => { this.getData().then((metricsResponse) => {
if (metricsResponse === {}) { if (Object.keys(metricsResponse).length === 0) {
new Flash('Empty metrics', 'alert'); new Flash('Empty metrics', 'alert');
} else { } else {
self.transformData(metricsResponse); this.transformData(metricsResponse);
self.createGraph(); this.createGraph();
} }
}); });
} }
...@@ -321,12 +319,14 @@ class PrometheusGraph { ...@@ -321,12 +319,14 @@ class PrometheusGraph {
transformData(metricsResponse) { transformData(metricsResponse) {
const metricTypes = {}; const metricTypes = {};
_.each(metricsResponse.metrics, (value, key) => { Object.keys(metricsResponse.metrics).forEach((key) => {
const metricValues = value[0].values; if (key === 'cpu_values' || key === 'memory_values') {
metricTypes[key] = _.map(metricValues, metric => ({ const metricValues = (metricsResponse.metrics[key])[0];
time: new Date(metric[0] * 1000), metricTypes[key] = metricValues.values.map(metric => ({
value: metric[1], time: new Date(metric[0] * 1000),
})); value: metric[1],
}));
}
}); });
this.data = metricTypes; this.data = metricTypes;
} }
......
...@@ -433,3 +433,9 @@ table { ...@@ -433,3 +433,9 @@ table {
@include str-truncated(100%); @include str-truncated(100%);
} }
} }
.tooltip {
.tooltip-inner {
word-wrap: break-word;
}
}
...@@ -76,12 +76,14 @@ ...@@ -76,12 +76,14 @@
} }
.input-token { .input-token {
flex: 1; max-width: 200px;
-webkit-flex: 1;
} }
.filtered-search-token + .input-token:not(:last-child) { .input-token:only-child,
max-width: 200px; .input-token:last-child {
flex: 1;
-webkit-flex: 1;
max-width: initial;
} }
} }
...@@ -158,8 +160,8 @@ ...@@ -158,8 +160,8 @@
background-color: $white-light; background-color: $white-light;
@media (max-width: $screen-xs-min) { @media (max-width: $screen-xs-min) {
-webkit-flex: 1 1 100%; -webkit-flex: 1 1 auto;
flex: 1 1 100%; flex: 1 1 auto;
margin-bottom: 10px; margin-bottom: 10px;
.dropdown-menu { .dropdown-menu {
...@@ -171,17 +173,26 @@ ...@@ -171,17 +173,26 @@
} }
} }
&:hover {
@extend .form-control:hover;
}
&.focus,
&.focus:hover {
border-color: $dropdown-input-focus-border;
box-shadow: 0 0 4px $search-input-focus-shadow-color;
}
&.focus .fa-filter {
color: $common-gray-dark;
}
.form-control { .form-control {
position: relative; position: relative;
min-width: 200px; min-width: 200px;
padding-left: 0; padding: 5px 25px 6px 0;
padding-right: 25px;
border-color: transparent; border-color: transparent;
&:focus ~ .fa-filter {
color: $common-gray-dark;
}
&:focus, &:focus,
&:hover { &:hover {
outline: none; outline: none;
...@@ -221,6 +232,10 @@ ...@@ -221,6 +232,10 @@
.filter-dropdown-container { .filter-dropdown-container {
display: -webkit-flex; display: -webkit-flex;
display: flex; display: flex;
.dropdown-toggle {
line-height: 22px;
}
} }
.dropdown-menu .filter-dropdown-item { .dropdown-menu .filter-dropdown-item {
...@@ -246,7 +261,9 @@ ...@@ -246,7 +261,9 @@
background-color: $white-light; background-color: $white-light;
border-top: 0; border-top: 0;
} }
}
@media (max-width: $screen-xs) {
.filter-dropdown-container { .filter-dropdown-container {
.dropdown-toggle, .dropdown-toggle,
.dropdown { .dropdown {
......
...@@ -148,6 +148,18 @@ ...@@ -148,6 +148,18 @@
.error-alert > .alert { .error-alert > .alert {
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;
&.alert-dismissable {
.close {
color: $white-light;
opacity: 0.85;
font-weight: normal;
&:hover {
opacity: 1;
}
}
}
} }
.discussion-body, .discussion-body,
......
...@@ -89,4 +89,9 @@ class Projects::ApplicationController < ApplicationController ...@@ -89,4 +89,9 @@ class Projects::ApplicationController < ApplicationController
def builds_enabled def builds_enabled
return render_404 unless @project.feature_available?(:builds, current_user) return render_404 unless @project.feature_available?(:builds, current_user)
end end
def update_ref
branch_exists = @repository.find_branch(@target_branch)
@ref = @target_branch if branch_exists
end
end end
...@@ -89,11 +89,6 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -89,11 +89,6 @@ class Projects::BlobController < Projects::ApplicationController
private private
def update_ref
branch_exists = @repository.find_branch(@target_branch)
@ref = @target_branch if branch_exists
end
def blob def blob
@blob ||= Blob.decorate(@repository.blob_at(@commit.id, @path)) @blob ||= Blob.decorate(@repository.blob_at(@commit.id, @path))
......
...@@ -6,7 +6,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -6,7 +6,7 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuableCollections include IssuableCollections
include SpammableActions include SpammableActions
prepend_before_action :authenticate_user!, only: [:export_csv] prepend_before_action :authenticate_user!, only: [:new, :export_csv]
before_action :redirect_to_external_issue_tracker, only: [:index, :new] before_action :redirect_to_external_issue_tracker, only: [:index, :new]
before_action :module_enabled before_action :module_enabled
...@@ -154,7 +154,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -154,7 +154,7 @@ class Projects::IssuesController < Projects::ApplicationController
end end
format.json do format.json do
render json: @issue.to_json(include: { milestone: {}, assignee: { methods: :avatar_url }, labels: { methods: :text_color } }, methods: [:task_status, :task_status_short]) render json: @issue.to_json(include: { milestone: {}, assignee: { only: [:name, :username], methods: [:avatar_url] }, labels: { methods: :text_color } }, methods: [:task_status, :task_status_short])
end end
end end
......
...@@ -319,7 +319,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -319,7 +319,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end end
format.json do format.json do
render json: @merge_request.to_json(include: { milestone: {}, assignee: { methods: :avatar_url }, labels: { methods: :text_color } }, methods: [:task_status, :task_status_short]) render json: @merge_request.to_json(include: { milestone: {}, assignee: { only: [:name, :username], methods: [:avatar_url] }, labels: { methods: :text_color } }, methods: [:task_status, :task_status_short])
end end
end end
rescue ActiveRecord::StaleObjectError rescue ActiveRecord::StaleObjectError
......
...@@ -9,6 +9,7 @@ module Projects ...@@ -9,6 +9,7 @@ module Projects
@skip_groups = @group_links.pluck(:group_id) @skip_groups = @group_links.pluck(:group_id)
@skip_groups << @project.namespace_id unless @project.personal? @skip_groups << @project.namespace_id unless @project.personal?
@skip_groups += @project.group.ancestors.pluck(:id) if @project.group
@project_members = MembersFinder.new(@project, current_user).execute @project_members = MembersFinder.new(@project, current_user).execute
......
...@@ -34,6 +34,7 @@ class Projects::TreeController < Projects::ApplicationController ...@@ -34,6 +34,7 @@ class Projects::TreeController < Projects::ApplicationController
def create_dir def create_dir
return render_404 unless @commit_params.values.all? return render_404 unless @commit_params.values.all?
update_ref
create_commit(Files::CreateDirService, success_notice: "The directory has been successfully created.", create_commit(Files::CreateDirService, success_notice: "The directory has been successfully created.",
success_path: namespace_project_tree_path(@project.namespace, @project, File.join(@target_branch, @dir_name)), success_path: namespace_project_tree_path(@project.namespace, @project, File.join(@target_branch, @dir_name)),
failure_path: namespace_project_tree_path(@project.namespace, @project, @ref)) failure_path: namespace_project_tree_path(@project.namespace, @project, @ref))
......
...@@ -215,6 +215,6 @@ module BlobHelper ...@@ -215,6 +215,6 @@ module BlobHelper
end end
def open_raw_file_button(path) def open_raw_file_button(path)
link_to icon('file-code-o'), path, class: 'btn btn-sm has-tooltip', target: '_blank', title: 'Open raw', data: { container: 'body' } link_to icon('file-code-o'), path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw', data: { container: 'body' }
end end
end end
...@@ -211,7 +211,7 @@ module CommitsHelper ...@@ -211,7 +211,7 @@ module CommitsHelper
external_url = environment.external_url_for(diff_new_path, commit_sha) external_url = environment.external_url_for(diff_new_path, commit_sha)
return unless external_url return unless external_url
link_to(external_url, class: 'btn btn-file-option has-tooltip', target: '_blank', title: "View on #{environment.formatted_external_url}", data: { container: 'body' }) do link_to(external_url, class: 'btn btn-file-option has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: "View on #{environment.formatted_external_url}", data: { container: 'body' }) do
icon('external-link') icon('external-link')
end end
end end
......
...@@ -7,7 +7,7 @@ module ImportHelper ...@@ -7,7 +7,7 @@ module ImportHelper
def provider_project_link(provider, path_with_namespace) def provider_project_link(provider, path_with_namespace)
url = __send__("#{provider}_project_url", path_with_namespace) url = __send__("#{provider}_project_url", path_with_namespace)
link_to path_with_namespace, url, target: '_blank' link_to path_with_namespace, url, target: '_blank', rel: 'noopener noreferrer'
end end
private private
......
...@@ -182,6 +182,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -182,6 +182,8 @@ class ApplicationSetting < ActiveRecord::Base
end end
def self.current def self.current
ensure_cache_setup
Rails.cache.fetch(CACHE_KEY) do Rails.cache.fetch(CACHE_KEY) do
ApplicationSetting.last ApplicationSetting.last
end end
...@@ -195,9 +197,16 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -195,9 +197,16 @@ class ApplicationSetting < ActiveRecord::Base
end end
def self.cached def self.cached
ensure_cache_setup
Rails.cache.fetch(CACHE_KEY) Rails.cache.fetch(CACHE_KEY)
end end
def self.ensure_cache_setup
# This is a workaround for a Rails bug that causes attribute methods not
# to be loaded when read from cache: https://github.com/rails/rails/issues/27348
ApplicationSetting.define_attribute_methods
end
def self.defaults_ce def self.defaults_ce
{ {
after_sign_up_text: nil, after_sign_up_text: nil,
......
...@@ -31,6 +31,7 @@ module HasStatus ...@@ -31,6 +31,7 @@ module HasStatus
WHEN (#{builds})=(#{created})+(#{skipped})+(#{pending}) THEN 'pending' WHEN (#{builds})=(#{created})+(#{skipped})+(#{pending}) THEN 'pending'
WHEN (#{running})+(#{pending})>0 THEN 'running' WHEN (#{running})+(#{pending})>0 THEN 'running'
WHEN (#{manual})>0 THEN 'manual' WHEN (#{manual})>0 THEN 'manual'
WHEN (#{created})>0 THEN 'running'
ELSE 'failed' ELSE 'failed'
END)" END)"
end end
......
...@@ -48,12 +48,14 @@ module Issuable ...@@ -48,12 +48,14 @@ module Issuable
delegate :name, delegate :name,
:email, :email,
:public_email,
to: :author, to: :author,
allow_nil: true, allow_nil: true,
prefix: true prefix: true
delegate :name, delegate :name,
:email, :email,
:public_email,
to: :assignee, to: :assignee,
allow_nil: true, allow_nil: true,
prefix: true prefix: true
......
...@@ -16,7 +16,7 @@ class Event < ActiveRecord::Base ...@@ -16,7 +16,7 @@ class Event < ActiveRecord::Base
RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour
delegate :name, :email, to: :author, prefix: true, allow_nil: true delegate :name, :email, :public_email, to: :author, prefix: true, allow_nil: true
delegate :title, to: :issue, prefix: true, allow_nil: true delegate :title, to: :issue, prefix: true, allow_nil: true
delegate :title, to: :merge_request, prefix: true, allow_nil: true delegate :title, to: :merge_request, prefix: true, allow_nil: true
delegate :title, to: :note, prefix: true, allow_nil: true delegate :title, to: :note, prefix: true, allow_nil: true
......
...@@ -251,7 +251,7 @@ class Group < Namespace ...@@ -251,7 +251,7 @@ class Group < Namespace
end end
def members_with_parents def members_with_parents
GroupMember.non_request.where(source_id: ancestors.map(&:id).push(id)) GroupMember.non_request.where(source_id: ancestors.pluck(:id).push(id))
end end
def users_with_parents def users_with_parents
......
...@@ -205,6 +205,7 @@ class Project < ActiveRecord::Base ...@@ -205,6 +205,7 @@ class Project < ActiveRecord::Base
validates :name, uniqueness: { scope: :namespace_id } validates :name, uniqueness: { scope: :namespace_id }
validates :path, uniqueness: { scope: :namespace_id } validates :path, uniqueness: { scope: :namespace_id }
validates :import_url, addressable_url: true, if: :external_import? validates :import_url, addressable_url: true, if: :external_import?
validates :import_url, importable_url: true, if: [:external_import?, :import_url_changed?]
validates :star_count, numericality: { greater_than_or_equal_to: 0 } validates :star_count, numericality: { greater_than_or_equal_to: 0 }
validate :check_limit, on: :create validate :check_limit, on: :create
validate :avatar_type, validate :avatar_type,
......
...@@ -30,7 +30,14 @@ class PrometheusService < MonitoringService ...@@ -30,7 +30,14 @@ class PrometheusService < MonitoringService
end end
def help def help
'Retrieves `container_cpu_usage_seconds_total` and `container_memory_usage_bytes` from the configured Prometheus server. An `environment` label is required on each metric to identify the Environment.' <<-MD.strip_heredoc
Retrieves the Kubernetes node metrics `container_cpu_usage_seconds_total`
and `container_memory_usage_bytes` from the configured Prometheus server.
If you are not using [Auto-Deploy](https://docs.gitlab.com/ee/ci/autodeploy/index.html)
or have set up your own Prometheus server, an `environment` label is required on each metric to
[identify the Environment](https://docs.gitlab.com/ce/user/project/integrations/prometheus.html#metrics-and-labels).
MD
end end
def self.to_param def self.to_param
......
...@@ -21,7 +21,7 @@ class Route < ActiveRecord::Base ...@@ -21,7 +21,7 @@ class Route < ActiveRecord::Base
attributes[:path] = route.path.sub(path_was, path) attributes[:path] = route.path.sub(path_was, path)
end end
if name_changed? && route.name.present? if name_changed? && name_was.present? && route.name.present?
attributes[:name] = route.name.sub(name_was, name) attributes[:name] = route.name.sub(name_was, name)
end end
......
...@@ -25,12 +25,12 @@ class CreateBranchService < BaseService ...@@ -25,12 +25,12 @@ class CreateBranchService < BaseService
private private
def create_master_branch def create_master_branch
project.repository.commit_file( project.repository.create_file(
current_user, current_user,
'/README.md', '/README.md',
'', '',
message: 'Add README.md', message: 'Add README.md',
branch_name: 'master', branch_name: 'master'
update: false) )
end end
end end
...@@ -33,6 +33,7 @@ module Projects ...@@ -33,6 +33,7 @@ module Projects
def import_repository def import_repository
begin begin
raise Error, "Blocked import URL." if Gitlab::UrlBlocker.blocked_url?(project.import_url)
gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url) gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
rescue => e rescue => e
# Expire cache to prevent scenarios such as: # Expire cache to prevent scenarios such as:
...@@ -40,7 +41,7 @@ module Projects ...@@ -40,7 +41,7 @@ module Projects
# 2. Retried import, repo is broken or not imported but +exists?+ still returns true # 2. Retried import, repo is broken or not imported but +exists?+ still returns true
project.repository.before_import if project.repository_exists? project.repository.before_import if project.repository_exists?
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}" raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end end
end end
......
...@@ -24,10 +24,9 @@ class SystemHooksService ...@@ -24,10 +24,9 @@ class SystemHooksService
key: model.key, key: model.key,
id: model.id id: model.id
) )
if model.user if model.user
data.merge!( data[:username] = model.user.username
username: model.user.username
)
end end
when Project when Project
data.merge!(project_data(model)) data.merge!(project_data(model))
...@@ -35,8 +34,6 @@ class SystemHooksService ...@@ -35,8 +34,6 @@ class SystemHooksService
if event == :rename || event == :transfer if event == :rename || event == :transfer
data[:old_path_with_namespace] = model.old_path_with_namespace data[:old_path_with_namespace] = model.old_path_with_namespace
end end
data
when User when User
data.merge!({ data.merge!({
name: model.name, name: model.name,
...@@ -59,6 +56,8 @@ class SystemHooksService ...@@ -59,6 +56,8 @@ class SystemHooksService
when GroupMember when GroupMember
data.merge!(group_member_data(model)) data.merge!(group_member_data(model))
end end
data
end end
def build_event_name(model, event) def build_event_name(model, event)
......
# ImportableUrlValidator
#
# This validator blocks projects from using dangerous import_urls to help
# protect against Server-side Request Forgery (SSRF).
class ImportableUrlValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if Gitlab::UrlBlocker.blocked_url?(value)
record.errors.add(attribute, "imports are not allowed from that URL")
end
end
end
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-save append-right-10' = f.submit 'Save', class: 'btn btn-save append-right-10'
- if @appearance.persisted? - if @appearance.persisted?
= link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank' = link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
- if @appearance.updated_at - if @appearance.updated_at
%span.pull-right %span.pull-right
......
...@@ -424,7 +424,7 @@ ...@@ -424,7 +424,7 @@
Enable Sentry Enable Sentry
.help-block .help-block
Sentry is an error reporting and logging tool which is currently not shipped with GitLab, get it here: Sentry is an error reporting and logging tool which is currently not shipped with GitLab, get it here:
%a{ href: 'https://getsentry.com', target: '_blank' } https://getsentry.com %a{ href: 'https://getsentry.com', target: '_blank', rel: 'noopener noreferrer' } https://getsentry.com
.form-group .form-group
= f.label :sentry_dsn, 'Sentry DSN', class: 'control-label col-sm-2' = f.label :sentry_dsn, 'Sentry DSN', class: 'control-label col-sm-2'
......
...@@ -9,7 +9,7 @@ xml.entry do ...@@ -9,7 +9,7 @@ xml.entry do
xml.author do xml.author do
xml.name event.author_name xml.name event.author_name
xml.email event.author_email xml.email event.author_public_email
end end
xml.summary(type: "xhtml") do |summary| xml.summary(type: "xhtml") do |summary|
......
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
= link_to note.attachment.url, target: '_blank' do = link_to note.attachment.url, target: '_blank' do
= image_tag note.attachment.url, class: 'note-image-attach' = image_tag note.attachment.url, class: 'note-image-attach'
- else - else
= link_to note.attachment.url, target: "_blank", class: 'note-file-attach' do = link_to note.attachment.url, target: '_blank', class: 'note-file-attach' do
%i.fa.fa-paperclip %i.fa.fa-paperclip
= note.attachment_identifier = note.attachment_identifier
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
- if current_application_settings.version_check_enabled - if current_application_settings.version_check_enabled
= version_status_badge = version_status_badge
%br %br
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank'}. Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank', rel: 'noopener noreferrer'}.
- if current_application_settings.help_text.present? - if current_application_settings.help_text.present?
%hr %hr
%p.slead %p.slead
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
- @already_added_projects.each do |project| - @already_added_projects.each do |project|
%tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" } %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
%td %td
= link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank' = link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank', rel: 'noopener noreferrer'
%td %td
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
%td.job-status %td.job-status
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
- @repos.each do |repo| - @repos.each do |repo|
%tr{ id: "repo_#{repo.owner}___#{repo.slug}" } %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
%td %td
= link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: "_blank" = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
%td.import-target %td.import-target
%fieldset.row %fieldset.row
.input-group .input-group
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
- @incompatible_repos.each do |repo| - @incompatible_repos.each do |repo|
%tr{ id: "repo_#{repo.owner}___#{repo.slug}" } %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
%td %td
= link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank' = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
%td.import-target %td.import-target
%td.import-actions-job-status %td.import-actions-job-status
= label_tag 'Incompatible Project', nil, class: 'label label-danger' = label_tag 'Incompatible Project', nil, class: 'label label-danger'
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
- @repos.each do |repo| - @repos.each do |repo|
%tr{ id: "repo_#{repo["id"]}" } %tr{ id: "repo_#{repo["id"]}" }
%td %td
= link_to repo["path_with_namespace"], "https://gitlab.com/#{repo["path_with_namespace"]}", target: "_blank" = link_to repo["path_with_namespace"], "https://gitlab.com/#{repo["path_with_namespace"]}", target: "_blank", rel: 'noopener noreferrer'
%td.import-target %td.import-target
= import_project_target(repo['namespace']['path'], repo['name']) = import_project_target(repo['namespace']['path'], repo['name'])
%td.import-actions.job-status %td.import-actions.job-status
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
%li %li
%p %p
Go to Go to
#{link_to "Google Takeout", "https://www.google.com/settings/takeout", target: "_blank"}. #{link_to "Google Takeout", "https://www.google.com/settings/takeout", target: '_blank', rel: 'noopener noreferrer'}.
%li %li
%p %p
Make sure you're logged into the account that owns the projects you'd like to import. Make sure you're logged into the account that owns the projects you'd like to import.
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
- @already_added_projects.each do |project| - @already_added_projects.each do |project|
%tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" } %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
%td %td
= link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank" = link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank", rel: 'noopener noreferrer'
%td %td
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
%td.job-status %td.job-status
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
- @repos.each do |repo| - @repos.each do |repo|
%tr{ id: "repo_#{repo.id}" } %tr{ id: "repo_#{repo.id}" }
%td %td
= link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank" = link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank", rel: 'noopener noreferrer'
%td.import-target %td.import-target
#{current_user.username}/#{repo.name} #{current_user.username}/#{repo.name}
%td.import-actions.job-status %td.import-actions.job-status
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
- @incompatible_repos.each do |repo| - @incompatible_repos.each do |repo|
%tr{ id: "repo_#{repo.id}" } %tr{ id: "repo_#{repo.id}" }
%td %td
= link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank" = link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank", rel: 'noopener noreferrer'
%td.import-target %td.import-target
%td.import-actions-job-status %td.import-actions-job-status
= label_tag "Incompatible Project", nil, class: "label label-danger" = label_tag "Incompatible Project", nil, class: "label label-danger"
......
...@@ -7,7 +7,7 @@ xml.entry do ...@@ -7,7 +7,7 @@ xml.entry do
xml.author do xml.author do
xml.name issue.author_name xml.name issue.author_name
xml.email issue.author_email xml.email issue.author_public_email
end end
xml.summary issue.title xml.summary issue.title
...@@ -26,7 +26,7 @@ xml.entry do ...@@ -26,7 +26,7 @@ xml.entry do
if issue.assignee if issue.assignee
xml.assignee do xml.assignee do
xml.name issue.assignee.name xml.name issue.assignee.name
xml.email issue.assignee.email xml.email issue.assignee_public_email
end end
end end
end end
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
%p %p
= icon('circle', class: 'cgreen') = icon('circle', class: 'cgreen')
Integration is active for Integration is active for
= link_to koding_project_url, target: '_blank' do = link_to koding_project_url, target: '_blank', rel: 'noopener noreferrer' do
#{current_application_settings.koding_url} #{current_application_settings.koding_url}
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host} or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
.col-lg-9 .col-lg-9
.clearfix.avatar-image.append-bottom-default .clearfix.avatar-image.append-bottom-default
= link_to avatar_icon(@user, 400), target: '_blank' do = link_to avatar_icon(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon(@user, 160), alt: '', class: 'avatar s160' = image_tag avatar_icon(@user, 160), alt: '', class: 'avatar s160'
%h5.prepend-top-0 %h5.prepend-top-0
Upload new avatar Upload new avatar
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
- else - else
.nothing-here-block .nothing-here-block
The SVG could not be displayed as it is too large, you can The SVG could not be displayed as it is too large, you can
#{link_to('view the raw file', namespace_project_raw_path(@project.namespace, @project, @id), target: '_blank')} #{link_to('view the raw file', namespace_project_raw_path(@project.namespace, @project, @id), target: '_blank', rel: 'noopener noreferrer')}
instead. instead.
- else - else
%img{ src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path)), alt: "#{blob.name}" } %img{ src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path)), alt: "#{blob.name}" }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.nothing-here-block .nothing-here-block
File too large, you can File too large, you can
= succeed '.' do = succeed '.' do
= link_to 'view the raw file', namespace_project_raw_path(@project.namespace, @project, @id), target: '_blank' = link_to 'view the raw file', namespace_project_raw_path(@project.namespace, @project, @id), target: '_blank', rel: 'noopener noreferrer'
- else - else
- blob.load_all_data!(@repository) - blob.load_all_data!(@repository)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
- if @conflict - if @conflict
.alert.alert-danger .alert.alert-danger
Someone edited the file the same time you did. Please check out Someone edited the file the same time you did. Please check out
= link_to "the file", namespace_project_blob_path(@project.namespace, @project, tree_join(@target_branch, @file_path)), target: "_blank" = link_to "the file", namespace_project_blob_path(@project.namespace, @project, tree_join(@target_branch, @file_path)), target: "_blank", rel: 'noopener noreferrer'
and make sure your changes will not unintentionally remove theirs. and make sure your changes will not unintentionally remove theirs.
.file-editor .file-editor
......
- if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch) - if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch)
= link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank' do = link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank', rel: 'noopener noreferrer' do
Run in IDE (Koding) Run in IDE (Koding)
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project. Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.
To set up CA, you must first define a production environment by setting up your CI and then deploy to production. To set up CA, you must first define a production environment by setting up your CI and then deploy to production.
%p %p
%a.btn{ href: help_page_path('user/project/cycle_analytics'), target: "_blank" } Read more %a.btn{ href: help_page_path('user/project/cycle_analytics'), target: '_blank' } Read more
.col-md-6.overview-image .col-md-6.overview-image
%span.overview-icon %span.overview-icon
= custom_icon ('icon_cycle_analytics_overview') = custom_icon ('icon_cycle_analytics_overview')
- if environment.external_url && can?(current_user, :read_environment, environment) - if environment.external_url && can?(current_user, :read_environment, environment)
= link_to environment.external_url, target: '_blank', class: 'btn external-url' do = link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn external-url' do
= icon('external-link') = icon('external-link')
- @no_container = true - @no_container = true
- page_title "Metrics for environment", @environment.name - page_title "Metrics for environment", @environment.name
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('monitoring')
= render "projects/pipelines/head" = render "projects/pipelines/head"
%div{ class: container_class } %div{ class: container_class }
......
...@@ -25,15 +25,14 @@ ...@@ -25,15 +25,14 @@
- if current_user - if current_user
%button.csv_download_link.btn.append-right-10.has-tooltip{ title: 'Export as CSV' } %button.csv_download_link.btn.append-right-10.has-tooltip{ title: 'Export as CSV' }
= icon('download') = icon('download')
- if can? current_user, :create_issue, @project = link_to new_namespace_project_issue_path(@project.namespace,
= link_to new_namespace_project_issue_path(@project.namespace, @project,
@project, issue: { assignee_id: issues_finder.assignee.try(:id),
issue: { assignee_id: issues_finder.assignee.try(:id), milestone_id: issues_finder.milestones.first.try(:id) }),
milestone_id: issues_finder.milestones.first.try(:id) }), class: "btn btn-new",
class: "btn btn-new", title: "New Issue",
title: "New Issue", id: "new_issue_link" do
id: "new_issue_link" do New Issue
New Issue
= render 'shared/issuable/search_bar', type: :issues = render 'shared/issuable/search_bar', type: :issues
.issues-holder .issues-holder
......
...@@ -20,37 +20,34 @@ ...@@ -20,37 +20,34 @@
= confidential_icon(@issue) = confidential_icon(@issue)
= issuable_meta(@issue, @project, "Issue") = issuable_meta(@issue, @project, "Issue")
- if can?(current_user, :create_issue, @project) || can?(current_user, :update_issue, @issue) .issuable-actions
.issuable-actions .clearfix.issue-btn-group.dropdown
.clearfix.issue-btn-group.dropdown %button.btn.btn-default.pull-left.hidden-md.hidden-lg{ type: "button", data: { toggle: "dropdown" } }
%button.btn.btn-default.pull-left.hidden-md.hidden-lg{ type: "button", data: { toggle: "dropdown" } } Options
Options = icon('caret-down')
= icon('caret-down') .dropdown-menu.dropdown-menu-align-right.hidden-lg
.dropdown-menu.dropdown-menu-align-right.hidden-lg %ul
%ul %li
- if can?(current_user, :create_issue, @project) = link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project), title: 'New issue', id: 'new_issue_link'
%li - if can?(current_user, :update_issue, @issue)
= link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project), title: 'New issue', id: 'new_issue_link' %li
- if can?(current_user, :update_issue, @issue) = link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), data: {no_turbolink: true}, class: "btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
%li %li
= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), data: {no_turbolink: true}, class: "btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' = link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), data: {no_turbolink: true}, class: "btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
%li %li
= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), data: {no_turbolink: true}, class: "btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' = link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue)
%li
= link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue)
- if @issue.submittable_as_spam_by?(current_user)
%li
= link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam'
- if can?(current_user, :create_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted', title: 'New issue', id: 'new_issue_link' do
New issue
- if can?(current_user, :update_issue, @issue)
= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), data: {no_turbolink: true}, class: "hidden-xs hidden-sm btn btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), data: {no_turbolink: true}, class: "hidden-xs hidden-sm btn btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
- if @issue.submittable_as_spam_by?(current_user) - if @issue.submittable_as_spam_by?(current_user)
= link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'hidden-xs hidden-sm btn btn-grouped btn-spam', title: 'Submit as spam' %li
= link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'hidden-xs hidden-sm btn btn-grouped issuable-edit' = link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam'
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted', title: 'New issue', id: 'new_issue_link' do
New issue
- if can?(current_user, :update_issue, @issue)
= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), data: {no_turbolink: true}, class: "hidden-xs hidden-sm btn btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), data: {no_turbolink: true}, class: "hidden-xs hidden-sm btn btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
- if @issue.submittable_as_spam_by?(current_user)
= link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'hidden-xs hidden-sm btn btn-grouped btn-spam', title: 'Submit as spam'
= link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'hidden-xs hidden-sm btn btn-grouped issuable-edit'
.issue-details.issuable-details .issue-details.issuable-details
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
.pull-right .pull-right
- if @merge_request.source_branch_exists? - if @merge_request.source_branch_exists?
- if koding_enabled? && @repository.koding_yml - if koding_enabled? && @repository.koding_yml
= link_to koding_project_url(@merge_request.source_project, @merge_request.source_branch, @merge_request.commits.first.short_id), class: "btn inline btn-grouped btn-sm", target: '_blank' do = link_to koding_project_url(@merge_request.source_project, @merge_request.source_branch, @merge_request.commits.first.short_id), class: "btn inline btn-grouped btn-sm", target: '_blank', rel: 'noopener noreferrer' do
Run in IDE (Koding) Run in IDE (Koding)
= link_to "#modal_merge_info", class: "btn inline btn-grouped btn-sm", "data-toggle" => "modal" do = link_to "#modal_merge_info", class: "btn inline btn-grouped btn-sm", "data-toggle" => "modal" do
Check out branch Check out branch
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
%strong Tip: %strong Tip:
= succeed '.' do = succeed '.' do
You can also checkout merge requests locally by You can also checkout merge requests locally by
= link_to 'following these guidelines', help_page_path('user/project/merge_requests.md', anchor: "checkout-merge-requests-locally"), target: '_blank' = link_to 'following these guidelines', help_page_path('user/project/merge_requests.md', anchor: "checkout-merge-requests-locally"), target: '_blank', rel: 'noopener noreferrer'
:javascript :javascript
$(function(){ $(function(){
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
%ul.list-unstyled.indent-list %ul.list-unstyled.indent-list
%li %li
1. 1.
= link_to 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands', target: '_blank', rel: 'noreferrer noopener nofollow' do = link_to 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands', target: '_blank', rel: 'noopener noreferrer nofollow' do
Enable custom slash commands Enable custom slash commands
= icon('external-link') = icon('external-link')
on your Mattermost installation on your Mattermost installation
%li %li
2. 2.
= link_to 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command', target: '_blank', rel: 'noreferrer noopener nofollow' do = link_to 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command', target: '_blank', rel: 'noopener noreferrer nofollow' do
Add a slash command Add a slash command
= icon('external-link') = icon('external-link')
in your Mattermost team with these options: in your Mattermost team with these options:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
%p %p
This service allows users to perform common operations on this This service allows users to perform common operations on this
project by entering slash commands in Mattermost. project by entering slash commands in Mattermost.
= link_to help_page_path('user/project/integrations/mattermost_slash_commands.md'), target: '_blank', ref: 'noreferrer nofollow noopener' do = link_to help_page_path('user/project/integrations/mattermost_slash_commands.md'), target: '_blank' do
View documentation View documentation
= icon('external-link') = icon('external-link')
%p.inline %p.inline
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%p %p
This service allows users to perform common operations on this This service allows users to perform common operations on this
project by entering slash commands in Slack. project by entering slash commands in Slack.
= link_to help_page_path('user/project/integrations/slack_slash_commands.md'), target: '_blank', ref: 'noreferrer nofollow noopener' do = link_to help_page_path('user/project/integrations/slack_slash_commands.md'), target: '_blank' do
View documentation View documentation
= icon('external-link') = icon('external-link')
%p.inline %p.inline
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
= label_tag nil, 'Customize icon', class: 'col-sm-2 col-xs-12 control-label' = label_tag nil, 'Customize icon', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block .col-sm-10.col-xs-12.text-block
= image_tag(asset_url('slash-command-logo.png'), width: 36, height: 36) = image_tag(asset_url('slash-command-logo.png'), width: 36, height: 36)
= link_to('Download image', asset_url('gitlab_logo.png'), class: 'btn btn-sm', target: '_blank') = link_to('Download image', asset_url('gitlab_logo.png'), class: 'btn btn-sm', target: '_blank', rel: 'noopener noreferrer')
.form-group .form-group
= label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label' = label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label'
......
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
%button.dropdown-toggle{ type: 'button', data: {toggle: 'dropdown' } } %button.dropdown-toggle{ type: 'button', data: {toggle: 'dropdown' } }
%span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
Also, issues are searchable and filterable. Also, issues are searchable and filterable.
- if project_select_button - if project_select_button
= render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue' = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue'
- else
= link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link'
- else - else
%h4.text-center There are no issues to show. %h4 There are no issues to show.
= link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link'
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
.alert.alert-danger .alert.alert-danger
Someone edited the #{issuable.class.model_name.human.downcase} the same time you did. Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
Please check out Please check out
= link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), target: "_blank" = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), target: "_blank", rel: 'noopener noreferrer'
and make sure your changes will not unintentionally remove theirs and make sure your changes will not unintentionally remove theirs
.form-group .form-group
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
.profile-header .profile-header
.avatar-holder .avatar-holder
= link_to avatar_icon(@user, 400), target: '_blank' do = link_to avatar_icon(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon(@user, 90), class: "avatar s90", alt: '' = image_tag avatar_icon(@user, 90), class: "avatar s90", alt: ''
.user-info .user-info
......
---
title: Only show public emails in atom feeds
merge_request:
author:
---
title: Fixes large file name tooltip cutoff in diff header
merge_request: 9529
author:
---
title: Fixes dismissable error close is not visible enough
merge_request: 9516
author:
---
title: New directory from interface on existing branch
merge_request: 9921
author: Jacopo Beschi @jacopo-beschi
---
title: Added tests for the w.gl.utils.backOff promise
merge_request:
author:
---
title: Return 404 in project issues API endpoint when project cannot be found
merge_request: 10093
author:
---
title: Fix bug when system hook for deploy key
merge_request: 9796
author: billy.lb
---
title: Hide ancestor groups in the share group dropdown list
merge_request: 9965
author:
---
title: New rake task to reset all email and private tokens
merge_request:
author:
---
title: Removed d3 from the main application.js bundle
merge_request: 10062
author:
---
title: Simplify trigger_docs build job for CE and EE
merge_request: 9820
author: winniehell
---
title: To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
merge_request:
author:
...@@ -37,6 +37,7 @@ var config = { ...@@ -37,6 +37,7 @@ var config = {
merge_conflicts: './merge_conflicts/merge_conflicts_bundle.js', merge_conflicts: './merge_conflicts/merge_conflicts_bundle.js',
merge_request_widget: './merge_request_widget/ci_bundle.js', merge_request_widget: './merge_request_widget/ci_bundle.js',
mr_widget_ee: './merge_request_widget/widget_bundle.js', mr_widget_ee: './merge_request_widget/widget_bundle.js',
monitoring: './monitoring/monitoring_bundle.js',
network: './network/network_bundle.js', network: './network/network_bundle.js',
profile: './profile/profile_bundle.js', profile: './profile/profile_bundle.js',
protected_branches: './protected_branches/protected_branches_bundle.js', protected_branches: './protected_branches/protected_branches_bundle.js',
...@@ -117,7 +118,7 @@ var config = { ...@@ -117,7 +118,7 @@ var config = {
// create cacheable common library bundle for all d3 chunks // create cacheable common library bundle for all d3 chunks
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
name: 'common_d3', name: 'common_d3',
chunks: ['graphs', 'users'], chunks: ['graphs', 'users', 'monitoring'],
}), }),
// create cacheable common library bundles // create cacheable common library bundles
...@@ -181,4 +182,4 @@ if (WEBPACK_REPORT) { ...@@ -181,4 +182,4 @@ if (WEBPACK_REPORT) {
); );
} }
module.exports = config; module.exports = config;
\ No newline at end of file
...@@ -155,7 +155,7 @@ class Gitlab::Seeder::CycleAnalytics ...@@ -155,7 +155,7 @@ class Gitlab::Seeder::CycleAnalytics
issue.project.repository.add_branch(@user, branch_name, 'master') issue.project.repository.add_branch(@user, branch_name, 'master')
commit_sha = issue.project.repository.create_file(@user, filename, "content", options, message: "Commit for ##{issue.iid}", branch_name: branch_name) commit_sha = issue.project.repository.create_file(@user, filename, "content", message: "Commit for ##{issue.iid}", branch_name: branch_name)
issue.project.repository.commit(commit_sha) issue.project.repository.commit(commit_sha)
GitPushService.new(issue.project, GitPushService.new(issue.project,
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddIndexToUserGhost < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
disable_ddl_transaction!
def up
add_concurrent_index :users, :ghost
end
def down
remove_index :users, :ghost
end
end
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class IndexRoutesPathForLike < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
INDEX_NAME = 'index_routes_on_path_text_pattern_ops'
disable_ddl_transaction!
def up
return unless Gitlab::Database.postgresql?
unless index_exists?(:routes, name: INDEX_NAME)
execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON routes (path varchar_pattern_ops);")
end
end
def down
return unless Gitlab::Database.postgresql?
if index_exists?(:routes, name: INDEX_NAME)
execute("DROP INDEX CONCURRENTLY #{INDEX_NAME};")
end
end
end
...@@ -6,41 +6,12 @@ class RenameMoreReservedProjectNames < ActiveRecord::Migration ...@@ -6,41 +6,12 @@ class RenameMoreReservedProjectNames < ActiveRecord::Migration
DOWNTIME = false DOWNTIME = false
THREAD_COUNT = 8
KNOWN_PATHS = %w(artifacts graphs refs badges).freeze KNOWN_PATHS = %w(artifacts graphs refs badges).freeze
def up def up
queues = Array.new(THREAD_COUNT) { Queue.new }
start = false
threads = Array.new(THREAD_COUNT) do |index|
Thread.new do
queue = queues[index]
# Wait until we have input to process.
until start; end
rename_projects(queue.pop) until queue.empty?
end
end
enum = queues.each
reserved_projects.each_slice(100) do |slice| reserved_projects.each_slice(100) do |slice|
begin rename_projects(slice)
queue = enum.next
rescue StopIteration
enum.rewind
retry
end
queue << slice
end end
start = true
threads.each(&:join)
end end
def down def down
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170315194013) do ActiveRecord::Schema.define(version: 20170317203554) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -1182,6 +1182,7 @@ ActiveRecord::Schema.define(version: 20170315194013) do ...@@ -1182,6 +1182,7 @@ ActiveRecord::Schema.define(version: 20170315194013) do
end end
add_index "routes", ["path"], name: "index_routes_on_path", unique: true, using: :btree add_index "routes", ["path"], name: "index_routes_on_path", unique: true, using: :btree
add_index "routes", ["path"], name: "index_routes_on_path_text_pattern_ops", using: :btree, opclasses: {"path"=>"varchar_pattern_ops"}
add_index "routes", ["source_type", "source_id"], name: "index_routes_on_source_type_and_source_id", unique: true, using: :btree add_index "routes", ["source_type", "source_id"], name: "index_routes_on_source_type_and_source_id", unique: true, using: :btree
create_table "sent_notifications", force: :cascade do |t| create_table "sent_notifications", force: :cascade do |t|
...@@ -1444,6 +1445,7 @@ ActiveRecord::Schema.define(version: 20170315194013) do ...@@ -1444,6 +1445,7 @@ ActiveRecord::Schema.define(version: 20170315194013) do
add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"} add_index "users", ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"}
add_index "users", ["ghost"], name: "index_users_on_ghost", using: :btree
add_index "users", ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree add_index "users", ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree
add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree
add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"} add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
...@@ -1519,4 +1521,4 @@ ActiveRecord::Schema.define(version: 20170315194013) do ...@@ -1519,4 +1521,4 @@ ActiveRecord::Schema.define(version: 20170315194013) do
add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade
add_foreign_key "trending_projects", "projects", on_delete: :cascade add_foreign_key "trending_projects", "projects", on_delete: :cascade
add_foreign_key "u2f_registrations", "users" add_foreign_key "u2f_registrations", "users"
end end
\ No newline at end of file
...@@ -96,21 +96,15 @@ Sample Prometheus queries: ...@@ -96,21 +96,15 @@ Sample Prometheus queries:
> Introduced in GitLab 9.0. > Introduced in GitLab 9.0.
If your GitLab server is running within Kubernetes, an option is now available If your GitLab server is running within Kubernetes, Prometheus will collect metrics from the Nodes in the cluster including performance data on each container. This is particularly helpful if your CI/CD environments run in the same cluster, as you can use the [Prometheus project integration][] to monitor them.
to monitor the health of each node in the cluster. This is particularly helpful
if your CI/CD environments run in the same cluster, and you would like enable
[Prometheus integration][] to monitor them.
When enabled, the bundled Prometheus server monitors Kubernetes and automatically To disable the monitoring of Kubernetes:
[collects metrics][prometheus-cadvisor-metrics] from each Node in the cluster.
To enable the Kubernetes monitoring:
1. Edit `/etc/gitlab/gitlab.rb` 1. Edit `/etc/gitlab/gitlab.rb`
1. Add or find and uncomment the following line: 1. Add or find and uncomment the following line and set it to `false`:
```ruby ```ruby
prometheus['monitor_kubernetes'] = true prometheus['monitor_kubernetes'] = false
``` ```
1. Save the file and [reconfigure GitLab][reconfigure] for the changes to 1. Save the file and [reconfigure GitLab][reconfigure] for the changes to
...@@ -165,4 +159,4 @@ The GitLab monitor exporter allows you to measure various GitLab metrics. ...@@ -165,4 +159,4 @@ The GitLab monitor exporter allows you to measure various GitLab metrics.
[reconfigure]: ../../restart_gitlab.md#omnibus-gitlab-reconfigure [reconfigure]: ../../restart_gitlab.md#omnibus-gitlab-reconfigure
[1261]: https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests/1261 [1261]: https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests/1261
[prometheus integration]: ../../../user/project/integrations/prometheus.md [prometheus integration]: ../../../user/project/integrations/prometheus.md
[rometheus-cadvisor-metrics]: https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md [prometheus-cadvisor-metrics]: https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md
...@@ -8,16 +8,16 @@ Below are the changes made between V3 and V4. ...@@ -8,16 +8,16 @@ Below are the changes made between V3 and V4.
### 8.17 ### 8.17
- Removed `/projects/:search` (use: `/projects?search=x`) [!8877](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8877) - Removed `GET /projects/:search` (use: `GET /projects?search=x`) [!8877](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8877)
- `iid` filter has been removed from `projects/:id/issues` [!8967](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8967) - `iid` filter has been removed from `GET /projects/:id/issues` [!8967](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8967)
- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793) - `GET /projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793)
- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793) - Endpoints under `GET /projects/merge_request/:id` have been removed (use: `GET /projects/merge_requests/:id`) [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793)
- Project snippets do not return deprecated field `expires_at` [!8723](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8723) - Project snippets do not return deprecated field `expires_at` [!8723](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8723)
- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`) [!8716](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8716) - Endpoints under `GET /projects/:id/keys` have been removed (use `GET /projects/:id/deploy_keys`) [!8716](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8716)
### 9.0 ### 9.0
- Status 409 returned for POST `project/:id/members` when a member already exists [!9093](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9093) - Status 409 returned for `POST /projects/:id/members` when a member already exists [!9093](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9093)
- Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` [!9328](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9328) - Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` [!9328](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9328)
- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) [!8853](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8853) - Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) [!8853](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8853)
- `/licences` - `/licences`
...@@ -28,31 +28,31 @@ Below are the changes made between V3 and V4. ...@@ -28,31 +28,31 @@ Below are the changes made between V3 and V4.
- `/gitignores/:key` - `/gitignores/:key`
- `/gitlab_ci_ymls/:key` - `/gitlab_ci_ymls/:key`
- `/dockerfiles/:key` - `/dockerfiles/:key`
- Moved `/projects/fork/:id` to `/projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940) - Moved `POST /projects/fork/:id` to `POST /projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940)
- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` [!9410](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9410) - Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` [!9410](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9410)
- Project filters are no longer available as `GET /projects/foo`, but as `GET /projects?foo=true` instead [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962) - Project filters are no longer available as `GET /projects/foo`, but as `GET /projects?foo=true` instead [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
- `GET /projects/visible` & `GET /projects/all` are consolidated into `GET /projects` and can be used with or without authorization - `GET /projects/visible` & `GET /projects/all` are consolidated into `GET /projects` and can be used with or without authorization
- `GET /projects/owned` moved to `GET /projects?owned=true` - `GET /projects/owned` moved to `GET /projects?owned=true`
- `GET /projects/starred` moved to `GET /projects?starred=true` - `GET /projects/starred` moved to `GET /projects?starred=true`
- `GET /projects` returns all projects visible to current user, even if the user is not a member [!9674](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9674) - `GET /projects` returns all projects visible to current user, even if the user is not a member [!9674](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9674)
- To get projects the user is a member of, use `/projects?membership=true` - To get projects the user is a member of, use `GET /projects?membership=true`
- Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606) - Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606)
- Added `POST /environments/:environment_id/stop` to stop an environment [!8808](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8808) - Added `POST /environments/:environment_id/stop` to stop an environment [!8808](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8808)
- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366) - Removed `DELETE /projects/:id/deploy_keys/:key_id/disable`. Use `DELETE /projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366)
- Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` [!9371](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9371) - Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` [!9371](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9371)
- Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. [!9325](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9325) - Make subscription API more RESTful. Use `POST /projects/:id/:subscribable_type/:subscribable_id/subscribe` to subscribe and `POST /projects/:id/:subscribable_type/:subscribable_id/unsubscribe` to unsubscribe from a resource. [!9325](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9325)
- Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) [!8849](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8849) - Labels filter on `GET /projects/:id/issues` and `GET /issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) [!8849](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8849)
- Renamed param `branch_name` to `branch` on the following endpoints [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936) - Renamed param `branch_name` to `branch` on the following endpoints [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936)
- POST `:id/repository/branches` - `POST /projects/:id/repository/branches`
- POST `:id/repository/commits` - `POST /projects/:id/repository/commits`
- POST/PUT/DELETE `:id/repository/files` - `POST/PUT/DELETE :id/repository/files`
- Renamed `merge when build succeeds` to merge `when pipeline succeeds parameters` on the following endpoints: [!9335](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/) - Renamed the `merge_when_build_succeeds` parameter to `merge_when_pipeline_succeeds` on the following endpoints: [!9335](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/)
- PUT `projects/:id/merge_requests/:merge_request_id/merge` - `PUT /projects/:id/merge_requests/:merge_request_id/merge`
- POST `projects/:id/merge_requests/:merge_request_id/cancel_merge_when_pipeline_succeeds` - `POST /projects/:id/merge_requests/:merge_request_id/cancel_merge_when_pipeline_succeeds`
- POST `projects` - `POST /projects`
- POST `projects/user/:user_id` - `POST /projects/user/:user_id`
- PUT `projects/:id` - `PUT /projects/:id`
- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936) - Renamed `branch_name` to `branch` on `DELETE /projects/:id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936)
- Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736) - Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736)
- Remove `subscribed` field from responses returning list of issues or merge - Remove `subscribed` field from responses returning list of issues or merge
requests. Fetch individual issues or merge requests to obtain the value requests. Fetch individual issues or merge requests to obtain the value
...@@ -62,25 +62,25 @@ Below are the changes made between V3 and V4. ...@@ -62,25 +62,25 @@ Below are the changes made between V3 and V4.
- Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384) - Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384)
- Return HTTP status code `400` for all validation errors when creating or updating a member instead of sometimes `422` error. [!9523](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9523) - Return HTTP status code `400` for all validation errors when creating or updating a member instead of sometimes `422` error. [!9523](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9523)
- Remove `GET /groups/owned`. Use `GET /groups?owned=true` instead [!9505](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9505) - Remove `GET /groups/owned`. Use `GET /groups?owned=true` instead [!9505](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9505)
- Return 202 with JSON body on async removals on V4 API (DELETE `/projects/:id/repository/merged_branches` and DELETE `/projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449) - Return 202 with JSON body on async removals on V4 API (`DELETE /projects/:id/repository/merged_branches` and `DELETE /projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449)
- `projects/:id/milestones?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!9096](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9096) - `GET /projects/:id/milestones?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!9096](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9096)
- Return basic info about pipeline in `GET /projects/:id/pipelines` [!8875](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8875) - Return basic info about pipeline in `GET /projects/:id/pipelines` [!8875](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8875)
- Simplify project payload exposed on Environment endpoints [!9675](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9675) - Simplify project payload exposed on Environment endpoints [!9675](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9675)
- Renamed all `build` references to `job` [!9463](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9463) - Renamed all `build` references to `job` [!9463](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9463)
- Drop GET '/projects/:id/repository/commits/:sha/jobs' [!9463](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9463) - Drop `GET /projects/:id/repository/commits/:sha/jobs` [!9463](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9463)
- Rename Build Triggers to be Pipeline Triggers API [!9713](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9713) - Rename Build Triggers to be Pipeline Triggers API [!9713](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9713)
- `POST /projects/:id/trigger/builds` to `POST /projects/:id/trigger/pipeline` - `POST /projects/:id/trigger/builds` to `POST /projects/:id/trigger/pipeline`
- Require description when creating a new trigger `POST /projects/:id/triggers` - Require description when creating a new trigger `POST /projects/:id/triggers`
- Simplify project payload exposed on Environment endpoints [!9675](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9675) - Simplify project payload exposed on Environment endpoints [!9675](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9675)
- API uses merge request `IID`s (internal ID, as in the web UI) rather than `ID`s. This affects the merge requests, award emoji, todos, and time tracking APIs. [!9530](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9530) - API uses merge request `IID`s (internal ID, as in the web UI) rather than `ID`s. This affects the merge requests, award emoji, todos, and time tracking APIs. [!9530](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9530)
- API uses issue `IID`s (internal ID, as in the web UI) rather than `ID`s. This affects the issues, award emoji, todos, and time tracking APIs. [!9530](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9530) - API uses issue `IID`s (internal ID, as in the web UI) rather than `ID`s. This affects the issues, award emoji, todos, and time tracking APIs. [!9530](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9530)
- Change initial page from `0` to `1` on `GET projects/:id/repository/commits` (like on the rest of the API) [!9679] (https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9679) - Change initial page from `0` to `1` on `GET /projects/:id/repository/commits` (like on the rest of the API) [!9679] (https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9679)
- Return correct `Link` header data for `GET projects/:id/repository/commits` [!9679] (https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9679) - Return correct `Link` header data for `GET /projects/:id/repository/commits` [!9679] (https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9679)
- Update endpoints for repository files [!9637](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9637) - Update endpoints for repository files [!9637](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9637)
- Moved `/projects/:id/repository/files?file_path=:file_path` to `/projects/:id/repository/files/:file_path` (`:file_path` should be URL-encoded) - Moved `GET /projects/:id/repository/files?file_path=:file_path` to `GET /projects/:id/repository/files/:file_path` (`:file_path` should be URL-encoded)
- `/projects/:id/repository/blobs/:sha` now returns JSON attributes for the blob identified by `:sha`, instead of finding the commit identified by `:sha` and returning the raw content of the blob in that commit identified by the required `?filepath=:filepath` - `GET /projects/:id/repository/blobs/:sha` now returns JSON attributes for the blob identified by `:sha`, instead of finding the commit identified by `:sha` and returning the raw content of the blob in that commit identified by the required `?filepath=:filepath`
- Moved `/projects/:id/repository/commits/:sha/blob?file_path=:file_path` and `/projects/:id/repository/blobs/:sha?file_path=:file_path` to `/projects/:id/repository/files/:file_path/raw?ref=:sha` - Moved `GET /projects/:id/repository/commits/:sha/blob?file_path=:file_path` and `GET /projects/:id/repository/blobs/:sha?file_path=:file_path` to `GET /projects/:id/repository/files/:file_path/raw?ref=:sha`
- `/projects/:id/repository/tree` parameter `ref_name` has been renamed to `ref` for consistency - `GET /projects/:id/repository/tree` parameter `ref_name` has been renamed to `ref` for consistency
#### EE-specific #### EE-specific
......
...@@ -170,12 +170,12 @@ Integration (CI) server. By using deploy keys, you don't have to setup a ...@@ -170,12 +170,12 @@ Integration (CI) server. By using deploy keys, you don't have to setup a
dummy user account. dummy user account.
If you are a project master or owner, you can add a deploy key in the If you are a project master or owner, you can add a deploy key in the
project settings under the section 'Deploy Keys'. Press the 'New Deploy project settings under the section 'Repository'. Specify a title for the new
Key' button and upload a public SSH key. After this, the machine that uses deploy key and paste a public SSH key. After this, the machine that uses
the corresponding private SSH key has read-only or read-write (if enabled) the corresponding private SSH key has read-only or read-write (if enabled)
access to the project. access to the project.
You can't add the same deploy key twice with the 'New Deploy Key' option. You can't add the same deploy key twice using the form.
If you want to add the same key to another project, please enable it in the If you want to add the same key to another project, please enable it in the
list that says 'Deploy keys from projects available to you'. All the deploy list that says 'Deploy keys from projects available to you'. All the deploy
keys of all the projects you have access to are available. This project keys of all the projects you have access to are available. This project
......
...@@ -115,11 +115,11 @@ sudo -u git -H bundle clean ...@@ -115,11 +115,11 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Install/update frontend asset dependencies # Update node dependencies and recompile assets
sudo -u git -H npm install --production sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
# Clean up assets and cache # Clean up cache
sudo -u git -H bundle exec rake gitlab:assets:clean gitlab:assets:compile cache:clear RAILS_ENV=production sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
``` ```
**MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md). **MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md).
......
...@@ -93,7 +93,7 @@ module API ...@@ -93,7 +93,7 @@ module API
use :issues_params use :issues_params
end end
get ":id/issues" do get ":id/issues" do
project = find_project(params[:id]) project = find_project!(params[:id])
issues = find_issues(project_id: project.id) issues = find_issues(project_id: project.id)
......
...@@ -104,7 +104,7 @@ module API ...@@ -104,7 +104,7 @@ module API
use :issues_params use :issues_params
end end
get ":id/issues" do get ":id/issues" do
project = find_project(params[:id]) project = find_project!(params[:id])
issues = find_issues(project_id: project.id) issues = find_issues(project_id: project.id)
......
...@@ -2,7 +2,6 @@ module Banzai ...@@ -2,7 +2,6 @@ module Banzai
module Filter module Filter
# HTML filter that wraps links around inline images. # HTML filter that wraps links around inline images.
class ImageLinkFilter < HTML::Pipeline::Filter class ImageLinkFilter < HTML::Pipeline::Filter
# Find every image that isn't already wrapped in an `a` tag, create # Find every image that isn't already wrapped in an `a` tag, create
# a new node (a link to the image source), copy the image as a child # a new node (a link to the image source), copy the image as a child
# of the anchor, and then replace the img with the link-wrapped version. # of the anchor, and then replace the img with the link-wrapped version.
...@@ -12,7 +11,8 @@ module Banzai ...@@ -12,7 +11,8 @@ module Banzai
'a', 'a',
class: 'no-attachment-icon', class: 'no-attachment-icon',
href: img['src'], href: img['src'],
target: '_blank' target: '_blank',
rel: 'noopener noreferrer'
) )
link.children = img.clone link.children = img.clone
......
...@@ -43,6 +43,7 @@ module Banzai ...@@ -43,6 +43,7 @@ module Banzai
element['title'] || element['alt'], element['title'] || element['alt'],
href: element['src'], href: element['src'],
target: '_blank', target: '_blank',
rel: 'noopener noreferrer',
title: "Download '#{element['title'] || element['alt']}'") title: "Download '#{element['title'] || element['alt']}'")
download_paragraph = doc.document.create_element('p') download_paragraph = doc.document.create_element('p')
download_paragraph.children = link download_paragraph.children = link
......
require 'resolv'
module Gitlab
class UrlBlocker
class << self
# Used to specify what hosts and port numbers should be prohibited for project
# imports.
VALID_PORTS = [22, 80, 443].freeze
def blocked_url?(url)
return false if url.nil?
blocked_ips = ["127.0.0.1", "::1", "0.0.0.0"]
blocked_ips.concat(Socket.ip_address_list.map(&:ip_address))
begin
uri = Addressable::URI.parse(url)
# Allow imports from the GitLab instance itself but only from the configured ports
return false if internal?(uri)
return true if blocked_port?(uri.port)
server_ips = Resolv.getaddresses(uri.hostname)
return true if (blocked_ips & server_ips).any?
rescue Addressable::URI::InvalidURIError
return true
end
false
end
private
def blocked_port?(port)
return false if port.blank?
port < 1024 && !VALID_PORTS.include?(port)
end
def internal?(uri)
internal_web?(uri) || internal_shell?(uri)
end
def internal_web?(uri)
uri.hostname == config.gitlab.host &&
(uri.port.blank? || uri.port == config.gitlab.port)
end
def internal_shell?(uri)
uri.hostname == config.gitlab_shell.ssh_host &&
(uri.port.blank? || uri.port == config.gitlab_shell.ssh_port)
end
def config
Gitlab.config
end
end
end
end
...@@ -96,8 +96,8 @@ module Gitlab ...@@ -96,8 +96,8 @@ module Gitlab
end end
def level_value(level) def level_value(level)
return string_options[level] if level.is_a? String return level.to_i if level.to_i.to_s == level.to_s && string_options.key(level.to_i)
level string_options[level] || PRIVATE
end end
def string_level(level) def string_level(level)
......
...@@ -3,16 +3,16 @@ namespace :gitlab do ...@@ -3,16 +3,16 @@ namespace :gitlab do
desc 'GitLab | Assets | Compile all frontend assets' desc 'GitLab | Assets | Compile all frontend assets'
task compile: [ task compile: [
'yarn:check', 'yarn:check',
'assets:precompile', 'rake:assets:precompile',
'webpack:compile', 'webpack:compile',
'gitlab:assets:fix_urls' 'fix_urls'
] ]
desc 'GitLab | Assets | Clean up old compiled frontend assets' desc 'GitLab | Assets | Clean up old compiled frontend assets'
task clean: ['assets:clean'] task clean: ['rake:assets:clean']
desc 'GitLab | Assets | Remove all compiled frontend assets' desc 'GitLab | Assets | Remove all compiled frontend assets'
task purge: ['assets:clobber'] task purge: ['rake:assets:clobber']
desc 'GitLab | Assets | Uninstall frontend dependencies' desc 'GitLab | Assets | Uninstall frontend dependencies'
task purge_modules: ['yarn:clobber'] task purge_modules: ['yarn:clobber']
......
...@@ -3,10 +3,12 @@ require Rails.root.join('lib/gitlab/database/migration_helpers') ...@@ -3,10 +3,12 @@ require Rails.root.join('lib/gitlab/database/migration_helpers')
require Rails.root.join('db/migrate/20151007120511_namespaces_projects_path_lower_indexes') require Rails.root.join('db/migrate/20151007120511_namespaces_projects_path_lower_indexes')
require Rails.root.join('db/migrate/20151008110232_add_users_lower_username_email_indexes') require Rails.root.join('db/migrate/20151008110232_add_users_lower_username_email_indexes')
require Rails.root.join('db/migrate/20161212142807_add_lower_path_index_to_routes') require Rails.root.join('db/migrate/20161212142807_add_lower_path_index_to_routes')
require Rails.root.join('db/migrate/20170317203554_index_routes_path_for_like')
desc 'GitLab | Sets up PostgreSQL' desc 'GitLab | Sets up PostgreSQL'
task setup_postgresql: :environment do task setup_postgresql: :environment do
NamespacesProjectsPathLowerIndexes.new.up NamespacesProjectsPathLowerIndexes.new.up
AddUsersLowerUsernameEmailIndexes.new.up AddUsersLowerUsernameEmailIndexes.new.up
AddLowerPathIndexToRoutes.new.up AddLowerPathIndexToRoutes.new.up
IndexRoutesPathForLike.new.up
end end
require_relative '../../app/models/concerns/token_authenticatable.rb'
namespace :tokens do
desc "Reset all GitLab user auth tokens"
task reset_all_auth: :environment do
reset_all_users_token(:reset_authentication_token!)
end
desc "Reset all GitLab email tokens"
task reset_all_email: :environment do
reset_all_users_token(:reset_incoming_email_token!)
end
def reset_all_users_token(reset_token_method)
TmpUser.find_in_batches do |batch|
puts "Processing batch starting with user ID: #{batch.first.id}"
STDOUT.flush
batch.each(&reset_token_method)
end
end
end
class TmpUser < ActiveRecord::Base
include TokenAuthenticatable
self.table_name = 'users'
def reset_authentication_token!
write_new_token(:authentication_token)
save!(validate: false)
end
def reset_incoming_email_token!
write_new_token(:incoming_email_token)
save!(validate: false)
end
end
...@@ -87,6 +87,12 @@ describe Projects::IssuesController do ...@@ -87,6 +87,12 @@ describe Projects::IssuesController do
end end
describe 'GET #new' do describe 'GET #new' do
it 'redirects to signin if not logged in' do
get :new, namespace_id: project.namespace, project_id: project
expect(response).to redirect_to(new_user_session_path)
end
context 'internal issue tracker' do context 'internal issue tracker' do
before do before do
sign_in(user) sign_in(user)
...@@ -121,6 +127,11 @@ describe Projects::IssuesController do ...@@ -121,6 +127,11 @@ describe Projects::IssuesController do
end end
context 'external issue tracker' do context 'external issue tracker' do
before do
sign_in(user)
project.team << [user, :developer]
end
it 'redirects to the external issue tracker' do it 'redirects to the external issue tracker' do
external = double(new_issue_path: 'https://example.com/issues/new') external = double(new_issue_path: 'https://example.com/issues/new')
allow(project).to receive(:external_issue_tracker).and_return(external) allow(project).to receive(:external_issue_tracker).and_return(external)
...@@ -141,6 +152,24 @@ describe Projects::IssuesController do ...@@ -141,6 +152,24 @@ describe Projects::IssuesController do
it_behaves_like 'update invalid issuable', Issue it_behaves_like 'update invalid issuable', Issue
context 'changing the assignee' do
it 'limits the attributes exposed on the assignee' do
assignee = create(:user)
project.add_developer(assignee)
put :update,
namespace_id: project.namespace.to_param,
project_id: project,
id: issue.iid,
issue: { assignee_id: assignee.id },
format: :json
body = JSON.parse(response.body)
expect(body['assignee'].keys)
.to match_array(%w(name username avatar_url))
end
end
context 'when moving issue to another private project' do context 'when moving issue to another private project' do
let(:another_project) { create(:empty_project, :private) } let(:another_project) { create(:empty_project, :private) }
......
...@@ -374,6 +374,24 @@ describe Projects::MergeRequestsController do ...@@ -374,6 +374,24 @@ describe Projects::MergeRequestsController do
merge_request: params merge_request: params
end end
context 'changing the assignee' do
it 'limits the attributes exposed on the assignee' do
assignee = create(:user)
project.add_developer(assignee)
put :update,
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid,
merge_request: { assignee_id: assignee.id },
format: :json
body = JSON.parse(response.body)
expect(body['assignee'].keys)
.to match_array(%w(name username avatar_url))
end
end
context 'there is no source project' do context 'there is no source project' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:fork_project) { create(:forked_project_with_submodules) } let(:fork_project) { create(:forked_project_with_submodules) }
......
...@@ -9,6 +9,13 @@ feature 'Admin updates settings', feature: true do ...@@ -9,6 +9,13 @@ feature 'Admin updates settings', feature: true do
visit admin_application_settings_path visit admin_application_settings_path
end end
scenario 'Change visibility settings' do
choose "application_setting_default_project_visibility_20"
click_button 'Save'
expect(page).to have_content "Application settings saved successfully"
end
scenario 'Change application settings' do scenario 'Change application settings' do
uncheck 'Gravatar enabled' uncheck 'Gravatar enabled'
fill_in 'Home page URL', with: 'https://about.gitlab.com/' fill_in 'Home page URL', with: 'https://about.gitlab.com/'
......
...@@ -2,7 +2,8 @@ require 'spec_helper' ...@@ -2,7 +2,8 @@ require 'spec_helper'
describe "Dashboard Issues Feed", feature: true do describe "Dashboard Issues Feed", feature: true do
describe "GET /issues" do describe "GET /issues" do
let!(:user) { create(:user) } let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
let!(:project1) { create(:project) } let!(:project1) { create(:project) }
let!(:project2) { create(:project) } let!(:project2) { create(:project) }
...@@ -31,7 +32,7 @@ describe "Dashboard Issues Feed", feature: true do ...@@ -31,7 +32,7 @@ describe "Dashboard Issues Feed", feature: true do
end end
context "issue with basic fields" do context "issue with basic fields" do
let!(:issue2) { create(:issue, author: user, assignee: user, project: project2, description: 'test desc') } let!(:issue2) { create(:issue, author: user, assignee: assignee, project: project2, description: 'test desc') }
it "renders issue fields" do it "renders issue fields" do
visit issues_dashboard_path(:atom, private_token: user.private_token) visit issues_dashboard_path(:atom, private_token: user.private_token)
...@@ -39,8 +40,8 @@ describe "Dashboard Issues Feed", feature: true do ...@@ -39,8 +40,8 @@ describe "Dashboard Issues Feed", feature: true do
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue2.title}')]") entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue2.title}')]")
expect(entry).to be_present expect(entry).to be_present
expect(entry).to have_selector('author email', text: issue2.author_email) expect(entry).to have_selector('author email', text: issue2.author_public_email)
expect(entry).to have_selector('assignee email', text: issue2.author_email) expect(entry).to have_selector('assignee email', text: issue2.assignee_public_email)
expect(entry).not_to have_selector('labels') expect(entry).not_to have_selector('labels')
expect(entry).not_to have_selector('milestone') expect(entry).not_to have_selector('milestone')
expect(entry).to have_selector('description', text: issue2.description) expect(entry).to have_selector('description', text: issue2.description)
...@@ -50,7 +51,7 @@ describe "Dashboard Issues Feed", feature: true do ...@@ -50,7 +51,7 @@ describe "Dashboard Issues Feed", feature: true do
context "issue with label and milestone" do context "issue with label and milestone" do
let!(:milestone1) { create(:milestone, project: project1, title: 'v1') } let!(:milestone1) { create(:milestone, project: project1, title: 'v1') }
let!(:label1) { create(:label, project: project1, title: 'label1') } let!(:label1) { create(:label, project: project1, title: 'label1') }
let!(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone1) } let!(:issue1) { create(:issue, author: user, assignee: assignee, project: project1, milestone: milestone1) }
before do before do
issue1.labels << label1 issue1.labels << label1
...@@ -62,8 +63,8 @@ describe "Dashboard Issues Feed", feature: true do ...@@ -62,8 +63,8 @@ describe "Dashboard Issues Feed", feature: true do
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue1.title}')]") entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue1.title}')]")
expect(entry).to be_present expect(entry).to be_present
expect(entry).to have_selector('author email', text: issue1.author_email) expect(entry).to have_selector('author email', text: issue1.author_public_email)
expect(entry).to have_selector('assignee email', text: issue1.author_email) expect(entry).to have_selector('assignee email', text: issue1.assignee_public_email)
expect(entry).to have_selector('labels label', text: label1.title) expect(entry).to have_selector('labels label', text: label1.title)
expect(entry).to have_selector('milestone', text: milestone1.title) expect(entry).to have_selector('milestone', text: milestone1.title)
expect(entry).not_to have_selector('description') expect(entry).not_to have_selector('description')
......
...@@ -2,10 +2,11 @@ require 'spec_helper' ...@@ -2,10 +2,11 @@ require 'spec_helper'
describe 'Issues Feed', feature: true do describe 'Issues Feed', feature: true do
describe 'GET /issues' do describe 'GET /issues' do
let!(:user) { create(:user) } let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
let!(:group) { create(:group) } let!(:group) { create(:group) }
let!(:project) { create(:project) } let!(:project) { create(:project) }
let!(:issue) { create(:issue, author: user, project: project) } let!(:issue) { create(:issue, author: user, assignee: assignee, project: project) }
before do before do
project.team << [user, :developer] project.team << [user, :developer]
...@@ -20,7 +21,8 @@ describe 'Issues Feed', feature: true do ...@@ -20,7 +21,8 @@ describe 'Issues Feed', feature: true do
expect(response_headers['Content-Type']). expect(response_headers['Content-Type']).
to have_content('application/atom+xml') to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignee email', text: issue.author_public_email)
expect(body).to have_selector('entry summary', text: issue.title) expect(body).to have_selector('entry summary', text: issue.title)
end end
end end
...@@ -33,7 +35,8 @@ describe 'Issues Feed', feature: true do ...@@ -33,7 +35,8 @@ describe 'Issues Feed', feature: true do
expect(response_headers['Content-Type']). expect(response_headers['Content-Type']).
to have_content('application/atom+xml') to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignee email', text: issue.author_public_email)
expect(body).to have_selector('entry summary', text: issue.title) expect(body).to have_selector('entry summary', text: issue.title)
end end
end end
......
require 'spec_helper' require 'spec_helper'
feature 'Group name toggle', js: true do feature 'Group name toggle', feature: true, js: true do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:nested_group_1) { create(:group, parent: group) } let(:nested_group_1) { create(:group, parent: group) }
let(:nested_group_2) { create(:group, parent: nested_group_1) } let(:nested_group_2) { create(:group, parent: nested_group_1) }
......
...@@ -6,7 +6,7 @@ describe 'Issues', feature: true do ...@@ -6,7 +6,7 @@ describe 'Issues', feature: true do
include SortingHelper include SortingHelper
include WaitForAjax include WaitForAjax
let(:project) { create(:project) } let(:project) { create(:project, :public) }
before do before do
login_as :user login_as :user
...@@ -597,6 +597,24 @@ describe 'Issues', feature: true do ...@@ -597,6 +597,24 @@ describe 'Issues', feature: true do
end end
describe 'new issue' do describe 'new issue' do
context 'by unauthenticated user' do
before do
logout
end
it 'redirects to signin then back to new issue after signin' do
visit namespace_project_issues_path(project.namespace, project)
click_link 'New issue'
expect(current_path).to eq new_user_session_path
login_as :user
expect(current_path).to eq new_namespace_project_issue_path(project.namespace, project)
end
end
context 'dropzone upload file', js: true do context 'dropzone upload file', js: true do
before do before do
visit new_namespace_project_issue_path(project.namespace, project) visit new_namespace_project_issue_path(project.namespace, project)
......
...@@ -35,6 +35,8 @@ feature 'Merge immediately', :feature, :js do ...@@ -35,6 +35,8 @@ feature 'Merge immediately', :feature, :js do
click_link 'Merge Immediately' click_link 'Merge Immediately'
expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress') expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress')
wait_for_ajax
end end
end end
end end
......
...@@ -49,6 +49,26 @@ feature 'Merge requests filter clear button', feature: true, js: true do ...@@ -49,6 +49,26 @@ feature 'Merge requests filter clear button', feature: true, js: true do
end end
end end
context 'when multiple label filters have been applied' do
let!(:label) { create(:label, project: project, name: 'Frontend') }
let(:filter_dropdown) { find("#js-dropdown-label .filter-dropdown") }
before do
visit_merge_requests(project)
init_label_search
end
it 'filters bug label' do
filtered_search.set('~bug')
filter_dropdown.find('.filter-dropdown-item', text: bug.title).click
init_label_search
expect(filter_dropdown.find('.filter-dropdown-item', text: bug.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: label.title)).to be_visible
end
end
context 'when a text search has been conducted' do context 'when a text search has been conducted' do
it 'resets the text search filter' do it 'resets the text search filter' do
visit_merge_requests(project, search: 'Bug') visit_merge_requests(project, search: 'Bug')
......
...@@ -2,6 +2,7 @@ require 'spec_helper' ...@@ -2,6 +2,7 @@ require 'spec_helper'
feature 'New blob creation', feature: true, js: true do feature 'New blob creation', feature: true, js: true do
include WaitForAjax include WaitForAjax
include TargetBranchHelpers
given(:user) { create(:user) } given(:user) { create(:user) }
given(:role) { :developer } given(:role) { :developer }
...@@ -20,19 +21,6 @@ feature 'New blob creation', feature: true, js: true do ...@@ -20,19 +21,6 @@ feature 'New blob creation', feature: true, js: true do
execute_script("ace.edit('editor').setValue('#{content}')") execute_script("ace.edit('editor').setValue('#{content}')")
end end
def select_branch_index(index)
first('button.js-target-branch').click
wait_for_ajax
all('a[data-group="Branches"]')[index].click
end
def create_new_branch(name)
first('button.js-target-branch').click
click_link 'Create new branch'
fill_in 'new_branch_name', with: name
click_button 'Create'
end
def commit_file def commit_file
click_button 'Commit Changes' click_button 'Commit Changes'
end end
...@@ -53,12 +41,12 @@ feature 'New blob creation', feature: true, js: true do ...@@ -53,12 +41,12 @@ feature 'New blob creation', feature: true, js: true do
context 'with different target branch' do context 'with different target branch' do
background do background do
edit_file edit_file
select_branch_index(0) select_branch('feature')
commit_file commit_file
end end
scenario 'creates the blob in the different branch' do scenario 'creates the blob in the different branch' do
expect(page).to have_content 'test' expect(page).to have_content 'feature'
expect(page).to have_content 'successfully created' expect(page).to have_content 'successfully created'
end end
end end
......
...@@ -8,7 +8,7 @@ feature 'Project group links', feature: true, js: true do ...@@ -8,7 +8,7 @@ feature 'Project group links', feature: true, js: true do
let!(:group) { create(:group) } let!(:group) { create(:group) }
background do background do
project.team << [master, :master] project.add_master(master)
login_as(master) login_as(master)
end end
...@@ -29,4 +29,26 @@ feature 'Project group links', feature: true, js: true do ...@@ -29,4 +29,26 @@ feature 'Project group links', feature: true, js: true do
end end
end end
end end
context 'nested group project' do
let!(:nested_group) { create(:group, parent: group) }
let!(:another_group) { create(:group) }
let!(:project) { create(:project, namespace: nested_group) }
background do
group.add_master(master)
another_group.add_master(master)
end
it 'does not show ancestors' do
visit namespace_project_settings_members_path(project.namespace, project)
click_link 'Search for a group'
page.within '.select2-drop' do
expect(page).to have_content(another_group.name)
expect(page).not_to have_content(group.name)
end
end
end
end end
require 'spec_helper'
feature 'New directory creation', feature: true, js: true do
include WaitForAjax
include TargetBranchHelpers
given(:user) { create(:user) }
given(:role) { :developer }
given(:project) { create(:project) }
background do
login_as(user)
project.team << [user, role]
visit namespace_project_tree_path(project.namespace, project, 'master')
open_new_directory_modal
fill_in 'dir_name', with: 'new_directory'
end
def open_new_directory_modal
first('.add-to-tree').click
click_link 'New directory'
end
def create_directory
click_button 'Create directory'
end
context 'with default target branch' do
background do
create_directory
end
scenario 'creates the directory in the default branch' do
expect(page).to have_content 'master'
expect(page).to have_content 'The directory has been successfully created'
expect(page).to have_content 'new_directory'
end
end
context 'with different target branch' do
background do
select_branch('feature')
create_directory
end
scenario 'creates the directory in the different branch' do
expect(page).to have_content 'feature'
expect(page).to have_content 'The directory has been successfully created'
end
end
context 'with a new target branch' do
given(:new_branch_name) { 'new-feature' }
background do
create_new_branch(new_branch_name)
create_directory
end
scenario 'creates the directory in the new branch' do
expect(page).to have_content new_branch_name
expect(page).to have_content 'The directory has been successfully created'
end
scenario 'redirects to the merge request' do
expect(page).to have_content 'New Merge Request'
expect(page).to have_content "From #{new_branch_name} into master"
expect(page).to have_content 'Add new directory'
expect(current_path).to eq(new_namespace_project_merge_request_path(project.namespace, project))
end
end
end
...@@ -246,5 +246,17 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper ...@@ -246,5 +246,17 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper
expect(gl.FilteredSearchVisualTokens.unselectTokens).toHaveBeenCalled(); expect(gl.FilteredSearchVisualTokens.unselectTokens).toHaveBeenCalled();
}); });
}); });
describe('toggleInputContainerFocus', () => {
it('toggles on focus', () => {
input.focus();
expect(document.querySelector('.filtered-search-input-container').classList.contains('focus')).toEqual(true);
});
it('toggles on blur', () => {
input.blur();
expect(document.querySelector('.filtered-search-input-container').classList.contains('focus')).toEqual(false);
});
});
}); });
})(); })();
...@@ -136,6 +136,21 @@ describe('Issue', function() { ...@@ -136,6 +136,21 @@ describe('Issue', function() {
expectErrorMessage(); expectErrorMessage();
expect($('.issue_counter')).toHaveText(1); expect($('.issue_counter')).toHaveText(1);
}); });
it('updates counter', () => {
spyOn(jQuery, 'ajax').and.callFake(function(req) {
expectPendingRequest(req, $btnClose);
req.success({
id: 34
});
});
expect($('.issue_counter')).toHaveText(1);
$('.issue_counter').text('1,001');
expect($('.issue_counter').text()).toEqual('1,001');
$btnClose.trigger('click');
expect($('.issue_counter').text()).toEqual('1,000');
});
}); });
describe('reopen issue', function() { describe('reopen issue', function() {
......
...@@ -163,5 +163,72 @@ require('~/lib/utils/common_utils'); ...@@ -163,5 +163,72 @@ require('~/lib/utils/common_utils');
expect(gl.utils.isMetaClick(e)).toBe(true); expect(gl.utils.isMetaClick(e)).toBe(true);
}); });
}); });
describe('gl.utils.backOff', () => {
it('solves the promise from the callback', (done) => {
const expectedResponseValue = 'Success!';
gl.utils.backOff((next, stop) => (
new Promise((resolve) => {
resolve(expectedResponseValue);
}).then((resp) => {
stop(resp);
})
)).then((respBackoff) => {
expect(respBackoff).toBe(expectedResponseValue);
done();
});
});
it('catches the rejected promise from the callback ', (done) => {
const errorMessage = 'Mistakes were made!';
gl.utils.backOff((next, stop) => {
new Promise((resolve, reject) => {
reject(new Error(errorMessage));
}).then((resp) => {
stop(resp);
}).catch(err => stop(err));
}).catch((errBackoffResp) => {
expect(errBackoffResp instanceof Error).toBe(true);
expect(errBackoffResp.message).toBe(errorMessage);
done();
});
});
it('solves the promise correctly after retrying a third time', (done) => {
let numberOfCalls = 1;
const expectedResponseValue = 'Success!';
gl.utils.backOff((next, stop) => (
new Promise((resolve) => {
resolve(expectedResponseValue);
}).then((resp) => {
if (numberOfCalls < 3) {
numberOfCalls += 1;
next();
} else {
stop(resp);
}
})
)).then((respBackoff) => {
expect(respBackoff).toBe(expectedResponseValue);
expect(numberOfCalls).toBe(3);
done();
});
}, 10000);
it('rejects the backOff promise after timing out', (done) => {
const expectedResponseValue = 'Success!';
gl.utils.backOff(next => (
new Promise((resolve) => {
resolve(expectedResponseValue);
}).then(() => {
setTimeout(next(), 5000); // it will time out
})
), 3000).catch((errBackoffResp) => {
expect(errBackoffResp instanceof Error).toBe(true);
expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT');
done();
});
}, 10000);
});
}); });
})(); })();
require 'spec_helper'
describe Gitlab::UrlBlocker, lib: true do
describe '#blocked_url?' do
it 'allows imports from configured web host and port' do
import_url = "http://#{Gitlab.config.gitlab.host}:#{Gitlab.config.gitlab.port}/t.git"
expect(described_class.blocked_url?(import_url)).to be false
end
it 'allows imports from configured SSH host and port' do
import_url = "http://#{Gitlab.config.gitlab_shell.ssh_host}:#{Gitlab.config.gitlab_shell.ssh_port}/t.git"
expect(described_class.blocked_url?(import_url)).to be false
end
it 'returns true for bad localhost hostname' do
expect(described_class.blocked_url?('https://localhost:65535/foo/foo.git')).to be true
end
it 'returns true for bad port' do
expect(described_class.blocked_url?('https://gitlab.com:25/foo/foo.git')).to be true
end
it 'returns true for invalid URL' do
expect(described_class.blocked_url?('http://:8080')).to be true
end
it 'returns false for legitimate URL' do
expect(described_class.blocked_url?('https://gitlab.com/foo/foo.git')).to be false
end
end
end
require 'spec_helper'
describe Gitlab::VisibilityLevel, lib: true do
describe '.level_value' do
it 'converts "public" to integer value' do
expect(described_class.level_value('public')).to eq(Gitlab::VisibilityLevel::PUBLIC)
end
it 'converts string integer to integer value' do
expect(described_class.level_value('20')).to eq(20)
end
it 'defaults to PRIVATE when string value is not valid' do
expect(described_class.level_value('invalid')).to eq(Gitlab::VisibilityLevel::PRIVATE)
end
it 'defaults to PRIVATE when integer value is not valid' do
expect(described_class.level_value(100)).to eq(Gitlab::VisibilityLevel::PRIVATE)
end
end
end
...@@ -110,6 +110,24 @@ describe HasStatus do ...@@ -110,6 +110,24 @@ describe HasStatus do
it { is_expected.to eq 'running' } it { is_expected.to eq 'running' }
end end
context 'when one status finished and second is still created' do
let!(:statuses) do
[create(type, status: :success), create(type, status: :created)]
end
it { is_expected.to eq 'running' }
end
context 'when there is a manual status before created status' do
let!(:statuses) do
[create(type, status: :success),
create(type, status: :manual, allow_failure: false),
create(type, status: :created)]
end
it { is_expected.to eq 'manual' }
end
context 'when one status is a blocking manual action' do context 'when one status is a blocking manual action' do
let!(:statuses) do let!(:statuses) do
[create(type, status: :failed), [create(type, status: :failed),
......
...@@ -230,6 +230,20 @@ describe Project, models: true do ...@@ -230,6 +230,20 @@ describe Project, models: true do
expect(project2.import_data).to be_nil expect(project2.import_data).to be_nil
end end
it "does not allow blocked import_url localhost" do
project2 = build(:empty_project, import_url: 'http://localhost:9000/t.git')
expect(project2).to be_invalid
expect(project2.errors[:import_url]).to include('imports are not allowed from that URL')
end
it "does not allow blocked import_url port" do
project2 = build(:empty_project, import_url: 'http://github.com:25/t.git')
expect(project2).to be_invalid
expect(project2.errors[:import_url]).to include('imports are not allowed from that URL')
end
describe 'project pending deletion' do describe 'project pending deletion' do
let!(:project_pending_deletion) do let!(:project_pending_deletion) do
create(:empty_project, create(:empty_project,
......
...@@ -43,14 +43,22 @@ describe Route, models: true do ...@@ -43,14 +43,22 @@ describe Route, models: true do
end end
context 'name update' do context 'name update' do
before { route.update_attributes(name: 'bar') }
it "updates children routes with new path" do it "updates children routes with new path" do
route.update_attributes(name: 'bar')
expect(described_class.exists?(name: 'bar')).to be_truthy expect(described_class.exists?(name: 'bar')).to be_truthy
expect(described_class.exists?(name: 'bar / test')).to be_truthy expect(described_class.exists?(name: 'bar / test')).to be_truthy
expect(described_class.exists?(name: 'bar / test / foo')).to be_truthy expect(described_class.exists?(name: 'bar / test / foo')).to be_truthy
expect(described_class.exists?(name: 'gitlab-org')).to be_truthy expect(described_class.exists?(name: 'gitlab-org')).to be_truthy
end end
it 'handles a rename from nil' do
# Note: using `update_columns` to skip all validation and callbacks
route.update_columns(name: nil)
expect { route.update_attributes(name: 'bar') }
.to change { route.name }.from(nil).to('bar')
end
end end
end end
end end
...@@ -534,6 +534,12 @@ describe API::Issues, api: true do ...@@ -534,6 +534,12 @@ describe API::Issues, api: true do
describe "GET /projects/:id/issues" do describe "GET /projects/:id/issues" do
let(:base_url) { "/projects/#{project.id}" } let(:base_url) { "/projects/#{project.id}" }
it 'returns 404 when project does not exist' do
get api('/projects/1000/issues', non_member)
expect(response).to have_http_status(404)
end
it "returns 404 on private projects for other users" do it "returns 404 on private projects for other users" do
private_project = create(:empty_project, :private) private_project = create(:empty_project, :private)
create(:issue, project: private_project) create(:issue, project: private_project)
......
...@@ -439,6 +439,12 @@ describe API::V3::Issues, api: true do ...@@ -439,6 +439,12 @@ describe API::V3::Issues, api: true do
describe "GET /projects/:id/issues" do describe "GET /projects/:id/issues" do
let(:base_url) { "/projects/#{project.id}" } let(:base_url) { "/projects/#{project.id}" }
it 'returns 404 when project does not exist' do
get v3_api('/projects/1000/issues', non_member)
expect(response).to have_http_status(404)
end
it "returns 404 on private projects for other users" do it "returns 404 on private projects for other users" do
private_project = create(:empty_project, :private) private_project = create(:empty_project, :private)
create(:issue, project: private_project) create(:issue, project: private_project)
......
require 'spec_helper'
describe CreateBranchService, services: true do
let(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
describe '#execute' do
context 'when repository is empty' do
let(:project) { create(:project_empty_repo) }
it 'creates master branch' do
service.execute('my-feature', 'master')
expect(project.repository.branch_exists?('master')).to be_truthy
end
it 'creates my-feature branch' do
service.execute('my-feature', 'master')
expect(project.repository.branch_exists?('my-feature')).to be_truthy
end
end
end
end
...@@ -120,6 +120,26 @@ describe Projects::ImportService, services: true do ...@@ -120,6 +120,26 @@ describe Projects::ImportService, services: true do
end end
end end
context 'with blocked import_URL' do
it 'fails with localhost' do
project.import_url = 'https://localhost:9000/vim/vim.git'
result = described_class.new(project, user).execute
expect(result[:status]).to eq :error
expect(result[:message]).to end_with 'Blocked import URL.'
end
it 'fails with port 25' do
project.import_url = "https://github.com:25/vim/vim.git"
result = described_class.new(project, user).execute
expect(result[:status]).to eq :error
expect(result[:message]).to end_with 'Blocked import URL.'
end
end
def stub_github_omniauth_provider def stub_github_omniauth_provider
provider = OpenStruct.new( provider = OpenStruct.new(
'name' => 'github', 'name' => 'github',
......
...@@ -5,6 +5,7 @@ describe SystemHooksService, services: true do ...@@ -5,6 +5,7 @@ describe SystemHooksService, services: true do
let(:project) { create :project } let(:project) { create :project }
let(:project_member) { create :project_member } let(:project_member) { create :project_member }
let(:key) { create(:key, user: user) } let(:key) { create(:key, user: user) }
let(:deploy_key) { create(:key) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:group_member) { create(:group_member) } let(:group_member) { create(:group_member) }
...@@ -18,6 +19,8 @@ describe SystemHooksService, services: true do ...@@ -18,6 +19,8 @@ describe SystemHooksService, services: true do
it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) } it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) }
it { expect(event_data(key, :create)).to include(:username, :key, :id) } it { expect(event_data(key, :create)).to include(:username, :key, :id) }
it { expect(event_data(key, :destroy)).to include(:username, :key, :id) } it { expect(event_data(key, :destroy)).to include(:username, :key, :id) }
it { expect(event_data(deploy_key, :create)).to include(:key, :id) }
it { expect(event_data(deploy_key, :destroy)).to include(:key, :id) }
it do it do
project.old_path_with_namespace = 'renamed_from_path' project.old_path_with_namespace = 'renamed_from_path'
......
module TargetBranchHelpers
def select_branch(name)
first('button.js-target-branch').click
wait_for_ajax
all('a[data-group="Branches"]').find do |el|
el.text == name
end.click
end
def create_new_branch(name)
first('button.js-target-branch').click
click_link 'Create new branch'
fill_in 'new_branch_name', with: name
click_button 'Create'
end
end
require 'rake_helper'
describe 'tokens rake tasks' do
let!(:user) { create(:user) }
before do
Rake.application.rake_require 'tasks/tokens'
end
describe 'reset_all task' do
it 'invokes create_hooks task' do
expect { run_rake_task('tokens:reset_all_auth') }.to change { user.reload.authentication_token }
end
end
describe 'reset_all_email task' do
it 'invokes create_hooks task' do
expect { run_rake_task('tokens:reset_all_email') }.to change { user.reload.incoming_email_token }
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment