Commit 7c526cf6 authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into ce_upstream

parents 3d8e2458 13bb9ed7
......@@ -10,6 +10,7 @@ v 8.12.0 (unreleased)
- Give project selection dropdowns responsive width, make non-wrapping.
- Make push events have equal vertical spacing.
- Add two-factor recovery endpoint to internal API !5510
- Pass the "Remember me" value to the U2F authentication form
- Remove vendor prefixes for linear-gradient CSS (ClemMakesApps)
- Add font color contrast to external label in admin area (ClemMakesApps)
- Change logo animation to CSS (ClemMakesApps)
......@@ -20,11 +21,13 @@ v 8.12.0 (unreleased)
- Change merge_error column from string to text type
- Reduce contributions calendar data payload (ClemMakesApps)
- Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel)
- Enable pipeline events by default !6278
- Move parsing of sidekiq ps into helper !6245 (pascalbetz)
- Expose `sha` and `merge_commit_sha` in merge request API (Ben Boeckel)
- Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling)
- Fix blame table layout width
- Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps)
- Request only the LDAP attributes we need !6187
- Center build stage columns in pipeline overview (ClemMakesApps)
- Rename behaviour to behavior in bug issue template for consistency (ClemMakesApps)
- Remove suggested colors hover underline (ClemMakesApps)
......@@ -34,6 +37,7 @@ v 8.12.0 (unreleased)
- Add textarea autoresize after comment (ClemMakesApps)
- Refresh todos count cache when an Issue/MR is deleted
- Fix branches page dropdown sort alignment (ClemMakesApps)
- Hides merge request button on branches page is user doesn't have permissions
- Add white background for no readme container (ClemMakesApps)
- API: Expose issue confidentiality flag. (Robert Schilling)
- Fix markdown anchor icon interaction (ClemMakesApps)
......@@ -102,6 +106,7 @@ v 8.12.0 (unreleased)
- Use the default branch for displaying the project icon instead of master !5792 (Hannes Rosenögger)
- Adds response mime type to transaction metric action when it's not HTML
- Fix hover leading space bug in pipeline graph !5980
- Avoid conflict with admin labels when importing GitHub labels
- User can edit closed MR with deleted fork (Katarzyna Kobierska Ula Budziszewska) !5496
- Fix repository page ui issues
- Fixed invisible scroll controls on build page on iPhone
......@@ -2065,1692 +2070,5 @@ v 8.0.0
- Redirect from incorrectly cased group or project path to correct one (Francesco Levorato)
- Removed API calls from CE to CI
v 7.14.3
- No changes
v 7.14.2
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
- Allow configuration of LDAP attributes GitLab will use for the new user account.
v 7.14.1
- Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Disabled DNS lookups for SSH in docker image (Rowan Wookey)
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks
v 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests.
- Update default robots.txt rules to disallow crawling of irrelevant pages (Ben Bodenmiller)
- Fix redirection after sign in when using auto_sign_in_with_provider
- Upgrade gitlab_git to 7.2.14 to ignore CRLFs in .gitmodules (Stan Hu)
- Clear cache to prevent listing deleted branches after MR removes source branch (Stan Hu)
- Provide more feedback what went wrong if HipChat service failed test (Stan Hu)
- Fix bug where backslashes in inline diffs could be dropped (Stan Hu)
- Disable turbolinks when linking to Bitbucket import status (Stan Hu)
- Fix broken code import and display error messages if something went wrong with creating project (Stan Hu)
- Fix corrupted binary files when using API files endpoint (Stan Hu)
- Bump Haml to 4.0.7 to speed up textarea rendering (Stan Hu)
- Show incompatible projects in Bitbucket import status (Stan Hu)
- Fix coloring of diffs on MR Discussion-tab (Gert Goet)
- Fix "Network" and "Graphs" pages for branches with encoded slashes (Stan Hu)
- Fix errors deleting and creating branches with encoded slashes (Stan Hu)
- Always add current user to autocomplete controller to support filter by "Me" (Stan Hu)
- Fix multi-line syntax highlighting (Stan Hu)
- Fix network graph when branch name has single quotes (Stan Hu)
- Add "Confirm user" button in user admin page (Stan Hu)
- Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu)
- Add support for Unicode filenames in relative links (Hiroyuki Sato)
- Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki)
- Fix commit data retrieval when branch name has single quotes (Stan Hu)
- Check that project was actually created rather than just validated in import:repos task (Stan Hu)
- Fix full screen mode for snippet comments (Daniel Gerhardt)
- Fix 404 error in files view after deleting the last file in a repository (Stan Hu)
- Fix the "Reload with full diff" URL button (Stan Hu)
- Fix label read access for unauthenticated users (Daniel Gerhardt)
- Fix access to disabled features for unauthenticated users (Daniel Gerhardt)
- Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu)
- Fix file upload dialog for comment editing (Daniel Gerhardt)
- Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu)
- Return comments in created order in merge request API (Stan Hu)
- Disable internal issue tracker controller if external tracker is used (Stan Hu)
- Expire Rails cache entries after two weeks to prevent endless Redis growth
- Add support for destroying project milestones (Stan Hu)
- Allow custom backup archive permissions
- Add project star and fork count, group avatar URL and user/group web URL attributes to API
- Show who last edited a comment if it wasn't the original author
- Send notification to all participants when MR is merged.
- Add ability to manage user email addresses via the API.
- Show buttons to add license, changelog and contribution guide if they're missing.
- Tweak project page buttons.
- Disabled autocapitalize and autocorrect on login field (Daryl Chan)
- Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis)
- Update gravatar link on profile page to link to configured gravatar host (Ben Bodenmiller)
- Remove redis-store TTL monkey patch
- Add support for CI skipped status
- Fetch code from forks to refs/merge-requests/:id/head when merge request created
- Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg)
- Add "Check out branch" button to the MR page.
- Improve MR merge widget text and UI consistency.
- Improve text in MR "How To Merge" modal.
- Cache all events
- Order commits by date when comparing branches
- Fix bug causing error when the target branch of a symbolic ref was deleted
- Include branch/tag name in archive file and directory name
- Add dropzone upload progress
- Add a label for merged branches on branches page (Florent Baldino)
- Detect .mkd and .mkdn files as markdown (Ben Boeckel)
- Fix: User search feature in admin area does not respect filters
- Set max-width for README, issue and merge request description for easier read on big screens
- Update Flowdock integration to support new Flowdock API (Boyan Tabakov)
- Remove author from files view (Sven Strickroth)
- Fix infinite loop when SAML was incorrectly configured.
v 7.13.5
- Satellites reverted
v 7.13.4
- Allow users to send abuse reports
v 7.13.3
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
- Allow users to send abuse reports
- Remove satellites
- Link username to profile on Group Members page (Tom Webster)
v 7.13.2
- Fix randomly failed spec
- Create project services on Project creation
- Add admin_merge_request ability to Developer level and up
- Fix Error 500 when browsing projects with no HEAD (Stan Hu)
- Fix labels / assignee / milestone for the merge requests when issues are disabled
- Show the first tab automatically on MergeRequests#new
- Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt)
- Fix Gmail Actions
v 7.13.1
- Fix: Label modifications are not reflected in existing notes and in the issue list
- Fix: Label not shown in the Issue list, although it's set through web interface
- Fix: Group/project references are linked incorrectly
- Improve documentation
- Fix of migration: Check if session_expire_delay column exists before adding the column
- Fix: ActionView::Template::Error
- Fix: "Create Merge Request" isn't always shown in event for newly pushed branch
- Fix bug causing "Remove source-branch" option not to work for merge requests from the same project.
- Render Note field hints consistently for "new" and "edit" forms
v 7.13.0
- Remove repository graph log to fix slow cache updates after push event (Stan Hu)
- Only enable HSTS header for HTTPS and port 443 (Stan Hu)
- Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu)
- Fix redirection to home page URL for unauthorized users (Daniel Gerhardt)
- Add branch switching support for graphs (Daniel Gerhardt)
- Fix external issue tracker hook/test for HTTPS URLs (Daniel Gerhardt)
- Remove link leading to a 404 error in Deploy Keys page (Stan Hu)
- Add support for unlocking users in admin settings (Stan Hu)
- Add Irker service configuration options (Stan Hu)
- Fix order of issues imported from GitHub (Hiroyuki Sato)
- Bump rugments to 1.0.0beta8 to fix C prototype function highlighting (Jonathon Reinhart)
- Fix Merge Request webhook to properly fire "merge" action when accepted from the web UI
- Add `two_factor_enabled` field to admin user API (Stan Hu)
- Fix invalid timestamps in RSS feeds (Rowan Wookey)
- Fix downloading of patches on public merge requests when user logged out (Stan Hu)
- Fix Error 500 when relative submodule resolves to a namespace that has a different name from its path (Stan Hu)
- Extract the longest-matching ref from a commit path when multiple matches occur (Stan Hu)
- Update maintenance documentation to explain no need to recompile asssets for omnibus installations (Stan Hu)
- Support commenting on diffs in side-by-side mode (Stan Hu)
- Fix JavaScript error when clicking on the comment button on a diff line that has a comment already (Stan Hu)
- Return 40x error codes if branch could not be deleted in UI (Stan Hu)
- Remove project visibility icons from dashboard projects list
- Rename "Design" profile settings page to "Preferences".
- Allow users to customize their default Dashboard page.
- Update ssl_ciphers in Nginx example to remove DHE settings. This will deny forward secrecy for Android 2.3.7, Java 6 and OpenSSL 0.9.8
- Admin can edit and remove user identities
- Convert CRLF newlines to LF when committing using the web editor.
- API request /projects/:project_id/merge_requests?state=closed will return only closed merge requests without merged one. If you need ones that were merged - use state=merged.
- Allow Administrators to filter the user list by those with or without Two-factor Authentication enabled.
- Show a user's Two-factor Authentication status in the administration area.
- Explicit error when commit not found in the CI
- Improve performance for issue and merge request pages
- Users with guest access level can not set assignee, labels or milestones for issue and merge request
- Reporter role can manage issue tracker now: edit any issue, set assignee or milestone and manage labels
- Better performance for pages with events list, issues list and commits list
- Faster automerge check and merge itself when source and target branches are in same repository
- Correctly show anonymous authorized applications under Profile > Applications.
- Query Optimization in MySQL.
- Allow users to be blocked and unblocked via the API
- Use native Postgres database cleaning during backup restore
- Redesign project page. Show README as default instead of activity. Move project activity to separate page
- Make left menu more hierarchical and less contextual by adding back item at top
- A fork can’t have a visibility level that is greater than the original project.
- Faster code search in repository and wiki. Fixes search page timeout for big repositories
- Allow administrators to disable 2FA for a specific user
- Add error message for SSH key linebreaks
- Store commits count in database (will populate with valid values only after first push)
- Rebuild cache after push to repository in background job
- Fix transferring of project to another group using the API.
v 7.12.2
- Correctly show anonymous authorized applications under Profile > Applications.
- Faster automerge check and merge itself when source and target branches are in same repository
- Audit log for user authentication
- Allow custom label to be set for authentication providers.
v 7.12.1
- Fix error when deleting a user who has projects (Stan Hu)
- Fix post-receive errors on a push when an external issue tracker is configured (Stan Hu)
- Add SAML to list of social_provider (Matt Firtion)
- Fix merge requests API scope to keep compatibility in 7.12.x patch release (Dmitriy Zaporozhets)
- Fix closed merge request scope at milestone page (Dmitriy Zaporozhets)
- Revert merge request states renaming
- Fix hooks for web based events with external issue references (Daniel Gerhardt)
- Improve performance for issue and merge request pages
- Compress database dumps to reduce backup size
v 7.12.0
- Fix Error 500 when one user attempts to access a personal, internal snippet (Stan Hu)
- Disable changing of target branch in new merge request page when a branch has already been specified (Stan Hu)
- Fix post-receive errors on a push when an external issue tracker is configured (Stan Hu)
- Update oauth button logos for Twitter and Google to recommended assets
- Update browser gem to version 0.8.0 for IE11 support (Stan Hu)
- Fix timeout when rendering file with thousands of lines.
- Add "Remember me" checkbox to LDAP signin form.
- Add session expiration delay configuration through UI application settings
- Don't notify users mentioned in code blocks or blockquotes.
- Omit link to generate labels if user does not have access to create them (Stan Hu)
- Show warning when a comment will add 10 or more people to the discussion.
- Disable changing of the source branch in merge request update API (Stan Hu)
- Shorten merge request WIP text.
- Add option to disallow users from registering any application to use GitLab as an OAuth provider
- Support editing target branch of merge request (Stan Hu)
- Refactor permission checks with issues and merge requests project settings (Stan Hu)
- Fix Markdown preview not working in Edit Milestone page (Stan Hu)
- Fix Zen Mode not closing with ESC key (Stan Hu)
- Allow HipChat API version to be blank and default to v2 (Stan Hu)
- Add file attachment support in Milestone description (Stan Hu)
- Fix milestone "Browse Issues" button.
- Set milestone on new issue when creating issue from index with milestone filter active.
- Make namespace API available to all users (Stan Hu)
- Add webhook support for note events (Stan Hu)
- Disable "New Issue" and "New Merge Request" buttons when features are disabled in project settings (Stan Hu)
- Remove Rack Attack monkey patches and bump to version 4.3.0 (Stan Hu)
- Fix clone URL losing selection after a single click in Safari and Chrome (Stan Hu)
- Fix git blame syntax highlighting when different commits break up lines (Stan Hu)
- Add "Resend confirmation e-mail" link in profile settings (Stan Hu)
- Allow to configure location of the `.gitlab_shell_secret` file. (Jakub Jirutka)
- Disabled expansion of top/bottom blobs for new file diffs
- Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka)
- Fix resolving of relative links to repository files in AsciiDoc documents. (Jakub Jirutka)
- Use the user list from the target project in a merge request (Stan Hu)
- Default extention for wiki pages is now .md instead of .markdown (Jeroen van Baarsen)
- Add validation to wiki page creation (only [a-zA-Z0-9/_-] are allowed) (Jeroen van Baarsen)
- Fix new/empty milestones showing 100% completion value (Jonah Bishop)
- Add a note when an Issue or Merge Request's title changes
- Consistently refer to MRs as either Merged or Closed.
- Add Merged tab to MR lists.
- Prefix EmailsOnPush email subject with `[Git]`.
- Group project contributions by both name and email.
- Clarify navigation labels for Project Settings and Group Settings.
- Move user avatar and logout button to sidebar
- You can not remove user if he/she is an only owner of group
- User should be able to leave group. If not - show him proper message
- User has ability to leave project
- Add SAML support as an omniauth provider
- Allow to configure a URL to show after sign out
- Add an option to automatically sign-in with an Omniauth provider
- GitLab CI service sends .gitlab-ci.yml in each push call
- When remove project - move repository and schedule it removal
- Improve group removing logic
- Trigger create-hooks on backup restore task
- Add option to automatically link omniauth and LDAP identities
- Allow special character in users bio. I.e.: I <3 GitLab
v 7.11.4
- Fix missing bullets when creating lists
- Set rel="nofollow" on external links
v 7.11.3
- no changes
- Fix upgrader script (Martins Polakovs)
v 7.11.2
- no changes
v 7.11.1
- no changes
v 7.11.0
- Fall back to Plaintext when Syntaxhighlighting doesn't work. Fixes some buggy lexers (Hannes Rosenögger)
- Get editing comments to work in Chrome 43 again.
- Fix broken view when viewing history of a file that includes a path that used to be another file (Stan Hu)
- Don't show duplicate deploy keys
- Fix commit time being displayed in the wrong timezone in some cases (Hannes Rosenögger)
- Make the first branch pushed to an empty repository the default HEAD (Stan Hu)
- Fix broken view when using a tag to display a tree that contains git submodules (Stan Hu)
- Make Reply-To config apply to change e-mail confirmation and other Devise notifications (Stan Hu)
- Add application setting to restrict user signups to e-mail domains (Stan Hu)
- Don't allow a merge request to be merged when its title starts with "WIP".
- Add a page title to every page.
- Allow primary email to be set to an email that you've already added.
- Fix clone URL field and X11 Primary selection (Dmitry Medvinsky)
- Ignore invalid lines in .gitmodules
- Fix "Cannot move project" error message from popping up after a successful transfer (Stan Hu)
- Redirect to sign in page after signing out.
- Fix "Hello @username." references not working by no longer allowing usernames to end in period.
- Fix "Revspec not found" errors when viewing diffs in a forked project with submodules (Stan Hu)
- Improve project page UI
- Fix broken file browsing with relative submodule in personal projects (Stan Hu)
- Add "Reply quoting selected text" shortcut key (`r`)
- Fix bug causing `@whatever` inside an issue's first code block to be picked up as a user mention.
- Fix bug causing `@whatever` inside an inline code snippet (backtick-style) to be picked up as a user mention.
- When use change branches link at MR form - save source branch selection instead of target one
- Improve handling of large diffs
- Added GitLab Event header for project hooks
- Add Two-factor authentication (2FA) for GitLab logins
- Show Atom feed buttons everywhere where applicable.
- Add project activity atom feed.
- Don't crash when an MR from a fork has a cross-reference comment from the target project on one of its commits.
- Explain how to get a new password reset token in welcome emails
- Include commit comments in MR from a forked project.
- Group milestones by title in the dashboard and all other issue views.
- Query issues, merge requests and milestones with their IID through API (Julien Bianchi)
- Add default project and snippet visibility settings to the admin web UI.
- Show incompatible projects in Google Code import status (Stan Hu)
- Fix bug where commit data would not appear in some subdirectories (Stan Hu)
- Task lists are now usable in comments, and will show up in Markdown previews.
- Fix bug where avatar filenames were not actually deleted from the database during removal (Stan Hu)
- Fix bug where Slack service channel was not saved in admin template settings. (Stan Hu)
- Protect OmniAuth request phase against CSRF.
- Don't send notifications to mentioned users that don't have access to the project in question.
- Add search issues/MR by number
- Change plots to bar graphs in commit statistics screen
- Move snippets UI to fluid layout
- Improve UI for sidebar. Increase separation between navigation and content
- Improve new project command options (Ben Bodenmiller)
- Add common method to force UTF-8 and use it to properly handle non-ascii OAuth user properties (Onur Küçük)
- Prevent sending empty messages to HipChat (Chulki Lee)
- Improve UI for mobile phones on dashboard and project pages
- Add room notification and message color option for HipChat
- Allow to use non-ASCII letters and dashes in project and namespace name. (Jakub Jirutka)
- Add footnotes support to Markdown (Guillaume Delbergue)
- Add current_sign_in_at to UserFull REST api.
- Make Sidekiq MemoryKiller shutdown signal configurable
- Add "Create Merge Request" buttons to commits and branches pages and push event.
- Show user roles by comments.
- Fix automatic blocking of auto-created users from Active Directory.
- Call merge request webhook for each new commits (Arthur Gautier)
- Use SIGKILL by default in Sidekiq::MemoryKiller
- Fix mentioning of private groups.
- Add style for <kbd> element in markdown
- Spin spinner icon next to "Checking for CI status..." on MR page.
- Fix reference links in dashboard activity and ATOM feeds.
- Ensure that the first added admin performs repository imports
v 7.10.4
- Fix migrations broken in 7.10.2
- Make tags for GitLab installations running on MySQL case sensitive
- Get Gitorious importer to work again.
- Fix adding new group members from admin area
- Fix DB error when trying to tag a repository (Stan Hu)
- Fix Error 500 when searching Wiki pages (Stan Hu)
- Unescape branch names in compare commit (Stan Hu)
- Order commit comments chronologically in API.
v 7.10.2
- Fix CI links on MR page
v 7.10.0
- Ignore submodules that are defined in .gitmodules but are checked in as directories.
- Allow projects to be imported from Google Code.
- Remove access control for uploaded images to fix broken images in emails (Hannes Rosenögger)
- Allow users to be invited by email to join a group or project.
- Don't crash when project repository doesn't exist.
- Add config var to block auto-created LDAP users.
- Don't use HTML ellipsis in EmailsOnPush subject truncated commit message.
- Set EmailsOnPush reply-to address to committer email when enabled.
- Fix broken file browsing with a submodule that contains a relative link (Stan Hu)
- Fix persistent XSS vulnerability around profile website URLs.
- Fix project import URL regex to prevent arbitary local repos from being imported.
- Fix directory traversal vulnerability around uploads routes.
- Fix directory traversal vulnerability around help pages.
- Don't leak existence of project via search autocomplete.
- Don't leak existence of group or project via search.
- Fix bug where Wiki pages that included a '/' were no longer accessible (Stan Hu)
- Fix bug where error messages from Dropzone would not be displayed on the issues page (Stan Hu)
- Add a rake task to check repository integrity with `git fsck`
- Add ability to configure Reply-To address in gitlab.yml (Stan Hu)
- Move current user to the top of the list in assignee/author filters (Stan Hu)
- Fix broken side-by-side diff view on merge request page (Stan Hu)
- Set Application controller default URL options to ensure all url_for calls are consistent (Stan Hu)
- Allow HTML tags in Markdown input
- Fix code unfold not working on Compare commits page (Stan Hu)
- Fix generating SSH key fingerprints with OpenSSH 6.8. (Sašo Stanovnik)
- Fix "Import projects from" button to show the correct instructions (Stan Hu)
- Fix dots in Wiki slugs causing errors (Stan Hu)
- Make maximum attachment size configurable via Application Settings (Stan Hu)
- Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
- Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- Disable reference creation for comments surrounded by code/preformatted blocks (Stan Hu)
- Reduce Rack Attack false positives causing 403 errors during HTTP authentication (Stan Hu)
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
- Fix a link in the patch update guide
- Add a service to support external wikis (Hannes Rosenögger)
- Omit the "email patches" link and fix plain diff view for merge commits
- List new commits for newly pushed branch in activity view.
- Add sidetiq gem dependency to match EE
- Add changelog, license and contribution guide links to project tab bar.
- Improve diff UI
- Fix alignment of navbar toggle button (Cody Mize)
- Fix checkbox rendering for nested task lists
- Identical look of selectboxes in UI
- Upgrade the gitlab_git gem to version 7.1.3
- Move "Import existing repository by URL" option to button.
- Improve error message when save profile has error.
- Passing the name of pushed ref to CI service (requires GitLab CI 7.9+)
- Add location field to user profile
- Fix print view for markdown files and wiki pages
- Fix errors when deleting old backups
- Improve GitLab performance when working with git repositories
- Add tag message and last commit to tag hook (Kamil Trzciński)
- Restrict permissions on backup files
- Improve oauth accounts UI in profile page
- Add ability to unlink connected accounts
- Replace commits calendar with faster contribution calendar that includes issues and merge requests
- Add inifinite scroll to user page activity
- Don't include system notes in issue/MR comment count.
- Don't mark merge request as updated when merge status relative to target branch changes.
- Link note avatar to user.
- Make Git-over-SSH errors more descriptive.
- Fix EmailsOnPush.
- Refactor issue filtering
- AJAX selectbox for issue assignee and author filters
- Fix issue with missing options in issue filtering dropdown if selected one
- Prevent holding Control-Enter or Command-Enter from posting comment multiple times.
- Prevent note form from being cleared when submitting failed.
- Improve file icons rendering on tree (Sullivan Sénéchal)
- API: Add pagination to project events
- Get issue links in notification mail to work again.
- Don't show commit comment button when user is not signed in.
- Fix admin user projects lists.
- Don't leak private group existence by redirecting from namespace controller to group controller.
- Ability to skip some items from backup (database, respositories or uploads)
- Archive repositories in background worker.
- Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.
- Project labels are now available over the API under the "tag_list" field (Cristian Medina)
- Fixed link paths for HTTP and SSH on the admin project view (Jeremy Maziarz)
- Fix and improve help rendering (Sullivan Sénéchal)
- Fix final line in EmailsOnPush email diff being rendered as error.
- Prevent duplicate Buildkite service creation.
- Fix git over ssh errors 'fatal: protocol error: bad line length character'
- Automatically setup GitLab CI project for forks if origin project has GitLab CI enabled
- Bust group page project list cache when namespace name or path changes.
- Explicitly set image alt-attribute to prevent graphical glitches if gravatars could not be loaded
- Allow user to choose a public email to show on public profile
- Remove truncation from issue titles on milestone page (Jason Blanchard)
- Fix stuck Merge Request merging events from old installations (Ben Bodenmiller)
- Fix merge request comments on files with multiple commits
- Fix Resource Owner Password Authentication Flow
- Add icons to Add dropdown items.
- Allow admin to create public deploy keys that are accessible to any project.
- Warn when gitlab-shell version doesn't match requirement.
- Skip email confirmation when set by admin or via LDAP.
- Only allow users to reference groups, projects, issues, MRs, commits they have access to.
v 7.9.4
- Security: Fix project import URL regex to prevent arbitary local repos from being imported
- Fixed issue where only 25 commits would load in file listings
- Fix LDAP identities after config update
v 7.9.3
- Contains no changes
v 7.9.2
- Contains no changes
v 7.9.1
- Include missing events and fix save functionality in admin service template settings form (Stan Hu)
- Fix "Import projects from" button to show the correct instructions (Stan Hu)
- Fix OAuth2 issue importing a new project from GitHub and GitLab (Stan Hu)
- Fix for LDAP with commas in DN
- Fix missing events and in admin Slack service template settings form (Stan Hu)
- Don't show commit comment button when user is not signed in.
- Downgrade gemnasium-gitlab-service gem
v 7.9.0
- Add HipChat integration documentation (Stan Hu)
- Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu)
- Fix broken email images (Hannes Rosenögger)
- Automatically config git if user forgot, where possible (Zeger-Jan van de Weg)
- Fix mass SQL statements on initial push (Hannes Rosenögger)
- Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu)
- Add comment notification events to HipChat and Slack services (Stan Hu)
- Add issue and merge request events to HipChat and Slack services (Stan Hu)
- Fix merge request URL passed to Webhooks. (Stan Hu)
- Fix bug that caused a server error when editing a comment to "+1" or "-1" (Stan Hu)
- Fix code preview theme setting for comments, issues, merge requests, and snippets (Stan Hu)
- Move labels/milestones tabs to sidebar
- Upgrade Rails gem to version 4.1.9.
- Improve error messages for file edit failures
- Improve UI for commits, issues and merge request lists
- Fix commit comments on first line of diff not rendering in Merge Request Discussion view.
- Allow admins to override restricted project visibility settings.
- Move restricted visibility settings from gitlab.yml into the web UI.
- Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev)
- Save web edit in new branch
- Fix ordering of imported but unchanged projects (Marco Wessel)
- Mobile UI improvements: make aside content expandable
- Expose avatar_url in projects API
- Fix checkbox alignment on the application settings page.
- Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger)
- Fix mass-unassignment of issues (Robert Speicher)
- Fix hidden diff comments in merge request discussion view
- Allow user confirmation to be skipped for new users via API
- Add a service to send updates to an Irker gateway (Romain Coltel)
- Add brakeman (security scanner for Ruby on Rails)
- Slack username and channel options
- Add grouped milestones from all projects to dashboard.
- Webhook sends pusher email as well as commiter
- Add Bitbucket omniauth provider.
- Add Bitbucket importer.
- Support referencing issues to a project whose name starts with a digit
- Condense commits already in target branch when updating merge request source branch.
- Send notifications and leave system comments when bulk updating issues.
- Automatically link commit ranges to compare page: sha1...sha4 or sha1..sha4 (includes sha1 in comparison)
- Move groups page from profile to dashboard
- Starred projects page at dashboard
- Blocking user does not remove him/her from project/groups but show blocked label
- Change subject of EmailsOnPush emails to include namespace, project and branch.
- Change subject of EmailsOnPush emails to include first commit message when multiple were pushed.
- Remove confusing footer from EmailsOnPush mail body.
- Add list of changed files to EmailsOnPush emails.
- Add option to send EmailsOnPush emails from committer email if domain matches.
- Add option to disable code diffs in EmailOnPush emails.
- Wrap commit message in EmailsOnPush email.
- Send EmailsOnPush emails when deleting commits using force push.
- Fix EmailsOnPush email comparison link to include first commit.
- Fix highliht of selected lines in file
- Reject access to group/project avatar if the user doesn't have access.
- Add database migration to clean group duplicates with same path and name (Make sure you have a backup before update)
- Add GitLab active users count to rake gitlab:check
- Starred projects page at dashboard
- Make email display name configurable
- Improve json validation in hook data
- Use Emoji One
- Updated emoji help documentation to properly reference EmojiOne.
- Fix missing GitHub organisation repositories on import page.
- Added blue theme
- Remove annoying notice messages when create/update merge request
- Allow smb:// links in Markdown text.
- Filter merge request by title or description at Merge Requests page
- Block user if he/she was blocked in Active Directory
- Fix import pages not working after first load.
- Use custom LDAP label in LDAP signin form.
- Execute hooks and services when branch or tag is created or deleted through web interface.
- Block and unblock user if he/she was blocked/unblocked in Active Directory
- Raise recommended number of unicorn workers from 2 to 3
- Use same layout and interactivity for project members as group members.
- Prevent gitlab-shell character encoding issues by receiving its changes as raw data.
- Ability to unsubscribe/subscribe to issue or merge request
- Delete deploy key when last connection to a project is destroyed.
- Fix invalid Atom feeds when using emoji, horizontal rules, or images (Christian Walther)
- Backup of repositories with tar instead of git bundle (only now are git-annex files included in the backup)
- Add canceled status for CI
- Send EmailsOnPush email when branch or tag is created or deleted.
- Faster merge request processing for large repository
- Prevent doubling AJAX request with each commit visit via Turbolink
- Prevent unnecessary doubling of js events on import pages and user calendar
v 7.8.4
- Fix issue_tracker_id substitution in custom issue trackers
- Fix path and name duplication in namespaces
v 7.8.3
- Bump version of gitlab_git fixing annotated tags without message
v 7.8.2
- Fix service migration issue when upgrading from versions prior to 7.3
- Fix setting of the default use project limit via admin UI
- Fix showing of already imported projects for GitLab and Gitorious importers
- Fix response of push to repository to return "Not found" if user doesn't have access
- Fix check if user is allowed to view the file attachment
- Fix import check for case sensetive namespaces
- Increase timeout for Git-over-HTTP requests to 1 hour since large pulls/pushes can take a long time.
- Properly handle autosave local storage exceptions.
- Escape wildcards when searching LDAP by username.
v 7.8.1
- Fix run of custom post receive hooks
- Fix migration that caused issues when upgrading to version 7.8 from versions prior to 7.3
- Fix the warning for LDAP users about need to set password
- Fix avatars which were not shown for non logged in users
- Fix urls for the issues when relative url was enabled
v 7.8.0
- Fix access control and protection against XSS for note attachments and other uploads.
- Replace highlight.js with rouge-fork rugments (Stefan Tatschner)
- Make project search case insensitive (Hannes Rosenögger)
- Include issue/mr participants in list of recipients for reassign/close/reopen emails
- Expose description in groups API
- Better UI for project services page
- Cleaner UI for web editor
- Add diff syntax highlighting in email-on-push service notifications (Hannes Rosenögger)
- Add API endpoint to fetch all changes on a MergeRequest (Jeroen van Baarsen)
- View note image attachments in new tab when clicked instead of downloading them
- Improve sorting logic in UI and API. Explicitly define what sorting method is used by default
- Fix overflow at sidebar when have several items
- Add notes for label changes in issue and merge requests
- Show tags in commit view (Hannes Rosenögger)
- Only count a user's vote once on a merge request or issue (Michael Clarke)
- Increase font size when browse source files and diffs
- Service Templates now let you set default values for all services
- Create new file in empty repository using GitLab UI
- Ability to clone project using oauth2 token
- Upgrade Sidekiq gem to version 3.3.0
- Stop git zombie creation during force push check
- Show success/error messages for test setting button in services
- Added Rubocop for code style checks
- Fix commits pagination
- Async load a branch information at the commit page
- Disable blacklist validation for project names
- Allow configuring protection of the default branch upon first push (Marco Wessel)
- Add gitlab.com importer
- Add an ability to login with gitlab.com
- Add a commit calendar to the user profile (Hannes Rosenögger)
- Submit comment on command-enter
- Notify all members of a group when that group is mentioned in a comment, for example: `@gitlab-org` or `@sales`.
- Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close" (Julien Bianchi and Hannes Rosenögger)
- Fix long broadcast message cut-off on left sidebar (Visay Keo)
- Add Project Avatars (Steven Thonus and Hannes Rosenögger)
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
- Edit group members via API
- Enable raw image paste from clipboard, currently Chrome only (Marco Cyriacks)
- Add action property to merge request hook (Julien Bianchi)
- Remove duplicates from group milestone participants list.
- Add a new API function that retrieves all issues assigned to a single milestone (Justin Whear and Hannes Rosenögger)
- API: Access groups with their path (Julien Bianchi)
- Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard)
- Allow notification email to be set separately from primary email.
- API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger)
- Don't have Markdown preview fail for long comments/wiki pages.
- When test webhook - show error message instead of 500 error page if connection to hook url was reset
- Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov)
- Added persistent collapse button for left side nav bar (Jason Blanchard)
- Prevent losing unsaved comments by automatically restoring them when comment page is loaded again.
- Don't allow page to be scaled on mobile.
- Clean the username acquired from OAuth/LDAP so it doesn't fail username validation and block signing up.
- Show assignees in merge request index page (Kelvin Mutuma)
- Link head panel titles to relevant root page.
- Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S).
- Show users button to share their newly created public or internal projects on twitter
- Add quick help links to the GitLab pricing and feature comparison pages.
- Fix duplicate authorized applications in user profile and incorrect application client count in admin area.
- Make sure Markdown previews always use the same styling as the eventual destination.
- Remove deprecated Group#owner_id from API
- Show projects user contributed to on user page. Show stars near project on user page.
- Improve database performance for GitLab
- Add Asana service (Jeremy Benoist)
- Improve project webhooks with extra data
v 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
- Fix issue when LDAP user can't login with existing GitLab account
v 7.7.1
- Improve mention autocomplete performance
- Show setup instructions for GitHub import if disabled
- Allow use http for OAuth applications
v 7.7.0
- Import from GitHub.com feature
- Add Jetbrains Teamcity CI service (Jason Lippert)
- Mention notification level
- Markdown preview in wiki (Yuriy Glukhov)
- Raise group avatar filesize limit to 200kb
- OAuth applications feature
- Show user SSH keys in admin area
- Developer can push to protected branches option
- Set project path instead of project name in create form
- Block Git HTTP access after 10 failed authentication attempts
- Updates to the messages returned by API (sponsored by O'Reilly Media)
- New UI layout with side navigation
- Add alert message in case of outdated browser (IE < 10)
- Added API support for sorting projects
- Update gitlab_git to version 7.0.0.rc14
- Add API project search filter option for authorized projects
- Fix File blame not respecting branch selection
- Change some of application settings on fly in admin area UI
- Redesign signin/signup pages
- Close standard input in Gitlab::Popen.popen
- Trigger GitLab CI when push tags
- When accept merge request - do merge using sidaekiq job
- Enable web signups by default
- Fixes for diff comments: drag-n-drop images, selecting images
- Fixes for edit comments: drag-n-drop images, preview mode, selecting images, save & update
- Remove password strength indicator
v 7.6.0
- Fork repository to groups
- New rugged version
- Add CRON=1 backup setting for quiet backups
- Fix failing wiki restore
- Add optional Sidekiq MemoryKiller middleware (enabled via SIDEKIQ_MAX_RSS env variable)
- Monokai highlighting style now more faithful to original design (Mark Riedesel)
- Create project with repository in synchrony
- Added ability to create empty repo or import existing one if project does not have repository
- Reactivate highlight.js language autodetection
- Mobile UI improvements
- Change maximum avatar file size from 100KB to 200KB
- Strict validation for snippet file names
- Enable Markdown preview for issues, merge requests, milestones, and notes (Vinnie Okada)
- In the docker directory is a container template based on the Omnibus packages.
- Update Sidekiq to version 2.17.8
- Add author filter to project issues and merge requests pages
- Atom feed for user activity
- Support multiple omniauth providers for the same user
- Rendering cross reference in issue title and tooltip for merge request
- Show username in comments
- Possibility to create Milestones or Labels when Issues are disabled
- Fix bug with showing gpg signature in tag
v 7.5.3
- Bump gitlab_git to 7.0.0.rc12 (includes Rugged 0.21.2)
v 7.5.2
- Don't log Sidekiq arguments by default
- Fix restore of wiki repositories from backups
v 7.5.1
- Add missing timestamps to 'members' table
v 7.5.0
- API: Add support for Hipchat (Kevin Houdebert)
- Add time zone configuration in gitlab.yml (Sullivan Senechal)
- Fix LDAP authentication for Git HTTP access
- Run 'GC.start' after every EmailsOnPushWorker job
- Fix LDAP config lookup for provider 'ldap'
- Drop all sequences during Postgres database restore
- Project title links to project homepage (Ben Bodenmiller)
- Add Atlassian Bamboo CI service (Drew Blessing)
- Mentioned @user will receive email even if he is not participating in issue or commit
- Session API: Use case-insensitive authentication like in UI (Andrey Krivko)
- Tie up loose ends with annotated tags: API & UI (Sean Edge)
- Return valid json for deleting branch via API (sponsored by O'Reilly Media)
- Expose username in project events API (sponsored by O'Reilly Media)
- Adds comments to commits in the API
- Performance improvements
- Fix post-receive issue for projects with deleted forks
- New gitlab-shell version with custom hooks support
- Improve code
- GitLab CI 5.2+ support (does not support older versions)
- Fixed bug when you can not push commits starting with 000000 to protected branches
- Added a password strength indicator
- Change project name and path in one form
- Display renamed files in diff views (Vinnie Okada)
- Fix raw view for public snippets
- Use secret token with GitLab internal API.
- Add missing timestamps to 'members' table
v 7.4.5
- Bump gitlab_git to 7.0.0.rc12 (includes Rugged 0.21.2)
v 7.4.4
- No changes
v 7.4.3
- Fix raw snippets view
- Fix security issue for member api
- Fix buildbox integration
v 7.4.2
- Fix internal snippet exposing for unauthenticated users
v 7.4.1
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
- Fix public snippets
- Fix 500 error on projects with nested submodules
v 7.4.0
- Refactored membership logic
- Improve error reporting on users API (Julien Bianchi)
- Refactor test coverage tools usage. Use SIMPLECOV=true to generate it locally
- Default branch is protected by default
- Increase unicorn timeout to 60 seconds
- Sort search autocomplete projects by stars count so most popular go first
- Add README to tab on project show page
- Do not delete tmp/repositories itself during clean-up, only its contents
- Support for backup uploads to remote storage
- Prevent notes polling when there are not notes
- Internal ForkService: Prepare support for fork to a given namespace
- API: Add support for forking a project via the API (Bernhard Kaindl)
- API: filter project issues by milestone (Julien Bianchi)
- Fail harder in the backup script
- Changes to Slack service structure, only webhook url needed
- Zen mode for wiki and milestones (Robert Schilling)
- Move Emoji parsing to html-pipeline-gitlab (Robert Schilling)
- Font Awesome 4.2 integration (Sullivan Senechal)
- Add Pushover service integration (Sullivan Senechal)
- Add select field type for services options (Sullivan Senechal)
- Add cross-project references to the Markdown parser (Vinnie Okada)
- Add task lists to issue and merge request descriptions (Vinnie Okada)
- Snippets can be public, internal or private
- Improve danger zone: ask project path to confirm data-loss action
- Raise exception on forgery
- Show build coverage in Merge Requests (requires GitLab CI v5.1)
- New milestone and label links on issue edit form
- Improved repository graphs
- Improve event note display in dashboard and project activity views (Vinnie Okada)
- Add users sorting to admin area
- UI improvements
- Fix ambiguous sha problem with mentioned commit
- Fixed bug with apostrophe when at mentioning users
- Add active directory ldap option
- Developers can push to wiki repo. Protected branches does not affect wiki repo any more
- Faster rev list
- Fix branch removal
v 7.3.2
- Fix creating new file via web editor
- Use gitlab-shell v2.0.1
v 7.3.1
- Fix ref parsing in Gitlab::GitAccess
- Fix error 500 when viewing diff on a file with changed permissions
- Fix adding comments to MR when source branch is master
- Fix error 500 when searching description contains relative link
v 7.3.0
- Always set the 'origin' remote in satellite actions
- Write authorized_keys in tmp/ during tests
- Use sockets to connect to Redis
- Add dormant New Relic gem (can be enabled via environment variables)
- Expire Rack sessions after 1 week
- Cleaner signin/signup pages
- Improved comments UI
- Better search with filtering, pagination etc
- Added a checkbox to toggle line wrapping in diff (Yuriy Glukhov)
- Prevent project stars duplication when fork project
- Use the default Unicorn socket backlog value of 1024
- Support Unix domain sockets for Redis
- Store session Redis keys in 'session:gitlab:' namespace
- Deprecate LDAP account takeover based on partial LDAP email / GitLab username match
- Use /bin/sh instead of Bash in bin/web, bin/background_jobs (Pavel Novitskiy)
- Keyboard shortcuts for productivity (Robert Schilling)
- API: filter issues by state (Julien Bianchi)
- API: filter issues by labels (Julien Bianchi)
- Add system hook for ssh key changes
- Add blob permalink link (Ciro Santilli)
- Create annotated tags through UI and API (Sean Edge)
- Snippets search (Charles Bushong)
- Comment new push to existing MR
- Add 'ci' to the blacklist of forbidden names
- Improve text filtering on issues page
- Comment & Close button
- Process git push --all much faster
- Don't allow edit of system notes
- Project wiki search (Ralf Seidler)
- Enabled Shibboleth authentication support (Matus Banas)
- Zen mode (fullscreen) for issues/MR/notes (Robert Schilling)
- Add ability to configure webhook timeout via gitlab.yml (Wes Gurney)
- Sort project merge requests in asc or desc order for updated_at or created_at field (sponsored by O'Reilly Media)
- Add Redis socket support to 'rake gitlab:shell:install'
v 7.2.1
- Delete orphaned labels during label migration (James Brooks)
- Security: prevent XSS with stricter MIME types for raw repo files
v 7.2.0
- Explore page
- Add project stars (Ciro Santilli)
- Log Sidekiq arguments
- Better labels: colors, ability to rename and remove
- Improve the way merge request collects diffs
- Improve compare page for large diffs
- Expose the full commit message via API
- Fix 500 error on repository rename
- Fix bug when MR download patch return invalid diff
- Test gitlab-shell integration
- Repository import timeout increased from 2 to 4 minutes allowing larger repos to be imported
- API for labels (Robert Schilling)
- API: ability to set an import url when creating project for specific user
v 7.1.1
- Fix cpu usage issue in Firefox
- Fix redirect loop when changing password by new user
- Fix 500 error on new merge request page
v 7.1.0
- Remove observers
- Improve MR discussions
- Filter by description on Issues#index page
- Fix bug with namespace select when create new project page
- Show README link after description for non-master members
- Add @all mention for comments
- Dont show reply button if user is not signed in
- Expose more information for issues with webhook
- Add a mention of the merge request into the default merge request commit message
- Improve code highlight, introduce support for more languages like Go, Clojure, Erlang etc
- Fix concurrency issue in repository download
- Dont allow repository name start with ?
- Improve email threading (Pierre de La Morinerie)
- Cleaner help page
- Group milestones
- Improved email notifications
- Contributors API (sponsored by Mobbr)
- Fix LDAP TLS authentication (Boris HUISGEN)
- Show VERSION information on project sidebar
- Improve branch removal logic when accept MR
- Fix bug where comment form is spawned inside the Reply button
- Remove Dir.chdir from Satellite#lock for thread-safety
- Increased default git max_size value from 5MB to 20MB in gitlab.yml. Please update your configs!
- Show error message in case of timeout in satellite when create MR
- Show first 100 files for huge diff instead of hiding all
- Change default admin email from admin@local.host to admin@example.com
v 7.0.0
- The CPU no longer overheats when you hold down the spacebar
- Improve edit file UI
- Add ability to upload group avatar when create
- Protected branch cannot be removed
- Developers can remove normal branches with UI
- Remove branch via API (sponsored by O'Reilly Media)
- Move protected branches page to Project settings area
- Redirect to Files view when create new branch via UI
- Drag and drop upload of image in every markdown-area (Earle Randolph Bunao and Neil Francis Calabroso)
- Refactor the markdown relative links processing
- Make it easier to implement other CI services for GitLab
- Group masters can create projects in group
- Deprecate ruby 1.9.3 support
- Only masters can rewrite/remove git tags
- Add X-Frame-Options SAMEORIGIN to Nginx config so Sidekiq admin is visible
- UI improvements
- Case-insensetive search for issues
- Update to rails 4.1
- Improve performance of application for projects and groups with a lot of members
- Formally support Ruby 2.1
- Include Nginx gitlab-ssl config
- Add manual language detection for highlight.js
- Added example.com/:username routing
- Show notice if your profile is public
- UI improvements for mobile devices
- Improve diff rendering performance
- Drag-n-drop for issues and merge requests between states at milestone page
- Fix '0 commits' message for huge repositories on project home page
- Prevent 500 error page when visit commit page from large repo
- Add notice about huge push over http to unicorn config
- File action in satellites uses default 30 seconds timeout instead of old 10 seconds one
- Overall performance improvements
- Skip init script check on omnibus-gitlab
- Be more selective when killing stray Sidekiqs
- Check LDAP user filter during sign-in
- Remove wall feature (no data loss - you can take it from database)
- Dont expose user emails via API unless you are admin
- Detect issues closed by Merge Request description
- Better email subject lines from email on push service (Alex Elman)
- Enable identicon for gravatar be default
v 6.9.2
- Revert the commit that broke the LDAP user filter
v 6.9.1
- Fix scroll to highlighted line
- Fix the pagination on load for commits page
v 6.9.0
- Store Rails cache data in the Redis `cache:gitlab` namespace
- Adjust MySQL limits for existing installations
- Add db index on project_id+iid column. This prevents duplicate on iid (During migration duplicates will be removed)
- Markdown preview or diff during editing via web editor (Evgeniy Sokovikov)
- Give the Rails cache its own Redis namespace
- Add ability to set different ssh host, if different from http/https
- Fix syntax highlighting for code comments blocks
- Improve comments loading logic
- Stop refreshing comments when the tab is hidden
- Improve issue and merge request mobile UI (Drew Blessing)
- Document how to convert a backup to PostgreSQL
- Fix locale bug in backup manager
- Fix can not automerge when MR description is too long
- Fix wiki backup skip bug
- Two Step MR creation process
- Remove unwanted files from satellite working directory with git clean -fdx
- Accept merge request via API (sponsored by O'Reilly Media)
- Add more access checks during API calls
- Block SSH access for 'disabled' Active Directory users
- Labels for merge requests (Drew Blessing)
- Threaded emails by setting a Message-ID (Philip Blatter)
v 6.8.0
- Ability to at mention users that are participating in issue and merge req. discussion
- Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu)
- Make user search case-insensitive (Christopher Arnold)
- Remove omniauth-ldap nickname bug workaround
- Drop all tables before restoring a Postgres backup
- Make the repository downloads path configurable
- Create branches via API (sponsored by O'Reilly Media)
- Changed permission of gitlab-satellites directory not to be world accessible
- Protected branch does not allow force push
- Fix popen bug in `rake gitlab:satellites:create`
- Disable connection reaping for MySQL
- Allow oauth signup without email for twitter and github
- Fix faulty namespace names that caused 500 on user creation
- Option to disable standard login
- Clean old created archives from repository downloads directory
- Fix download link for huge MR diffs
- Expose event and mergerequest timestamps in API
- Fix emails on push service when only one commit is pushed
v 6.7.3
- Fix the merge notification email not being sent (Pierre de La Morinerie)
- Drop all tables before restoring a Postgres backup
- Remove yanked modernizr gem
v 6.7.2
- Fix upgrader script
v 6.7.1
- Fix GitLab CI integration
v 6.7.0
- Increased the example Nginx client_max_body_size from 5MB to 20MB, consider updating it manually on existing installations
- Add support for Gemnasium as a Project Service (Olivier Gonzalez)
- Add edit file button to MergeRequest diff
- Public groups (Jason Hollingsworth)
- Cleaner headers in Notification Emails (Pierre de La Morinerie)
- Blob and tree gfm links to anchors work
- Piwik Integration (Sebastian Winkler)
- Show contribution guide link for new issue form (Jeroen van Baarsen)
- Fix CI status for merge requests from fork
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
- New page load indicator that includes a spinner that scrolls with the page
- Converted all the help sections into markdown
- LDAP user filters
- Streamline the content of notification emails (Pierre de La Morinerie)
- Fixes a bug with group member administration (Matt DeTullio)
- Sort tag names using VersionSorter (Robert Speicher)
- Add GFM autocompletion for MergeRequests (Robert Speicher)
- Add webhook when a new tag is pushed (Jeroen van Baarsen)
- Add button for toggling inline comments in diff view
- Add retry feature for repository import
- Reuse the GitLab LDAP connection within each request
- Changed markdown new line behaviour to conform to markdown standards
- Fix global search
- Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5)
- Create and Update MR calls now support the description parameter (Greg Messner)
- Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository
- Added Slack service integration (Federico Ravasio)
- Better API responses for access_levels (sponsored by O'Reilly Media)
- Requires at least 2 unicorn workers
- Requires gitlab-shell v1.9+
- Replaced gemoji(due to closed licencing problem) with Phantom Open Emoji library(combined SIL Open Font License, MIT License and the CC 3.0 License)
- Fix `/:username.keys` response content type (Dmitry Medvinsky)
v 6.6.5
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
- Hide mr close button for comment form if merge request was closed or inline comment
- Adds ability to reopen closed merge request
v 6.6.4
- Add missing html escape for highlighted code blocks in comments, issues
v 6.6.3
- Fix 500 error when edit yourself from admin area
- Hide private groups for public profiles
v 6.6.2
- Fix 500 error on branch/tag create or remove via UI
v 6.6.1
- Fix 500 error on files tab if submodules presents
v 6.6.0
- Retrieving user ssh keys publically(github style): http://__HOST__/__USERNAME__.keys
- Permissions: Developer now can manage issue tracker (modify any issue)
- Improve Code Compare page performance
- Group avatar
- Pygments.rb replaced with highlight.js
- Improve Merge request diff store logic
- Improve render performnace for MR show page
- Fixed Assembla hardcoded project name
- Jira integration documentation
- Refactored app/services
- Remove snippet expiration
- Mobile UI improvements (Drew Blessing)
- Fix block/remove UI for admin::users#show page
- Show users' group membership on users' activity page (Robert Djurasaj)
- User pages are visible without login if user is authorized to a public project
- Markdown rendered headers have id derived from their name and link to their id
- Improve application to work faster with large groups (100+ members)
- Multiple emails per user
- Show last commit for file when view file source
- Restyle Issue#show page and MR#show page
- Ability to filter by multiple labels for Issues page
- Rails version to 4.0.3
- Fixed attachment identifier displaying underneath note text (Jason Blanchard)
v 6.5.1
- Fix branch selectbox when create merge request from fork
v 6.5.0
- Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard)
- Add color custimization and previewing to broadcast messages
- Fixed notes anchors
- Load new comments in issues dynamically
- Added sort options to Public page
- New filters (assigned/authored/all) for Dashboard#issues/merge_requests (sponsored by Say Media)
- Add project visibility icons to dashboard
- Enable secure cookies if https used
- Protect users/confirmation with rack_attack
- Default HTTP headers to protect against MIME-sniffing, force https if enabled
- Bootstrap 3 with responsive UI
- New repository download formats: tar.bz2, zip, tar (Jason Hollingsworth)
- Restyled accept widgets for MR
- SCSS refactored
- Use jquery timeago plugin
- Fix 500 error for rdoc files
- Ability to customize merge commit message (sponsored by Say Media)
- Search autocomplete via ajax
- Add website url to user profile
- Files API supports base64 encoded content (sponsored by O'Reilly Media)
- Added support for Go's repository retrieval (Bruno Albuquerque)
v 6.4.3
- Don't use unicorn worker killer if PhusionPassenger is defined
v 6.4.2
- Fixed wrong behaviour of script/upgrade.rb
v 6.4.1
- Fixed bug with repository rename
- Fixed bug with project transfer
v 6.4.0
- Added sorting to project issues page (Jason Blanchard)
- Assembla integration (Carlos Paramio)
- Fixed another 500 error with submodules
- UI: More compact issues page
- Minimal password length increased to 8 symbols
- Side-by-side diff view (Steven Thonus)
- Internal projects (Jason Hollingsworth)
- Allow removal of avatar (Drew Blessing)
- Project webhooks now support issues and merge request events
- Visiting project page while not logged in will redirect to sign-in instead of 404 (Jason Hollingsworth)
- Expire event cache on avatar creation/removal (Drew Blessing)
- Archiving old projects (Steven Thonus)
- Rails 4
- Add time ago tooltips to show actual date/time
- UI: Fixed UI for admin system hooks
- Ruby script for easier GitLab upgrade
- Do not remove Merge requests if fork project was removed
- Improve sign-in/signup UX
- Add resend confirmation link to sign-in page
- Set noreply@HOSTNAME for reply_to field in all emails
- Show GitLab API version on Admin#dashboard
- API Cross-origin resource sharing
- Show READMe link at project home page
- Show repo size for projects in Admin area
v 6.3.0
- API for adding gitlab-ci service
- Init script now waits for pids to appear after (re)starting before reporting status (Rovanion Luckey)
- Restyle project home page
- Grammar fixes
- Show branches list (which branches contains commit) on commit page (Andrew Kumanyaev)
- Security improvements
- Added support for GitLab CI 4.0
- Fixed issue with 500 error when group did not exist
- Ability to leave project
- You can create file in repo using UI
- You can remove file from repo using UI
- API: dropped default_branch attribute from project during creation
- Project default_branch is not stored in db any more. It takes from repo now.
- Admin broadcast messages
- UI improvements
- Dont show last push widget if user removed this branch
- Fix 500 error for repos with newline in file name
- Extended html titles
- API: create/update/delete repo files
- Admin can transfer project to any namespace
- API: projects/all for admin users
- Fix recent branches order
v 6.2.4
- Security: Cast API private_token to string (CVE-2013-4580)
- Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583)
- Fix for Git SSH access for LDAP users
v 6.2.3
- Security: More protection against CVE-2013-4489
- Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546)
- Fix sidekiq rake tasks
v 6.2.2
- Security: Update gitlab_git (CVE-2013-4489)
v 6.2.1
- Security: Fix issue with generated passwords for new users
v 6.2.0
- Public project pages are now visible to everyone (files, issues, wik, etc.)
THIS MEANS YOUR ISSUES AND WIKI FOR PUBLIC PROJECTS ARE PUBLICLY VISIBLE AFTER THE UPGRADE
- Add group access to permissions page
- Require current password to change one
- Group owner or admin can remove other group owners
- Remove group transfer since we have multiple owners
- Respect authorization in Repository API
- Improve UI for Project#files page
- Add more security specs
- Added search for projects by name to api (Izaak Alpert)
- Make default user theme configurable (Izaak Alpert)
- Update logic for validates_merge_request for tree of MR (Andrew Kumanyaev)
- Rake tasks for webhooks management (Jonhnny Weslley)
- Extended User API to expose admin and can_create_group for user creation/updating (Boyan Tabakov)
- API: Remove group
- API: Remove project
- Avatar upload on profile page with a maximum of 100KB (Steven Thonus)
- Store the sessions in Redis instead of the cookie store
- Fixed relative links in markdown
- User must confirm their email if signup enabled
- User must confirm changed email
v 6.1.0
- Project specific IDs for issues, mr, milestones
Above items will get a new id and for example all bookmarked issue urls will change.
Old issue urls are redirected to the new one if the issue id is too high for an internal id.
- Description field added to Merge Request
- API: Sudo api calls (Izaak Alpert)
- API: Group membership api (Izaak Alpert)
- Improved commit diff
- Improved large commit handling (Boyan Tabakov)
- Rewrite: Init script now less prone to errors and keeps better track of the service (Rovanion Luckey)
- Link issues, merge requests, and commits when they reference each other with GFM (Ash Wilson)
- Close issues automatically when pushing commits with a special message
- Improve user removal from admin area
- Invalidate events cache when project was moved
- Remove deprecated classes and rake tasks
- Add event filter for group and project show pages
- Add links to create branch/tag from project home page
- Add public-project? checkbox to new-project view
- Improved compare page. Added link to proceed into Merge Request
- Send an email to a user when they are added to group
- New landing page when you have 0 projects
v 6.0.0
- Feature: Replace teams with group membership
We introduce group membership in 6.0 as a replacement for teams.
The old combination of groups and teams was confusing for a lot of people.
And when the members of a team where changed this wasn't reflected in the project permissions.
In GitLab 6.0 you will be able to add members to a group with a permission level for each member.
These group members will have access to the projects in that group.
Any changes to group members will immediately be reflected in the project permissions.
You can even have multiple owners for a group, greatly simplifying administration.
- Feature: Ability to have multiple owners for group
- Feature: Merge Requests between fork and project (Izaak Alpert)
- Feature: Generate fingerprint for ssh keys
- Feature: Ability to create and remove branches with UI
- Feature: Ability to create and remove git tags with UI
- Feature: Groups page in profile. You can leave group there
- API: Allow login with LDAP credentials
- Redesign: project settings navigation
- Redesign: snippets area
- Redesign: ssh keys page
- Redesign: buttons, blocks and other ui elements
- Add comment title to rss feed
- You can use arrows to navigate at tree view
- Add project filter on dashboard
- Cache project graph
- Drop support of root namespaces
- Default theme is classic now
- Cache result of methods like authorize_projects, project.team.members etc
- Remove $.ready events
- Fix onclick events being double binded
- Add notification level to group membership
- Move all project controllers/views under Projects:: module
- Move all profile controllers/views under Profiles:: module
- Apply user project limit only for personal projects
- Unicorn is default web server again
- Store satellites lock files inside satellites dir
- Disabled threadsafety mode in rails
- Fixed bug with loosing MR comments
- Improved MR comments logic
- Render readme file for projects in public area
v 5.4.2
- Security: Cast API private_token to string (CVE-2013-4580)
- Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583)
v 5.4.1
- Security: Fixes for CVE-2013-4489
- Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546)
v 5.4.0
- Ability to edit own comments
- Documentation improvements
- Improve dashboard projects page
- Fixed nav for empty repos
- GitLab Markdown help page
- Misspelling fixes
- Added support of unicorn and fog gems
- Added client list to API doc
- Fix PostgreSQL database restoration problem
- Increase snippet content column size
- allow project import via git:// url
- Show participants on issues, including mentions
- Notify mentioned users with email
v 5.3.0
- Refactored services
- Campfire service added
- HipChat service added
- Fixed bug with LDAP + git over http
- Fixed bug with google analytics code being ignored
- Improve sign-in page if ldap enabled
- Respect newlines in wall messages
- Generate the Rails secret token on first run
- Rename repo feature
- Init.d: remove gitlab.socket on service start
- Api: added teams api
- Api: Prevent blob content being escaped
- Api: Smart deploy key add behaviour
- Api: projects/owned.json return user owned project
- Fix bug with team assignation on project from #4109
- Advanced snippets: public/private, project/personal (Andrew Kulakov)
- Repository Graphs (Karlo Nicholas T. Soriano)
- Fix dashboard lost if comment on commit
- Update gitlab-grack. Fixes issue with --depth option
- Fix project events duplicate on project page
- Fix postgres error when displaying network graph.
- Fix dashboard event filter when navigate via turbolinks
- init.d: Ensure socket is removed before starting service
- Admin area: Style teams:index, group:show pages
- Own page for failed forking
- Scrum view for milestone
v 5.2.0
- Turbolinks
- Git over http with ldap credentials
- Diff with better colors and some spacing on the corners
- Default values for project features
- Fixed huge_commit view
- Restyle project clone panel
- Move Gitlab::Git code to gitlab_git gem
- Move update docs in repo
- Requires gitlab-shell v1.4.0
- Fixed submodules listing under file tab
- Fork feature (Angus MacArthur)
- git version check in gitlab:check
- Shared deploy keys feature
- Ability to generate default labels set for issues
- Improve gfm autocomplete (Harold Luo)
- Added support for Google Analytics
- Code search feature (Javier Castro)
v 5.1.0
- You can login with email or username now
- Corrected project transfer rollback when repository cannot be moved
- Move both repo and wiki when project transfer requested
- Admin area: project editing was removed from admin namespace
- Access: admin user has now access to any project.
- Notification settings
- Gitlab::Git set of objects to abstract from grit library
- Replace Unicorn web server with Puma
- Backup/Restore refactored. Backup dump project wiki too now
- Restyled Issues list. Show milestone version in issue row
- Restyled Merge Request list
- Backup now dump/restore uploads
- Improved performance of dashboard (Andrew Kumanyaev)
- File history now tracks renames (Akzhan Abdulin)
- Drop wiki migration tools
- Drop sqlite migration tools
- project tagging
- Paginate users in API
- Restyled network graph (Hiroyuki Sato)
v 5.0.1
- Fixed issue with gitlab-grit being overridden by grit
v 5.0.0
- Replaced gitolite with gitlab-shell
- Removed gitolite-related libraries
- State machine added
- Setup gitlab as git user
- Internal API
- Show team tab for empty projects
- Import repository feature
- Updated rails
- Use lambda for scopes
- Redesign admin area -> users
- Redesign admin area -> user
- Secure link to file attachments
- Add validations for Group and Team names
- Restyle team page for project
- Update capybara, rspec-rails, poltergeist to recent versions
- Wiki on git using Gollum
- Added Solarized Dark theme for code review
- Don't show user emails in autocomplete lists, profile pages
- Added settings tab for group, team, project
- Replace user popup with icons in header
- Handle project moving with gitlab-shell
- Added select2-rails for selectboxes with ajax data load
- Fixed search field on projects page
- Added teams to search autocomplete
- Move groups and teams on dashboard sidebar to sub-tabs
- API: improved return codes and docs. (Felix Gilcher, Sebastian Ziebell)
- Redesign wall to be more like chat
- Snippets, Wall features are disabled by default for new projects
v 4.2.0
- Teams
- User show page. Via /u/username
- Show help contents on pages for better navigation
- Async gitolite calls
- added satellites logs
- can_create_group, can_create_team booleans for User
- Process webhooks async
- GFM: Fix images escaped inside links
- Network graph improved
- Switchable branches for network graph
- API: Groups
- Fixed project download
v 4.1.0
- Optional Sign-Up
- Discussions
- Satellites outside of tmp
- Line numbers for blame
- Project public mode
- Public area with unauthorized access
- Load dashboard events with ajax
- remember dashboard filter in cookies
- replace resque with sidekiq
- fix routing issues
- cleanup rake tasks
- fix backup/restore
- scss cleanup
- show preview for note images
- improved network-graph
- get rid of app/roles/
- added new classes Team, Repository
- Reduce amount of gitolite calls
- Ability to add user in all group projects
- remove deprecated configs
- replaced Korolev font with open font
- restyled admin/dashboard page
- restyled admin/projects page
v 4.0.0
- Remove project code and path from API. Use id instead
- Return valid cloneable url to repo for webhook
- Fixed backup issue
- Reorganized settings
- Fixed commits compare
- Refactored scss
- Improve status checks
- Validates presence of User#name
- Fixed postgres support
- Removed sqlite support
- Modified post-receive hook
- Milestones can be closed now
- Show comment events on dashboard
- Quick add team members via group#people page
- [API] expose created date for hooks and SSH keys
- [API] list, create issue notes
- [API] list, create snippet notes
- [API] list, create wall notes
- Remove project code - use path instead
- added username field to user
- rake task to fill usernames based on emails create namespaces for users
- STI Group < Namespace
- Project has namespace_id
- Projects with namespaces also namespaced in gitolite and stored in subdir
- Moving project to group will move it under group namespace
- Ability to move project from namespaces to another
- Fixes commit patches getting escaped (see #2036)
- Support diff and patch generation for commits and merge request
- MergeReqest doesn't generate a temporary file for the patch any more
- Update the UI to allow downloading Patch or Diff
v 3.1.0
- Updated gems
- Services: Gitlab CI integration
- Events filter on dashboard
- Own namespace for redis/resque
- Optimized commit diff views
- add alphabetical order for projects admin page
- Improved web editor
- Commit stats page
- Documentation split and cleanup
- Link to commit authors everywhere
- Restyled milestones list
- added Milestone to Merge Request
- Restyled Top panel
- Refactored Satellite Code
- Added file line links
- moved from capybara-webkit to poltergeist + phantomjs
v 3.0.3
- Fixed bug with issues list in Chrome
- New Feature: Import team from another project
v 3.0.2
- Fixed gitlab:app:setup
- Fixed application error on empty project in admin area
- Restyled last push widget
v 3.0.1
- Fixed git over http
v 3.0.0
- Projects groups
- Web Editor
- Fixed bug with gitolite keys
- UI improved
- Increased performance of application
- Show user avatar in last commit when browsing Files
- Refactored Gitlab::Merge
- Use Font Awesome for icons
- Separate observing of Note and MergeRequests
- Milestone "All Issues" filter
- Fix issue close and reopen button text and styles
- Fix forward/back while browsing Tree hierarchy
- Show number of notes for commits and merge requests
- Added support pg from box and update installation doc
- Reject ssh keys that break gitolite
- [API] list one project hook
- [API] edit project hook
- [API] list project snippets
- [API] allow to authorize using private token in HTTP header
- [API] add user creation
v 2.9.1
- Fixed resque custom config init
v 2.9.0
- fixed inline notes bugs
- refactored rspecs
- refactored gitolite backend
- added factory_girl
- restyled projects list on dashboard
- ssh keys validation to prevent gitolite crash
- send notifications if changed permission in project
- scss refactoring. gitlab_bootstrap/ dir
- fix git push http body bigger than 112k problem
- list of labels page under issues tab
- API for milestones, keys
- restyled buttons
- OAuth
- Comment order changed
v 2.8.1
- ability to disable gravatars
- improved MR diff logic
- ssh key help page
v 2.8.0
- Gitlab Flavored Markdown
- Bulk issues update
- Issues API
- Cucumber coverage increased
- Post-receive files fixed
- UI improved
- Application cleanup
- more cucumber
- capybara-webkit + headless
v 2.7.0
- Issue Labels
- Inline diff
- Git HTTP
- API
- UI improved
- System hooks
- UI improved
- Dashboard events endless scroll
- Source performance increased
v 2.6.0
- UI polished
- Improved network graph + keyboard nav
- Handle huge commits
- Last Push widget
- Bugfix
- Better performance
- Email in resque
- Increased test coverage
- Ability to remove branch with MR accept
- a lot of code refactored
v 2.5.0
- UI polished
- Git blame for file
- Bugfix
- Email in resque
- Better test coverage
v 2.4.0
- Admin area stats page
- Ability to block user
- Simplified dashboard area
- Improved admin area
- Bootstrap 2.0
- Responsive layout
- Big commits handling
- Performance improved
- Milestones
v 2.3.1
- Issues pagination
- ssl fixes
- Merge Request pagination
v 2.3.0
- Dashboard r1
- Search r1
- Project page
- Close merge request on push
- Persist MR diff after merge
- mysql support
- Documentation
v 2.2.0
- We’ve added support of LDAP auth
- Improved permission logic (4 roles system)
- Protected branches (now only masters can push to protected branches)
- Usability improved
- twitter bootstrap integrated
- compare view between commits
- wiki feature
- now you can enable/disable issues, wiki, wall features per project
- security fixes
- improved code browsing (ajax branch switch etc)
- improved per-line commenting
- git submodules displayed
- moved to rails 3.2
- help section improved
v 2.1.0
- Project tab r1
- List branches/tags
- per line comments
- mass user import
v 2.0.0
- gitolite as main git host system
- merge requests
- project/repo access
- link to commit/issue feed
- design tab
- improved email notifications
- restyled dashboard
- bugfix
v 1.2.2
- common config file gitlab.yml
- issues restyle
- snippets restyle
- clickable news feed header on dashboard
- bugfix
v 1.2.1
- bugfix
v 1.2.0
- new design
- user dashboard
- network graph
- markdown support for comments
- encoding issues
- wall like twitter timeline
v 1.1.0
- project dashboard
- wall redesigned
- feature: code snippets
- fixed horizontal scroll on file preview
- fixed app crash if commit message has invalid chars
- bugfix & code cleaning
v 1.0.2
- fixed bug with empty project
- added adv validation for project path & code
- feature: issues can be sortable
- bugfix
- username displayed on top panel
v 1.0.1
- fixed: with invalid source code for commit
- fixed: lose branch/tag selection when use tree navigation
- when history clicked - display path
- bug fix & code cleaning
v 1.0.0
- bug fix
- projects preview mode
v 0.9.6
- css fix
- new repo empty tree until restart server - fixed
v 0.9.4
- security improved
- authorization improved
- html escaping
- bug fix
- increased test coverage
- design improvements
v 0.9.1
- increased test coverage
- design improvements
- new issue email notification
- updated app name
- issue redesigned
- issue can be edit
v 0.8.0
- syntax highlight for main file types
- redesign
- stability
- security fixes
- increased test coverage
- email notification
v 7.14.3 through 0.8.0
- See changelogs/archive.md
......@@ -3,6 +3,7 @@
LabelManager.prototype.errorMessage = 'Unable to update label prioritization at this time';
function LabelManager(opts) {
// Defaults
var ref, ref1, ref2;
if (opts == null) {
opts = {};
......@@ -28,6 +29,7 @@
$btn = $(e.currentTarget);
$label = $("#" + ($btn.data('domId')));
action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
// Make sure tooltip will hide
$tooltip = $("#" + ($btn.find('.has-tooltip:visible').attr('aria-describedby')));
$tooltip.tooltip('destroy');
return _this.toggleLabelPriority($label, action);
......@@ -42,6 +44,7 @@
url = $label.find('.js-toggle-priority').data('url');
$target = this.prioritizedLabels;
$from = this.otherLabels;
// Optimistic update
if (action === 'remove') {
$target = this.otherLabels;
$from = this.prioritizedLabels;
......@@ -53,6 +56,7 @@
$target.find('.empty-message').addClass('hidden');
}
$label.detach().appendTo($target);
// Return if we are not persisting state
if (!persistState) {
return;
}
......@@ -61,6 +65,7 @@
url: url,
type: 'DELETE'
});
// Restore empty message
if (!$from.find('li').length) {
$from.find('.empty-message').removeClass('hidden');
}
......
......@@ -25,6 +25,8 @@
return callback(group);
});
},
// Return groups list. Filtered by query
// Only active groups retrieved
groups: function(query, skip_ldap, callback) {
var url = Api.buildUrl(Api.groupsPath);
return $.ajax({
......@@ -39,6 +41,7 @@
return callback(groups);
});
},
// Return namespaces list. Filtered by query
namespaces: function(query, callback) {
var url = Api.buildUrl(Api.namespacesPath);
return $.ajax({
......@@ -53,6 +56,7 @@
return callback(namespaces);
});
},
// Return projects list. Filtered by query
projects: function(query, order, callback) {
var url = Api.buildUrl(Api.projectsPath);
return $.ajax({
......@@ -83,6 +87,7 @@
return callback(message.responseJSON);
});
},
// Return group projects list. Filtered by query
groupProjects: function(group_id, query, callback) {
var url = Api.buildUrl(Api.groupProjectsPath)
.replace(':id', group_id);
......@@ -98,6 +103,7 @@
return callback(projects);
});
},
// Return text for a specific license
licenseText: function(key, data, callback) {
var url = Api.buildUrl(Api.licensePath)
.replace(':key', key);
......
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
/*= require jquery2 */
/*= require jquery-ui/autocomplete */
/*= require jquery-ui/datepicker */
......@@ -77,6 +83,7 @@
}
};
// Disable button if text field is empty
window.disableButtonIfEmptyField = function(field_selector, button_selector) {
var closest_submit, field;
field = $(field_selector);
......@@ -93,6 +100,7 @@
});
};
// Disable button if any input field with given selector is empty
window.disableButtonIfAnyEmptyField = function(form, form_selector, button_selector) {
var closest_submit, updateButtons;
closest_submit = form.find(button_selector);
......@@ -131,6 +139,8 @@
$.timeago.settings.allowFuture = true;
window.onload = function() {
// Scroll the window to avoid the topnav bar
// https://github.com/twitter/bootstrap/issues/1768
if (location.hash) {
return setTimeout(shiftWindow, 100);
}
......@@ -152,6 +162,8 @@
return $(this).select().one('mouseup', function(e) {
return e.preventDefault();
});
// Click a .js-select-on-focus field, select the contents
// Prevent a mouseup event from deselecting the input
});
$('.remove-row').bind('ajax:success', function() {
$(this).tooltip('destroy')
......@@ -166,6 +178,7 @@
});
$('select.select2').select2({
width: 'resolve',
// Initialize select2 selects
dropdownAutoWidth: true
});
$('.js-select2').bind('select2-close', function() {
......@@ -173,7 +186,9 @@
$('.select2-container-active').removeClass('select2-container-active');
return $(':focus').blur();
}), 1);
// Close select2 on escape
});
// Initialize tooltips
$body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]',
placement: function(_, el) {
......@@ -182,14 +197,17 @@
});
$('.trigger-submit').on('change', function() {
return $(this).parents('form').submit();
// Form submitter
});
gl.utils.localTimeAgo($('abbr.timeago, .js-timeago'), true);
// Flash
if ((flash = $(".flash-container")).length > 0) {
flash.click(function() {
return $(this).fadeOut();
});
flash.show();
}
// Disable form buttons while a form is submitting
$body.on('ajax:complete, ajax:beforeSend, submit', 'form', function(e) {
var buttons;
buttons = $('[type="submit"]', this);
......@@ -210,6 +228,7 @@
}
});
$('.account-box').hover(function() {
// Show/Hide the profile menu when hovering the account box
return $(this).toggleClass('hover');
});
$document.on('click', '.diff-content .js-show-suppressed-diff', function() {
......@@ -217,6 +236,7 @@
$container = $(this).parent();
$container.next('table').show();
return $container.remove();
// Commit show suppressed diff
});
$('.navbar-toggle').on('click', function() {
$('.header-content .title').toggle();
......@@ -224,6 +244,7 @@
$('.header-content .navbar-collapse').toggle();
return $('.navbar-toggle').toggleClass('active');
});
// Show/hide comments on diff
$body.on("click", ".js-toggle-diff-comments", function(e) {
var $this = $(this);
$this.toggleClass('active');
......
......@@ -16,7 +16,7 @@
}
Autosave.prototype.restore = function() {
var e, error, text;
var e, text;
if (window.localStorage == null) {
return;
}
......@@ -41,7 +41,7 @@
if ((text != null ? text.length : void 0) > 0) {
try {
return window.localStorage.setItem(this.key, text);
} catch (undefined) {}
} catch (error) {}
} else {
return this.reset();
}
......@@ -53,7 +53,7 @@
}
try {
return window.localStorage.removeItem(this.key);
} catch (undefined) {}
} catch (error) {}
};
return Autosave;
......
......@@ -86,6 +86,8 @@
AwardsHandler.prototype.positionMenu = function($menu, $addBtn) {
var css, position;
position = $addBtn.data('position');
// The menu could potentially be off-screen or in a hidden overflow element
// So we position the element absolute in the body
css = {
top: ($addBtn.offset().top + $addBtn.outerHeight()) + "px"
};
......@@ -284,6 +286,7 @@
if (emojiIcon.length > 0) {
unicodeName = emojiIcon.data('unicode-name');
} else {
// Find by alias
unicodeName = $(".emoji-menu-content [data-aliases*=':" + emoji + ":']").data('unicode-name');
}
return "emoji-" + unicodeName;
......@@ -350,8 +353,10 @@
return function(ev) {
var found_emojis, h5, term, ul;
term = $(ev.target).val();
// Clean previous search results
$('ul.emoji-menu-search, h5.emoji-search').remove();
if (term) {
// Generate a search result block
h5 = $('<h5>').text('Search results');
found_emojis = _this.searchEmojis(term).show();
ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(found_emojis);
......
/*= require jquery.ba-resize */
/*= require autosize */
(function() {
......
......@@ -5,6 +5,12 @@
container = $(this).closest(".js-details-container");
return container.toggleClass("open");
});
// Show details content. Hides link after click.
//
// %div
// %a.js-details-expand
// %div.js-details-content
//
return $("body").on("click", ".js-details-expand", function(e) {
$(this).next('.js-details-content').removeClass("hide");
$(this).hide();
......
// Quick Submit behavior
//
// When a child field of a form with a `js-quick-submit` class receives a
// "Meta+Enter" (Mac) or "Ctrl+Enter" (Linux/Windows) key combination, the form
// is submitted.
//
/*= require extensions/jquery */
//
// ### Example Markup
//
// <form action="/foo" class="js-quick-submit">
// <input type="text" />
// <textarea></textarea>
// <input type="submit" value="Submit" />
// </form>
//
(function() {
var isMac, keyCodeIs;
......@@ -17,6 +31,7 @@
$(document).on('keydown.quick_submit', '.js-quick-submit', function(e) {
var $form, $submit_button;
// Enter
if (!keyCodeIs(e, 13)) {
return;
}
......@@ -33,8 +48,11 @@
return $form.submit();
});
// If the user tabs to a submit button on a `js-quick-submit` form, display a
// tooltip to let them know they could've used the hotkey
$(document).on('keyup.quick_submit', '.js-quick-submit input[type=submit], .js-quick-submit button[type=submit]', function(e) {
var $this, title;
// Tab
if (!keyCodeIs(e, 9)) {
return;
}
......
// Requires Input behavior
//
// When called on a form with input fields with the `required` attribute, the
// form's submit button will be disabled until all required fields have values.
//
/*= require extensions/jquery */
//
// ### Example Markup
//
// <form class="js-requires-input">
// <input type="text" required="required">
// <input type="submit" value="Submit">
// </form>
//
(function() {
$.fn.requiresInput = function() {
var $button, $form, fieldSelector, requireInput, required;
......@@ -11,14 +23,17 @@
requireInput = function() {
var values;
values = _.map($(fieldSelector, $form), function(field) {
// Collect the input values of *all* required fields
return field.value;
});
// Disable the button if any required fields are empty
if (values.length && _.any(values, _.isEmpty)) {
return $button.disable();
} else {
return $button.enable();
}
};
// Set initial button state
requireInput();
return $form.on('change input', fieldSelector, requireInput);
};
......@@ -27,6 +42,8 @@
var $form, hideOrShowHelpBlock;
$form = $('form.js-requires-input');
$form.requiresInput();
// Hide or Show the help block when creating a new project
// based on the option selected
hideOrShowHelpBlock = function(form) {
var selected;
selected = $('.js-select-namespace option:selected');
......
(function(w) {
$(function() {
// Toggle button. Show/hide content inside parent container.
// Button does not change visibility. If button has icon - it changes chevron style.
//
// %div.js-toggle-container
// %a.js-toggle-button
// %div.js-toggle-content
//
$('body').on('click', '.js-toggle-button', function(e) {
e.preventDefault();
$(this)
......
......@@ -8,6 +8,8 @@
autoDiscover: false,
autoProcessQueue: false,
url: form.attr('action'),
// Rails uses a hidden input field for PUT
// http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails
method: method,
clickable: true,
uploadMultiple: false,
......@@ -36,6 +38,7 @@
formData.append('commit_message', form.find('.js-commit-message').val());
});
},
// Override behavior of adding error underneath preview
error: function(file, errorMessage) {
var stripped;
stripped = $("<div/>").html(errorMessage).text();
......
......@@ -66,6 +66,9 @@
// be added by all subclasses.
};
// To be implemented on the extending class
// e.g.
// Api.gitignoreText item.name, @requestFileSuccess.bind(@)
TemplateSelector.prototype.requestFileSuccess = function(file, skipFocus) {
this.editor.setValue(file.content, 1);
if (!skipFocus) this.editor.focus();
......
......@@ -18,6 +18,8 @@
return function() {
return $("#file-content").val(_this.editor.getValue());
};
// Before a form submission, move the content from the Ace editor into the
// submitted textarea
})(this));
this.initModePanesAndLinks();
new BlobLicenseSelectors({
......
......@@ -23,6 +23,7 @@
if ($(allDeviceSelector.join(",")).length) {
return;
}
// Create all the elements
els = $.map(BREAKPOINTS, function(breakpoint) {
return "<div class='device-" + breakpoint + " visible-" + breakpoint + "'></div>";
});
......@@ -40,6 +41,7 @@
BreakpointInstance.prototype.getBreakpointSize = function() {
var $visibleDevice;
$visibleDevice = this.visibleDevice;
// the page refreshed via turbolinks
if (!$visibleDevice().length) {
this.setup();
}
......
......@@ -16,6 +16,7 @@
this.toggleSidebar = bind(this.toggleSidebar, this);
this.updateDropdown = bind(this.updateDropdown, this);
clearInterval(Build.interval);
// Init breakpoint checker
this.bp = Breakpoints.get();
$('.js-build-sidebar').niceScroll();
......@@ -42,6 +43,9 @@
$(this).data("state", "enabled");
return $(this).text("disable autoscroll");
}
//
// Bind autoscroll button to follow build output
//
});
Build.interval = setInterval((function(_this) {
return function() {
......@@ -49,6 +53,10 @@
return _this.getBuildTrace();
}
};
//
// Check for new build output if user still watching build page
// Only valid for runnig build when output changes during time
//
})(this), 4000);
}
}
......
......@@ -2,6 +2,7 @@
this.ImageFile = (function() {
var prepareFrames;
// Width where images must fits in, for 2-up this gets divided by 2
ImageFile.availWidth = 900;
ImageFile.viewModes = ['two-up', 'swipe'];
......@@ -9,6 +10,7 @@
function ImageFile(file) {
this.file = file;
this.requestImageInfo($('.two-up.view .frame.deleted img', this.file), (function(_this) {
// Determine if old and new file has same dimensions, if not show 'two-up' view
return function(deletedWidth, deletedHeight) {
return _this.requestImageInfo($('.two-up.view .frame.added img', _this.file), function(width, height) {
if (width === deletedWidth && height === deletedHeight) {
......
......@@ -45,6 +45,7 @@
CommitsList.content.html(data.html);
return history.replaceState({
page: commitsUrl
// Change url so if user reload a page - search results are saved
}, document.title, commitsUrl);
},
dataType: "json"
......
......@@ -6,14 +6,19 @@
genericSuccess = function(e) {
showTooltip(e.trigger, 'Copied!');
// Clear the selection and blur the trigger so it loses its border
e.clearSelection();
return $(e.trigger).blur();
};
// Safari doesn't support `execCommand`, so instead we inform the user to
// copy manually.
//
// See http://clipboardjs.com/#browser-support
genericError = function(e) {
var key;
if (/Mac/i.test(navigator.userAgent)) {
key = '&#8984;';
key = '&#8984;'; // Command
} else {
key = 'Ctrl';
}
......
......@@ -39,6 +39,9 @@
bottom: unfoldBottom,
offset: offset,
unfold: unfold,
// indent is used to compensate for single space indent to fit
// '+' and '-' prepended to diff lines,
// see https://gitlab.com/gitlab-org/gitlab-ce/issues/707
indent: 1,
view: file.data('view')
};
......
......@@ -164,6 +164,8 @@
}
break;
case 'projects:network:show':
// Ensure we don't create a particular shortcut handler here. This is
// already created, where the network graph is created.
shortcut_handler = true;
break;
case 'projects:forks:new':
......@@ -267,12 +269,14 @@
shortcut_handler = new ShortcutsNavigation();
}
}
// If we haven't installed a custom shortcut handler, install the default one
if (!shortcut_handler) {
return new Shortcuts();
}
};
Dispatcher.prototype.initSearch = function() {
// Only when search form is present
if ($('.search').length) {
return new SearchAutocomplete();
}
......
......@@ -2,6 +2,7 @@
this.DueDateSelect = (function() {
function DueDateSelect() {
var $datePicker, $dueDate, $loading;
// Milestone edit/new form
$datePicker = $('.datepicker');
if ($datePicker.length) {
$dueDate = $('#milestone_due_date');
......@@ -16,6 +17,7 @@
e.preventDefault();
return $.datepicker._clearDate($datePicker);
});
// Issuable sidebar
$loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
$('.js-due-date-select').each(function(i, dropdown) {
var $block, $dropdown, $dropdownParent, $selectbox, $sidebarValue, $value, $valueContent, abilityName, addDueDate, fieldName, issueUpdateURL;
......@@ -38,6 +40,7 @@
});
addDueDate = function(isDropdown) {
var data, date, mediumDate, value;
// Create the post date
value = $("input[name='" + fieldName + "']").val();
if (value !== '') {
date = new Date(value.replace(new RegExp('-', 'g'), ','));
......
// Disable an element and add the 'disabled' Bootstrap class
(function() {
$.fn.extend({
disable: function() {
......@@ -5,6 +6,7 @@
}
});
// Enable an element and remove the 'disabled' Bootstrap class
$.fn.extend({
enable: function() {
return $(this).removeAttr('disabled').removeClass('disabled');
......
// Creates the variables for setting up GFM auto-completion
(function() {
if (window.GitLab == null) {
window.GitLab = {};
......@@ -8,18 +9,22 @@
dataLoaded: false,
cachedData: {},
dataSource: '',
// Emoji
Emoji: {
template: '<li>${name} <img alt="${name}" height="20" src="${path}" width="20" /></li>'
},
// Team Members
Members: {
template: '<li>${username} <small>${title}</small></li>'
},
Labels: {
template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>'
},
// Issues and MergeRequests
Issues: {
template: '<li><small>${id}</small> ${title}</li>'
},
// Milestones
Milestones: {
template: '<li>${title}</li>'
},
......@@ -48,8 +53,11 @@
}
},
setup: function(input) {
// Add GFM auto-completion to all input fields, that accept GFM input.
this.input = input || $('.js-gfm-input');
// destroy previous instances
this.destroyAtWho();
// set up instances
this.setupAtWho();
if (this.dataSource) {
if (!this.dataLoading && !this.cachedData) {
......@@ -63,6 +71,11 @@
return _this.loadData(data);
});
};
// We should wait until initializations are done
// and only trigger the last .setup since
// The previous .dataSource belongs to the previous issuable
// and the last one will have the **proper** .dataSource property
// TODO: Make this a singleton and turn off events when moving to another page
})(this), 1000);
}
if (this.cachedData != null) {
......@@ -71,6 +84,7 @@
}
},
setupAtWho: function() {
// Emoji
this.input.atwho({
at: ':',
displayTpl: (function(_this) {
......@@ -90,6 +104,7 @@
beforeInsert: this.DefaultOptions.beforeInsert
}
});
// Team Members
this.input.atwho({
at: '@',
displayTpl: (function(_this) {
......@@ -321,13 +336,22 @@
loadData: function(data) {
this.cachedData = data;
this.dataLoaded = true;
// load members
this.input.atwho('load', '@', data.members);
// load issues
this.input.atwho('load', 'issues', data.issues);
// load milestones
this.input.atwho('load', 'milestones', data.milestones);
// load merge requests
this.input.atwho('load', 'mergerequests', data.mergerequests);
// load emojis
this.input.atwho('load', ':', data.emojis);
// load labels
this.input.atwho('load', '~', data.labels);
// load commands
this.input.atwho('load', '/', data.commands);
// This trigger at.js again
// otherwise we would be stuck with loading until the user types
return $(':focus').trigger('keyup');
}
};
......
......@@ -21,12 +21,14 @@
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
this.indeterminateIds = [];
$clearButton.on('click', (function(_this) {
// Clear click
return function(e) {
e.preventDefault();
e.stopPropagation();
return _this.input.val('').trigger('keyup').focus();
};
})(this));
// Key events
timeout = "";
this.input
.on('keydown', function (e) {
......@@ -49,6 +51,7 @@
if (keyCode === 13 && !options.elIsInput) {
return false;
}
// Only filter asynchronously only if option remote is set
if (this.options.remote) {
clearTimeout(timeout);
return timeout = setTimeout(function() {
......@@ -79,11 +82,27 @@
if ((data != null) && !this.options.filterByText) {
results = data;
if (search_text !== '') {
// When data is an array of objects therefore [object Array] e.g.
// [
// { prop: 'foo' },
// { prop: 'baz' }
// ]
if (_.isArray(data)) {
results = fuzzaldrinPlus.filter(data, search_text, {
key: this.options.keys
});
} else {
// If data is grouped therefore an [object Object]. e.g.
// {
// groupName1: [
// { prop: 'foo' },
// { prop: 'baz' }
// ],
// groupName2: [
// { prop: 'abc' },
// { prop: 'def' }
// ]
// }
if (gl.utils.isObject(data)) {
results = {};
for (key in data) {
......@@ -140,6 +159,7 @@
this.options.beforeSend();
}
return this.dataEndpoint("", (function(_this) {
// Fetch the data by calling the data funcfion
return function(data) {
if (_this.options.success) {
_this.options.success(data);
......@@ -171,6 +191,7 @@
};
})(this)
});
// Fetch the data through ajax if the data is a string
};
return GitLabDropdownRemote;
......@@ -209,13 +230,18 @@
self = this;
selector = $(this.el).data("target");
this.dropdown = selector != null ? $(selector) : $(this.el).parent();
// Set Defaults
ref = this.options, this.filterInput = (ref1 = ref.filterInput) != null ? ref1 : this.getElement(FILTER_INPUT), this.highlight = (ref2 = ref.highlight) != null ? ref2 : false, this.filterInputBlur = (ref3 = ref.filterInputBlur) != null ? ref3 : true;
// If no input is passed create a default one
self = this;
// If selector was passed
if (_.isString(this.filterInput)) {
this.filterInput = this.getElement(this.filterInput);
}
searchFields = this.options.search ? this.options.search.fields : [];
if (this.options.data) {
// If we provided data
// data could be an array of objects or a group of arrays
if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) {
this.fullData = this.options.data;
currentIndex = -1;
......@@ -232,10 +258,12 @@
return _this.filter.input.trigger('keyup');
}
};
// Remote data
})(this)
});
}
}
// Init filterable
if (this.options.filterable) {
this.filter = new GitLabDropdownFilter(this.filterInput, {
elIsInput: $(this.el).is('input'),
......@@ -278,12 +306,14 @@
})(this)
});
}
// Event listeners
this.dropdown.on("shown.bs.dropdown", this.opened);
this.dropdown.on("hidden.bs.dropdown", this.hidden);
$(this.el).on("update.label", this.updateLabel);
this.dropdown.on("click", ".dropdown-menu, .dropdown-menu-close", this.shouldPropagate);
this.dropdown.on('keyup', (function(_this) {
return function(e) {
// Escape key
if (e.which === 27) {
return $('.dropdown-menu-close', _this.dropdown).trigger('click');
}
......@@ -327,6 +357,7 @@
}
}
// Finds an element inside wrapper element
GitLabDropdown.prototype.getElement = function(selector) {
return this.dropdown.find(selector);
};
......@@ -344,6 +375,7 @@
}
}
menu.toggleClass(PAGE_TWO_CLASS);
// Focus first visible input on active page
return this.dropdown.find('[class^="dropdown-page-"]:visible :text:visible:first').focus();
};
......@@ -351,23 +383,28 @@
var full_html, groupData, html, name;
this.renderedData = data;
if (this.options.filterable && data.length === 0) {
// render no matching results
html = [this.noResults()];
} else {
// Handle array groups
if (gl.utils.isObject(data)) {
html = [];
for (name in data) {
groupData = data[name];
html.push(this.renderItem({
header: name
// Add header for each group
}, name));
this.renderData(groupData, name).map(function(item) {
return html.push(item);
});
}
} else {
// Render each row
html = this.renderData(data);
}
}
// Render the full menu
full_html = this.renderMenu(html);
return this.appendMenu(full_html);
};
......@@ -406,6 +443,7 @@
if (this.options.setActiveIds) {
this.options.setActiveIds.call(this);
}
// Makes indeterminate items effective
if (this.fullData && this.dropdown.find('.dropdown-menu-toggle').hasClass('js-filter-bulk-update')) {
this.parseData(this.fullData);
}
......@@ -427,6 +465,8 @@
if (this.options.filterable) {
$input.blur().val("");
}
// Triggering 'keyup' will re-render the dropdown which is not always required
// specially if we want to keep the state of the dropdown needed for bulk-assignment
if (!this.options.persistWhenHide) {
$input.trigger("keyup");
}
......@@ -439,6 +479,7 @@
return this.dropdown.trigger('hidden.gl.dropdown');
};
// Render the full menu
GitLabDropdown.prototype.renderMenu = function(html) {
var menu_html;
menu_html = "";
......@@ -450,6 +491,7 @@
return menu_html;
};
// Append the menu into the dropdown
GitLabDropdown.prototype.appendMenu = function(html) {
var selector;
selector = '.dropdown-content';
......@@ -465,19 +507,24 @@
group = false;
}
if (index == null) {
// Render the row
index = false;
}
html = "";
// Divider
if (data === "divider") {
return "<li class='divider'></li>";
}
// Separator is a full-width divider
if (data === "separator") {
return "<li class='separator'></li>";
}
// Header
if (data.header != null) {
return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header });
}
if (this.options.renderRow) {
// Call the render function
html = this.options.renderRow.call(this.options, data, this);
} else {
if (!selected) {
......@@ -489,11 +536,13 @@
selected = true;
}
}
// Set URL
if (this.options.url != null) {
url = this.options.url(data);
} else {
url = data.url != null ? data.url : '#';
}
// Set Text
if (this.options.text != null) {
text = this.options.text(data);
} else {
......@@ -584,6 +633,7 @@
if (value == null) {
field.remove();
}
// Toggle active class for the tick mark
el.addClass(ACTIVE_CLASS);
if (value != null) {
if (!field.length && fieldName) {
......@@ -604,6 +654,7 @@
GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject) {
var $input;
// Create hidden input for form
$input = $('<input>').attr('type', 'hidden').attr('name', fieldName).val(value);
if (this.options.inputId != null) {
$input.attr('id', this.options.inputId);
......@@ -625,6 +676,7 @@
if (this.dropdown.find(".dropdown-toggle-page").length) {
selector = ".dropdown-page-one " + selector;
}
// simulate a click on the first link
$el = $(selector, this.dropdown);
if ($el.length) {
var href = $el.attr('href');
......@@ -653,11 +705,15 @@
e.stopImmediatePropagation();
PREV_INDEX = currentIndex;
$listItems = $(selector, _this.dropdown);
// if @options.filterable
// $input.blur()
if (currentKeyCode === 40) {
// Move down
if (currentIndex < ($listItems.length - 1)) {
currentIndex += 1;
}
} else if (currentKeyCode === 38) {
// Move up
if (currentIndex > 0) {
currentIndex -= 1;
}
......@@ -685,24 +741,32 @@
GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
var $dropdownContent, $listItem, dropdownContentBottom, dropdownContentHeight, dropdownContentTop, dropdownScrollTop, listItemBottom, listItemHeight, listItemTop;
// Remove the class for the previously focused row
$('.is-focused', this.dropdown).removeClass('is-focused');
// Update the class for the row at the specific index
$listItem = $listItems.eq(index);
$listItem.find('a:first-child').addClass("is-focused");
// Dropdown content scroll area
$dropdownContent = $listItem.closest('.dropdown-content');
dropdownScrollTop = $dropdownContent.scrollTop();
dropdownContentHeight = $dropdownContent.outerHeight();
dropdownContentTop = $dropdownContent.prop('offsetTop');
dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
// Get the offset bottom of the list item
listItemHeight = $listItem.outerHeight();
listItemTop = $listItem.prop('offsetTop');
listItemBottom = listItemTop + listItemHeight;
if (!index) {
// Scroll the dropdown content to the top
$dropdownContent.scrollTop(0)
} else if (index === ($listItems.length - 1)) {
// Scroll the dropdown content to the bottom
$dropdownContent.scrollTop($dropdownContent.prop('scrollHeight'));
} else if (listItemBottom > (dropdownContentBottom + dropdownScrollTop)) {
// Scroll the dropdown content down
$dropdownContent.scrollTop(listItemBottom - dropdownContentBottom + CURSOR_SELECT_SCROLL_PADDING);
} else if (listItemTop < (dropdownContentTop + dropdownScrollTop)) {
// Scroll the dropdown content up
return $dropdownContent.scrollTop(listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING);
}
};
......
......@@ -3,12 +3,15 @@
function GLForm(form) {
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
// Before we start, we should clean up any previous data for this form
this.destroy();
// Setup the form
this.setupForm();
this.form.data('gl-form', this);
}
GLForm.prototype.destroy = function() {
// Clean form listeners
this.clearEventListeners();
return this.form.data('gl-form', null);
};
......@@ -21,12 +24,15 @@
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
// remove notify commit author checkbox for non-commit notes
GitLab.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
new DropzoneInput(this.form);
autosize(this.textarea);
// form and textarea event listeners
this.addEventListeners();
gl.text.init(this.form);
}
// hide discard button
this.form.find('.js-note-discard').hide();
return this.form.show();
};
......
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
/*= require_tree . */
(function() {
}).call(this);
......@@ -204,6 +204,7 @@
function ContributorsAuthorGraph(data1) {
this.data = data1;
// Don't split graph size in half for mobile devices.
if ($(window).width() < 768) {
this.width = $('.content').width() - 80;
} else {
......
......@@ -53,6 +53,7 @@
return _this.formatSelection.apply(_this, args);
},
dropdownCssClass: "ajax-groups-dropdown",
// we do not want to escape markup since we are displaying html in results
escapeMarkup: function(m) {
return m;
}
......
......@@ -38,9 +38,11 @@
return $(document).off('click', '.js-label-filter-remove').on('click', '.js-label-filter-remove', function(e) {
var $button;
$button = $(this);
// Remove the label input box
$('input[name="label_name[]"]').filter(function() {
return this.value === $button.data('label');
}).remove();
// Submit the form to get new data
Issuable.filterResults($('.filter-form'));
return $('.js-label-select').trigger('update.label');
});
......
/*= require flash */
/*= require jquery.waitforimages */
/*= require task_list */
(function() {
......@@ -13,6 +9,7 @@
this.Issue = (function() {
function Issue() {
this.submitNoteForm = bind(this.submitNoteForm, this);
// Prevent duplicate event bindings
this.disableTaskList();
if ($('a.btn-close').length) {
this.initTaskList();
......@@ -99,6 +96,8 @@
url: $('form.js-issuable-update').attr('action'),
data: patchData
});
// TODO (rspeicher): Make the issue description inline-editable like a note so
// that we can re-use its form here
};
Issue.prototype.initMergeRequests = function() {
......@@ -128,6 +127,8 @@
Issue.prototype.initCanCreateBranch = function() {
var $container;
$container = $('#new-branch');
// If the user doesn't have the required permissions the container isn't
// rendered at all.
if ($container.length === 0) {
return;
}
......
(function() {
this.IssuableBulkActions = (function() {
function IssuableBulkActions(opts) {
// Set defaults
var ref, ref1, ref2;
if (opts == null) {
opts = {};
}
this.container = (ref = opts.container) != null ? ref : $('.content'), this.form = (ref1 = opts.form) != null ? ref1 : this.getElement('.bulk-update'), this.issues = (ref2 = opts.issues) != null ? ref2 : this.getElement('.issuable-list > li');
// Save instance
this.form.data('bulkActions', this);
this.willUpdateLabels = false;
this.bindEvents();
// Fixes bulk-assign not working when navigating through pages
Issuable.initChecks();
}
......@@ -86,6 +89,7 @@
ref1 = this.getLabelsFromSelection();
for (j = 0, len1 = ref1.length; j < len1; j++) {
id = ref1[j];
// Only the ones that we are not going to keep
if (labelsToKeep.indexOf(id) === -1) {
result.push(id);
}
......@@ -147,6 +151,8 @@
indeterminatedLabels = this.getUnmarkedIndeterminedLabels();
labelsToApply = this.getLabelsToApply();
indeterminatedLabels.map(function(id) {
// We need to exclude label IDs that will be applied
// By not doing this will cause issues from selection to not add labels at all
if (labelsToApply.indexOf(id) === -1) {
return result.push(id);
}
......
......@@ -26,13 +26,16 @@
var previewColor;
previewColor = $('input#label_color').val();
return $('div.label-color-preview').css('background-color', previewColor);
// Updates the the preview color with the hex-color input
};
// Updates the preview color with a click on a suggested color
Labels.prototype.setSuggestedColor = function(e) {
var color;
color = $(e.currentTarget).data('color');
$('input#label_color').val(color);
this.updateColorPreview();
// Notify the form, that color has changed
$('.label-form').trigger('keyup');
return e.preventDefault();
};
......
......@@ -156,11 +156,13 @@
selectedClass.push('is-indeterminate');
}
if (active.indexOf(label.id) !== -1) {
// Remove is-indeterminate class if the item will be marked as active
i = selectedClass.indexOf('is-indeterminate');
if (i !== -1) {
selectedClass.splice(i, 1);
}
selectedClass.push('is-active');
// Add input manually
instance.addInput(this.fieldName, label.id);
}
}
......@@ -172,6 +174,7 @@
}
if (label.duplicate) {
spacing = 100 / label.color.length;
// Reduce the colors to 4
label.color = label.color.filter(function(color, i) {
return i < 4;
});
......@@ -192,11 +195,13 @@
} else {
colorEl = '';
}
// We need to identify which items are actually labels
if (label.id) {
selectedClass.push('label-item');
$a.attr('data-label-id', label.id);
}
$a.addClass(selectedClass.join(' ')).html(colorEl + " " + label.title);
// Return generated html
return $li.html($a).prop('outerHTML');
},
persistWhenHide: $dropdown.data('persistWhenHide'),
......@@ -238,6 +243,7 @@
isIssueIndex = page === 'projects:issues:index';
isMRIndex = page === 'projects:merge_requests:index';
$selectbox.hide();
// display:block overrides the hide-collapse rule
$value.removeAttr('style');
if (page === 'projects:boards:show') {
return;
......@@ -255,6 +261,7 @@
}
}
if ($dropdown.hasClass('js-filter-bulk-update')) {
// If we are persisting state we need the classes
if (!this.options.persistWhenHide) {
return $dropdown.parent().find('.is-active, .is-indeterminate').removeClass();
}
......@@ -324,7 +331,9 @@
if ($('.selected_issue:checked').length) {
return;
}
// Remove inputs
$('.issues_bulk_update .labels-filter input[type="hidden"]').remove();
// Also restore button text
return $('.issues_bulk_update .labels-filter .dropdown-toggle-text').text('Label');
};
......
......@@ -3,5 +3,4 @@
(function() {
}).call(this);
......@@ -3,5 +3,4 @@
(function() {
}).call(this);
......@@ -3,5 +3,4 @@
(function() {
}).call(this);
/*= require raphael */
/*= require g.raphael */
/*= require g.bar */
(function() {
}).call(this);
......@@ -29,6 +29,7 @@
if (setTimeago) {
$timeagoEls.timeago();
$timeagoEls.tooltip('destroy');
// Recreate with custom template
return $timeagoEls.tooltip({
template: '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
});
......
gl.emojiAliases = ->
JSON.parse('<%= Gitlab::AwardEmoji.aliases.to_json %>')
(function() {
gl.emojiAliases = function() {
return JSON.parse('<%= Gitlab::AwardEmoji.aliases.to_json %>');
};
}).call(this);
......@@ -6,6 +6,7 @@
notification = new Notification(message, opts);
setTimeout(function() {
return notification.close();
// Hide the notification after X amount of seconds
}, 8000);
if (onclick) {
return notification.onclick = onclick;
......@@ -22,12 +23,16 @@
body: body,
icon: icon
};
// Let's check if the browser supports notifications
if (!('Notification' in window)) {
// do nothing
} else if (Notification.permission === 'granted') {
// If it's okay let's create a notification
return notificationGranted(message, opts, onclick);
} else if (Notification.permission !== 'denied') {
return Notification.requestPermission(function(permission) {
// If the user accepts, let's create a notification
if (permission === 'granted') {
return notificationGranted(message, opts, onclick);
}
......
......@@ -29,6 +29,7 @@
lineBefore = this.lineBefore(text, textArea);
lineAfter = this.lineAfter(text, textArea);
if (lineBefore === blockTag && lineAfter === blockTag) {
// To remove the block tag we have to select the line before & after
if (blockTag != null) {
textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1);
textArea.selectionEnd = textArea.selectionEnd + (blockTag.length + 1);
......@@ -63,11 +64,11 @@
if (!inserted) {
try {
document.execCommand("ms-beginUndoUnit");
} catch (undefined) {}
} catch (error) {}
textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText);
try {
document.execCommand("ms-endUndoUnit");
} catch (undefined) {}
} catch (error) {}
}
return this.moveCursor(textArea, tag, wrap);
};
......
......@@ -7,6 +7,8 @@
if ((base = w.gl).utils == null) {
base.utils = {};
}
// Returns an array containing the value(s) of the
// of the key passed as an argument
w.gl.utils.getParameterValues = function(sParam) {
var i, sPageURL, sParameterName, sURLVariables, values;
sPageURL = decodeURIComponent(window.location.search.substring(1));
......@@ -23,6 +25,8 @@
}
return values;
};
// @param {Object} params - url keys and value to merge
// @param {String} url
w.gl.utils.mergeUrlParams = function(params, url) {
var lastChar, newUrl, paramName, paramValue, pattern;
newUrl = decodeURIComponent(url);
......@@ -37,12 +41,14 @@
newUrl = "" + newUrl + (newUrl.indexOf('?') > 0 ? '&' : '?') + paramName + "=" + paramValue;
}
}
// Remove a trailing ampersand
lastChar = newUrl[newUrl.length - 1];
if (lastChar === '&') {
newUrl = newUrl.slice(0, -1);
}
return newUrl;
};
// removes parameter query string from url. returns the modified url
w.gl.utils.removeParamQueryString = function(url, param) {
var urlVariables, variables;
url = decodeURIComponent(url);
......
// LineHighlighter
//
// Handles single- and multi-line selection and highlight for blob views.
//
/*= require jquery.scrollTo */
//
// ### Example Markup
//
// <div id="blob-content-holder">
// <div class="file-content">
// <div class="line-numbers">
// <a href="#L1" id="L1" data-line-number="1">1</a>
// <a href="#L2" id="L2" data-line-number="2">2</a>
// <a href="#L3" id="L3" data-line-number="3">3</a>
// <a href="#L4" id="L4" data-line-number="4">4</a>
// <a href="#L5" id="L5" data-line-number="5">5</a>
// </div>
// <pre class="code highlight">
// <code>
// <span id="LC1" class="line">...</span>
// <span id="LC2" class="line">...</span>
// <span id="LC3" class="line">...</span>
// <span id="LC4" class="line">...</span>
// <span id="LC5" class="line">...</span>
// </code>
// </pre>
// </div>
// </div>
//
(function() {
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
this.LineHighlighter = (function() {
// CSS class applied to highlighted lines
LineHighlighter.prototype.highlightClass = 'hll';
// Internal copy of location.hash so we're not dependent on `location` in tests
LineHighlighter.prototype._hash = '';
function LineHighlighter(hash) {
var range;
if (hash == null) {
// Initialize a LineHighlighter object
//
// hash - String URL hash for dependency injection in tests
hash = location.hash;
}
this.setHash = bind(this.setHash, this);
......@@ -24,6 +56,8 @@
if (range[0]) {
this.highlightRange(range);
$.scrollTo("#L" + range[0], {
// Scroll to the first highlighted line on initial load
// Offset -50 for the sticky top bar, and another -100 for some context
offset: -150
});
}
......@@ -32,6 +66,12 @@
LineHighlighter.prototype.bindEvents = function() {
$('#blob-content-holder').on('mousedown', 'a[data-line-number]', this.clickHandler);
// While it may seem odd to bind to the mousedown event and then throw away
// the click event, there is a method to our madness.
//
// If not done this way, the line number anchor will sometimes keep its
// active state even when the event is cancelled, resulting in an ugly border
// around the link and/or a persisted underline text decoration.
return $('#blob-content-holder').on('click', 'a[data-line-number]', function(event) {
return event.preventDefault();
});
......@@ -44,6 +84,8 @@
lineNumber = $(event.target).closest('a').data('line-number');
current = this.hashToRange(this._hash);
if (!(current[0] && event.shiftKey)) {
// If there's no current selection, or there is but Shift wasn't held,
// treat this like a single-line selection.
this.setHash(lineNumber);
return this.highlightLine(lineNumber);
} else if (event.shiftKey) {
......@@ -59,10 +101,23 @@
LineHighlighter.prototype.clearHighlight = function() {
return $("." + this.highlightClass).removeClass(this.highlightClass);
// Unhighlight previously highlighted lines
};
// Convert a URL hash String into line numbers
//
// hash - Hash String
//
// Examples:
//
// hashToRange('#L5') # => [5, null]
// hashToRange('#L5-15') # => [5, 15]
// hashToRange('#foo') # => [null, null]
//
// Returns an Array
LineHighlighter.prototype.hashToRange = function(hash) {
var first, last, matches;
//?L(\d+)(?:-(\d+))?$/)
matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/);
if (matches && matches.length) {
first = parseInt(matches[1]);
......@@ -73,10 +128,16 @@
}
};
// Highlight a single line
//
// lineNumber - Line number to highlight
LineHighlighter.prototype.highlightLine = function(lineNumber) {
return $("#LC" + lineNumber).addClass(this.highlightClass);
};
// Highlight all lines within a range
//
// range - Array containing the starting and ending line numbers
LineHighlighter.prototype.highlightRange = function(range) {
var i, lineNumber, ref, ref1, results;
if (range[1]) {
......@@ -90,6 +151,7 @@
}
};
// Set the URL hash string
LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
var hash;
if (lastLineNumber) {
......@@ -101,10 +163,15 @@
return this.__setLocationHash__(hash);
};
// Make the actual hash change in the browser
//
// This method is stubbed in tests.
LineHighlighter.prototype.__setLocationHash__ = function(value) {
return history.pushState({
turbolinks: false,
url: value
// We're using pushState instead of assigning location.hash directly to
// prevent the page from scrolling on the hashchange event
}, document.title, value);
};
......
/*= require jquery.waitforimages */
/*= require task_list */
/*= require merge_request_tabs */
(function() {
......@@ -12,6 +8,11 @@
this.MergeRequest = (function() {
function MergeRequest(opts) {
// Initialize MergeRequest behavior
//
// Options:
// action - String, current controller action
//
this.opts = opts != null ? opts : {};
this.submitNoteForm = bind(this.submitNoteForm, this);
this.$el = $('.merge-request');
......@@ -21,6 +22,7 @@
};
})(this));
this.initTabs();
// Prevent duplicate event bindings
this.disableTaskList();
this.initMRBtnListeners();
if ($("a.btn-close").length) {
......@@ -28,14 +30,17 @@
}
}
// Local jQuery finder
MergeRequest.prototype.$ = function(selector) {
return this.$el.find(selector);
};
MergeRequest.prototype.initTabs = function() {
if (this.opts.action !== 'new') {
// `MergeRequests#new` has no tab-persisting or lazy-loading behavior
window.mrTabs = new MergeRequestTabs(this.opts);
} else {
// Show the first tab (Commits)
return $('.merge-request-tabs a[data-toggle="tab"]:first').tab('show');
}
};
......@@ -96,6 +101,8 @@
url: $('form.js-issuable-update').attr('action'),
data: patchData
});
// TODO (rspeicher): Make the merge request description inline-editable like a
// note so that we can re-use its form here
};
return MergeRequest;
......
// MergeRequestTabs
//
// Handles persisting and restoring the current tab selection and lazily-loading
// content on the MergeRequests#show page.
//
/*= require jquery.cookie */
//
// ### Example Markup
//
// <ul class="nav-links merge-request-tabs">
// <li class="notes-tab active">
// <a data-action="notes" data-target="#notes" data-toggle="tab" href="/foo/bar/merge_requests/1">
// Discussion
// </a>
// </li>
// <li class="commits-tab">
// <a data-action="commits" data-target="#commits" data-toggle="tab" href="/foo/bar/merge_requests/1/commits">
// Commits
// </a>
// </li>
// <li class="diffs-tab">
// <a data-action="diffs" data-target="#diffs" data-toggle="tab" href="/foo/bar/merge_requests/1/diffs">
// Diffs
// </a>
// </li>
// </ul>
//
// <div class="tab-content">
// <div class="notes tab-pane active" id="notes">
// Notes Content
// </div>
// <div class="commits tab-pane" id="commits">
// Commits Content
// </div>
// <div class="diffs tab-pane" id="diffs">
// Diffs Content
// </div>
// </div>
//
// <div class="mr-loading-status">
// <div class="loading">
// Loading Animation
// </div>
// </div>
//
(function() {
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
......@@ -19,6 +62,7 @@
this.setCurrentAction = bind(this.setCurrentAction, this);
this.tabShown = bind(this.tabShown, this);
this.showTab = bind(this.showTab, this);
// Store the `location` object, allowing for easier stubbing in tests
this._location = location;
this.bindEvents();
this.activateTab(this.opts.action);
......@@ -77,6 +121,7 @@
}
};
// Activate a tab based on the current action
MergeRequestTabs.prototype.activateTab = function(action) {
if (action === 'show') {
action = 'notes';
......@@ -84,20 +129,48 @@
return $(".merge-request-tabs a[data-action='" + action + "']").tab('show');
};
// Replaces the current Merge Request-specific action in the URL with a new one
//
// If the action is "notes", the URL is reset to the standard
// `MergeRequests#show` route.
//
// Examples:
//
// location.pathname # => "/namespace/project/merge_requests/1"
// setCurrentAction('diffs')
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
//
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
// setCurrentAction('notes')
// location.pathname # => "/namespace/project/merge_requests/1"
//
// location.pathname # => "/namespace/project/merge_requests/1/diffs"
// setCurrentAction('commits')
// location.pathname # => "/namespace/project/merge_requests/1/commits"
//
// Returns the new URL String
MergeRequestTabs.prototype.setCurrentAction = function(action) {
var new_state;
// Normalize action, just to be safe
if (action === 'show') {
action = 'notes';
}
this.currentAction = action;
// Remove a trailing '/commits' or '/diffs'
new_state = this._location.pathname.replace(/\/(commits|diffs|builds|pipelines)(\.html)?\/?$/, '');
// Append the new action if we're on a tab other than 'notes'
if (action !== 'notes') {
new_state += "/" + action;
}
// Ensure parameters and hash come along for the ride
new_state += this._location.search + this._location.hash;
history.replaceState({
turbolinks: true,
url: new_state
// Replace the current history state with the new one without breaking
// Turbolinks' history.
//
// See https://github.com/rails/turbolinks/issues/363
}, document.title, new_state);
return new_state;
};
......@@ -206,6 +279,9 @@
});
};
// Show or hide the loading spinner
//
// status - Boolean, true to show, false to hide
MergeRequestTabs.prototype.toggleLoading = function(status) {
return $('.mr-loading-status .loading').toggle(status);
};
......@@ -232,6 +308,7 @@
MergeRequestTabs.prototype.diffViewType = function() {
return $('.inline-parallel-buttons a.active').data('view-type');
// Returns diff view type
};
MergeRequestTabs.prototype.expandViewContainer = function() {
......@@ -245,6 +322,8 @@
if ($gutterIcon.is('.fa-angle-double-right')) {
return $gutterIcon.closest('a').trigger('click', [true]);
}
// Wait until listeners are set
// Only when sidebar is expanded
}, 0);
};
......@@ -259,6 +338,9 @@
return $gutterIcon.closest('a').trigger('click', [true]);
}
}, 0);
// Expand the issuable sidebar unless the user explicitly collapsed it
// Wait until listeners are set
// Only when sidebar is collapsed
};
return MergeRequestTabs;
......
......@@ -3,6 +3,12 @@
this.MergeRequestWidget = (function() {
function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior
//
// check_enable - Boolean, whether to check automerge status
// merge_check_url - String, URL to use to check automerge status
// ci_status_url - String, URL to use to check CI status
//
this.opts = opts;
$('#modal_merge_info').modal({
show: false
......@@ -135,6 +141,8 @@
if (data.coverage) {
_this.showCICoverage(data.coverage);
}
// The first check should only update the UI, a notification
// should only be displayed on status changes
if (showNotification && !_this.firstCICheck) {
status = _this.ciLabelForStatus(data.status);
if (status === "preparing") {
......
......@@ -110,6 +110,7 @@
},
update: function(event, ui) {
var data;
// Prevents sorting from container which element has been removed.
if ($(this).find(ui.item).length > 0) {
data = $(this).sortable("serialize");
return Milestone.sortIssues(data);
......
......@@ -92,6 +92,7 @@
},
hidden: function() {
$selectbox.hide();
// display:block overrides the hide-collapse rule
return $value.css('display', '');
},
clicked: function(selected, $el, e) {
......
......@@ -90,6 +90,7 @@
results = [];
while (k < this.mspace) {
this.colors.push(Raphael.getColor(.8));
// Skipping a few colors in the spectrum to get more contrast between colors
Raphael.getColor();
Raphael.getColor();
results.push(k++);
......@@ -112,6 +113,7 @@
for (mm = j = 0, len = ref.length; j < len; mm = ++j) {
day = ref[mm];
if (cuday !== day[0] || cumonth !== day[1]) {
// Dates
r.text(55, this.offsetY + this.unitTime * mm, day[0]).attr({
font: "12px Monaco, monospace",
fill: "#BBB"
......@@ -119,6 +121,7 @@
cuday = day[0];
}
if (cumonth !== day[1]) {
// Months
r.text(20, this.offsetY + this.unitTime * mm, day[1]).attr({
font: "12px Monaco, monospace",
fill: "#EEE"
......@@ -207,6 +210,7 @@
}
r = this.r;
shortrefs = commit.refs;
// Truncate if longer than 15 chars
if (shortrefs.length > 17) {
shortrefs = shortrefs.substr(0, 15) + "";
}
......@@ -217,6 +221,7 @@
title: commit.refs
});
textbox = text.getBBox();
// Create rectangle based on the size of the textbox
rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr({
fill: "#000",
"fill-opacity": .5,
......@@ -229,6 +234,7 @@
});
label = r.set(rect, text);
label.transform(["t", -rect.getBBox().width - 15, 0]);
// Set text to front
return text.toFront();
};
......@@ -283,11 +289,13 @@
parentY = this.offsetY + this.unitTime * parentCommit.time;
parentX1 = this.offsetX + this.unitSpace * (this.mspace - parentCommit.space);
parentX2 = this.offsetX + this.unitSpace * (this.mspace - parent[1]);
// Set line color
if (parentCommit.space <= commit.space) {
color = this.colors[commit.space];
} else {
color = this.colors[parentCommit.space];
}
// Build line shape
if (parent[1] === commit.space) {
offset = [0, 5];
arrow = "l-2,5,4,0,-2,-5,0,5";
......@@ -298,13 +306,17 @@
offset = [-3, 3];
arrow = "l-5,0,2,4,3,-4,-4,2";
}
// Start point
route = ["M", x + offset[0], y + offset[1]];
// Add arrow if not first parent
if (i > 0) {
route.push(arrow);
}
// Circumvent if overlap
if (commit.space !== parentCommit.space || commit.space !== parent[1]) {
route.push("L", parentX2, y + 10, "L", parentX2, parentY - 5);
}
// End point
route.push("L", parentX1, parentY);
results.push(r.path(route).attr({
stroke: color,
......@@ -325,6 +337,7 @@
"fill-opacity": .5,
stroke: "none"
});
// Displayed in the center
return this.element.scrollTop(y - this.graphHeight / 2);
}
};
......
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
/*= require_tree . */
(function() {
......
/*= require autosave */
/*= require autosize */
/*= require dropzone */
/*= require dropzone_input */
/*= require gfm_auto_complete */
/*= require jquery.atwho */
/*= require task_list */
(function() {
......@@ -60,26 +48,43 @@
}
Notes.prototype.addBinding = function() {
// add note to UI after creation
$(document).on("ajax:success", ".js-main-target-form", this.addNote);
$(document).on("ajax:success", ".js-discussion-note-form", this.addDiscussionNote);
// catch note ajax errors
$(document).on("ajax:error", ".js-main-target-form", this.addNoteError);
// change note in UI after update
$(document).on("ajax:success", "form.edit-note", this.updateNote);
// Edit note link
$(document).on("click", ".js-note-edit", this.showEditForm);
$(document).on("click", ".note-edit-cancel", this.cancelEdit);
// Reopen and close actions for Issue/MR combined with note form submit
$(document).on("click", ".js-comment-button", this.updateCloseButton);
$(document).on("keyup input", ".js-note-text", this.updateTargetButtons);
// resolve a discussion
$(document).on('click', '.js-comment-resolve-button', this.resolveDiscussion);
// remove a note (in general)
$(document).on("click", ".js-note-delete", this.removeNote);
// delete note attachment
$(document).on("click", ".js-note-attachment-delete", this.removeAttachment);
// reset main target form after submit
$(document).on("ajax:complete", ".js-main-target-form", this.reenableTargetFormSubmitButton);
$(document).on("ajax:success", ".js-main-target-form", this.resetMainTargetForm);
// reset main target form when clicking discard
$(document).on("click", ".js-note-discard", this.resetMainTargetForm);
// update the file name when an attachment is selected
$(document).on("change", ".js-note-attachment-input", this.updateFormAttachment);
// reply to diff/discussion notes
$(document).on("click", ".js-discussion-reply-button", this.replyToDiscussionNote);
// add diff note
$(document).on("click", ".js-add-diff-note-button", this.addDiffNote);
// hide diff note form
$(document).on("click", ".js-close-discussion-note-form", this.cancelDiscussionForm);
// fetch notes when tab becomes visible
$(document).on("visibilitychange", this.visibilityChange);
// when issue status changes, we need to refresh data
$(document).on("issuable:change", this.refresh);
// when a key is clicked on the notes
return $(document).on("keydown", ".js-note-text", this.keydownNoteText);
};
......@@ -112,6 +117,7 @@
return;
}
$textarea = $(e.target);
// Edit previous note when UP arrow is hit
switch (e.which) {
case 38:
if ($textarea.val() !== '') {
......@@ -123,6 +129,7 @@
return myLastNoteEditBtn.trigger('click', [true, myLastNote]);
}
break;
// Cancel creating diff note or editing any note when ESCAPE is hit
case 27:
discussionNoteForm = $textarea.closest('.js-discussion-note-form');
if (discussionNoteForm.length) {
......@@ -247,10 +254,13 @@
votesBlock = $('.js-awards-block').eq(0);
gl.awardsHandler.addAwardToEmojiBar(votesBlock, note.name);
return gl.awardsHandler.scrollToAwards();
// render note if it not present in loaded list
// or skip if rendered
} else if (this.isNewNote(note)) {
this.note_ids.push(note.id);
$notesList = $('ul.main-notes-list');
$notesList.append(note.html).syntaxHighlight();
// Update datetime format on the recent note
gl.utils.localTimeAgo($notesList.find("#note_" + note.id + " .js-timeago"), false);
this.initTaskList();
this.refresh();
......@@ -291,19 +301,26 @@
row = form.closest("tr");
note_html = $(note.html);
note_html.syntaxHighlight();
// is this the first note of discussion?
discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']");
if ((note.original_discussion_id != null) && discussionContainer.length === 0) {
discussionContainer = $(".notes[data-discussion-id='" + note.original_discussion_id + "']");
}
if (discussionContainer.length === 0) {
// insert the note and the reply button after the temp row
row.after(note.diff_discussion_html);
// remove the note (will be added again below)
row.next().find(".note").remove();
// Before that, the container didn't exist
discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']");
// Add note to 'Changes' page discussions
discussionContainer.append(note_html);
// Init discussion on 'Discussion' page if it is merge request page
if ($('body').attr('data-page').indexOf('projects:merge_request') === 0) {
$('ul.main-notes-list').append(note.discussion_html).syntaxHighlight();
}
} else {
// append new note to all matching discussions
discussionContainer.append(note_html);
}
......@@ -327,7 +344,9 @@
Notes.prototype.resetMainTargetForm = function(e) {
var form;
form = $(".js-main-target-form");
// remove validation errors
form.find(".js-errors").remove();
// reset text and preview
form.find(".js-md-write-button").click();
form.find(".js-note-text").val("").trigger("input");
form.find(".js-note-text").data("autosave").reset();
......@@ -354,9 +373,13 @@
Notes.prototype.setupMainTargetNoteForm = function() {
var form;
// find the form
form = $(".js-new-note-form");
// Set a global clone of the form for later cloning
this.formClone = form.clone();
// show the form
this.setupNoteForm(form);
// fix classes
form.removeClass("js-new-note-form");
form.addClass("js-main-target-form");
form.find("#note_line_code").remove();
......@@ -421,6 +444,7 @@
}
this.renderDiscussionNote(note);
// cleanup after successfully creating a diff/discussion note
this.removeDiscussionNoteForm($form);
};
......@@ -433,10 +457,12 @@
Notes.prototype.updateNote = function(_xhr, note, _status) {
var $html, $note_li;
// Convert returned HTML to a jQuery object so we can modify it further
$html = $(note.html);
gl.utils.localTimeAgo($('.js-timeago', $html));
$html.syntaxHighlight();
$html.find('.js-task-list-container').taskList('enable');
// Find the note's `li` element by ID and replace it with the updated HTML
$note_li = $('.note-row-' + note.id);
$note_li.replaceWith($html);
......@@ -461,15 +487,20 @@
note.addClass("is-editting");
form = note.find(".note-edit-form");
form.addClass('current-note-edit-form');
// Show the attachment delete link
note.find(".js-note-attachment-delete").show();
done = function($noteText) {
var noteTextVal;
// Neat little trick to put the cursor at the end
noteTextVal = $noteText.val();
// Store the original note text in a data attribute to retrieve if a user cancels edit.
form.find('form.edit-note').data('original-note', noteTextVal);
return $noteText.val('').val(noteTextVal);
};
new GLForm(form);
if ((scrollTo != null) && (myLastNote != null)) {
// scroll to the bottom
// so the open of the last element doesn't make a jump
$('html, body').scrollTop($(document).height());
return $('html, body').animate({
scrollTop: myLastNote.offset().top - 150
......@@ -505,6 +536,7 @@
form = note.find(".current-note-edit-form");
note.removeClass("is-editting");
form.removeClass("current-note-edit-form");
// Replace markdown textarea text with original note text.
return form.find(".js-note-text").val(form.find('form.edit-note').data('original-note'));
};
......@@ -520,6 +552,9 @@
var noteId;
noteId = $(e.currentTarget).closest(".note").attr("id");
$(".note[id='" + noteId + "']").each((function(_this) {
// A same note appears in the "Discussion" and in the "Changes" tab, we have
// to remove all. Using $(".note[id='noteId']") ensure we get all the notes,
// where $("#noteId") would return only one.
return function(i, el) {
var note, notes;
note = $(el);
......@@ -533,13 +568,17 @@
}
}
// check if this is the last note for this line
if (notes.find(".note").length === 1) {
// "Discussions" tab
notes.closest(".timeline-entry").remove();
// "Changes" tab / commit view
notes.closest("tr").remove();
}
return note.remove();
};
})(this));
// Decrement the "Discussions" counter only once
return this.updateNotesCount(-1);
};
......@@ -571,10 +610,12 @@
var form, replyLink;
form = this.formClone.clone();
replyLink = $(e.target).closest(".js-discussion-reply-button");
// insert the form after the button
replyLink
.closest('.discussion-reply-holder')
.hide()
.after(form);
// show the form
return this.setupDiscussionNoteForm(replyLink, form);
};
......@@ -589,6 +630,7 @@
*/
Notes.prototype.setupDiscussionNoteForm = function(dataHolder, form) {
// setup note target
form.attr('id', "new-discussion-note-form-" + (dataHolder.data("discussionId")));
form.attr("data-line-code", dataHolder.data("lineCode"));
form.find("#note_type").val(dataHolder.data("noteType"));
......@@ -636,6 +678,7 @@
addForm = false;
notesContentSelector = ".notes_content";
rowCssToAdd = "<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line\" colspan=\"2\"></td><td class=\"notes_content\"><div class=\"content\"></div></td></tr>";
// In parallel view, look inside the correct left/right pane
if (this.isParallelView()) {
lineType = $link.data("lineType");
notesContentSelector += "." + lineType;
......@@ -652,6 +695,7 @@
e.target = replyButton[0];
$.proxy(this.replyToDiscussionNote, replyButton[0], e).call();
} else {
// In parallel view, the form may not be present in one of the panes
noteForm = notesContent.find(".js-discussion-note-form");
if (noteForm.length === 0) {
addForm = true;
......@@ -659,6 +703,7 @@
}
}
} else {
// add a notes row and insert the form
row.after(rowCssToAdd);
nextRow = row.next();
notesContent = nextRow.find(notesContentSelector);
......@@ -667,6 +712,7 @@
if (addForm) {
newForm = this.formClone.clone();
newForm.appendTo(notesContent);
// show the form
return this.setupDiscussionNoteForm($link, newForm);
}
};
......@@ -685,12 +731,15 @@
glForm = form.data('gl-form');
glForm.destroy();
form.find(".js-note-text").data("autosave").reset();
// show the reply button (will only work for replies)
form
.prev('.discussion-reply-holder')
.show();
if (row.is(".js-temp-notes-holder")) {
// remove temporary row for diff lines
return row.remove();
} else {
// only remove the form
return form.remove();
}
};
......@@ -712,6 +761,7 @@
Notes.prototype.updateFormAttachment = function() {
var filename, form;
form = $(this).closest("form");
// get only the basename
filename = $(this).val().replace(/^.*[\\\/]/, "");
return form.find(".js-attachment-filename").text(filename);
};
......
// MarkdownPreview
//
// Handles toggling the "Write" and "Preview" tab clicks, rendering the preview,
// and showing a warning when more than `x` users are referenced.
//
(function() {
var lastTextareaPreviewed, markdownPreview, previewButtonSelector, writeButtonSelector;
this.MarkdownPreview = (function() {
function MarkdownPreview() {}
// Minimum number of users referenced before triggering a warning
MarkdownPreview.prototype.referenceThreshold = 10;
MarkdownPreview.prototype.ajaxCache = {};
......@@ -101,8 +107,10 @@
return;
}
lastTextareaPreviewed = $form.find('textarea.markdown-area');
// toggle tabs
$form.find(writeButtonSelector).parent().removeClass('active');
$form.find(previewButtonSelector).parent().addClass('active');
// toggle content
$form.find('.md-write-holder').hide();
$form.find('.md-preview-holder').show();
return markdownPreview.showPreview($form);
......@@ -113,8 +121,10 @@
return;
}
lastTextareaPreviewed = null;
// toggle tabs
$form.find(writeButtonSelector).parent().addClass('active');
$form.find(previewButtonSelector).parent().removeClass('active');
// toggle content
$form.find('.md-write-holder').show();
$form.find('textarea.markdown-area').focus();
return $form.find('.md-preview-holder').hide();
......
......@@ -5,6 +5,7 @@
GitLabCrop = (function() {
var FILENAMEREGEX;
// Matches everything but the file name
FILENAMEREGEX = /^.*[\\\/]/;
function GitLabCrop(input, opts) {
......@@ -17,11 +18,18 @@
this.onModalShow = bind(this.onModalShow, this);
this.onPickImageClick = bind(this.onPickImageClick, this);
this.fileInput = $(input);
// We should rename to avoid spec to fail
// Form will submit the proper input filed with a file using FormData
this.fileInput.attr('name', (this.fileInput.attr('name')) + "-trigger").attr('id', (this.fileInput.attr('id')) + "-trigger");
// Set defaults
this.exportWidth = (ref = opts.exportWidth) != null ? ref : 200, this.exportHeight = (ref1 = opts.exportHeight) != null ? ref1 : 200, this.cropBoxWidth = (ref2 = opts.cropBoxWidth) != null ? ref2 : 200, this.cropBoxHeight = (ref3 = opts.cropBoxHeight) != null ? ref3 : 200, this.form = (ref4 = opts.form) != null ? ref4 : this.fileInput.parents('form'), this.filename = opts.filename, this.previewImage = opts.previewImage, this.modalCrop = opts.modalCrop, this.pickImageEl = opts.pickImageEl, this.uploadImageBtn = opts.uploadImageBtn, this.modalCropImg = opts.modalCropImg;
// Required params
// Ensure needed elements are jquery objects
// If selector is provided we will convert them to a jQuery Object
this.filename = this.getElement(this.filename);
this.previewImage = this.getElement(this.previewImage);
this.pickImageEl = this.getElement(this.pickImageEl);
// Modal elements usually are outside the @form element
this.modalCrop = _.isString(this.modalCrop) ? $(this.modalCrop) : this.modalCrop;
this.uploadImageBtn = _.isString(this.uploadImageBtn) ? $(this.uploadImageBtn) : this.uploadImageBtn;
this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg;
......@@ -93,8 +101,8 @@
return this.modalCropImg.attr('src', '').cropper('destroy');
};
GitLabCrop.prototype.onUploadImageBtnClick = function(e) {
e.preventDefault();
GitLabCrop.prototype.onUploadImageBtnClick = function(e) { // Remove attached image
e.preventDefault(); // Destroy cropper instance
this.setBlob();
this.setPreview();
this.modalCrop.modal('hide');
......
......@@ -11,9 +11,11 @@
this.form = (ref = opts.form) != null ? ref : $('.edit-user');
$('.js-preferences-form').on('change.preference', 'input[type=radio]', function() {
return $(this).parents('form').submit();
// Automatically submit the Preferences form when any of its radio buttons change
});
$('#user_notification_email').on('change', function() {
return $(this).parents('form').submit();
// Automatically submit email form when it changes
});
$('.update-username').on('ajax:before', function() {
$('.loading-username').show();
......@@ -76,6 +78,7 @@
},
complete: function() {
window.scrollTo(0, 0);
// Enable submit button after requests ends
return self.form.find(':input[disabled]').enable();
}
});
......@@ -93,6 +96,7 @@
if (comment && comment.length > 1 && $title.val() === '') {
return $title.val(comment[1]).change();
}
// Extract the SSH Key title from its comment
});
if (gl.utils.getPagePath() === 'profiles') {
return new Profile();
......
......@@ -3,5 +3,4 @@
(function() {
}).call(this);
......@@ -11,7 +11,13 @@
url = $("#project_clone").val();
$('#project_clone').val(url);
return $('.clone').text(url);
// Git protocol switcher
// Remove the active class for all buttons (ssh, http, kerberos if shown)
// Add the active class for the clicked button
// Update the input field
// Update the command line instructions
});
// Ref switcher
this.initRefSwitcher();
$('.project-refs-select').on('change', function() {
return $(this).parents('form').submit();
......
......@@ -13,8 +13,11 @@
this.selectRowUp = bind(this.selectRowUp, this);
this.filePaths = {};
this.inputElement = this.element.find(".file-finder-input");
// init event
this.initEvent();
// focus text input box
this.inputElement.focus();
// load file list
this.load(this.options.url);
}
......@@ -42,6 +45,7 @@
}
}
});
// init event
};
ProjectFindFile.prototype.findFile = function() {
......@@ -49,8 +53,10 @@
searchText = this.inputElement.val();
result = searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
return this.renderList(result, searchText);
// find file
};
// files pathes load
ProjectFindFile.prototype.load = function(url) {
return $.ajax({
url: url,
......@@ -67,6 +73,7 @@
});
};
// render result
ProjectFindFile.prototype.renderList = function(filePaths, searchText) {
var blobItemUrl, filePath, html, i, j, len, matches, results;
this.element.find(".tree-table > tbody").empty();
......@@ -86,6 +93,7 @@
return results;
};
// highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
highlighter = function(element, text, matches) {
var highlightText, j, lastIndex, len, matchIndex, matchedChars, unmatched;
lastIndex = 0;
......@@ -110,6 +118,7 @@
return element.append(document.createTextNode(text.substring(lastIndex)));
};
// make tbody row html
ProjectFindFile.prototype.makeHtml = function(filePath, matches, blobItemUrl) {
var $tr;
$tr = $("<tr class='tree-item'><td class='tree-item-file-name'><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'><a></a></span></td></tr>");
......
......@@ -7,3 +7,5 @@
})();
}).call(this);
// I kept class for future
......@@ -33,6 +33,7 @@
$('.projects-list-holder').replaceWith(data.html);
return history.replaceState({
page: project_filter_url
// Change url so if user reload a page - search results are saved
}, document.title, project_filter_url);
},
dataType: "json"
......
......@@ -43,6 +43,12 @@
});
}
onClickCreateWildcard() {
// Refresh the dropdown's data, which ends up calling `getProtectedBranches`
this.$dropdown.data('glDropdown').remote.execute();
this.$dropdown.data('glDropdown').selectRowAtIndex(0);
}
bindEvents() {
this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this));
}
......
......@@ -24,6 +24,7 @@
this.onSearchInputKeyUp = bind(this.onSearchInputKeyUp, this);
this.onSearchInputKeyDown = bind(this.onSearchInputKeyDown, this);
this.wrap = (ref = opts.wrap) != null ? ref : $('.search'), this.optsEl = (ref1 = opts.optsEl) != null ? ref1 : this.wrap.find('.search-autocomplete-opts'), this.autocompletePath = (ref2 = opts.autocompletePath) != null ? ref2 : this.optsEl.data('autocomplete-path'), this.projectId = (ref3 = opts.projectId) != null ? ref3 : this.optsEl.data('autocomplete-project-id') || '', this.projectRef = (ref4 = opts.projectRef) != null ? ref4 : this.optsEl.data('autocomplete-project-ref') || '';
// Dropdown Element
this.dropdown = this.wrap.find('.dropdown');
this.dropdownContent = this.dropdown.find('.dropdown-content');
this.locationBadgeEl = this.getElement('.location-badge');
......@@ -35,6 +36,7 @@
this.repositoryInputEl = this.getElement('#repository_ref');
this.clearInput = this.getElement('.js-clear-input');
this.saveOriginalState();
// Only when user is logged in
if (gon.current_user_id) {
this.createAutocomplete();
}
......@@ -43,6 +45,7 @@
this.bindEvents();
}
// Finds an element inside wrapper element
SearchAutocomplete.prototype.getElement = function(selector) {
return this.wrap.find(selector);
};
......@@ -82,6 +85,7 @@
}
return;
}
// Prevent multiple ajax calls
if (this.loadingSuggestions) {
return;
}
......@@ -92,14 +96,17 @@
term: term
}, function(response) {
var data, firstCategory, i, lastCategory, len, suggestion;
// Hide dropdown menu if no suggestions returns
if (!response.length) {
_this.disableAutocomplete();
return;
}
data = [];
// List results
firstCategory = true;
for (i = 0, len = response.length; i < len; i++) {
suggestion = response[i];
// Add group header before list each group
if (lastCategory !== suggestion.category) {
if (!firstCategory) {
data.push('separator');
......@@ -119,6 +126,7 @@
url: suggestion.url
});
}
// Add option to proceed with the search
if (data.length) {
data.push('separator');
data.push({
......@@ -169,11 +177,13 @@
SearchAutocomplete.prototype.serializeState = function() {
return {
// Search Criteria
search_project_id: this.projectInputEl.val(),
group_id: this.groupInputEl.val(),
search_code: this.searchCodeInputEl.val(),
repository_ref: this.repositoryInputEl.val(),
scope: this.scopeInputEl.val(),
// Location badge
_location: this.locationBadgeEl.text()
};
};
......@@ -194,6 +204,7 @@
SearchAutocomplete.prototype.enableAutocomplete = function() {
var _this;
// No need to enable anything if user is not logged in
if (!gon.current_user_id) {
return;
}
......@@ -206,18 +217,22 @@
};
SearchAutocomplete.prototype.onSearchInputKeyDown = function() {
// Saves last length of the entered text
return this.saveTextLength();
};
SearchAutocomplete.prototype.onSearchInputKeyUp = function(e) {
switch (e.keyCode) {
case KEYCODE.BACKSPACE:
// when trying to remove the location badge
if (this.lastTextLength === 0 && this.badgePresent()) {
this.removeLocationBadge();
}
// When removing the last character and no badge is present
if (this.lastTextLength === 1) {
this.disableAutocomplete();
}
// When removing any character from existin value
if (this.lastTextLength > 1) {
this.enableAutocomplete();
}
......@@ -232,9 +247,12 @@
case KEYCODE.DOWN:
return;
default:
// Handle the case when deleting the input value other than backspace
// e.g. Pressing ctrl + backspace or ctrl + x
if (this.searchInput.val() === '') {
this.disableAutocomplete();
} else {
// We should display the menu only when input is not empty
if (e.keyCode !== KEYCODE.ENTER) {
this.enableAutocomplete();
}
......@@ -243,7 +261,9 @@
this.wrap.toggleClass('has-value', !!e.target.value);
};
// Avoid falsy value to be returned
SearchAutocomplete.prototype.onSearchInputClick = function(e) {
// Prevents closing the dropdown menu
return e.stopImmediatePropagation();
};
......@@ -267,6 +287,7 @@
SearchAutocomplete.prototype.onSearchInputBlur = function(e) {
this.isFocused = false;
this.wrap.removeClass('search-active');
// If input is blank then restore state
if (this.searchInput.val() === '') {
return this.restoreOriginalState();
}
......@@ -311,6 +332,7 @@
results = [];
for (i = 0, len = inputs.length; i < len; i++) {
input = inputs[i];
// _location isnt a input
if (input === '_location') {
break;
}
......
......@@ -86,6 +86,7 @@
var defaultStopCallback;
defaultStopCallback = Mousetrap.stopCallback;
return function(e, element, combo) {
// allowed shortcuts if textarea, input, contenteditable are focused
if (['ctrl+shift+p', 'command+shift+p'].indexOf(combo) !== -1) {
return false;
} else {
......
......@@ -14,8 +14,10 @@
ShortcutsFindFile.__super__.constructor.call(this);
_oldStopCallback = Mousetrap.stopCallback;
Mousetrap.stopCallback = (function(_this) {
// override to fire shortcuts action when focus in textbox
return function(event, element, combo) {
if (element === _this.projectFindFile.inputElement[0] && (combo === 'up' || combo === 'down' || combo === 'esc' || combo === 'enter')) {
// when press up/down key in textbox, cusor prevent to move to home/end
event.preventDefault();
return false;
}
......
/*= require mousetrap */
/*= require shortcuts_navigation */
(function() {
......@@ -43,16 +41,20 @@
if (selected.trim() === "") {
return;
}
// Put a '>' character before each non-empty line in the selection
quote = _.map(selected.split("\n"), function(val) {
if (val.trim() !== '') {
return "> " + val + "\n";
}
});
// If replyField already has some content, add a newline before our quote
separator = replyField.val().trim() !== "" && "\n" || '';
replyField.val(function(_, current) {
return current + separator + quote.join('') + "\n";
});
// Trigger autosave for the added text
replyField.trigger('input');
// Focus the input field
return replyField.focus();
}
};
......
// Syntax Highlighter
//
// Applies a syntax highlighting color scheme CSS class to any element with the
// `js-syntax-highlight` class
//
// ### Example Markup
//
// <div class="js-syntax-highlight"></div>
//
(function() {
$.fn.syntaxHighlight = function() {
var $children;
if ($(this).hasClass('js-syntax-highlight')) {
// Given the element itself, apply highlighting
return $(this).addClass(gon.user_color_scheme);
} else {
// Given a parent element, recurse to any of its applicable children
$children = $(this).find('.js-syntax-highlight');
if ($children.length) {
return $children.syntaxHighlight();
......
......@@ -129,16 +129,21 @@
var currPage, currPages, newPages, pageParams, url;
currPages = this.getTotalPages();
currPage = this.getCurrentPage();
// Refresh if no remaining Todos
if (!total) {
location.reload();
return;
}
// Do nothing if no pagination
if (!currPages) {
return;
}
newPages = Math.ceil(total / this.getTodosPerPage());
// Includes query strings
url = location.href;
// If new total of pages is different than we have now
if (newPages !== currPages) {
// Redirect to previous page if there's one available
if (currPages > 1 && currPage === currPages) {
pageParams = {
page: currPages - 1
......@@ -155,6 +160,7 @@
if (!todoLink) {
return;
}
// Allow Meta-Click or Mouse3-click to open in a new tab
if (e.metaKey || e.which === 2) {
e.preventDefault();
return window.open(todoLink, '_blank');
......
......@@ -2,6 +2,8 @@
this.TreeView = (function() {
function TreeView() {
this.initKeyNav();
// Code browser tree slider
// Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$(".tree-content-holder .tree-item").on('click', function(e) {
var $clickedEl, path;
$clickedEl = $(e.target);
......@@ -15,6 +17,7 @@
}
}
});
// Show the "Loading commit data" for only the first element
$('span.log_loading:first').removeClass('hide');
}
......
// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
//
// State Flow #1: setup -> in_progress -> authenticated -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
(function() {
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
......@@ -15,6 +19,17 @@
this.appId = u2fParams.app_id;
this.challenge = u2fParams.challenge;
this.signRequests = u2fParams.sign_requests.map(function(request) {
// The U2F Javascript API v1.1 requires a single challenge, with
// _no challenges per-request_. The U2F Javascript API v1.0 requires a
// challenge per-request, which is done by copying the single challenge
// into every request.
//
// In either case, we don't need the per-request challenges that the server
// has generated, so we can remove them.
//
// Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
// This can be removed once we upgrade.
// https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
return _(request).omit('challenge');
});
}
......@@ -41,6 +56,7 @@
})(this), 10);
};
// Rendering #
U2FAuthenticate.prototype.templates = {
"notSupported": "#js-authenticate-u2f-not-supported",
"setup": '#js-authenticate-u2f-setup',
......@@ -75,6 +91,8 @@
U2FAuthenticate.prototype.renderAuthenticated = function(deviceResponse) {
this.renderTemplate('authenticated');
// Prefer to do this instead of interpolating using Underscore templates
// because of JSON escaping issues.
return this.container.find("#js-device-response").val(deviceResponse);
};
......
// Register U2F (universal 2nd factor) devices for users to authenticate with.
//
// State Flow #1: setup -> in_progress -> registered -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
(function() {
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
......@@ -39,6 +43,7 @@
})(this), 10);
};
// Rendering #
U2FRegister.prototype.templates = {
"notSupported": "#js-register-u2f-not-supported",
"setup": '#js-register-u2f-setup',
......@@ -73,6 +78,8 @@
U2FRegister.prototype.renderRegistered = function(deviceResponse) {
this.renderTemplate('registered');
// Prefer to do this instead of interpolating using Underscore templates
// because of JSON escaping issues.
return this.container.find("#js-device-response").val(deviceResponse);
};
......
// UserTabs
//
// Handles persisting and restoring the current tab selection and lazily-loading
// content on the Users#show page.
//
// ### Example Markup
//
// <ul class="nav-links">
// <li class="activity-tab active">
// <a data-action="activity" data-target="#activity" data-toggle="tab" href="/u/username">
// Activity
// </a>
// </li>
// <li class="groups-tab">
// <a data-action="groups" data-target="#groups" data-toggle="tab" href="/u/username/groups">
// Groups
// </a>
// </li>
// <li class="contributed-tab">
// <a data-action="contributed" data-target="#contributed" data-toggle="tab" href="/u/username/contributed">
// Contributed projects
// </a>
// </li>
// <li class="projects-tab">
// <a data-action="projects" data-target="#projects" data-toggle="tab" href="/u/username/projects">
// Personal projects
// </a>
// </li>
// <li class="snippets-tab">
// <a data-action="snippets" data-target="#snippets" data-toggle="tab" href="/u/username/snippets">
// </a>
// </li>
// </ul>
//
// <div class="tab-content">
// <div class="tab-pane" id="activity">
// Activity Content
// </div>
// <div class="tab-pane" id="groups">
// Groups Content
// </div>
// <div class="tab-pane" id="contributed">
// Contributed projects content
// </div>
// <div class="tab-pane" id="projects">
// Projects content
// </div>
// <div class="tab-pane" id="snippets">
// Snippets content
// </div>
// </div>
//
// <div class="loading-status">
// <div class="loading">
// Loading Animation
// </div>
// </div>
//
(function() {
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
......@@ -6,18 +64,23 @@
this.tabShown = bind(this.tabShown, this);
var i, item, len, ref, ref1, ref2, ref3;
this.action = (ref = opts.action) != null ? ref : 'activity', this.defaultAction = (ref1 = opts.defaultAction) != null ? ref1 : 'activity', this.parentEl = (ref2 = opts.parentEl) != null ? ref2 : $(document);
// Make jQuery object if selector is provided
if (typeof this.parentEl === 'string') {
this.parentEl = $(this.parentEl);
}
// Store the `location` object, allowing for easier stubbing in tests
this._location = location;
// Set tab states
this.loaded = {};
ref3 = this.parentEl.find('.nav-links a');
for (i = 0, len = ref3.length; i < len; i++) {
item = ref3[i];
this.loaded[$(item).attr('data-action')] = false;
}
// Actions
this.actions = Object.keys(this.loaded);
this.bindEvents();
// Set active tab
if (this.action === 'show') {
this.action = this.defaultAction;
}
......@@ -25,6 +88,7 @@
}
UserTabs.prototype.bindEvents = function() {
// Toggle event listeners
return this.parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]').on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', this.tabShown);
};
......@@ -74,6 +138,7 @@
tabSelector = 'div#' + action;
_this.parentEl.find(tabSelector).html(data.html);
_this.loaded[action] = true;
// Fix tooltips
return gl.utils.localTimeAgo($('.js-timeago', tabSelector));
};
})(this)
......@@ -97,13 +162,17 @@
UserTabs.prototype.setCurrentAction = function(action) {
var new_state, regExp;
// Remove possible actions from URL
regExp = new RegExp('\/(' + this.actions.join('|') + ')(\.html)?\/?$');
new_state = this._location.pathname;
// remove trailing slashes
new_state = new_state.replace(/\/+$/, "");
new_state = new_state.replace(regExp, '');
// Append the new action if we're on a tab other than 'activity'
if (action !== this.defaultAction) {
new_state += "/" + action;
}
// Ensure parameters and hash come along for the ride
new_state += this._location.search + this._location.hash;
history.replaceState({
turbolinks: true,
......
......@@ -11,6 +11,8 @@
this.daySizeWithSpace = this.daySize + (this.daySpace * 2);
this.monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
this.months = [];
// Loop through the timestamps to create a group of objects
// The group of objects will be grouped based on the day of the week they are
this.timestampsTmp = [];
var group = 0;
......@@ -29,12 +31,15 @@
var day = date.getDay();
var count = timestamps[date.getTime() * 0.001];
// Create a new group array if this is the first day of the week
// or if is first object
if ((day === 0 && i !== 0) || i === 0) {
this.timestampsTmp.push([]);
group++;
}
var innerArray = this.timestampsTmp[group - 1];
// Push to the inner array the values that will be used to render map
innerArray.push({
count: count || 0,
date: date,
......@@ -42,8 +47,10 @@
});
}
// Init color functions
this.colorKey = this.initColorKey();
this.color = this.initColor();
// Init the svg element
this.renderSvg(group);
this.renderDays();
this.renderMonths();
......
......@@ -3,5 +3,4 @@
(function() {
}).call(this);
......@@ -81,6 +81,7 @@
if (term.length === 0) {
showDivider = 0;
if (firstUser) {
// Move current user to the front of the list
for (index = j = 0, len = users.length; j < len; index = ++j) {
obj = users[index];
if (obj.username === firstUser) {
......@@ -115,6 +116,7 @@
if (showDivider) {
users.splice(showDivider, 0, "divider");
}
// Send the data back
return callback(users);
});
},
......@@ -139,6 +141,7 @@
inputId: 'issue_assignee_id',
hidden: function(e) {
$selectbox.hide();
// display:block overrides the hide-collapse rule
return $value.css('display', '');
},
clicked: function(user, $el, e) {
......@@ -177,6 +180,7 @@
img = "<img src='" + avatar + "' class='avatar avatar-inline' width='30' />";
}
}
// split into three parts so we can remove the username section if nessesary
listWithName = "<li> <a href='#' class='dropdown-menu-user-link " + selected + "'> " + img + " <strong class='dropdown-menu-user-full-name'> " + user.name + " </strong>";
listWithUserName = "<span class='dropdown-menu-user-username'> " + username + " </span>";
listClosingTags = "</a> </li>";
......@@ -215,6 +219,7 @@
};
if (query.term.length === 0) {
if (firstUser) {
// Move current user to the front of the list
ref = data.results;
for (index = j = 0, len = ref.length; j < len; index = ++j) {
obj = ref[index];
......@@ -271,6 +276,7 @@
return _this.formatSelection.apply(_this, args);
},
dropdownCssClass: "ajax-users-dropdown",
// we do not want to escape markup since we are displaying html in results
escapeMarkup: function(m) {
return m;
}
......@@ -318,6 +324,8 @@
});
};
// Return users list. Filtered by query
// Only active users retrieved
UsersSelect.prototype.users = function(query, options, callback) {
var url;
url = this.buildUrl(this.usersPath);
......
// Zen Mode (full screen) textarea
//
/*= provides zen_mode:enter */
/*= provides zen_mode:leave */
//
/*= require jquery.scrollTo */
/*= require dropzone */
/*= require mousetrap */
/*= require mousetrap/pause */
//
// ### Events
//
// `zen_mode:enter`
//
// Fired when the "Edit in fullscreen" link is clicked.
//
// **Synchronicity** Sync
// **Bubbles** Yes
// **Cancelable** No
// **Target** a.js-zen-enter
//
// `zen_mode:leave`
//
// Fired when the "Leave Fullscreen" link is clicked.
//
// **Synchronicity** Sync
// **Bubbles** Yes
// **Cancelable** No
// **Target** a.js-zen-leave
//
(function() {
this.ZenMode = (function() {
function ZenMode() {
......@@ -40,6 +53,7 @@
};
})(this));
$(document).on('keydown', function(e) {
// Esc
if (e.keyCode === 27) {
e.preventDefault();
return $(document).trigger('zen_mode:leave');
......@@ -52,6 +66,7 @@
this.active_backdrop = $(backdrop);
this.active_backdrop.addClass('fullscreen');
this.active_textarea = this.active_backdrop.find('textarea');
// Prevent a user-resized textarea from persisting to fullscreen
this.active_textarea.removeAttr('style');
return this.active_textarea.focus();
};
......
......@@ -62,6 +62,7 @@ module AuthenticatesWithTwoFactor
session.delete(:otp_user_id)
session.delete(:challenges)
remember_me(user) if user_params[:remember_me] == '1'
sign_in(user)
else
flash.now[:alert] = 'Authentication via U2F device failed.'
......
......@@ -154,7 +154,7 @@ class ApplicationSetting < ActiveRecord::Base
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
domain_whitelist: Settings.gitlab['domain_whitelist'],
import_sources: %w[github bitbucket gitlab google_code fogbugz git gitlab_project],
import_sources: Gitlab::ImportSources.values,
shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
max_artifacts_size: Settings.artifacts['max_size'],
require_two_factor_authentication: false,
......
......@@ -12,6 +12,7 @@ class Service < ActiveRecord::Base
default_value_for :tag_push_events, true
default_value_for :note_events, true
default_value_for :build_events, true
default_value_for :pipeline_events, true
default_value_for :wiki_page_events, true
after_initialize :initialize_properties
......
......@@ -18,6 +18,5 @@
= f.submit "Verify code", class: "btn btn-save"
- if @user.two_factor_u2f_enabled?
%hr
= render "u2f/authenticate"
= render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name }
......@@ -3,6 +3,7 @@
- diverging_commit_counts = @repository.diverging_commit_counts(branch)
- number_commits_behind = diverging_commit_counts[:behind]
- number_commits_ahead = diverging_commit_counts[:ahead]
- merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
%li(class="js-branch-#{branch.name}")
%div
= link_to namespace_project_tree_path(@project.namespace, @project, branch.name), class: 'item-title str-truncated' do
......@@ -25,12 +26,12 @@
diverged from upstream
.controls.hidden-xs
- if create_mr_button?(@repository.root_ref, branch.name)
- if merge_project && create_mr_button?(@repository.root_ref, branch.name)
= link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do
Merge Request
- if branch.name != @repository.root_ref
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: 'btn btn-default', method: :post, title: "Compare" do
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: "btn btn-default #{'prepend-left-10' unless merge_project}", method: :post, title: "Compare" do
Compare
= render 'projects/buttons/download', project: @project, ref: branch.name
......
......@@ -20,6 +20,8 @@
%div
%p We heard back from your U2F device. Click this button to authenticate with the GitLab server.
= form_tag(new_user_session_path, method: :post) do |f|
- resource_params = params[resource_name].presence || params
= hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0)
= hidden_field_tag 'user[device_response]', nil, class: 'form-control', required: true, id: "js-device-response"
= submit_tag "Authenticate via U2F Device", class: "btn btn-success"
......
## 7.14.3
- No changes
## 7.14.2
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
- Allow configuration of LDAP attributes GitLab will use for the new user account.
## 7.14.1
- Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Disabled DNS lookups for SSH in docker image (Rowan Wookey)
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks
## 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests.
- Update default robots.txt rules to disallow crawling of irrelevant pages (Ben Bodenmiller)
- Fix redirection after sign in when using auto_sign_in_with_provider
- Upgrade gitlab_git to 7.2.14 to ignore CRLFs in .gitmodules (Stan Hu)
- Clear cache to prevent listing deleted branches after MR removes source branch (Stan Hu)
- Provide more feedback what went wrong if HipChat service failed test (Stan Hu)
- Fix bug where backslashes in inline diffs could be dropped (Stan Hu)
- Disable turbolinks when linking to Bitbucket import status (Stan Hu)
- Fix broken code import and display error messages if something went wrong with creating project (Stan Hu)
- Fix corrupted binary files when using API files endpoint (Stan Hu)
- Bump Haml to 4.0.7 to speed up textarea rendering (Stan Hu)
- Show incompatible projects in Bitbucket import status (Stan Hu)
- Fix coloring of diffs on MR Discussion-tab (Gert Goet)
- Fix "Network" and "Graphs" pages for branches with encoded slashes (Stan Hu)
- Fix errors deleting and creating branches with encoded slashes (Stan Hu)
- Always add current user to autocomplete controller to support filter by "Me" (Stan Hu)
- Fix multi-line syntax highlighting (Stan Hu)
- Fix network graph when branch name has single quotes (Stan Hu)
- Add "Confirm user" button in user admin page (Stan Hu)
- Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu)
- Add support for Unicode filenames in relative links (Hiroyuki Sato)
- Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki)
- Fix commit data retrieval when branch name has single quotes (Stan Hu)
- Check that project was actually created rather than just validated in import:repos task (Stan Hu)
- Fix full screen mode for snippet comments (Daniel Gerhardt)
- Fix 404 error in files view after deleting the last file in a repository (Stan Hu)
- Fix the "Reload with full diff" URL button (Stan Hu)
- Fix label read access for unauthenticated users (Daniel Gerhardt)
- Fix access to disabled features for unauthenticated users (Daniel Gerhardt)
- Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu)
- Fix file upload dialog for comment editing (Daniel Gerhardt)
- Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu)
- Return comments in created order in merge request API (Stan Hu)
- Disable internal issue tracker controller if external tracker is used (Stan Hu)
- Expire Rails cache entries after two weeks to prevent endless Redis growth
- Add support for destroying project milestones (Stan Hu)
- Allow custom backup archive permissions
- Add project star and fork count, group avatar URL and user/group web URL attributes to API
- Show who last edited a comment if it wasn't the original author
- Send notification to all participants when MR is merged.
- Add ability to manage user email addresses via the API.
- Show buttons to add license, changelog and contribution guide if they're missing.
- Tweak project page buttons.
- Disabled autocapitalize and autocorrect on login field (Daryl Chan)
- Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis)
- Update gravatar link on profile page to link to configured gravatar host (Ben Bodenmiller)
- Remove redis-store TTL monkey patch
- Add support for CI skipped status
- Fetch code from forks to refs/merge-requests/:id/head when merge request created
- Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg)
- Add "Check out branch" button to the MR page.
- Improve MR merge widget text and UI consistency.
- Improve text in MR "How To Merge" modal.
- Cache all events
- Order commits by date when comparing branches
- Fix bug causing error when the target branch of a symbolic ref was deleted
- Include branch/tag name in archive file and directory name
- Add dropzone upload progress
- Add a label for merged branches on branches page (Florent Baldino)
- Detect .mkd and .mkdn files as markdown (Ben Boeckel)
- Fix: User search feature in admin area does not respect filters
- Set max-width for README, issue and merge request description for easier read on big screens
- Update Flowdock integration to support new Flowdock API (Boyan Tabakov)
- Remove author from files view (Sven Strickroth)
- Fix infinite loop when SAML was incorrectly configured.
## 7.13.5
- Satellites reverted
## 7.13.4
- Allow users to send abuse reports
## 7.13.3
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
- Allow users to send abuse reports
- Remove satellites
- Link username to profile on Group Members page (Tom Webster)
## 7.13.2
- Fix randomly failed spec
- Create project services on Project creation
- Add admin_merge_request ability to Developer level and up
- Fix Error 500 when browsing projects with no HEAD (Stan Hu)
- Fix labels / assignee / milestone for the merge requests when issues are disabled
- Show the first tab automatically on MergeRequests#new
- Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt)
- Fix Gmail Actions
## 7.13.1
- Fix: Label modifications are not reflected in existing notes and in the issue list
- Fix: Label not shown in the Issue list, although it's set through web interface
- Fix: Group/project references are linked incorrectly
- Improve documentation
- Fix of migration: Check if session_expire_delay column exists before adding the column
- Fix: ActionView::Template::Error
- Fix: "Create Merge Request" isn't always shown in event for newly pushed branch
- Fix bug causing "Remove source-branch" option not to work for merge requests from the same project.
- Render Note field hints consistently for "new" and "edit" forms
## 7.13.0
- Remove repository graph log to fix slow cache updates after push event (Stan Hu)
- Only enable HSTS header for HTTPS and port 443 (Stan Hu)
- Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu)
- Fix redirection to home page URL for unauthorized users (Daniel Gerhardt)
- Add branch switching support for graphs (Daniel Gerhardt)
- Fix external issue tracker hook/test for HTTPS URLs (Daniel Gerhardt)
- Remove link leading to a 404 error in Deploy Keys page (Stan Hu)
- Add support for unlocking users in admin settings (Stan Hu)
- Add Irker service configuration options (Stan Hu)
- Fix order of issues imported from GitHub (Hiroyuki Sato)
- Bump rugments to 1.0.0beta8 to fix C prototype function highlighting (Jonathon Reinhart)
- Fix Merge Request webhook to properly fire "merge" action when accepted from the web UI
- Add `two_factor_enabled` field to admin user API (Stan Hu)
- Fix invalid timestamps in RSS feeds (Rowan Wookey)
- Fix downloading of patches on public merge requests when user logged out (Stan Hu)
- Fix Error 500 when relative submodule resolves to a namespace that has a different name from its path (Stan Hu)
- Extract the longest-matching ref from a commit path when multiple matches occur (Stan Hu)
- Update maintenance documentation to explain no need to recompile asssets for omnibus installations (Stan Hu)
- Support commenting on diffs in side-by-side mode (Stan Hu)
- Fix JavaScript error when clicking on the comment button on a diff line that has a comment already (Stan Hu)
- Return 40x error codes if branch could not be deleted in UI (Stan Hu)
- Remove project visibility icons from dashboard projects list
- Rename "Design" profile settings page to "Preferences".
- Allow users to customize their default Dashboard page.
- Update ssl_ciphers in Nginx example to remove DHE settings. This will deny forward secrecy for Android 2.3.7, Java 6 and OpenSSL 0.9.8
- Admin can edit and remove user identities
- Convert CRLF newlines to LF when committing using the web editor.
- API request /projects/:project_id/merge_requests?state=closed will return only closed merge requests without merged one. If you need ones that were merged - use state=merged.
- Allow Administrators to filter the user list by those with or without Two-factor Authentication enabled.
- Show a user's Two-factor Authentication status in the administration area.
- Explicit error when commit not found in the CI
- Improve performance for issue and merge request pages
- Users with guest access level can not set assignee, labels or milestones for issue and merge request
- Reporter role can manage issue tracker now: edit any issue, set assignee or milestone and manage labels
- Better performance for pages with events list, issues list and commits list
- Faster automerge check and merge itself when source and target branches are in same repository
- Correctly show anonymous authorized applications under Profile > Applications.
- Query Optimization in MySQL.
- Allow users to be blocked and unblocked via the API
- Use native Postgres database cleaning during backup restore
- Redesign project page. Show README as default instead of activity. Move project activity to separate page
- Make left menu more hierarchical and less contextual by adding back item at top
- A fork can’t have a visibility level that is greater than the original project.
- Faster code search in repository and wiki. Fixes search page timeout for big repositories
- Allow administrators to disable 2FA for a specific user
- Add error message for SSH key linebreaks
- Store commits count in database (will populate with valid values only after first push)
- Rebuild cache after push to repository in background job
- Fix transferring of project to another group using the API.
## 7.12.2
- Correctly show anonymous authorized applications under Profile > Applications.
- Faster automerge check and merge itself when source and target branches are in same repository
- Audit log for user authentication
- Allow custom label to be set for authentication providers.
## 7.12.1
- Fix error when deleting a user who has projects (Stan Hu)
- Fix post-receive errors on a push when an external issue tracker is configured (Stan Hu)
- Add SAML to list of social_provider (Matt Firtion)
- Fix merge requests API scope to keep compatibility in 7.12.x patch release (Dmitriy Zaporozhets)
- Fix closed merge request scope at milestone page (Dmitriy Zaporozhets)
- Revert merge request states renaming
- Fix hooks for web based events with external issue references (Daniel Gerhardt)
- Improve performance for issue and merge request pages
- Compress database dumps to reduce backup size
## 7.12.0
- Fix Error 500 when one user attempts to access a personal, internal snippet (Stan Hu)
- Disable changing of target branch in new merge request page when a branch has already been specified (Stan Hu)
- Fix post-receive errors on a push when an external issue tracker is configured (Stan Hu)
- Update oauth button logos for Twitter and Google to recommended assets
- Update browser gem to version 0.8.0 for IE11 support (Stan Hu)
- Fix timeout when rendering file with thousands of lines.
- Add "Remember me" checkbox to LDAP signin form.
- Add session expiration delay configuration through UI application settings
- Don't notify users mentioned in code blocks or blockquotes.
- Omit link to generate labels if user does not have access to create them (Stan Hu)
- Show warning when a comment will add 10 or more people to the discussion.
- Disable changing of the source branch in merge request update API (Stan Hu)
- Shorten merge request WIP text.
- Add option to disallow users from registering any application to use GitLab as an OAuth provider
- Support editing target branch of merge request (Stan Hu)
- Refactor permission checks with issues and merge requests project settings (Stan Hu)
- Fix Markdown preview not working in Edit Milestone page (Stan Hu)
- Fix Zen Mode not closing with ESC key (Stan Hu)
- Allow HipChat API version to be blank and default to v2 (Stan Hu)
- Add file attachment support in Milestone description (Stan Hu)
- Fix milestone "Browse Issues" button.
- Set milestone on new issue when creating issue from index with milestone filter active.
- Make namespace API available to all users (Stan Hu)
- Add webhook support for note events (Stan Hu)
- Disable "New Issue" and "New Merge Request" buttons when features are disabled in project settings (Stan Hu)
- Remove Rack Attack monkey patches and bump to version 4.3.0 (Stan Hu)
- Fix clone URL losing selection after a single click in Safari and Chrome (Stan Hu)
- Fix git blame syntax highlighting when different commits break up lines (Stan Hu)
- Add "Resend confirmation e-mail" link in profile settings (Stan Hu)
- Allow to configure location of the `.gitlab_shell_secret` file. (Jakub Jirutka)
- Disabled expansion of top/bottom blobs for new file diffs
- Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka)
- Fix resolving of relative links to repository files in AsciiDoc documents. (Jakub Jirutka)
- Use the user list from the target project in a merge request (Stan Hu)
- Default extention for wiki pages is now .md instead of .markdown (Jeroen van Baarsen)
- Add validation to wiki page creation (only [a-zA-Z0-9/_-] are allowed) (Jeroen van Baarsen)
- Fix new/empty milestones showing 100% completion value (Jonah Bishop)
- Add a note when an Issue or Merge Request's title changes
- Consistently refer to MRs as either Merged or Closed.
- Add Merged tab to MR lists.
- Prefix EmailsOnPush email subject with `[Git]`.
- Group project contributions by both name and email.
- Clarify navigation labels for Project Settings and Group Settings.
- Move user avatar and logout button to sidebar
- You can not remove user if he/she is an only owner of group
- User should be able to leave group. If not - show him proper message
- User has ability to leave project
- Add SAML support as an omniauth provider
- Allow to configure a URL to show after sign out
- Add an option to automatically sign-in with an Omniauth provider
- GitLab CI service sends .gitlab-ci.yml in each push call
- When remove project - move repository and schedule it removal
- Improve group removing logic
- Trigger create-hooks on backup restore task
- Add option to automatically link omniauth and LDAP identities
- Allow special character in users bio. I.e.: I <3 GitLab
## 7.11.4
- Fix missing bullets when creating lists
- Set rel="nofollow" on external links
## 7.11.3
- no changes
- Fix upgrader script (Martins Polakovs)
## 7.11.2
- no changes
## 7.11.1
- no changes
## 7.11.0
- Fall back to Plaintext when Syntaxhighlighting doesn't work. Fixes some buggy lexers (Hannes Rosenögger)
- Get editing comments to work in Chrome 43 again.
- Fix broken view when viewing history of a file that includes a path that used to be another file (Stan Hu)
- Don't show duplicate deploy keys
- Fix commit time being displayed in the wrong timezone in some cases (Hannes Rosenögger)
- Make the first branch pushed to an empty repository the default HEAD (Stan Hu)
- Fix broken view when using a tag to display a tree that contains git submodules (Stan Hu)
- Make Reply-To config apply to change e-mail confirmation and other Devise notifications (Stan Hu)
- Add application setting to restrict user signups to e-mail domains (Stan Hu)
- Don't allow a merge request to be merged when its title starts with "WIP".
- Add a page title to every page.
- Allow primary email to be set to an email that you've already added.
- Fix clone URL field and X11 Primary selection (Dmitry Medvinsky)
- Ignore invalid lines in .gitmodules
- Fix "Cannot move project" error message from popping up after a successful transfer (Stan Hu)
- Redirect to sign in page after signing out.
- Fix "Hello @username." references not working by no longer allowing usernames to end in period.
- Fix "Revspec not found" errors when viewing diffs in a forked project with submodules (Stan Hu)
- Improve project page UI
- Fix broken file browsing with relative submodule in personal projects (Stan Hu)
- Add "Reply quoting selected text" shortcut key (`r`)
- Fix bug causing `@whatever` inside an issue's first code block to be picked up as a user mention.
- Fix bug causing `@whatever` inside an inline code snippet (backtick-style) to be picked up as a user mention.
- When use change branches link at MR form - save source branch selection instead of target one
- Improve handling of large diffs
- Added GitLab Event header for project hooks
- Add Two-factor authentication (2FA) for GitLab logins
- Show Atom feed buttons everywhere where applicable.
- Add project activity atom feed.
- Don't crash when an MR from a fork has a cross-reference comment from the target project on one of its commits.
- Explain how to get a new password reset token in welcome emails
- Include commit comments in MR from a forked project.
- Group milestones by title in the dashboard and all other issue views.
- Query issues, merge requests and milestones with their IID through API (Julien Bianchi)
- Add default project and snippet visibility settings to the admin web UI.
- Show incompatible projects in Google Code import status (Stan Hu)
- Fix bug where commit data would not appear in some subdirectories (Stan Hu)
- Task lists are now usable in comments, and will show up in Markdown previews.
- Fix bug where avatar filenames were not actually deleted from the database during removal (Stan Hu)
- Fix bug where Slack service channel was not saved in admin template settings. (Stan Hu)
- Protect OmniAuth request phase against CSRF.
- Don't send notifications to mentioned users that don't have access to the project in question.
- Add search issues/MR by number
- Change plots to bar graphs in commit statistics screen
- Move snippets UI to fluid layout
- Improve UI for sidebar. Increase separation between navigation and content
- Improve new project command options (Ben Bodenmiller)
- Add common method to force UTF-8 and use it to properly handle non-ascii OAuth user properties (Onur Küçük)
- Prevent sending empty messages to HipChat (Chulki Lee)
- Improve UI for mobile phones on dashboard and project pages
- Add room notification and message color option for HipChat
- Allow to use non-ASCII letters and dashes in project and namespace name. (Jakub Jirutka)
- Add footnotes support to Markdown (Guillaume Delbergue)
- Add current_sign_in_at to UserFull REST api.
- Make Sidekiq MemoryKiller shutdown signal configurable
- Add "Create Merge Request" buttons to commits and branches pages and push event.
- Show user roles by comments.
- Fix automatic blocking of auto-created users from Active Directory.
- Call merge request webhook for each new commits (Arthur Gautier)
- Use SIGKILL by default in Sidekiq::MemoryKiller
- Fix mentioning of private groups.
- Add style for <kbd> element in markdown
- Spin spinner icon next to "Checking for CI status..." on MR page.
- Fix reference links in dashboard activity and ATOM feeds.
- Ensure that the first added admin performs repository imports
## 7.10.4
- Fix migrations broken in 7.10.2
- Make tags for GitLab installations running on MySQL case sensitive
- Get Gitorious importer to work again.
- Fix adding new group members from admin area
- Fix DB error when trying to tag a repository (Stan Hu)
- Fix Error 500 when searching Wiki pages (Stan Hu)
- Unescape branch names in compare commit (Stan Hu)
- Order commit comments chronologically in API.
## 7.10.2
- Fix CI links on MR page
## 7.10.0
- Ignore submodules that are defined in .gitmodules but are checked in as directories.
- Allow projects to be imported from Google Code.
- Remove access control for uploaded images to fix broken images in emails (Hannes Rosenögger)
- Allow users to be invited by email to join a group or project.
- Don't crash when project repository doesn't exist.
- Add config var to block auto-created LDAP users.
- Don't use HTML ellipsis in EmailsOnPush subject truncated commit message.
- Set EmailsOnPush reply-to address to committer email when enabled.
- Fix broken file browsing with a submodule that contains a relative link (Stan Hu)
- Fix persistent XSS vulnerability around profile website URLs.
- Fix project import URL regex to prevent arbitary local repos from being imported.
- Fix directory traversal vulnerability around uploads routes.
- Fix directory traversal vulnerability around help pages.
- Don't leak existence of project via search autocomplete.
- Don't leak existence of group or project via search.
- Fix bug where Wiki pages that included a '/' were no longer accessible (Stan Hu)
- Fix bug where error messages from Dropzone would not be displayed on the issues page (Stan Hu)
- Add a rake task to check repository integrity with `git fsck`
- Add ability to configure Reply-To address in gitlab.yml (Stan Hu)
- Move current user to the top of the list in assignee/author filters (Stan Hu)
- Fix broken side-by-side diff view on merge request page (Stan Hu)
- Set Application controller default URL options to ensure all url_for calls are consistent (Stan Hu)
- Allow HTML tags in Markdown input
- Fix code unfold not working on Compare commits page (Stan Hu)
- Fix generating SSH key fingerprints with OpenSSH 6.8. (Sašo Stanovnik)
- Fix "Import projects from" button to show the correct instructions (Stan Hu)
- Fix dots in Wiki slugs causing errors (Stan Hu)
- Make maximum attachment size configurable via Application Settings (Stan Hu)
- Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
- Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- Disable reference creation for comments surrounded by code/preformatted blocks (Stan Hu)
- Reduce Rack Attack false positives causing 403 errors during HTTP authentication (Stan Hu)
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
- Fix a link in the patch update guide
- Add a service to support external wikis (Hannes Rosenögger)
- Omit the "email patches" link and fix plain diff view for merge commits
- List new commits for newly pushed branch in activity view.
- Add sidetiq gem dependency to match EE
- Add changelog, license and contribution guide links to project tab bar.
- Improve diff UI
- Fix alignment of navbar toggle button (Cody Mize)
- Fix checkbox rendering for nested task lists
- Identical look of selectboxes in UI
- Upgrade the gitlab_git gem to version 7.1.3
- Move "Import existing repository by URL" option to button.
- Improve error message when save profile has error.
- Passing the name of pushed ref to CI service (requires GitLab CI 7.9+)
- Add location field to user profile
- Fix print view for markdown files and wiki pages
- Fix errors when deleting old backups
- Improve GitLab performance when working with git repositories
- Add tag message and last commit to tag hook (Kamil Trzciński)
- Restrict permissions on backup files
- Improve oauth accounts UI in profile page
- Add ability to unlink connected accounts
- Replace commits calendar with faster contribution calendar that includes issues and merge requests
- Add inifinite scroll to user page activity
- Don't include system notes in issue/MR comment count.
- Don't mark merge request as updated when merge status relative to target branch changes.
- Link note avatar to user.
- Make Git-over-SSH errors more descriptive.
- Fix EmailsOnPush.
- Refactor issue filtering
- AJAX selectbox for issue assignee and author filters
- Fix issue with missing options in issue filtering dropdown if selected one
- Prevent holding Control-Enter or Command-Enter from posting comment multiple times.
- Prevent note form from being cleared when submitting failed.
- Improve file icons rendering on tree (Sullivan Sénéchal)
- API: Add pagination to project events
- Get issue links in notification mail to work again.
- Don't show commit comment button when user is not signed in.
- Fix admin user projects lists.
- Don't leak private group existence by redirecting from namespace controller to group controller.
- Ability to skip some items from backup (database, respositories or uploads)
- Archive repositories in background worker.
- Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.
- Project labels are now available over the API under the "tag_list" field (Cristian Medina)
- Fixed link paths for HTTP and SSH on the admin project view (Jeremy Maziarz)
- Fix and improve help rendering (Sullivan Sénéchal)
- Fix final line in EmailsOnPush email diff being rendered as error.
- Prevent duplicate Buildkite service creation.
- Fix git over ssh errors 'fatal: protocol error: bad line length character'
- Automatically setup GitLab CI project for forks if origin project has GitLab CI enabled
- Bust group page project list cache when namespace name or path changes.
- Explicitly set image alt-attribute to prevent graphical glitches if gravatars could not be loaded
- Allow user to choose a public email to show on public profile
- Remove truncation from issue titles on milestone page (Jason Blanchard)
- Fix stuck Merge Request merging events from old installations (Ben Bodenmiller)
- Fix merge request comments on files with multiple commits
- Fix Resource Owner Password Authentication Flow
- Add icons to Add dropdown items.
- Allow admin to create public deploy keys that are accessible to any project.
- Warn when gitlab-shell version doesn't match requirement.
- Skip email confirmation when set by admin or via LDAP.
- Only allow users to reference groups, projects, issues, MRs, commits they have access to.
## 7.9.4
- Security: Fix project import URL regex to prevent arbitary local repos from being imported
- Fixed issue where only 25 commits would load in file listings
- Fix LDAP identities after config update
## 7.9.3
- Contains no changes
## 7.9.2
- Contains no changes
## 7.9.1
- Include missing events and fix save functionality in admin service template settings form (Stan Hu)
- Fix "Import projects from" button to show the correct instructions (Stan Hu)
- Fix OAuth2 issue importing a new project from GitHub and GitLab (Stan Hu)
- Fix for LDAP with commas in DN
- Fix missing events and in admin Slack service template settings form (Stan Hu)
- Don't show commit comment button when user is not signed in.
- Downgrade gemnasium-gitlab-service gem
## 7.9.0
- Add HipChat integration documentation (Stan Hu)
- Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu)
- Fix broken email images (Hannes Rosenögger)
- Automatically config git if user forgot, where possible (Zeger-Jan van de Weg)
- Fix mass SQL statements on initial push (Hannes Rosenögger)
- Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu)
- Add comment notification events to HipChat and Slack services (Stan Hu)
- Add issue and merge request events to HipChat and Slack services (Stan Hu)
- Fix merge request URL passed to Webhooks. (Stan Hu)
- Fix bug that caused a server error when editing a comment to "+1" or "-1" (Stan Hu)
- Fix code preview theme setting for comments, issues, merge requests, and snippets (Stan Hu)
- Move labels/milestones tabs to sidebar
- Upgrade Rails gem to version 4.1.9.
- Improve error messages for file edit failures
- Improve UI for commits, issues and merge request lists
- Fix commit comments on first line of diff not rendering in Merge Request Discussion view.
- Allow admins to override restricted project visibility settings.
- Move restricted visibility settings from gitlab.yml into the web UI.
- Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev)
- Save web edit in new branch
- Fix ordering of imported but unchanged projects (Marco Wessel)
- Mobile UI improvements: make aside content expandable
- Expose avatar_url in projects API
- Fix checkbox alignment on the application settings page.
- Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger)
- Fix mass-unassignment of issues (Robert Speicher)
- Fix hidden diff comments in merge request discussion view
- Allow user confirmation to be skipped for new users via API
- Add a service to send updates to an Irker gateway (Romain Coltel)
- Add brakeman (security scanner for Ruby on Rails)
- Slack username and channel options
- Add grouped milestones from all projects to dashboard.
- Webhook sends pusher email as well as commiter
- Add Bitbucket omniauth provider.
- Add Bitbucket importer.
- Support referencing issues to a project whose name starts with a digit
- Condense commits already in target branch when updating merge request source branch.
- Send notifications and leave system comments when bulk updating issues.
- Automatically link commit ranges to compare page: sha1...sha4 or sha1..sha4 (includes sha1 in comparison)
- Move groups page from profile to dashboard
- Starred projects page at dashboard
- Blocking user does not remove him/her from project/groups but show blocked label
- Change subject of EmailsOnPush emails to include namespace, project and branch.
- Change subject of EmailsOnPush emails to include first commit message when multiple were pushed.
- Remove confusing footer from EmailsOnPush mail body.
- Add list of changed files to EmailsOnPush emails.
- Add option to send EmailsOnPush emails from committer email if domain matches.
- Add option to disable code diffs in EmailOnPush emails.
- Wrap commit message in EmailsOnPush email.
- Send EmailsOnPush emails when deleting commits using force push.
- Fix EmailsOnPush email comparison link to include first commit.
- Fix highliht of selected lines in file
- Reject access to group/project avatar if the user doesn't have access.
- Add database migration to clean group duplicates with same path and name (Make sure you have a backup before update)
- Add GitLab active users count to rake gitlab:check
- Starred projects page at dashboard
- Make email display name configurable
- Improve json validation in hook data
- Use Emoji One
- Updated emoji help documentation to properly reference EmojiOne.
- Fix missing GitHub organisation repositories on import page.
- Added blue theme
- Remove annoying notice messages when create/update merge request
- Allow smb:// links in Markdown text.
- Filter merge request by title or description at Merge Requests page
- Block user if he/she was blocked in Active Directory
- Fix import pages not working after first load.
- Use custom LDAP label in LDAP signin form.
- Execute hooks and services when branch or tag is created or deleted through web interface.
- Block and unblock user if he/she was blocked/unblocked in Active Directory
- Raise recommended number of unicorn workers from 2 to 3
- Use same layout and interactivity for project members as group members.
- Prevent gitlab-shell character encoding issues by receiving its changes as raw data.
- Ability to unsubscribe/subscribe to issue or merge request
- Delete deploy key when last connection to a project is destroyed.
- Fix invalid Atom feeds when using emoji, horizontal rules, or images (Christian Walther)
- Backup of repositories with tar instead of git bundle (only now are git-annex files included in the backup)
- Add canceled status for CI
- Send EmailsOnPush email when branch or tag is created or deleted.
- Faster merge request processing for large repository
- Prevent doubling AJAX request with each commit visit via Turbolink
- Prevent unnecessary doubling of js events on import pages and user calendar
## 7.8.4
- Fix issue_tracker_id substitution in custom issue trackers
- Fix path and name duplication in namespaces
## 7.8.3
- Bump version of gitlab_git fixing annotated tags without message
## 7.8.2
- Fix service migration issue when upgrading from versions prior to 7.3
- Fix setting of the default use project limit via admin UI
- Fix showing of already imported projects for GitLab and Gitorious importers
- Fix response of push to repository to return "Not found" if user doesn't have access
- Fix check if user is allowed to view the file attachment
- Fix import check for case sensetive namespaces
- Increase timeout for Git-over-HTTP requests to 1 hour since large pulls/pushes can take a long time.
- Properly handle autosave local storage exceptions.
- Escape wildcards when searching LDAP by username.
## 7.8.1
- Fix run of custom post receive hooks
- Fix migration that caused issues when upgrading to version 7.8 from versions prior to 7.3
- Fix the warning for LDAP users about need to set password
- Fix avatars which were not shown for non logged in users
- Fix urls for the issues when relative url was enabled
## 7.8.0
- Fix access control and protection against XSS for note attachments and other uploads.
- Replace highlight.js with rouge-fork rugments (Stefan Tatschner)
- Make project search case insensitive (Hannes Rosenögger)
- Include issue/mr participants in list of recipients for reassign/close/reopen emails
- Expose description in groups API
- Better UI for project services page
- Cleaner UI for web editor
- Add diff syntax highlighting in email-on-push service notifications (Hannes Rosenögger)
- Add API endpoint to fetch all changes on a MergeRequest (Jeroen van Baarsen)
- View note image attachments in new tab when clicked instead of downloading them
- Improve sorting logic in UI and API. Explicitly define what sorting method is used by default
- Fix overflow at sidebar when have several items
- Add notes for label changes in issue and merge requests
- Show tags in commit view (Hannes Rosenögger)
- Only count a user's vote once on a merge request or issue (Michael Clarke)
- Increase font size when browse source files and diffs
- Service Templates now let you set default values for all services
- Create new file in empty repository using GitLab UI
- Ability to clone project using oauth2 token
- Upgrade Sidekiq gem to version 3.3.0
- Stop git zombie creation during force push check
- Show success/error messages for test setting button in services
- Added Rubocop for code style checks
- Fix commits pagination
- Async load a branch information at the commit page
- Disable blacklist validation for project names
- Allow configuring protection of the default branch upon first push (Marco Wessel)
- Add gitlab.com importer
- Add an ability to login with gitlab.com
- Add a commit calendar to the user profile (Hannes Rosenögger)
- Submit comment on command-enter
- Notify all members of a group when that group is mentioned in a comment, for example: `@gitlab-org` or `@sales`.
- Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close" (Julien Bianchi and Hannes Rosenögger)
- Fix long broadcast message cut-off on left sidebar (Visay Keo)
- Add Project Avatars (Steven Thonus and Hannes Rosenögger)
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
- Edit group members via API
- Enable raw image paste from clipboard, currently Chrome only (Marco Cyriacks)
- Add action property to merge request hook (Julien Bianchi)
- Remove duplicates from group milestone participants list.
- Add a new API function that retrieves all issues assigned to a single milestone (Justin Whear and Hannes Rosenögger)
- API: Access groups with their path (Julien Bianchi)
- Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard)
- Allow notification email to be set separately from primary email.
- API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger)
- Don't have Markdown preview fail for long comments/wiki pages.
- When test webhook - show error message instead of 500 error page if connection to hook url was reset
- Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov)
- Added persistent collapse button for left side nav bar (Jason Blanchard)
- Prevent losing unsaved comments by automatically restoring them when comment page is loaded again.
- Don't allow page to be scaled on mobile.
- Clean the username acquired from OAuth/LDAP so it doesn't fail username validation and block signing up.
- Show assignees in merge request index page (Kelvin Mutuma)
- Link head panel titles to relevant root page.
- Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S).
- Show users button to share their newly created public or internal projects on twitter
- Add quick help links to the GitLab pricing and feature comparison pages.
- Fix duplicate authorized applications in user profile and incorrect application client count in admin area.
- Make sure Markdown previews always use the same styling as the eventual destination.
- Remove deprecated Group#owner_id from API
- Show projects user contributed to on user page. Show stars near project on user page.
- Improve database performance for GitLab
- Add Asana service (Jeremy Benoist)
- Improve project webhooks with extra data
## 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
- Fix issue when LDAP user can't login with existing GitLab account
## 7.7.1
- Improve mention autocomplete performance
- Show setup instructions for GitHub import if disabled
- Allow use http for OAuth applications
## 7.7.0
- Import from GitHub.com feature
- Add Jetbrains Teamcity CI service (Jason Lippert)
- Mention notification level
- Markdown preview in wiki (Yuriy Glukhov)
- Raise group avatar filesize limit to 200kb
- OAuth applications feature
- Show user SSH keys in admin area
- Developer can push to protected branches option
- Set project path instead of project name in create form
- Block Git HTTP access after 10 failed authentication attempts
- Updates to the messages returned by API (sponsored by O'Reilly Media)
- New UI layout with side navigation
- Add alert message in case of outdated browser (IE < 10)
- Added API support for sorting projects
- Update gitlab_git to version 7.0.0.rc14
- Add API project search filter option for authorized projects
- Fix File blame not respecting branch selection
- Change some of application settings on fly in admin area UI
- Redesign signin/signup pages
- Close standard input in Gitlab::Popen.popen
- Trigger GitLab CI when push tags
- When accept merge request - do merge using sidaekiq job
- Enable web signups by default
- Fixes for diff comments: drag-n-drop images, selecting images
- Fixes for edit comments: drag-n-drop images, preview mode, selecting images, save & update
- Remove password strength indicator
## 7.6.0
- Fork repository to groups
- New rugged version
- Add CRON=1 backup setting for quiet backups
- Fix failing wiki restore
- Add optional Sidekiq MemoryKiller middleware (enabled via SIDEKIQ_MAX_RSS env variable)
- Monokai highlighting style now more faithful to original design (Mark Riedesel)
- Create project with repository in synchrony
- Added ability to create empty repo or import existing one if project does not have repository
- Reactivate highlight.js language autodetection
- Mobile UI improvements
- Change maximum avatar file size from 100KB to 200KB
- Strict validation for snippet file names
- Enable Markdown preview for issues, merge requests, milestones, and notes (Vinnie Okada)
- In the docker directory is a container template based on the Omnibus packages.
- Update Sidekiq to version 2.17.8
- Add author filter to project issues and merge requests pages
- Atom feed for user activity
- Support multiple omniauth providers for the same user
- Rendering cross reference in issue title and tooltip for merge request
- Show username in comments
- Possibility to create Milestones or Labels when Issues are disabled
- Fix bug with showing gpg signature in tag
## 7.5.3
- Bump gitlab_git to 7.0.0.rc12 (includes Rugged 0.21.2)
## 7.5.2
- Don't log Sidekiq arguments by default
- Fix restore of wiki repositories from backups
## 7.5.1
- Add missing timestamps to 'members' table
## 7.5.0
- API: Add support for Hipchat (Kevin Houdebert)
- Add time zone configuration in gitlab.yml (Sullivan Senechal)
- Fix LDAP authentication for Git HTTP access
- Run 'GC.start' after every EmailsOnPushWorker job
- Fix LDAP config lookup for provider 'ldap'
- Drop all sequences during Postgres database restore
- Project title links to project homepage (Ben Bodenmiller)
- Add Atlassian Bamboo CI service (Drew Blessing)
- Mentioned @user will receive email even if he is not participating in issue or commit
- Session API: Use case-insensitive authentication like in UI (Andrey Krivko)
- Tie up loose ends with annotated tags: API & UI (Sean Edge)
- Return valid json for deleting branch via API (sponsored by O'Reilly Media)
- Expose username in project events API (sponsored by O'Reilly Media)
- Adds comments to commits in the API
- Performance improvements
- Fix post-receive issue for projects with deleted forks
- New gitlab-shell version with custom hooks support
- Improve code
- GitLab CI 5.2+ support (does not support older versions)
- Fixed bug when you can not push commits starting with 000000 to protected branches
- Added a password strength indicator
- Change project name and path in one form
- Display renamed files in diff views (Vinnie Okada)
- Fix raw view for public snippets
- Use secret token with GitLab internal API.
- Add missing timestamps to 'members' table
## 7.4.5
- Bump gitlab_git to 7.0.0.rc12 (includes Rugged 0.21.2)
## 7.4.4
- No changes
## 7.4.3
- Fix raw snippets view
- Fix security issue for member api
- Fix buildbox integration
## 7.4.2
- Fix internal snippet exposing for unauthenticated users
## 7.4.1
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
- Fix public snippets
- Fix 500 error on projects with nested submodules
## 7.4.0
- Refactored membership logic
- Improve error reporting on users API (Julien Bianchi)
- Refactor test coverage tools usage. Use SIMPLECOV=true to generate it locally
- Default branch is protected by default
- Increase unicorn timeout to 60 seconds
- Sort search autocomplete projects by stars count so most popular go first
- Add README to tab on project show page
- Do not delete tmp/repositories itself during clean-up, only its contents
- Support for backup uploads to remote storage
- Prevent notes polling when there are not notes
- Internal ForkService: Prepare support for fork to a given namespace
- API: Add support for forking a project via the API (Bernhard Kaindl)
- API: filter project issues by milestone (Julien Bianchi)
- Fail harder in the backup script
- Changes to Slack service structure, only webhook url needed
- Zen mode for wiki and milestones (Robert Schilling)
- Move Emoji parsing to html-pipeline-gitlab (Robert Schilling)
- Font Awesome 4.2 integration (Sullivan Senechal)
- Add Pushover service integration (Sullivan Senechal)
- Add select field type for services options (Sullivan Senechal)
- Add cross-project references to the Markdown parser (Vinnie Okada)
- Add task lists to issue and merge request descriptions (Vinnie Okada)
- Snippets can be public, internal or private
- Improve danger zone: ask project path to confirm data-loss action
- Raise exception on forgery
- Show build coverage in Merge Requests (requires GitLab CI v5.1)
- New milestone and label links on issue edit form
- Improved repository graphs
- Improve event note display in dashboard and project activity views (Vinnie Okada)
- Add users sorting to admin area
- UI improvements
- Fix ambiguous sha problem with mentioned commit
- Fixed bug with apostrophe when at mentioning users
- Add active directory ldap option
- Developers can push to wiki repo. Protected branches does not affect wiki repo any more
- Faster rev list
- Fix branch removal
## 7.3.2
- Fix creating new file via web editor
- Use gitlab-shell v2.0.1
## 7.3.1
- Fix ref parsing in Gitlab::GitAccess
- Fix error 500 when viewing diff on a file with changed permissions
- Fix adding comments to MR when source branch is master
- Fix error 500 when searching description contains relative link
## 7.3.0
- Always set the 'origin' remote in satellite actions
- Write authorized_keys in tmp/ during tests
- Use sockets to connect to Redis
- Add dormant New Relic gem (can be enabled via environment variables)
- Expire Rack sessions after 1 week
- Cleaner signin/signup pages
- Improved comments UI
- Better search with filtering, pagination etc
- Added a checkbox to toggle line wrapping in diff (Yuriy Glukhov)
- Prevent project stars duplication when fork project
- Use the default Unicorn socket backlog value of 1024
- Support Unix domain sockets for Redis
- Store session Redis keys in 'session:gitlab:' namespace
- Deprecate LDAP account takeover based on partial LDAP email / GitLab username match
- Use /bin/sh instead of Bash in bin/web, bin/background_jobs (Pavel Novitskiy)
- Keyboard shortcuts for productivity (Robert Schilling)
- API: filter issues by state (Julien Bianchi)
- API: filter issues by labels (Julien Bianchi)
- Add system hook for ssh key changes
- Add blob permalink link (Ciro Santilli)
- Create annotated tags through UI and API (Sean Edge)
- Snippets search (Charles Bushong)
- Comment new push to existing MR
- Add 'ci' to the blacklist of forbidden names
- Improve text filtering on issues page
- Comment & Close button
- Process git push --all much faster
- Don't allow edit of system notes
- Project wiki search (Ralf Seidler)
- Enabled Shibboleth authentication support (Matus Banas)
- Zen mode (fullscreen) for issues/MR/notes (Robert Schilling)
- Add ability to configure webhook timeout via gitlab.yml (Wes Gurney)
- Sort project merge requests in asc or desc order for updated_at or created_at field (sponsored by O'Reilly Media)
- Add Redis socket support to 'rake gitlab:shell:install'
## 7.2.1
- Delete orphaned labels during label migration (James Brooks)
- Security: prevent XSS with stricter MIME types for raw repo files
## 7.2.0
- Explore page
- Add project stars (Ciro Santilli)
- Log Sidekiq arguments
- Better labels: colors, ability to rename and remove
- Improve the way merge request collects diffs
- Improve compare page for large diffs
- Expose the full commit message via API
- Fix 500 error on repository rename
- Fix bug when MR download patch return invalid diff
- Test gitlab-shell integration
- Repository import timeout increased from 2 to 4 minutes allowing larger repos to be imported
- API for labels (Robert Schilling)
- API: ability to set an import url when creating project for specific user
## 7.1.1
- Fix cpu usage issue in Firefox
- Fix redirect loop when changing password by new user
- Fix 500 error on new merge request page
## 7.1.0
- Remove observers
- Improve MR discussions
- Filter by description on Issues#index page
- Fix bug with namespace select when create new project page
- Show README link after description for non-master members
- Add @all mention for comments
- Dont show reply button if user is not signed in
- Expose more information for issues with webhook
- Add a mention of the merge request into the default merge request commit message
- Improve code highlight, introduce support for more languages like Go, Clojure, Erlang etc
- Fix concurrency issue in repository download
- Dont allow repository name start with ?
- Improve email threading (Pierre de La Morinerie)
- Cleaner help page
- Group milestones
- Improved email notifications
- Contributors API (sponsored by Mobbr)
- Fix LDAP TLS authentication (Boris HUISGEN)
- Show VERSION information on project sidebar
- Improve branch removal logic when accept MR
- Fix bug where comment form is spawned inside the Reply button
- Remove Dir.chdir from Satellite#lock for thread-safety
- Increased default git max_size value from 5MB to 20MB in gitlab.yml. Please update your configs!
- Show error message in case of timeout in satellite when create MR
- Show first 100 files for huge diff instead of hiding all
- Change default admin email from admin@local.host to admin@example.com
## 7.0.0
- The CPU no longer overheats when you hold down the spacebar
- Improve edit file UI
- Add ability to upload group avatar when create
- Protected branch cannot be removed
- Developers can remove normal branches with UI
- Remove branch via API (sponsored by O'Reilly Media)
- Move protected branches page to Project settings area
- Redirect to Files view when create new branch via UI
- Drag and drop upload of image in every markdown-area (Earle Randolph Bunao and Neil Francis Calabroso)
- Refactor the markdown relative links processing
- Make it easier to implement other CI services for GitLab
- Group masters can create projects in group
- Deprecate ruby 1.9.3 support
- Only masters can rewrite/remove git tags
- Add X-Frame-Options SAMEORIGIN to Nginx config so Sidekiq admin is visible
- UI improvements
- Case-insensetive search for issues
- Update to rails 4.1
- Improve performance of application for projects and groups with a lot of members
- Formally support Ruby 2.1
- Include Nginx gitlab-ssl config
- Add manual language detection for highlight.js
- Added example.com/:username routing
- Show notice if your profile is public
- UI improvements for mobile devices
- Improve diff rendering performance
- Drag-n-drop for issues and merge requests between states at milestone page
- Fix '0 commits' message for huge repositories on project home page
- Prevent 500 error page when visit commit page from large repo
- Add notice about huge push over http to unicorn config
- File action in satellites uses default 30 seconds timeout instead of old 10 seconds one
- Overall performance improvements
- Skip init script check on omnibus-gitlab
- Be more selective when killing stray Sidekiqs
- Check LDAP user filter during sign-in
- Remove wall feature (no data loss - you can take it from database)
- Dont expose user emails via API unless you are admin
- Detect issues closed by Merge Request description
- Better email subject lines from email on push service (Alex Elman)
- Enable identicon for gravatar be default
## 6.9.2
- Revert the commit that broke the LDAP user filter
## 6.9.1
- Fix scroll to highlighted line
- Fix the pagination on load for commits page
## 6.9.0
- Store Rails cache data in the Redis `cache:gitlab` namespace
- Adjust MySQL limits for existing installations
- Add db index on project_id+iid column. This prevents duplicate on iid (During migration duplicates will be removed)
- Markdown preview or diff during editing via web editor (Evgeniy Sokovikov)
- Give the Rails cache its own Redis namespace
- Add ability to set different ssh host, if different from http/https
- Fix syntax highlighting for code comments blocks
- Improve comments loading logic
- Stop refreshing comments when the tab is hidden
- Improve issue and merge request mobile UI (Drew Blessing)
- Document how to convert a backup to PostgreSQL
- Fix locale bug in backup manager
- Fix can not automerge when MR description is too long
- Fix wiki backup skip bug
- Two Step MR creation process
- Remove unwanted files from satellite working directory with git clean -fdx
- Accept merge request via API (sponsored by O'Reilly Media)
- Add more access checks during API calls
- Block SSH access for 'disabled' Active Directory users
- Labels for merge requests (Drew Blessing)
- Threaded emails by setting a Message-ID (Philip Blatter)
## 6.8.0
- Ability to at mention users that are participating in issue and merge req. discussion
- Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu)
- Make user search case-insensitive (Christopher Arnold)
- Remove omniauth-ldap nickname bug workaround
- Drop all tables before restoring a Postgres backup
- Make the repository downloads path configurable
- Create branches via API (sponsored by O'Reilly Media)
- Changed permission of gitlab-satellites directory not to be world accessible
- Protected branch does not allow force push
- Fix popen bug in `rake gitlab:satellites:create`
- Disable connection reaping for MySQL
- Allow oauth signup without email for twitter and github
- Fix faulty namespace names that caused 500 on user creation
- Option to disable standard login
- Clean old created archives from repository downloads directory
- Fix download link for huge MR diffs
- Expose event and mergerequest timestamps in API
- Fix emails on push service when only one commit is pushed
## 6.7.3
- Fix the merge notification email not being sent (Pierre de La Morinerie)
- Drop all tables before restoring a Postgres backup
- Remove yanked modernizr gem
## 6.7.2
- Fix upgrader script
## 6.7.1
- Fix GitLab CI integration
## 6.7.0
- Increased the example Nginx client_max_body_size from 5MB to 20MB, consider updating it manually on existing installations
- Add support for Gemnasium as a Project Service (Olivier Gonzalez)
- Add edit file button to MergeRequest diff
- Public groups (Jason Hollingsworth)
- Cleaner headers in Notification Emails (Pierre de La Morinerie)
- Blob and tree gfm links to anchors work
- Piwik Integration (Sebastian Winkler)
- Show contribution guide link for new issue form (Jeroen van Baarsen)
- Fix CI status for merge requests from fork
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
- New page load indicator that includes a spinner that scrolls with the page
- Converted all the help sections into markdown
- LDAP user filters
- Streamline the content of notification emails (Pierre de La Morinerie)
- Fixes a bug with group member administration (Matt DeTullio)
- Sort tag names using VersionSorter (Robert Speicher)
- Add GFM autocompletion for MergeRequests (Robert Speicher)
- Add webhook when a new tag is pushed (Jeroen van Baarsen)
- Add button for toggling inline comments in diff view
- Add retry feature for repository import
- Reuse the GitLab LDAP connection within each request
- Changed markdown new line behaviour to conform to markdown standards
- Fix global search
- Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5)
- Create and Update MR calls now support the description parameter (Greg Messner)
- Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository
- Added Slack service integration (Federico Ravasio)
- Better API responses for access_levels (sponsored by O'Reilly Media)
- Requires at least 2 unicorn workers
- Requires gitlab-shell v1.9+
- Replaced gemoji(due to closed licencing problem) with Phantom Open Emoji library(combined SIL Open Font License, MIT License and the CC 3.0 License)
- Fix `/:username.keys` response content type (Dmitry Medvinsky)
## 6.6.5
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
- Hide mr close button for comment form if merge request was closed or inline comment
- Adds ability to reopen closed merge request
## 6.6.4
- Add missing html escape for highlighted code blocks in comments, issues
## 6.6.3
- Fix 500 error when edit yourself from admin area
- Hide private groups for public profiles
## 6.6.2
- Fix 500 error on branch/tag create or remove via UI
## 6.6.1
- Fix 500 error on files tab if submodules presents
## 6.6.0
- Retrieving user ssh keys publically(github style): http://__HOST__/__USERNAME__.keys
- Permissions: Developer now can manage issue tracker (modify any issue)
- Improve Code Compare page performance
- Group avatar
- Pygments.rb replaced with highlight.js
- Improve Merge request diff store logic
- Improve render performnace for MR show page
- Fixed Assembla hardcoded project name
- Jira integration documentation
- Refactored app/services
- Remove snippet expiration
- Mobile UI improvements (Drew Blessing)
- Fix block/remove UI for admin::users#show page
- Show users' group membership on users' activity page (Robert Djurasaj)
- User pages are visible without login if user is authorized to a public project
- Markdown rendered headers have id derived from their name and link to their id
- Improve application to work faster with large groups (100+ members)
- Multiple emails per user
- Show last commit for file when view file source
- Restyle Issue#show page and MR#show page
- Ability to filter by multiple labels for Issues page
- Rails version to 4.0.3
- Fixed attachment identifier displaying underneath note text (Jason Blanchard)
## 6.5.1
- Fix branch selectbox when create merge request from fork
## 6.5.0
- Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard)
- Add color custimization and previewing to broadcast messages
- Fixed notes anchors
- Load new comments in issues dynamically
- Added sort options to Public page
- New filters (assigned/authored/all) for Dashboard#issues/merge_requests (sponsored by Say Media)
- Add project visibility icons to dashboard
- Enable secure cookies if https used
- Protect users/confirmation with rack_attack
- Default HTTP headers to protect against MIME-sniffing, force https if enabled
- Bootstrap 3 with responsive UI
- New repository download formats: tar.bz2, zip, tar (Jason Hollingsworth)
- Restyled accept widgets for MR
- SCSS refactored
- Use jquery timeago plugin
- Fix 500 error for rdoc files
- Ability to customize merge commit message (sponsored by Say Media)
- Search autocomplete via ajax
- Add website url to user profile
- Files API supports base64 encoded content (sponsored by O'Reilly Media)
- Added support for Go's repository retrieval (Bruno Albuquerque)
## 6.4.3
- Don't use unicorn worker killer if PhusionPassenger is defined
## 6.4.2
- Fixed wrong behaviour of script/upgrade.rb
## 6.4.1
- Fixed bug with repository rename
- Fixed bug with project transfer
## 6.4.0
- Added sorting to project issues page (Jason Blanchard)
- Assembla integration (Carlos Paramio)
- Fixed another 500 error with submodules
- UI: More compact issues page
- Minimal password length increased to 8 symbols
- Side-by-side diff view (Steven Thonus)
- Internal projects (Jason Hollingsworth)
- Allow removal of avatar (Drew Blessing)
- Project webhooks now support issues and merge request events
- Visiting project page while not logged in will redirect to sign-in instead of 404 (Jason Hollingsworth)
- Expire event cache on avatar creation/removal (Drew Blessing)
- Archiving old projects (Steven Thonus)
- Rails 4
- Add time ago tooltips to show actual date/time
- UI: Fixed UI for admin system hooks
- Ruby script for easier GitLab upgrade
- Do not remove Merge requests if fork project was removed
- Improve sign-in/signup UX
- Add resend confirmation link to sign-in page
- Set noreply@HOSTNAME for reply_to field in all emails
- Show GitLab API version on Admin#dashboard
- API Cross-origin resource sharing
- Show READMe link at project home page
- Show repo size for projects in Admin area
## 6.3.0
- API for adding gitlab-ci service
- Init script now waits for pids to appear after (re)starting before reporting status (Rovanion Luckey)
- Restyle project home page
- Grammar fixes
- Show branches list (which branches contains commit) on commit page (Andrew Kumanyaev)
- Security improvements
- Added support for GitLab CI 4.0
- Fixed issue with 500 error when group did not exist
- Ability to leave project
- You can create file in repo using UI
- You can remove file from repo using UI
- API: dropped default_branch attribute from project during creation
- Project default_branch is not stored in db any more. It takes from repo now.
- Admin broadcast messages
- UI improvements
- Dont show last push widget if user removed this branch
- Fix 500 error for repos with newline in file name
- Extended html titles
- API: create/update/delete repo files
- Admin can transfer project to any namespace
- API: projects/all for admin users
- Fix recent branches order
## 6.2.4
- Security: Cast API private_token to string (CVE-2013-4580)
- Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583)
- Fix for Git SSH access for LDAP users
## 6.2.3
- Security: More protection against CVE-2013-4489
- Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546)
- Fix sidekiq rake tasks
## 6.2.2
- Security: Update gitlab_git (CVE-2013-4489)
## 6.2.1
- Security: Fix issue with generated passwords for new users
## 6.2.0
- Public project pages are now visible to everyone (files, issues, wik, etc.)
THIS MEANS YOUR ISSUES AND WIKI FOR PUBLIC PROJECTS ARE PUBLICLY VISIBLE AFTER THE UPGRADE
- Add group access to permissions page
- Require current password to change one
- Group owner or admin can remove other group owners
- Remove group transfer since we have multiple owners
- Respect authorization in Repository API
- Improve UI for Project#files page
- Add more security specs
- Added search for projects by name to api (Izaak Alpert)
- Make default user theme configurable (Izaak Alpert)
- Update logic for validates_merge_request for tree of MR (Andrew Kumanyaev)
- Rake tasks for webhooks management (Jonhnny Weslley)
- Extended User API to expose admin and can_create_group for user creation/updating (Boyan Tabakov)
- API: Remove group
- API: Remove project
- Avatar upload on profile page with a maximum of 100KB (Steven Thonus)
- Store the sessions in Redis instead of the cookie store
- Fixed relative links in markdown
- User must confirm their email if signup enabled
- User must confirm changed email
## 6.1.0
- Project specific IDs for issues, mr, milestones
Above items will get a new id and for example all bookmarked issue urls will change.
Old issue urls are redirected to the new one if the issue id is too high for an internal id.
- Description field added to Merge Request
- API: Sudo api calls (Izaak Alpert)
- API: Group membership api (Izaak Alpert)
- Improved commit diff
- Improved large commit handling (Boyan Tabakov)
- Rewrite: Init script now less prone to errors and keeps better track of the service (Rovanion Luckey)
- Link issues, merge requests, and commits when they reference each other with GFM (Ash Wilson)
- Close issues automatically when pushing commits with a special message
- Improve user removal from admin area
- Invalidate events cache when project was moved
- Remove deprecated classes and rake tasks
- Add event filter for group and project show pages
- Add links to create branch/tag from project home page
- Add public-project? checkbox to new-project view
- Improved compare page. Added link to proceed into Merge Request
- Send an email to a user when they are added to group
- New landing page when you have 0 projects
## 6.0.0
- Feature: Replace teams with group membership
We introduce group membership in 6.0 as a replacement for teams.
The old combination of groups and teams was confusing for a lot of people.
And when the members of a team where changed this wasn't reflected in the project permissions.
In GitLab 6.0 you will be able to add members to a group with a permission level for each member.
These group members will have access to the projects in that group.
Any changes to group members will immediately be reflected in the project permissions.
You can even have multiple owners for a group, greatly simplifying administration.
- Feature: Ability to have multiple owners for group
- Feature: Merge Requests between fork and project (Izaak Alpert)
- Feature: Generate fingerprint for ssh keys
- Feature: Ability to create and remove branches with UI
- Feature: Ability to create and remove git tags with UI
- Feature: Groups page in profile. You can leave group there
- API: Allow login with LDAP credentials
- Redesign: project settings navigation
- Redesign: snippets area
- Redesign: ssh keys page
- Redesign: buttons, blocks and other ui elements
- Add comment title to rss feed
- You can use arrows to navigate at tree view
- Add project filter on dashboard
- Cache project graph
- Drop support of root namespaces
- Default theme is classic now
- Cache result of methods like authorize_projects, project.team.members etc
- Remove $.ready events
- Fix onclick events being double binded
- Add notification level to group membership
- Move all project controllers/views under Projects:: module
- Move all profile controllers/views under Profiles:: module
- Apply user project limit only for personal projects
- Unicorn is default web server again
- Store satellites lock files inside satellites dir
- Disabled threadsafety mode in rails
- Fixed bug with loosing MR comments
- Improved MR comments logic
- Render readme file for projects in public area
## 5.4.2
- Security: Cast API private_token to string (CVE-2013-4580)
- Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583)
## 5.4.1
- Security: Fixes for CVE-2013-4489
- Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546)
## 5.4.0
- Ability to edit own comments
- Documentation improvements
- Improve dashboard projects page
- Fixed nav for empty repos
- GitLab Markdown help page
- Misspelling fixes
- Added support of unicorn and fog gems
- Added client list to API doc
- Fix PostgreSQL database restoration problem
- Increase snippet content column size
- allow project import via git:// url
- Show participants on issues, including mentions
- Notify mentioned users with email
## 5.3.0
- Refactored services
- Campfire service added
- HipChat service added
- Fixed bug with LDAP + git over http
- Fixed bug with google analytics code being ignored
- Improve sign-in page if ldap enabled
- Respect newlines in wall messages
- Generate the Rails secret token on first run
- Rename repo feature
- Init.d: remove gitlab.socket on service start
- Api: added teams api
- Api: Prevent blob content being escaped
- Api: Smart deploy key add behaviour
- Api: projects/owned.json return user owned project
- Fix bug with team assignation on project from #4109
- Advanced snippets: public/private, project/personal (Andrew Kulakov)
- Repository Graphs (Karlo Nicholas T. Soriano)
- Fix dashboard lost if comment on commit
- Update gitlab-grack. Fixes issue with --depth option
- Fix project events duplicate on project page
- Fix postgres error when displaying network graph.
- Fix dashboard event filter when navigate via turbolinks
- init.d: Ensure socket is removed before starting service
- Admin area: Style teams:index, group:show pages
- Own page for failed forking
- Scrum view for milestone
## 5.2.0
- Turbolinks
- Git over http with ldap credentials
- Diff with better colors and some spacing on the corners
- Default values for project features
- Fixed huge_commit view
- Restyle project clone panel
- Move Gitlab::Git code to gitlab_git gem
- Move update docs in repo
- Requires gitlab-shell v1.4.0
- Fixed submodules listing under file tab
- Fork feature (Angus MacArthur)
- git version check in gitlab:check
- Shared deploy keys feature
- Ability to generate default labels set for issues
- Improve gfm autocomplete (Harold Luo)
- Added support for Google Analytics
- Code search feature (Javier Castro)
## 5.1.0
- You can login with email or username now
- Corrected project transfer rollback when repository cannot be moved
- Move both repo and wiki when project transfer requested
- Admin area: project editing was removed from admin namespace
- Access: admin user has now access to any project.
- Notification settings
- Gitlab::Git set of objects to abstract from grit library
- Replace Unicorn web server with Puma
- Backup/Restore refactored. Backup dump project wiki too now
- Restyled Issues list. Show milestone version in issue row
- Restyled Merge Request list
- Backup now dump/restore uploads
- Improved performance of dashboard (Andrew Kumanyaev)
- File history now tracks renames (Akzhan Abdulin)
- Drop wiki migration tools
- Drop sqlite migration tools
- project tagging
- Paginate users in API
- Restyled network graph (Hiroyuki Sato)
## 5.0.1
- Fixed issue with gitlab-grit being overridden by grit
## 5.0.0
- Replaced gitolite with gitlab-shell
- Removed gitolite-related libraries
- State machine added
- Setup gitlab as git user
- Internal API
- Show team tab for empty projects
- Import repository feature
- Updated rails
- Use lambda for scopes
- Redesign admin area -> users
- Redesign admin area -> user
- Secure link to file attachments
- Add validations for Group and Team names
- Restyle team page for project
- Update capybara, rspec-rails, poltergeist to recent versions
- Wiki on git using Gollum
- Added Solarized Dark theme for code review
- Don't show user emails in autocomplete lists, profile pages
- Added settings tab for group, team, project
- Replace user popup with icons in header
- Handle project moving with gitlab-shell
- Added select2-rails for selectboxes with ajax data load
- Fixed search field on projects page
- Added teams to search autocomplete
- Move groups and teams on dashboard sidebar to sub-tabs
- API: improved return codes and docs. (Felix Gilcher, Sebastian Ziebell)
- Redesign wall to be more like chat
- Snippets, Wall features are disabled by default for new projects
## 4.2.0
- Teams
- User show page. Via /u/username
- Show help contents on pages for better navigation
- Async gitolite calls
- added satellites logs
- can_create_group, can_create_team booleans for User
- Process webhooks async
- GFM: Fix images escaped inside links
- Network graph improved
- Switchable branches for network graph
- API: Groups
- Fixed project download
## 4.1.0
- Optional Sign-Up
- Discussions
- Satellites outside of tmp
- Line numbers for blame
- Project public mode
- Public area with unauthorized access
- Load dashboard events with ajax
- remember dashboard filter in cookies
- replace resque with sidekiq
- fix routing issues
- cleanup rake tasks
- fix backup/restore
- scss cleanup
- show preview for note images
- improved network-graph
- get rid of app/roles/
- added new classes Team, Repository
- Reduce amount of gitolite calls
- Ability to add user in all group projects
- remove deprecated configs
- replaced Korolev font with open font
- restyled admin/dashboard page
- restyled admin/projects page
## 4.0.0
- Remove project code and path from API. Use id instead
- Return valid cloneable url to repo for webhook
- Fixed backup issue
- Reorganized settings
- Fixed commits compare
- Refactored scss
- Improve status checks
- Validates presence of User#name
- Fixed postgres support
- Removed sqlite support
- Modified post-receive hook
- Milestones can be closed now
- Show comment events on dashboard
- Quick add team members via group#people page
- [API] expose created date for hooks and SSH keys
- [API] list, create issue notes
- [API] list, create snippet notes
- [API] list, create wall notes
- Remove project code - use path instead
- added username field to user
- rake task to fill usernames based on emails create namespaces for users
- STI Group < Namespace
- Project has namespace_id
- Projects with namespaces also namespaced in gitolite and stored in subdir
- Moving project to group will move it under group namespace
- Ability to move project from namespaces to another
- Fixes commit patches getting escaped (see #2036)
- Support diff and patch generation for commits and merge request
- MergeReqest doesn't generate a temporary file for the patch any more
- Update the UI to allow downloading Patch or Diff
## 3.1.0
- Updated gems
- Services: Gitlab CI integration
- Events filter on dashboard
- Own namespace for redis/resque
- Optimized commit diff views
- add alphabetical order for projects admin page
- Improved web editor
- Commit stats page
- Documentation split and cleanup
- Link to commit authors everywhere
- Restyled milestones list
- added Milestone to Merge Request
- Restyled Top panel
- Refactored Satellite Code
- Added file line links
- moved from capybara-webkit to poltergeist + phantomjs
## 3.0.3
- Fixed bug with issues list in Chrome
- New Feature: Import team from another project
## 3.0.2
- Fixed gitlab:app:setup
- Fixed application error on empty project in admin area
- Restyled last push widget
## 3.0.1
- Fixed git over http
## 3.0.0
- Projects groups
- Web Editor
- Fixed bug with gitolite keys
- UI improved
- Increased performance of application
- Show user avatar in last commit when browsing Files
- Refactored Gitlab::Merge
- Use Font Awesome for icons
- Separate observing of Note and MergeRequests
- Milestone "All Issues" filter
- Fix issue close and reopen button text and styles
- Fix forward/back while browsing Tree hierarchy
- Show number of notes for commits and merge requests
- Added support pg from box and update installation doc
- Reject ssh keys that break gitolite
- [API] list one project hook
- [API] edit project hook
- [API] list project snippets
- [API] allow to authorize using private token in HTTP header
- [API] add user creation
## 2.9.1
- Fixed resque custom config init
## 2.9.0
- fixed inline notes bugs
- refactored rspecs
- refactored gitolite backend
- added factory_girl
- restyled projects list on dashboard
- ssh keys validation to prevent gitolite crash
- send notifications if changed permission in project
- scss refactoring. gitlab_bootstrap/ dir
- fix git push http body bigger than 112k problem
- list of labels page under issues tab
- API for milestones, keys
- restyled buttons
- OAuth
- Comment order changed
## 2.8.1
- ability to disable gravatars
- improved MR diff logic
- ssh key help page
## 2.8.0
- Gitlab Flavored Markdown
- Bulk issues update
- Issues API
- Cucumber coverage increased
- Post-receive files fixed
- UI improved
- Application cleanup
- more cucumber
- capybara-webkit + headless
## 2.7.0
- Issue Labels
- Inline diff
- Git HTTP
- API
- UI improved
- System hooks
- UI improved
- Dashboard events endless scroll
- Source performance increased
## 2.6.0
- UI polished
- Improved network graph + keyboard nav
- Handle huge commits
- Last Push widget
- Bugfix
- Better performance
- Email in resque
- Increased test coverage
- Ability to remove branch with MR accept
- a lot of code refactored
## 2.5.0
- UI polished
- Git blame for file
- Bugfix
- Email in resque
- Better test coverage
## 2.4.0
- Admin area stats page
- Ability to block user
- Simplified dashboard area
- Improved admin area
- Bootstrap 2.0
- Responsive layout
- Big commits handling
- Performance improved
- Milestones
## 2.3.1
- Issues pagination
- ssl fixes
- Merge Request pagination
## 2.3.0
- Dashboard r1
- Search r1
- Project page
- Close merge request on push
- Persist MR diff after merge
- mysql support
- Documentation
## 2.2.0
- We’ve added support of LDAP auth
- Improved permission logic (4 roles system)
- Protected branches (now only masters can push to protected branches)
- Usability improved
- twitter bootstrap integrated
- compare view between commits
- wiki feature
- now you can enable/disable issues, wiki, wall features per project
- security fixes
- improved code browsing (ajax branch switch etc)
- improved per-line commenting
- git submodules displayed
- moved to rails 3.2
- help section improved
## 2.1.0
- Project tab r1
- List branches/tags
- per line comments
- mass user import
## 2.0.0
- gitolite as main git host system
- merge requests
- project/repo access
- link to commit/issue feed
- design tab
- improved email notifications
- restyled dashboard
- bugfix
## 1.2.2
- common config file gitlab.yml
- issues restyle
- snippets restyle
- clickable news feed header on dashboard
- bugfix
## 1.2.1
- bugfix
## 1.2.0
- new design
- user dashboard
- network graph
- markdown support for comments
- encoding issues
- wall like twitter timeline
## 1.1.0
- project dashboard
- wall redesigned
- feature: code snippets
- fixed horizontal scroll on file preview
- fixed app crash if commit message has invalid chars
- bugfix & code cleaning
## 1.0.2
- fixed bug with empty project
- added adv validation for project path & code
- feature: issues can be sortable
- bugfix
- username displayed on top panel
## 1.0.1
- fixed: with invalid source code for commit
- fixed: lose branch/tag selection when use tree navigation
- when history clicked - display path
- bug fix & code cleaning
## 1.0.0
- bug fix
- projects preview mode
## 0.9.6
- css fix
- new repo empty tree until restart server - fixed
## 0.9.4
- security improved
- authorization improved
- html escaping
- bug fix
- increased test coverage
- design improvements
## 0.9.1
- increased test coverage
- design improvements
- new issue email notification
- updated app name
- issue redesigned
- issue can be edit
## 0.8.0
- syntax highlight for main file types
- redesign
- stability
- security fixes
- increased test coverage
- email notification
......@@ -403,7 +403,7 @@ If you are not using Linux you may have to run `gmake` instead of
cd /home/git
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git
cd gitlab-workhorse
sudo -u git -H git checkout v0.8.0
sudo -u git -H git checkout v0.8.1
sudo -u git -H make
### Initialize Database and Activate Advanced Features
......
......@@ -82,7 +82,7 @@ GitLab 8.1.
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all
sudo -u git -H git checkout v0.8.0
sudo -u git -H git checkout v0.8.1
sudo -u git -H make
```
......
......@@ -133,8 +133,7 @@ module Gitlab
if issue.labels.count > 0
label_ids = issue.labels
.map { |raw| LabelFormatter.new(project, raw).attributes }
.map { |attrs| Label.find_by(attrs).try(:id) }
.map { |attrs| project.labels.find_by(title: attrs.name).try(:id) }
.compact
issuable.update_attribute(:label_ids, label_ids)
......
......@@ -13,6 +13,12 @@ module Gitlab
Label
end
def create!
project.labels.find_or_create_by!(title: title) do |label|
label.color = color
end
end
private
def color
......
......@@ -29,31 +29,7 @@ module Gitlab
end
def users(field, value, limit = nil)
if field.to_sym == :dn
options = {
base: value,
scope: Net::LDAP::SearchScope_BaseObject
}
else
options = {
base: config.base,
filter: Net::LDAP::Filter.eq(field, value)
}
end
if config.user_filter.present?
user_filter = Net::LDAP::Filter.construct(config.user_filter)
options[:filter] = if options[:filter]
Net::LDAP::Filter.join(options[:filter], user_filter)
else
user_filter
end
end
if limit.present?
options.merge!(size: limit)
end
options = user_options(field, value, limit)
entries = ldap_search(options).select do |entry|
entry.respond_to? config.uid
......@@ -98,6 +74,38 @@ module Gitlab
Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
[]
end
private
def user_options(field, value, limit)
options = { attributes: %W(#{config.uid} cn mail dn) }
options[:size] = limit if limit
if field.to_sym == :dn
options[:base] = value
options[:scope] = Net::LDAP::SearchScope_BaseObject
options[:filter] = user_filter
else
options[:base] = config.base
options[:filter] = user_filter(Net::LDAP::Filter.eq(field, value))
end
options
end
def user_filter(filter = nil)
if config.user_filter.present?
user_filter = Net::LDAP::Filter.construct(config.user_filter)
end
if user_filter && filter
Net::LDAP::Filter.join(filter, user_filter)
elsif user_filter
user_filter
else
filter
end
end
end
end
end
......@@ -136,6 +136,29 @@ describe SessionsController do
post(:create, { user: user_params }, { otp_user_id: user.id })
end
context 'remember_me field' do
it 'sets a remember_user_token cookie when enabled' do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
allow(controller).to receive(:find_user).and_return(user)
expect(controller).
to receive(:remember_me).with(user).and_call_original
authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}")
expect(response.cookies['remember_user_token']).to be_present
end
it 'does nothing when disabled' do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
allow(controller).to receive(:find_user).and_return(user)
expect(controller).not_to receive(:remember_me)
authenticate_2fa_u2f(remember_me: '0', login: user.username, device_response: "{}")
expect(response.cookies['remember_user_token']).to be_nil
end
end
it "creates an audit log record" do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
expect { authenticate_2fa_u2f(login: user.username, device_response: "{}") }.to change { SecurityEvent.count }.by(1)
......
require 'spec_helper'
describe 'Branches', feature: true do
let(:project) { create(:project) }
let(:project) { create(:project, :public) }
let(:repository) { project.repository }
before do
login_as :user
project.team << [@user, :developer]
end
context 'logged in' do
before do
login_as :user
project.team << [@user, :developer]
end
describe 'Initial branches page' do
it 'shows all the branches' do
visit namespace_project_branches_path(project.namespace, project)
describe 'Initial branches page' do
it 'shows all the branches' do
visit namespace_project_branches_path(project.namespace, project)
repository.branches { |branch| expect(page).to have_content("#{branch.name}") }
expect(page).to have_content("Protected branches can be managed in project settings")
repository.branches { |branch| expect(page).to have_content("#{branch.name}") }
expect(page).to have_content("Protected branches can be managed in project settings")
end
end
describe 'Find branches' do
it 'shows filtered branches', js: true do
visit namespace_project_branches_path(project.namespace, project)
fill_in 'branch-search', with: 'fix'
find('#branch-search').native.send_keys(:enter)
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
end
end
end
describe 'Find branches' do
it 'shows filtered branches', js: true do
context 'logged out' do
before do
visit namespace_project_branches_path(project.namespace, project)
end
fill_in 'branch-search', with: 'fix'
find('#branch-search').native.send_keys(:enter)
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
it 'does not show merge request button' do
page.within first('.all-branches li') do
expect(page).not_to have_content 'Merge Request'
end
end
end
end
......@@ -156,6 +156,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
describe "when 2FA via OTP is disabled" do
it "allows logging in with the U2F device" do
user.update_attribute(:otp_required_for_login, false)
login_with(user)
@u2f_device.respond_to_u2f_authentication
......@@ -181,6 +182,19 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
end
end
it 'persists remember_me value via hidden field' do
login_with(user, remember: true)
@u2f_device.respond_to_u2f_authentication
click_on "Login Via U2F Device"
expect(page.body).to match('We heard back from your U2F device')
within 'div#js-authenticate-u2f' do
field = first('input#user_remember_me', visible: false)
expect(field.value).to eq '1'
end
end
describe "when a given U2F device has already been registered by another user" do
describe "but not the current user" do
it "does not allow logging in with that particular device" do
......
/*= require awards_handler */
/*= require jquery */
/*= require jquery.cookie */
/*= require ./fixtures/emoji_menu */
(function() {
......@@ -33,6 +27,7 @@
return setTimeout(function() {
assertFn();
return done();
// Maybe jasmine.clock here?
}, 333);
};
......
......@@ -8,6 +8,7 @@
beforeEach(function() {
fixture.load('behaviors/quick_submit.html');
$('form').submit(function(e) {
// Prevent a form submit from moving us off the testing page
return e.preventDefault();
});
return this.spies = {
......@@ -38,6 +39,8 @@
expect($('input[type=submit]')).toBeDisabled();
return expect($('button[type=submit]')).toBeDisabled();
});
// We cannot stub `navigator.userAgent` for CI's `rake teaspoon` task, so we'll
// only run the tests that apply to the current platform
if (navigator.userAgent.match(/Macintosh/)) {
it('responds to Meta+Enter', function() {
$('input.quick-submit-input').trigger(keydownEvent());
......
= render partial: "u2f/authenticate", locals: { new_user_session_path: "/users/sign_in" }
= render partial: "u2f/authenticate", locals: { new_user_session_path: "/users/sign_in", params: {}, resource_name: "user" }
......@@ -7,7 +7,7 @@ describe("ContributorsGraph", function () {
expect(ContributorsGraph.prototype.x_domain).toEqual(20)
})
})
describe("#set_y_domain", function () {
it("sets the y_domain", function () {
ContributorsGraph.set_y_domain([{commits: 30}])
......@@ -89,7 +89,7 @@ describe("ContributorsGraph", function () {
})
describe("ContributorsMasterGraph", function () {
// TODO: fix or remove
//describe("#process_dates", function () {
//it("gets and parses dates", function () {
......@@ -103,7 +103,7 @@ describe("ContributorsMasterGraph", function () {
//expect(graph.get_dates).toHaveBeenCalledWith(data)
//expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get")
//})
//})
//})
describe("#get_dates", function () {
it("plucks the date field from data collection", function () {
......@@ -124,5 +124,5 @@ describe("ContributorsMasterGraph", function () {
})
})
})
/*= require lib/utils/text_utility */
/*= require issue */
(function() {
......
/*= require jquery-ui/autocomplete */
/*= require new_branch_form */
(function() {
......
/*= require bootstrap */
/*= require select2 */
/*= require lib/utils/type_utility */
/*= require gl_dropdown */
/*= require api */
/*= require project_select */
/*= require project */
(function() {
......
/*= require right_sidebar */
/*= require jquery */
/*= require jquery.cookie */
(function() {
......
/*= require gl_dropdown */
/*= require search_autocomplete */
/*= require jquery */
/*= require lib/utils/common_utils */
/*= require lib/utils/type_utility */
/*= require fuzzaldrin-plus */
(function() {
......@@ -43,6 +33,8 @@
groupName = 'Gitlab Org';
// Add required attributes to body before starting the test.
// section would be dashboard|group|project
addBodyAttributes = function(section) {
var $body;
if (section == null) {
......@@ -64,6 +56,7 @@
}
};
// Mock `gl` object in window for dashboard specific page. App code will need it.
mockDashboardOptions = function() {
window.gl || (window.gl = {});
return window.gl.dashboardOptions = {
......@@ -72,6 +65,7 @@
};
};
// Mock `gl` object in window for project specific page. App code will need it.
mockProjectOptions = function() {
window.gl || (window.gl = {});
return window.gl.projectOptions = {
......
......@@ -10,6 +10,7 @@
});
return describe('#replyWithSelectedText', function() {
var stubSelection;
// Stub window.getSelection to return the provided String.
stubSelection = function(text) {
return window.getSelection = function() {
return text;
......
// PhantomJS (Teaspoons default driver) doesn't have support for
// Function.prototype.bind, which has caused confusion. Use this polyfill to
// avoid the confusion.
/*= require support/bind-poly */
// You can require your own javascript files here. By default this will include
// everything in application, however you may get better load performance if you
// require the specific files that are being used in the spec that tests them.
/*= require jquery */
/*= require jquery.turbolinks */
/*= require bootstrap */
/*= require underscore */
// Teaspoon includes some support files, but you can use anything from your own
// support path too.
// require support/jasmine-jquery-1.7.0
// require support/jasmine-jquery-2.0.0
/*= require support/jasmine-jquery-2.1.0 */
// require support/sinon
// require support/your-support-file
// Deferring execution
// If you're using CommonJS, RequireJS or some other asynchronous library you can
// defer execution. Call Teaspoon.execute() after everything has been loaded.
// Simple example of a timeout:
// Teaspoon.defer = true
// setTimeout(Teaspoon.execute, 1000)
// Matching files
// By default Teaspoon will look for files that match
// _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your spec path
// and it'll be included in the default suite automatically. If you want to
// customize suites, check out the configuration in teaspoon_env.rb
// Manifest
// If you'd rather require your spec files manually (to control order for
// instance) you can disable the suite matcher in the configuration and use this
// file as a manifest.
// For more information: http://github.com/modeset/teaspoon
(function() {
......
/*= require u2f/authenticate */
/*= require u2f/util */
/*= require u2f/error */
/*= require u2f */
/*= require ./mock_u2f_device */
(function() {
......
/*= require u2f/register */
/*= require u2f/util */
/*= require u2f/error */
/*= require u2f */
/*= require ./mock_u2f_device */
(function() {
......
......@@ -14,8 +14,10 @@
return true;
}
};
// Stub Dropzone.forElement(...).enable()
});
this.zen = new ZenMode();
// Set this manually because we can't actually scroll the window
return this.zen.scroll_position = 456;
});
describe('on enter', function() {
......@@ -60,7 +62,7 @@
return $('a.js-zen-enter').click();
};
exitZen = function() {
exitZen = function() { // Ohmmmmmmm
return $('a.js-zen-leave').click();
};
......
......@@ -13,7 +13,7 @@ describe Gitlab::GithubImport::Importer, lib: true do
let(:target_sha) { create(:commit, project: project, git_commit: RepoHelpers.another_sample_commit).id }
let(:target_branch) { double(ref: 'master', repo: repository, sha: target_sha) }
let(:label) do
let(:label1) do
double(
name: 'Bug',
color: 'ff0000',
......@@ -21,6 +21,14 @@ describe Gitlab::GithubImport::Importer, lib: true do
)
end
let(:label2) do
double(
name: nil,
color: 'ff0000',
url: 'https://api.github.com/repos/octocat/Hello-World/labels/bug'
)
end
let(:milestone) do
double(
number: 1347,
......@@ -93,7 +101,7 @@ describe Gitlab::GithubImport::Importer, lib: true do
before do
allow(project).to receive(:import_data).and_return(double.as_null_object)
allow_any_instance_of(Octokit::Client).to receive(:rate_limit!).and_raise(Octokit::NotFound)
allow_any_instance_of(Octokit::Client).to receive(:labels).and_return([label, label])
allow_any_instance_of(Octokit::Client).to receive(:labels).and_return([label1, label2])
allow_any_instance_of(Octokit::Client).to receive(:milestones).and_return([milestone, milestone])
allow_any_instance_of(Octokit::Client).to receive(:issues).and_return([issue1, issue2])
allow_any_instance_of(Octokit::Client).to receive(:pull_requests).and_return([pull_request, pull_request])
......@@ -113,7 +121,7 @@ describe Gitlab::GithubImport::Importer, lib: true do
error = {
message: 'The remote data could not be fully imported.',
errors: [
{ type: :label, url: "https://api.github.com/repos/octocat/Hello-World/labels/bug", errors: "Validation failed: Title has already been taken" },
{ type: :label, url: "https://api.github.com/repos/octocat/Hello-World/labels/bug", errors: "Validation failed: Title can't be blank, Title is invalid" },
{ type: :milestone, url: "https://api.github.com/repos/octocat/Hello-World/milestones/1", errors: "Validation failed: Title has already been taken" },
{ type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1347", errors: "Invalid Repository. Use user/repo format." },
{ type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank, Title is too short (minimum is 0 characters)" },
......
require 'spec_helper'
describe Gitlab::GithubImport::LabelFormatter, lib: true do
describe '#attributes' do
it 'returns formatted attributes' do
project = create(:project)
raw = double(name: 'improvements', color: 'e6e6e6')
let(:project) { create(:project) }
let(:raw) { double(name: 'improvements', color: 'e6e6e6') }
formatter = described_class.new(project, raw)
subject { described_class.new(project, raw) }
expect(formatter.attributes).to eq({
describe '#attributes' do
it 'returns formatted attributes' do
expect(subject.attributes).to eq({
project: project,
title: 'improvements',
color: '#e6e6e6'
})
end
end
describe '#create!' do
context 'when label does not exist' do
it 'creates a new label' do
expect { subject.create! }.to change(Label, :count).by(1)
end
end
context 'when label exists' do
it 'does not create a new label' do
project.labels.create(name: raw.name)
expect { subject.create! }.not_to change(Label, :count)
end
end
end
end
require 'spec_helper'
describe Gitlab::LDAP::Adapter, lib: true do
let(:adapter) { Gitlab::LDAP::Adapter.new 'ldapmain' }
include LdapHelpers
let(:ldap) { double(:ldap) }
let(:adapter) { ldap_adapter('ldapmain', ldap) }
describe '#users' do
before do
stub_ldap_config(base: 'dc=example,dc=com')
end
it 'searches with the proper options when searching by uid' do
# Requires this expectation style to match the filter
expect(adapter).to receive(:ldap_search) do |arg|
expect(arg[:filter].to_s).to eq('(uid=johndoe)')
expect(arg[:base]).to eq('dc=example,dc=com')
expect(arg[:attributes]).to match(%w{uid cn mail dn})
end.and_return({})
adapter.users('uid', 'johndoe')
end
it 'searches with the proper options when searching by dn' do
expect(adapter).to receive(:ldap_search).with(
base: 'uid=johndoe,ou=users,dc=example,dc=com',
scope: Net::LDAP::SearchScope_BaseObject,
attributes: %w{uid cn mail dn},
filter: nil
).and_return({})
adapter.users('dn', 'uid=johndoe,ou=users,dc=example,dc=com')
end
it 'searches with the proper options when searching with a limit' do
expect(adapter)
.to receive(:ldap_search).with(hash_including(size: 100)).and_return({})
adapter.users('uid', 'johndoe', 100)
end
it 'returns an LDAP::Person if search returns a result' do
entry = ldap_user_entry('johndoe')
allow(adapter).to receive(:ldap_search).and_return([entry])
results = adapter.users('uid', 'johndoe')
expect(results.size).to eq(1)
expect(results.first.uid).to eq('johndoe')
end
it 'returns empty array if search entry does not respond to uid' do
entry = Net::LDAP::Entry.new
entry['dn'] = user_dn('johndoe')
allow(adapter).to receive(:ldap_search).and_return([entry])
results = adapter.users('uid', 'johndoe')
expect(results).to be_empty
end
it 'uses the right uid attribute when non-default' do
stub_ldap_config(uid: 'sAMAccountName')
expect(adapter).to receive(:ldap_search).with(
hash_including(attributes: %w{sAMAccountName cn mail dn})
).and_return({})
adapter.users('sAMAccountName', 'johndoe')
end
end
describe '#dn_matches_filter?' do
let(:ldap) { double(:ldap) }
subject { adapter.dn_matches_filter?(:dn, :filter) }
before { allow(adapter).to receive(:ldap).and_return(ldap) }
context "when the search is successful" do
context "and the result is non-empty" do
......
module LdapHelpers
<<<<<<< HEAD
def adapter(provider = 'ldapmain')
::Gitlab::LDAP::Adapter.new(provider, double(:ldap))
end
def proxy(adapter, provider = 'ldapmain')
EE::Gitlab::LDAP::Sync::Proxy.new(provider, adapter)
=======
def ldap_adapter(provider = 'ldapmain', ldap = double(:ldap))
::Gitlab::LDAP::Adapter.new(provider, ldap)
>>>>>>> 13bb9ed77f405c5f6ee4fdbc964ecf635c9a223f
end
def user_dn(uid)
......@@ -34,16 +39,21 @@ module LdapHelpers
#
# stub_ldap_person_find_by_uid('john_doe', ldap_user_entry, adapter)
def stub_ldap_person_find_by_uid(uid, entry, provider = 'ldapmain')
<<<<<<< HEAD
return_value = if entry.present?
::Gitlab::LDAP::Person.new(entry, provider)
else
nil
end
=======
return_value = ::Gitlab::LDAP::Person.new(entry, provider) if entry.present?
>>>>>>> 13bb9ed77f405c5f6ee4fdbc964ecf635c9a223f
allow(::Gitlab::LDAP::Person)
.to receive(:find_by_uid).with(uid, any_args).and_return(return_value)
end
<<<<<<< HEAD
# Stub an LDAP group search and provide the return entry. Specify `nil` for
# `entry` to simulate when an LDAP group is not found
#
......@@ -105,6 +115,14 @@ module LdapHelpers
members = [members].flatten
entry[member_attr] = members if members.any?
=======
# Create a simple LDAP user entry.
def ldap_user_entry(uid)
entry = Net::LDAP::Entry.new
entry['dn'] = user_dn(uid)
entry['uid'] = uid
>>>>>>> 13bb9ed77f405c5f6ee4fdbc964ecf635c9a223f
entry
end
end
// The MIT License (MIT)
//
// Copyright (c) 2014 GitHub, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// TaskList Behavior
//
/*= provides tasklist:enabled */
/*= provides tasklist:disabled */
/*= provides tasklist:change */
/*= provides tasklist:changed */
//
//
// Enables Task List update behavior.
//
// ### Example Markup
//
// <div class="js-task-list-container">
// <ul class="task-list">
// <li class="task-list-item">
// <input type="checkbox" class="js-task-list-item-checkbox" disabled />
// text
// </li>
// </ul>
// <form>
// <textarea class="js-task-list-field">- [ ] text</textarea>
// </form>
// </div>
//
// ### Specification
//
// TaskLists MUST be contained in a `(div).js-task-list-container`.
//
// TaskList Items SHOULD be an a list (`UL`/`OL`) element.
//
// Task list items MUST match `(input).task-list-item-checkbox` and MUST be
// `disabled` by default.
//
// TaskLists MUST have a `(textarea).js-task-list-field` form element whose
// `value` attribute is the source (Markdown) to be udpated. The source MUST
// follow the syntax guidelines.
//
// TaskList updates trigger `tasklist:change` events. If the change is
// successful, `tasklist:changed` is fired. The change can be canceled.
//
// jQuery is required.
//
// ### Methods
//
// `.taskList('enable')` or `.taskList()`
//
// Enables TaskList updates for the container.
//
// `.taskList('disable')`
//
// Disables TaskList updates for the container.
//
//# ### Events
//
// `tasklist:enabled`
//
// Fired when the TaskList is enabled.
//
// * **Synchronicity** Sync
// * **Bubbles** Yes
// * **Cancelable** No
// * **Target** `.js-task-list-container`
//
// `tasklist:disabled`
//
// Fired when the TaskList is disabled.
//
// * **Synchronicity** Sync
// * **Bubbles** Yes
// * **Cancelable** No
// * **Target** `.js-task-list-container`
//
// `tasklist:change`
//
// Fired before the TaskList item change takes affect.
//
// * **Synchronicity** Sync
// * **Bubbles** Yes
// * **Cancelable** Yes
// * **Target** `.js-task-list-field`
//
// `tasklist:changed`
//
// Fired once the TaskList item change has taken affect.
//
// * **Synchronicity** Sync
// * **Bubbles** Yes
// * **Cancelable** No
// * **Target** `.js-task-list-field`
//
// ### NOTE
//
// Task list checkboxes are rendered as disabled by default because rendered
// user content is cached without regard for the viewer.
(function() {
var codeFencesPattern, complete, completePattern, disableTaskList, disableTaskLists, enableTaskList, enableTaskLists, escapePattern, incomplete, incompletePattern, itemPattern, itemsInParasPattern, updateTaskList, updateTaskListItem,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
......@@ -18,20 +121,48 @@
complete = "[x]";
// Escapes the String for regular expression matching.
escapePattern = function(str) {
return str.replace(/([\[\]])/g, "\\$1").replace(/\s/, "\\s").replace("x", "[xX]");
};
incompletePattern = RegExp("" + (escapePattern(incomplete)));
completePattern = RegExp("" + (escapePattern(complete)));
incompletePattern = RegExp("" + (escapePattern(incomplete))); // escape square brackets
// match all white space
completePattern = RegExp("" + (escapePattern(complete))); // match all cases
// Pattern used to identify all task list items.
// Useful when you need iterate over all items.
itemPattern = RegExp("^(?:\\s*(?:>\\s*)*(?:[-+*]|(?:\\d+\\.)))\\s*(" + (escapePattern(complete)) + "|" + (escapePattern(incomplete)) + ")\\s+(?!\\(.*?\\))(?=(?:\\[.*?\\]\\s*(?:\\[.*?\\]|\\(.*?\\))\\s*)*(?:[^\\[]|$))");
// prefix, consisting of
// optional leading whitespace
// zero or more blockquotes
// list item indicator
// optional whitespace prefix
// checkbox
// is followed by whitespace
// is not part of a [foo](url) link
// and is followed by zero or more links
// and either a non-link or the end of the string
// Used to filter out code fences from the source for comparison only.
// http://rubular.com/r/x5EwZVrloI
// Modified slightly due to issues with JS
codeFencesPattern = /^`{3}(?:\s*\w+)?[\S\s].*[\S\s]^`{3}$/mg;
// ```
// followed by optional language
// whitespace
// code
// whitespace
// ```
// Used to filter out potential mismatches (items not in lists).
// http://rubular.com/r/OInl6CiePy
itemsInParasPattern = RegExp("^(" + (escapePattern(complete)) + "|" + (escapePattern(incomplete)) + ").+$", "g");
// Given the source text, updates the appropriate task list item to match the
// given checked value.
//
// Returns the updated String text.
updateTaskListItem = function(source, itemIndex, checked) {
var clean, index, line, result;
clean = source.replace(/\r/g, '').replace(codeFencesPattern, '').replace(itemsInParasPattern, '').split("\n");
......@@ -55,6 +186,9 @@
return result.join("\n");
};
// Updates the $field value to reflect the state of $item.
// Triggers the `tasklist:change` event before the value has changed, and fires
// a `tasklist:changed` event once the value has changed.
updateTaskList = function($item) {
var $container, $field, checked, event, index;
$container = $item.closest('.js-task-list-container');
......@@ -70,10 +204,12 @@
}
};
// When the task list item checkbox is updated, submit the change
$(document).on('change', '.task-list-item-checkbox', function() {
return updateTaskList($(this));
});
// Enables TaskList item changes.
enableTaskList = function($container) {
if ($container.find('.js-task-list-field').length > 0) {
$container.find('.task-list-item').addClass('enabled').find('.task-list-item-checkbox').attr('disabled', null);
......@@ -81,6 +217,7 @@
}
};
// Enables a collection of TaskList containers.
enableTaskLists = function($containers) {
var container, i, len, results;
results = [];
......@@ -91,11 +228,13 @@
return results;
};
// Disable TaskList item changes.
disableTaskList = function($container) {
$container.find('.task-list-item').removeClass('enabled').find('.task-list-item-checkbox').attr('disabled', 'disabled');
return $container.removeClass('is-task-list-enabled').trigger('tasklist:disabled');
};
// Disables a collection of TaskList containers.
disableTaskLists = function($containers) {
var container, i, len, results;
results = [];
......
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