diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..2e88b7aa0a --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,3 @@ +We’re closing our issue tracker on GitHub so we can focus on the GitLab.com project and respond to issues more quickly. + +We encourage you to open an issue on the [GitLab.com issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues). You can log into GitLab.com using your GitHub account. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..c3b0402644 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +Thank you for taking the time to contribute back to GitLab! + +Please open a merge request [on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests), we look forward to reviewing your contribution! You can log into GitLab.com using your GitHub account. diff --git a/.gitignore b/.gitignore index 8f861d76a3..ce6a363fe3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,46 +4,46 @@ .bundle .chef .directory -.envrc -.gitlab_shell_secret +/.envrc +/.gitlab_shell_secret .idea -.rbenv-version +/.rbenv-version .rbx/ -.ruby-gemset -.ruby-version -.rvmrc +/.ruby-gemset +/.ruby-version +/.rvmrc .sass-cache/ -.secret -.vagrant -.byebug_history -Vagrantfile -backups/* -config/aws.yml -config/database.yml -config/gitlab.yml -config/gitlab_ci.yml -config/initializers/rack_attack.rb -config/initializers/smtp_settings.rb -config/initializers/relative_url.rb -config/resque.yml -config/unicorn.rb -config/secrets.yml -config/sidekiq.yml -coverage/* -db/*.sqlite3 -db/*.sqlite3-journal -db/data.yml -doc/code/* -dump.rdb -log/*.log* -nohup.out -public/assets/ -public/uploads.* -public/uploads/ -shared/artifacts/ -rails_best_practices_output.html +/.secret +/.vagrant +/.byebug_history +/Vagrantfile +/backups/* +/config/aws.yml +/config/database.yml +/config/gitlab.yml +/config/gitlab_ci.yml +/config/initializers/rack_attack.rb +/config/initializers/smtp_settings.rb +/config/initializers/relative_url.rb +/config/resque.yml +/config/unicorn.rb +/config/secrets.yml +/config/sidekiq.yml +/coverage/* +/db/*.sqlite3 +/db/*.sqlite3-journal +/db/data.yml +/doc/code/* +/dump.rdb +/log/*.log* +/nohup.out +/public/assets/ +/public/uploads.* +/public/uploads/ +/shared/artifacts/ +/rails_best_practices_output.html /tags -tmp/ -vendor/bundle/* -builds/* -shared/* +/tmp/* +/vendor/bundle/* +/builds/* +/shared/* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85730e1b68..83a906932d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,111 +2,199 @@ image: "ruby:2.1" services: - mysql:latest - - redis:latest + - redis:alpine cache: key: "ruby21" paths: - - vendor + - vendor/apt + - vendor/ruby variables: MYSQL_ALLOW_EMPTY_PASSWORD: "1" # retry tests only in CI environment RSPEC_RETRY_RETRY_COUNT: "3" + RAILS_ENV: "test" + SIMPLECOV: "true" + USE_DB: "true" + USE_BUNDLE_INSTALL: "true" before_script: - source ./scripts/prepare_build.sh - - ruby -v - - which ruby - - retry gem install bundler --no-ri --no-rdoc - cp config/gitlab.yml.example config/gitlab.yml - - touch log/application.log - - touch log/test.log - - retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}" - - RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load db:migrate + - bundle --version + - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"' + - retry gem install knapsack + - '[ "$USE_DB" != "true" ] || bundle exec rake db:drop db:create db:schema:load db:migrate' stages: +- prepare - test -- notifications +- post-test -spec:feature: +# Prepare and merge knapsack tests + +.knapsack-state: &knapsack-state + services: [] + variables: + USE_DB: "false" + USE_BUNDLE_INSTALL: "false" + cache: + key: "knapsack" + paths: + - knapsack/ + artifacts: + paths: + - knapsack/ + +knapsack: + <<: *knapsack-state + stage: prepare + script: + - mkdir -p knapsack/ + - '[[ -f knapsack/rspec_report.json ]] || echo "{}" > knapsack/rspec_report.json' + - '[[ -f knapsack/spinach_report.json ]] || echo "{}" > knapsack/spinach_report.json' + +update-knapsack: + <<: *knapsack-state + stage: post-test + script: + - scripts/merge-reports knapsack/rspec_report.json knapsack/rspec_node_*.json + - scripts/merge-reports knapsack/spinach_report.json knapsack/spinach_node_*.json + - rm -f knapsack/*_node_*.json + only: + - master + +# Execute all testing suites + +.rspec-knapsack: &rspec-knapsack stage: test script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:feature + - bundle exec rake assets:precompile 2>/dev/null + - JOB_NAME=( $CI_BUILD_NAME ) + - export CI_NODE_INDEX=${JOB_NAME[1]} + - export CI_NODE_TOTAL=${JOB_NAME[2]} + - export KNAPSACK_REPORT_PATH=knapsack/rspec_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json + - export KNAPSACK_GENERATE_REPORT=true + - cp knapsack/rspec_report.json ${KNAPSACK_REPORT_PATH} + - knapsack rspec + artifacts: + paths: + - knapsack/ -spec:api: +.spinach-knapsack: &spinach-knapsack stage: test script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:api + - bundle exec rake assets:precompile 2>/dev/null + - JOB_NAME=( $CI_BUILD_NAME ) + - export CI_NODE_INDEX=${JOB_NAME[1]} + - export CI_NODE_TOTAL=${JOB_NAME[2]} + - export KNAPSACK_REPORT_PATH=knapsack/spinach_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json + - export KNAPSACK_GENERATE_REPORT=true + - cp knapsack/spinach_report.json ${KNAPSACK_REPORT_PATH} + - knapsack spinach "-r rerun" || retry '[ ! -e tmp/spinach-rerun.txt ] || bundle exec spinach -r rerun $(cat tmp/spinach-rerun.txt)' + artifacts: + paths: + - knapsack/ -spec:models: +rspec 0 20: *rspec-knapsack +rspec 1 20: *rspec-knapsack +rspec 2 20: *rspec-knapsack +rspec 3 20: *rspec-knapsack +rspec 4 20: *rspec-knapsack +rspec 5 20: *rspec-knapsack +rspec 6 20: *rspec-knapsack +rspec 7 20: *rspec-knapsack +rspec 8 20: *rspec-knapsack +rspec 9 20: *rspec-knapsack +rspec 10 20: *rspec-knapsack +rspec 11 20: *rspec-knapsack +rspec 12 20: *rspec-knapsack +rspec 13 20: *rspec-knapsack +rspec 14 20: *rspec-knapsack +rspec 15 20: *rspec-knapsack +rspec 16 20: *rspec-knapsack +rspec 17 20: *rspec-knapsack +rspec 18 20: *rspec-knapsack +rspec 19 20: *rspec-knapsack + +spinach 0 10: *spinach-knapsack +spinach 1 10: *spinach-knapsack +spinach 2 10: *spinach-knapsack +spinach 3 10: *spinach-knapsack +spinach 4 10: *spinach-knapsack +spinach 5 10: *spinach-knapsack +spinach 6 10: *spinach-knapsack +spinach 7 10: *spinach-knapsack +spinach 8 10: *spinach-knapsack +spinach 9 10: *spinach-knapsack + +# Execute all testing suites against Ruby 2.2 + +.ruby-22: &ruby-22 + image: "ruby:2.2" + only: + - master + cache: + key: "ruby22" + paths: + - vendor + +.rspec-knapsack-ruby22: &rspec-knapsack-ruby22 + <<: *rspec-knapsack + <<: *ruby-22 + +.spinach-knapsack-ruby22: &spinach-knapsack-ruby22 + <<: *spinach-knapsack + <<: *ruby-22 + +rspec 0 20 ruby22: *rspec-knapsack-ruby22 +rspec 1 20 ruby22: *rspec-knapsack-ruby22 +rspec 2 20 ruby22: *rspec-knapsack-ruby22 +rspec 3 20 ruby22: *rspec-knapsack-ruby22 +rspec 4 20 ruby22: *rspec-knapsack-ruby22 +rspec 5 20 ruby22: *rspec-knapsack-ruby22 +rspec 6 20 ruby22: *rspec-knapsack-ruby22 +rspec 7 20 ruby22: *rspec-knapsack-ruby22 +rspec 8 20 ruby22: *rspec-knapsack-ruby22 +rspec 9 20 ruby22: *rspec-knapsack-ruby22 +rspec 10 20 ruby22: *rspec-knapsack-ruby22 +rspec 11 20 ruby22: *rspec-knapsack-ruby22 +rspec 12 20 ruby22: *rspec-knapsack-ruby22 +rspec 13 20 ruby22: *rspec-knapsack-ruby22 +rspec 14 20 ruby22: *rspec-knapsack-ruby22 +rspec 15 20 ruby22: *rspec-knapsack-ruby22 +rspec 16 20 ruby22: *rspec-knapsack-ruby22 +rspec 17 20 ruby22: *rspec-knapsack-ruby22 +rspec 18 20 ruby22: *rspec-knapsack-ruby22 +rspec 19 20 ruby22: *rspec-knapsack-ruby22 + +spinach 0 10 ruby22: *spinach-knapsack-ruby22 +spinach 1 10 ruby22: *spinach-knapsack-ruby22 +spinach 2 10 ruby22: *spinach-knapsack-ruby22 +spinach 3 10 ruby22: *spinach-knapsack-ruby22 +spinach 4 10 ruby22: *spinach-knapsack-ruby22 +spinach 5 10 ruby22: *spinach-knapsack-ruby22 +spinach 6 10 ruby22: *spinach-knapsack-ruby22 +spinach 7 10 ruby22: *spinach-knapsack-ruby22 +spinach 8 10 ruby22: *spinach-knapsack-ruby22 +spinach 9 10 ruby22: *spinach-knapsack-ruby22 + +# Other generic tests + +.exec: &exec stage: test script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:models + - bundle exec $CI_BUILD_NAME -spec:lib: - stage: test - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:lib - -spec:services: - stage: test - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:services - -spec:other: - stage: test - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:other - -spinach:project:half: - stage: test - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:half - -spinach:project:rest: - stage: test - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:rest - -spinach:other: - stage: test - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:other - -teaspoon: - stage: test - script: - - RAILS_ENV=test bundle exec teaspoon - -rubocop: - stage: test - script: - - bundle exec rubocop - -scss-lint: - stage: test - script: - - bundle exec rake scss_lint - -brakeman: - stage: test - script: - - bundle exec rake brakeman - -flog: - stage: test - script: - - bundle exec rake flog - -flay: - stage: test - script: - - bundle exec rake flay +teaspoon: *exec +rubocop: *exec +rake scss_lint: *exec +rake brakeman: *exec +rake flog: *exec +rake flay: *exec +rake db:migrate:reset: *exec +license_finder: *exec bundler:audit: stage: test @@ -115,127 +203,10 @@ bundler:audit: script: - "bundle exec bundle-audit check --update --ignore OSVDB-115941" -db-migrate-reset: - stage: test - script: - - RAILS_ENV=test bundle exec rake db:migrate:reset - -# Ruby 2.2 jobs - -spec:feature:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:feature - cache: - key: "ruby22" - paths: - - vendor - -spec:api:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:api - cache: - key: "ruby22" - paths: - - vendor - -spec:models:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:models - cache: - key: "ruby22" - paths: - - vendor - -spec:lib:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:lib - cache: - key: "ruby22" - paths: - - vendor - -spec:services:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:services - cache: - key: "ruby22" - paths: - - vendor - -spec:other:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:other - cache: - key: "ruby22" - paths: - - vendor - -spinach:project:half:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:half - cache: - key: "ruby22" - paths: - - vendor - -spinach:project:rest:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:rest - cache: - key: "ruby22" - paths: - - vendor - -spinach:other:ruby22: - stage: test - image: ruby:2.2 - only: - - master - script: - - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:other - cache: - key: "ruby22" - paths: - - vendor +# Notify slack in the end notify:slack: - stage: notifications + stage: post-test script: - ./scripts/notify_slack.sh "#builds" "Build on \`$CI_BUILD_REF_NAME\` failed! Commit \`$(git log -1 --oneline)\` See " when: on_failure diff --git a/.rubocop.yml b/.rubocop.yml index 0946ef5d84..dbdabbb9d4 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +require: rubocop-rspec + AllCops: TargetRubyVersion: 2.1 # Cop names are not displayed in offense messages by default. Change behavior @@ -11,7 +13,8 @@ AllCops: # Exclude some GitLab files Exclude: - 'vendor/**/*' - - 'db/**/*' + - 'db/*' + - 'db/fixtures/**/*' - 'tmp/**/*' - 'bin/**/*' - 'lib/backup/**/*' @@ -57,7 +60,7 @@ Style/AndOr: # Use `Array#join` instead of `Array#*`. Style/ArrayJoin: - Enabled: false + Enabled: true # Use only ascii symbols in comments. Style/AsciiComments: @@ -69,7 +72,7 @@ Style/AsciiIdentifiers: # Checks for uses of Module#attr. Style/Attr: - Enabled: false + Enabled: true # Avoid the use of BEGIN blocks. Style/BeginBlock: @@ -81,7 +84,7 @@ Style/BarePercentLiterals: # Do not use block comments. Style/BlockComments: - Enabled: false + Enabled: true # Put end statement of multiline block on its own line. Style/BlockEndNewline: @@ -122,7 +125,7 @@ Style/ClassCheck: # Use self when defining module/class methods. Style/ClassMethods: - Enabled: false + Enabled: true # Avoid the use of class variables. Style/ClassVars: @@ -152,7 +155,7 @@ Style/ConstantName: # Use def with parentheses when there are arguments. Style/DefWithParentheses: - Enabled: false + Enabled: true # Checks for use of deprecated Hash methods. Style/DeprecatedHashMethods: @@ -192,7 +195,7 @@ Style/EmptyLines: # Keep blank lines around access modifiers. Style/EmptyLinesAroundAccessModifier: - Enabled: false + Enabled: true # Keeps track of empty lines around block bodies. Style/EmptyLinesAroundBlockBody: @@ -216,15 +219,15 @@ Style/EmptyLiteral: # Avoid the use of END blocks. Style/EndBlock: - Enabled: false + Enabled: true # Use Unix-style line endings. Style/EndOfLine: - Enabled: false + Enabled: true # Favor the use of Fixnum#even? && Fixnum#odd? Style/EvenOdd: - Enabled: false + Enabled: true # Do not use unnecessary spacing. Style/ExtraSpacing: @@ -232,15 +235,20 @@ Style/ExtraSpacing: # Use snake_case for source file names. Style/FileName: - Enabled: false + Enabled: true + +# Checks for a line break before the first parameter in a multi-line method +# parameter definition. +Style/FirstMethodParameterLineBreak: + Enabled: true # Checks for flip flops. Style/FlipFlop: - Enabled: false + Enabled: true # Checks use of for or each in multiline loops. Style/For: - Enabled: false + Enabled: true # Enforce the use of Kernel#sprintf, Kernel#format or String#%. Style/FormatString: @@ -248,7 +256,7 @@ Style/FormatString: # Do not introduce global variables. Style/GlobalVars: - Enabled: false + Enabled: true # Check for conditionals that can be replaced with guard clauses. Style/GuardClause: @@ -269,7 +277,7 @@ Style/IfUnlessModifier: # Do not use if x; .... Use the ternary operator instead. Style/IfWithSemicolon: - Enabled: false + Enabled: true # Checks that conditional statements do not have an identical line at the # end of each branch, which can validly be moved out of the conditional. @@ -279,7 +287,7 @@ Style/IdenticalConditionalBranches: # Checks the indentation of the first line of the right-hand-side of a # multi-line assignment. Style/IndentAssignment: - Enabled: false + Enabled: true # Keep indentation straight. Style/IndentationConsistency: @@ -299,7 +307,7 @@ Style/IndentHash: # Use Kernel#loop for infinite loops. Style/InfiniteLoop: - Enabled: false + Enabled: true # Use the new lambda literal syntax for single-line blocks. Style/Lambda: @@ -307,11 +315,11 @@ Style/Lambda: # Use lambda.call(...) instead of lambda.(...). Style/LambdaCall: - Enabled: false + Enabled: true # Comments should start with a space. Style/LeadingCommentSpace: - Enabled: false + Enabled: true # Use \ instead of + or << to concatenate two string literals at line end. Style/LineEndConcatenation: @@ -323,33 +331,56 @@ Style/MethodCallParentheses: # Checks if the method definitions have or don't have parentheses. Style/MethodDefParentheses: - Enabled: false + Enabled: true # Use the configured style when naming methods. Style/MethodName: - Enabled: false + Enabled: true # Checks for usage of `extend self` in modules. Style/ModuleFunction: Enabled: false +# Checks that the closing brace in an array literal is either on the same line +# as the last array element, or a new line. +Style/MultilineArrayBraceLayout: + Enabled: false + EnforcedStyle: symmetrical + # Avoid multi-line chains of blocks. Style/MultilineBlockChain: - Enabled: false + Enabled: true # Ensures newlines after multiline block do statements. Style/MultilineBlockLayout: Enabled: true +# Checks that the closing brace in a hash literal is either on the same line as +# the last hash element, or a new line. +Style/MultilineHashBraceLayout: + Enabled: false + EnforcedStyle: symmetrical + # Do not use then for multi-line if/unless. Style/MultilineIfThen: + Enabled: true + +# Checks that the closing brace in a method call is either on the same line as +# the last method argument, or a new line. +Style/MultilineMethodCallBraceLayout: Enabled: false + EnforcedStyle: symmetrical # Checks indentation of method calls with the dot operator that span more than # one line. Style/MultilineMethodCallIndentation: Enabled: false +# Checks that the closing brace in a method definition is symmetrical with +# respect to the opening brace and the method parameters. +Style/MultilineMethodDefinitionBraceLayout: + Enabled: false + # Checks indentation of binary operations that span more than one line. Style/MultilineOperationIndentation: Enabled: false @@ -364,7 +395,7 @@ Style/MutableConstant: # Favor unless over if for negative conditions (or control flow or). Style/NegatedIf: - Enabled: false + Enabled: true # Favor until over while for negative conditions. Style/NegatedWhile: @@ -372,7 +403,7 @@ Style/NegatedWhile: # Avoid using nested modifiers. Style/NestedModifier: - Enabled: false + Enabled: true # Parenthesize method calls which are nested inside the argument list of # another parenthesized method call. @@ -409,7 +440,7 @@ Style/OneLineConditional: # When defining binary operators, name the argument other. Style/OpMethod: - Enabled: false + Enabled: true # Check for simple usages of parallel assignment. It will only warn when # the number of variables matches on both sides of the assignment. @@ -456,10 +487,9 @@ Style/RedundantException: Style/RedundantFreeze: Enabled: false -# TODO: Enable RedundantParentheses Cop. # Checks for parentheses that seem not to serve any purpose. Style/RedundantParentheses: - Enabled: false + Enabled: true # Don't use return where it's not required. Style/RedundantReturn: @@ -485,11 +515,12 @@ Style/SelfAssignment: # Don't use semicolons to terminate expressions. Style/Semicolon: - Enabled: false + Enabled: true # Checks for proper usage of fail and raise. Style/SignalException: - Enabled: false + EnforcedStyle: only_raise + Enabled: true # Enforces the names of some block params. Style/SingleLineBlockParams: @@ -510,25 +541,24 @@ Style/SpaceAfterComma: # Do not put a space between a method name and the opening parenthesis in a # method definition. Style/SpaceAfterMethodName: - Enabled: false + Enabled: true # Tracks redundant space after the ! operator. Style/SpaceAfterNot: - Enabled: false + Enabled: true # Use spaces after semicolons. Style/SpaceAfterSemicolon: - Enabled: false + Enabled: true # Checks that the equals signs in parameter default assignments have or don't # have surrounding space depending on configuration. Style/SpaceAroundEqualsInParameterDefault: Enabled: false -# TODO: Enable SpaceAroundKeyword Cop. # Use a space around keywords if appropriate. Style/SpaceAroundKeyword: - Enabled: false + Enabled: true # Use a single space around operators. Style/SpaceAroundOperators: @@ -540,11 +570,11 @@ Style/SpaceBeforeBlockBraces: # No spaces before commas. Style/SpaceBeforeComma: - Enabled: false + Enabled: true # Checks for missing space between code and a comment on the same line. Style/SpaceBeforeComment: - Enabled: false + Enabled: true # Checks that exactly one space is used between a method name and the first # argument for method calls without parentheses. @@ -553,7 +583,7 @@ Style/SpaceBeforeFirstArg: # No spaces before semicolons. Style/SpaceBeforeSemicolon: - Enabled: false + Enabled: true # Checks that block braces have or don't have surrounding space. # For blocks taking parameters, checks that the left brace has or doesn't @@ -575,11 +605,12 @@ Style/SpaceInsideParens: # No spaces inside range literals. Style/SpaceInsideRangeLiteral: - Enabled: false + Enabled: true # Checks for padding/surrounding spaces inside string interpolation. Style/SpaceInsideStringInterpolation: - Enabled: false + EnforcedStyle: no_space + Enabled: true # Avoid Perl-style global variables. Style/SpecialGlobalVars: @@ -587,7 +618,8 @@ Style/SpecialGlobalVars: # Check for the usage of parentheses around stabby lambda arguments. Style/StabbyLambdaParentheses: - Enabled: false + EnforcedStyle: require_parentheses + Enabled: true # Checks if uses of quotes match the configured preference. Style/StringLiterals: @@ -600,7 +632,9 @@ Style/StringLiteralsInInterpolation: # Checks if configured preferred methods are used over non-preferred. Style/StringMethods: - Enabled: false + PreferredMethods: + intern: to_sym + Enabled: true # Use %i or %I for arrays of symbols. Style/SymbolArray: @@ -658,23 +692,24 @@ Style/UnneededPercentQ: # Don't interpolate global, instance and class variables directly in strings. Style/VariableInterpolation: - Enabled: false + Enabled: true # Use the configured style when naming variables. Style/VariableName: - Enabled: false + EnforcedStyle: snake_case + Enabled: true # Use when x then ... for one-line cases. Style/WhenThen: - Enabled: false + Enabled: true # Checks for redundant do after while or until. Style/WhileUntilDo: - Enabled: false + Enabled: true # Favor modifier while/until usage when you have a single-line body. Style/WhileUntilModifier: - Enabled: false + Enabled: true # Use %w or %W for arrays of words. Style/WordArray: @@ -737,7 +772,7 @@ Metrics/PerceivedComplexity: # Checks for ambiguous operators in the first argument of a method invocation # without parentheses. Lint/AmbiguousOperator: - Enabled: false + Enabled: true # Checks for ambiguous regexp literals in the first argument of a method # invocation without parentheses. @@ -750,24 +785,24 @@ Lint/AssignmentInCondition: # Align block ends correctly. Lint/BlockAlignment: - Enabled: false + Enabled: true # Default values in optional keyword arguments and optional ordinal arguments # should not refer back to the name of the argument. Lint/CircularArgumentReference: - Enabled: false + Enabled: true # Checks for condition placed in a confusing position relative to the keyword. Lint/ConditionPosition: - Enabled: false + Enabled: true # Check for debugger calls. Lint/Debugger: - Enabled: false + Enabled: true # Align ends corresponding to defs correctly. Lint/DefEndAlignment: - Enabled: false + Enabled: true # Check for deprecated class method calls. Lint/DeprecatedClassMethods: @@ -783,15 +818,15 @@ Lint/DuplicatedKey: # Check for immutable argument given to each_with_object. Lint/EachWithObjectArgument: - Enabled: false + Enabled: true # Check for odd code arrangement in an else block. Lint/ElseLayout: - Enabled: false + Enabled: true # Checks for empty ensure block. Lint/EmptyEnsure: - Enabled: false + Enabled: true # Checks for empty string interpolation. Lint/EmptyInterpolation: @@ -799,37 +834,36 @@ Lint/EmptyInterpolation: # Align ends correctly. Lint/EndAlignment: - Enabled: false + Enabled: true # END blocks should not be placed inside method definitions. Lint/EndInMethod: - Enabled: false + Enabled: true # Do not use return in an ensure block. Lint/EnsureReturn: - Enabled: false + Enabled: true # The use of eval represents a serious security risk. Lint/Eval: - Enabled: false + Enabled: true # Catches floating-point literals too large or small for Ruby to represent. Lint/FloatOutOfRange: - Enabled: false + Enabled: true # The number of parameters to format/sprint must match the fields. Lint/FormatParameterMismatch: - Enabled: false + Enabled: true # Don't suppress exception. Lint/HandleExceptions: Enabled: false -# TODO: Enable ImplicitStringConcatenation Cop. # Checks for adjacent string literals on the same line, which could better be # represented as a single string literal. Lint/ImplicitStringConcatenation: - Enabled: false + Enabled: true # TODO: Enable IneffectiveAccessModifier Cop. # Checks for attempts to use `private` or `protected` to set the visibility @@ -840,15 +874,15 @@ Lint/IneffectiveAccessModifier: # Checks for invalid character literals with a non-escaped whitespace # character. Lint/InvalidCharacterLiteral: - Enabled: false + Enabled: true # Checks of literals used in conditions. Lint/LiteralInCondition: - Enabled: false + Enabled: true # Checks for literals used in interpolation. Lint/LiteralInInterpolation: - Enabled: false + Enabled: true # Use Kernel#loop with break rather than begin/end/until or begin/end/while # for post-loop tests. @@ -857,11 +891,11 @@ Lint/Loop: # Do not use nested method definitions. Lint/NestedMethodDefinition: - Enabled: false + Enabled: true # Do not omit the accumulator when calling `next` in a `reduce`/`inject` block. Lint/NextWithoutAccumulator: - Enabled: false + Enabled: true # Checks for method calls with a space before the opening parenthesis. Lint/ParenthesesAsGroupedExpression: @@ -870,11 +904,11 @@ Lint/ParenthesesAsGroupedExpression: # Checks for `rand(1)` calls. Such calls always return `0` and most likely # a mistake. Lint/RandOne: - Enabled: false + Enabled: true # Use parentheses in the method call to avoid confusion about precedence. Lint/RequireParentheses: - Enabled: false + Enabled: true # Avoid rescuing the Exception class. Lint/RescueException: @@ -909,7 +943,7 @@ Lint/UnusedMethodArgument: # Unreachable code. Lint/UnreachableCode: - Enabled: false + Enabled: true # Checks for useless access modifiers. Lint/UselessAccessModifier: @@ -921,19 +955,19 @@ Lint/UselessAssignment: # Checks for comparison of something with itself. Lint/UselessComparison: - Enabled: false + Enabled: true # Checks for useless `else` in `begin..end` without `rescue`. Lint/UselessElseWithoutRescue: - Enabled: false + Enabled: true # Checks for useless setter call to a local variable. Lint/UselessSetterCall: - Enabled: false + Enabled: true # Possible use of operator/literal/variable in void context. Lint/Void: - Enabled: false + Enabled: true ##################### Performance ############################ @@ -942,11 +976,10 @@ Lint/Void: Performance/Casecmp: Enabled: true -# TODO: Enable DoubleStartEndWith Cop. # Use `str.{start,end}_with?(x, ..., y, ...)` instead of # `str.{start,end}_with?(x, ...) || str.{start,end}_with?(y, ...)`. Performance/DoubleStartEndWith: - Enabled: false + Enabled: true # TODO: Enable EndWith Cop. # Use `end_with?` instead of a regex match anchored to the end of a string. @@ -957,10 +990,9 @@ Performance/EndWith: Performance/LstripRstrip: Enabled: true -# TODO: Enable RangeInclude Cop. # Use `Range#cover?` instead of `Range#include?`. Performance/RangeInclude: - Enabled: false + Enabled: true # TODO: Enable RedundantBlockCall Cop. # Use `yield` instead of `block.call`. @@ -980,16 +1012,14 @@ Performance/RedundantMerge: MaxKeyValuePairs: 2 Enabled: false -# TODO: Enable RedundantSortBy Cop. # Use `sort` instead of `sort_by { |x| x }`. Performance/RedundantSortBy: - Enabled: false + Enabled: true -# TODO: Enable StartWith Cop. # Use `start_with?` instead of a regex match anchored to the beginning of a # string. Performance/StartWith: - Enabled: false + Enabled: true # Use `tr` instead of `gsub` when you are replacing the same number of # characters. Use `delete` instead of `gsub` when you are deleting @@ -997,10 +1027,9 @@ Performance/StartWith: Performance/StringReplacement: Enabled: true -# TODO: Enable TimesMap Cop. # Checks for `.times.map` calls. Performance/TimesMap: - Enabled: false + Enabled: true ##################### Rails ################################## @@ -1025,11 +1054,11 @@ Rails/Delegate: # Prefer `find_by` over `where.first`. Rails/FindBy: - Enabled: false + Enabled: true # Prefer `all.find_each` over `all.find`. Rails/FindEach: - Enabled: false + Enabled: true # Prefer has_many :through to has_and_belongs_to_many. Rails/HasAndBelongsToMany: @@ -1041,7 +1070,7 @@ Rails/Output: # Checks for incorrect grammar when using methods like `3.day.ago`. Rails/PluralizationGrammar: - Enabled: false + Enabled: true # Checks for `read_attribute(:attr)` and `write_attribute(:attr, val)`. Rails/ReadWriteAttribute: @@ -1049,7 +1078,7 @@ Rails/ReadWriteAttribute: # Checks the arguments of ActiveRecord scopes. Rails/ScopeArgs: - Enabled: false + Enabled: true # Checks the correct usage of time zone aware methods. # http://danilenko.org/2012/7/6/rails_timezones @@ -1059,3 +1088,68 @@ Rails/TimeZone: # Use validates :attribute, hash of validations. Rails/Validation: Enabled: false + +Rails/UniqBeforePluck: + Enabled: false + +##################### RSpec ################################## + +# Check that instances are not being stubbed globally. +RSpec/AnyInstance: + Enabled: false + +# Check that the first argument to the top level describe is the tested class or +# module. +RSpec/DescribeClass: + Enabled: false + +# Use `described_class` for tested class / module. +RSpec/DescribeMethod: + Enabled: false + +# Checks that the second argument to top level describe is the tested method +# name. +RSpec/DescribedClass: + Enabled: false + +# Checks for long example. +RSpec/ExampleLength: + Enabled: false + Max: 5 + +# Do not use should when describing your tests. +RSpec/ExampleWording: + Enabled: false + CustomTransform: + be: is + have: has + not: does not + IgnoredWords: [] + +# Checks the file and folder naming of the spec file. +RSpec/FilePath: + Enabled: false + CustomTransform: + RuboCop: rubocop + RSpec: rspec + +# Checks if there are focused specs. +RSpec/Focus: + Enabled: true + +# Checks for the usage of instance variables. +RSpec/InstanceVariable: + Enabled: false + +# Checks for multiple top-level describes. +RSpec/MultipleDescribes: + Enabled: false + +# Enforces the usage of the same method on all negative message expectations. +RSpec/NotToNot: + EnforcedStyle: not_to + Enabled: true + +# Prefer using verifying doubles over normal doubles. +RSpec/VerifiedDoubles: + Enabled: false diff --git a/.vagrant_enabled b/.vagrant_enabled new file mode 100644 index 0000000000..e69de29bb2 diff --git a/CHANGELOG b/CHANGELOG index 6cdfdefe38..bb5bde9b08 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,140 @@ Please view this file on the master branch, on stable branches it's out of date. +v 8.9.0 (unreleased) + - Fix Error 500 when using closes_issues API with an external issue tracker + - Add more information into RSS feed for issues (Alexander Matyushentsev) + - Bulk assign/unassign labels to issues. + - Ability to prioritize labels !4009 / !3205 (Thijs Wouters) + - Fix endless redirections when accessing user OAuth applications when they are disabled + - Allow enabling wiki page events from Webhook management UI + - Bump rouge to 1.11.0 + - Fix issue with arrow keys not working in search autocomplete dropdown + - Fix an issue where note polling stopped working if a window was in the + background during a refresh. + - Make EmailsOnPushWorker use Sidekiq mailers queue + - Fix wiki page events' webhook to point to the wiki repository + - Don't show tags for revert and cherry-pick operations + - Fix issue todo not remove when leave project !4150 (Long Nguyen) + - Allow customisable text on the 'nearly there' page after a user signs up + - Bump recaptcha gem to 3.0.0 to remove deprecated stoken support + - Fix SVG sanitizer to allow more elements + - Allow forking projects with restricted visibility level + - Added descriptions to notification settings dropdown + - Improve note validation to prevent errors when creating invalid note via API + - Reduce number of fog gem dependencies + - Remove project notification settings associated with deleted projects + - Fix 404 page when viewing TODOs that contain milestones or labels in different projects + - Add a metric for the number of new Redis connections created by a transaction + - Fix Error 500 when viewing a blob with binary characters after the 1024-byte mark + - Redesign navigation for project pages + - Fix groups API to list only user's accessible projects + - Add Environments and Deployments + - Redesign account and email confirmation emails + - Don't fail builds for projects that are deleted + - Support Docker Registry manifest v1 + - `git clone https://host/namespace/project` now works, in addition to using the `.git` suffix + - Bump nokogiri to 1.6.8 + - Use gitlab-shell v3.0.0 + - Upgrade to jQuery 2 + - Use Knapsack to evenly distribute tests across multiple nodes + - Add `sha` parameter to MR merge API, to ensure only reviewed changes are merged + - Don't allow MRs to be merged when commits were added since the last review / page load + - Add DB index on users.state + - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database + - Changed the Slack build message to use the singular duration if necessary (Aran Koning) + - Links from a wiki page to other wiki pages should be rewritten as expected + - Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos) + - Fix issues filter when ordering by milestone + - Added artifacts:when to .gitlab-ci.yml - this requires GitLab Runner 1.3 + - Bamboo Service: Fix missing credentials & URL handling when base URL contains a path (Benjamin Schmid) + - TeamCity Service: Fix URL handling when base URL contains a path + - Todos will display target state if issuable target is 'Closed' or 'Merged' + - Fix bug when sorting issues by milestone due date and filtering by two or more labels + - Add support for using Yubikeys (U2F) for two-factor authentication + - Link to blank group icon doesn't throw a 404 anymore + - Remove 'main language' feature + - Pipelines can be canceled only when there are running builds + - Use downcased path to container repository as this is expected path by Docker + - Projects pending deletion will render a 404 page + - Measure queue duration between gitlab-workhorse and Rails + - Make Omniauth providers specs to not modify global configuration + - Make authentication service for Container Registry to be compatible with < Docker 1.11 + - Add Application Setting to configure Container Registry token expire delay (default 5min) + - Cache assigned issue and merge request counts in sidebar nav + - Use Knapsack only in CI environment + - Cache project build count in sidebar nav + - Add milestone expire date to the right sidebar + - Manually mark a issue or merge request as a todo + - Fix markdown_spec to use before instead of before(:all) to properly cleanup database after testing + - Reduce number of queries needed to render issue labels in the sidebar + - Improve error handling importing projects + - Remove duplicated notification settings + - Put project Files and Commits tabs under Code tab + - Decouple global notification level from user model + - Replace Colorize with Rainbow for coloring console output in Rake tasks. + - Add workhorse controller and API helpers + - An indicator is now displayed at the top of the comment field for confidential issues. + - RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented + - Improve issuables APIs performance when accessing notes !4471 + - External links now open in a new tab + - Prevent default actions of disabled buttons and links + - Markdown editor now correctly resets the input value on edit cancellation !4175 + - Toggling a task list item in a issue/mr description does not creates a Todo for mentions + - Improved UX of date pickers on issue & milestone forms + - Cache on the database if a project has an active external issue tracker. + - Put project Labels and Milestones pages links under Issues and Merge Requests tabs as subnav + - All classes in the Banzai::ReferenceParser namespace are now instrumented + - Remove deprecated issues_tracker and issues_tracker_id from project model + - Allow users to create confidential issues in private projects + - Measure CPU time for instrumented methods + - Instrument private methods and private instance methods by default instead just public methods + - Only show notes through JSON on confidential issues that the user has access to + - Updated the allocations Gem to version 1.0.5 + - The background sampler now ignores classes without names + - Update design for `Close` buttons + - New custom icons for navigation + - Horizontally scrolling navigation on project, group, and profile settings pages + - Hide global side navigation by default + - Fix project Star/Unstar project button tooltip + - Remove tanuki logo from side navigation; center on top nav + - Include user relationships when retrieving award_emoji + - Various associations are now eager loaded when parsing issue references to reduce the number of queries executed + +v 8.8.5 (unreleased) + - Ensure branch cleanup regardless of whether the GitHub import process succeeds + - Fix todos page throwing errors when you have a project pending deletion + - Reduce number of SQL queries when rendering user references + - Import GitHub repositories respecting the API rate limit + - Fix importer for GitHub comments on diff + - Disable Webhooks before proceeding with the GitHub import + - Fix incremental trace upload API when using multi-byte UTF-8 chars in trace + +v 8.8.4 + - Fix LDAP-based login for users with 2FA enabled. !4493 + +v 8.8.3 + - Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312 + - Fixed JS error when trying to remove discussion form. !4303 + - Fixed issue with button color when no CI enabled. !4287 + - Fixed potential issue with 2 CI status polling events happening. !3869 + - Improve design of Pipeline view. !4230 + - Fix gitlab importer failing to import new projects due to missing credentials. !4301 + - Fix import URL migration not rescuing with the correct Error. !4321 + - Fix health check access token changing due to old application settings being used. !4332 + - Make authentication service for Container Registry to be compatible with Docker versions before 1.11. !4363 + - Add Application Setting to configure Container Registry token expire delay (default 5 min). !4364 + - Pass the "Remember me" value to the 2FA token form. !4369 + - Fix incorrect links on pipeline page when merge request created from fork. !4376 + - Use downcased path to container repository as this is expected path by Docker. !4420 + - Fix wiki project clone address error (chujinjin). !4429 + - Fix serious performance bug with rendering Markdown with InlineDiffFilter. !4392 + - Fix missing number on generated ordered list element. !4437 + - Prevent disclosure of notes on confidential issues in search results. + v 8.8.2 - Added remove due date button. !4209 - - Fix access to Pipelines by Anonymous user. !4233 - Fix Error 500 when accessing application settings due to nil disabled OAuth sign-in sources. !4242 - - Fix Error 500 in CI charts by gracefully handling commits with no durations. !4245 + - Fix Error 500 in CI charts by gracefully handling commits with no durations. !4245 - Fix table UI on CI builds page. !4249 - Fix backups if registry is disabled. !4263 - Fixed issue with merge button color. !4211 @@ -14,7 +144,7 @@ v 8.8.2 v 8.8.1 - Add documentation for the "Health Check" feature - - Allow anonymous users to access a public project's pipelines + - Allow anonymous users to access a public project's pipelines !4233 - Fix MySQL compatibility in zero downtime migrations helpers - Fix the CI login to Container Registry (the gitlab-ci-token user) @@ -31,6 +161,7 @@ v 8.8.0 - Added inline diff styling for `change_title` system notes. (Adam Butler) - Project#open_branches has been cleaned up and no longer loads entire records into memory. - Escape HTML in commit titles in system note messages + - Improve design of Pipeline View - Fix scope used when accessing container registry - Fix creation of Ci::Commit object which can lead to pending, failed in some scenarios - Improve multiple branch push performance by memoizing permission checking @@ -90,11 +221,18 @@ v 8.8.0 - Improve Issue formatting for the Slack Service (Jeroen van Baarsen) - Fixed advice on invalid permissions on upload path !2948 (Ludovic Perrine) - Allows MR authors to have the source branch removed when merging the MR. !2801 (Jeroen Jacobs) + - When creating a .gitignore file a dropdown with templates will be provided + - Shows the issue/MR list search/filter form and corrects the mobile styling for guest users. #17562 + +v 8.7.7 + - Fix import by `Any Git URL` broken if the URL contains a space v 8.7.6 - Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko) - Fix import from GitLab.com to a private instance failure. !4181 - Fix external imports not finding the import data. !4106 + - Fix notification delay when changing status of an issue + - Bump Workhorse to 0.7.5 so it can serve raw diffs v 8.7.5 - Fix relative links in wiki pages. !4050 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9fe4cf7b0f..f447221477 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,7 +96,7 @@ The designs are made using Antetype (`.atype` files). You can use the [free Antetype viewer (Mac OSX only)] or grab an exported PNG from the design (the PNG is 1:1). -The current designs can be found in the [`gitlab1.atype` file]. +The current designs can be found in the [`gitlab8.atype` file]. ### UI development kit @@ -308,16 +308,14 @@ tests are least likely to receive timely feedback. The workflow to make a merge request is as follows: 1. Fork the project into your personal space on GitLab.com -1. Create a feature branch +1. Create a feature branch, branch away from `master`. 1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code 1. Add your changes to the [CHANGELOG](CHANGELOG) -1. If you are changing the README, some documentation or other things which - have no effect on the tests, add `[ci skip]` somewhere in the commit message - and make sure to read the [documentation styleguide][doc-styleguide] +1. If you are writing documentation, make sure to read the [documentation styleguide][doc-styleguide] 1. If you have multiple commits please combine them into one commit by [squashing them][git-squash] 1. Push the commit(s) to your fork -1. Submit a merge request (MR) to the master branch +1. Submit a merge request (MR) to the `master` branch 1. The MR title should describe the change you want to make 1. The MR description should give a motive for your change and the method you used to achieve it, see the [merge request description format] @@ -407,6 +405,7 @@ description area. Copy-paste it to retain the markdown format. entire line to follow it. This prevents linting tools from generating warnings. - Don't touch neighbouring lines. As an exception, automatic mass refactoring modifications may leave style non-compliant. +1. If the merge request adds any new libraries (gems, JavaScript libraries, etc.), they should conform to our [Licensing guidelines][license-finder-doc]. See the instructions in that document for help if your MR fails the "license-finder" test with a "Dependencies that need approval" error. ## Changes for Stable Releases @@ -532,4 +531,5 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor [scss-styleguide]: doc/development/scss_styleguide.md "SCSS styleguide" [gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design [free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12 -[`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/ +[`gitlab8.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/current/ +[license-finder-doc]: doc/development/licensing.md diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 37c2961c24..4a36342fca 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.7.2 +3.0.0 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 39e898a4f9..8bd6ba8c5c 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.7.1 +0.7.5 diff --git a/Gemfile b/Gemfile index 91ad1706a0..3b28789300 100644 --- a/Gemfile +++ b/Gemfile @@ -18,9 +18,8 @@ gem "mysql2", '~> 0.3.16', group: :mysql gem "pg", '~> 0.18.2', group: :postgres # Authentication libraries -gem 'devise', '~> 3.5.4' +gem 'devise', '~> 4.0' gem 'doorkeeper', '~> 3.1' -gem 'devise-async', '~> 0.9.0' gem 'omniauth', '~> 1.3.1' gem 'omniauth-auth0', '~> 1.4.1' gem 'omniauth-azure-oauth2', '~> 0.0.6' @@ -39,16 +38,17 @@ gem 'rack-oauth2', '~> 1.2.1' gem 'jwt' # Spam and anti-bot protection -gem 'recaptcha', require: 'recaptcha/rails' +gem 'recaptcha', '~> 3.0', require: 'recaptcha/rails' gem 'akismet', '~> 2.0' # Two-factor authentication -gem 'devise-two-factor', '~> 2.0.0' +gem 'devise-two-factor', '~> 3.0.0' gem 'rqrcode-rails3', '~> 0.1.7' -gem 'attr_encrypted', '~> 1.3.4' +gem 'attr_encrypted', '~> 3.0.0' +gem 'u2f', '~> 0.2.1' # Browser detection -gem "browser", '~> 1.0.0' +gem "browser", '~> 2.0.3' # Extracting information from a git repository # Provide access to Gitlab::Git library @@ -73,7 +73,7 @@ gem 'grape-entity', '~> 0.4.2' gem 'rack-cors', '~> 0.4.0', require: 'rack/cors' # Pagination -gem "kaminari", "~> 0.16.3" +gem "kaminari", "~> 0.17.0" # HAML gem "haml-rails", '~> 0.9.0' @@ -84,8 +84,15 @@ gem "carrierwave", '~> 0.10.0' # Drag and Drop UI gem 'dropzonejs-rails', '~> 0.7.1' +# for backups +gem 'fog-aws', '~> 0.9' +gem 'fog-azure', '~> 0.0' +gem 'fog-core', '~> 1.40' +gem 'fog-local', '~> 0.3' +gem 'fog-google', '~> 0.3' +gem 'fog-openstack', '~> 0.1' + # for aws storage -gem "fog", "~> 1.36.0" gem "unf", '~> 0.1.4' # Authorization @@ -105,7 +112,7 @@ gem 'org-ruby', '~> 0.9.12' gem 'creole', '~> 0.5.0' gem 'wikicloth', '0.8.1' gem 'asciidoctor', '~> 1.5.2' -gem 'rouge', '~> 1.10.1' +gem 'rouge', '~> 1.11' # See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s # and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM @@ -121,7 +128,7 @@ group :unicorn do end # State machine -gem "state_machines-activerecord", '~> 0.3.0' +gem "state_machines-activerecord", '~> 0.4.0' # Run events after state machine commits gem 'after_commit_queue' @@ -138,7 +145,7 @@ gem 'redis-namespace' gem "httparty", '~> 0.13.3' # Colored output to console -gem "colorize", '~> 0.7.0' +gem "rainbow", '~> 2.1.0' # GitLab settings gem 'settingslogic', '~> 2.0.9' @@ -178,9 +185,6 @@ gem 'ruby-fogbugz', '~> 0.2.1' # d3 gem 'd3_rails', '~> 3.5.0' -#cal-heatmap -gem 'cal-heatmap-rails', '~> 3.6.0' - # underscore-rails gem "underscore-rails", "~> 1.8.0" @@ -206,6 +210,9 @@ gem 'mousetrap-rails', '~> 1.4.6' # Detect and convert string character encoding gem 'charlock_holmes', '~> 0.7.3' +# Parse duration +gem 'chronic_duration', '~> 0.10.6' + gem "sass-rails", '~> 5.0.0' gem "coffee-rails", '~> 4.1.0' gem "uglifier", '~> 2.7.2' @@ -241,7 +248,7 @@ end group :development do gem "foreman" - gem 'brakeman', '~> 3.2.0', require: false + gem 'brakeman', '~> 3.3.0', require: false gem 'letter_opener_web', '~> 1.3.0' gem 'quiet_assets', '~> 1.0.2' @@ -293,15 +300,19 @@ group :development, :test do gem 'spring-commands-spinach', '~> 1.1.0' gem 'spring-commands-teaspoon', '~> 0.0.2' - gem 'rubocop', '~> 0.38.0', require: false + gem 'rubocop', '~> 0.40.0', require: false + gem 'rubocop-rspec', '~> 1.5.0', require: false gem 'scss_lint', '~> 0.47.0', require: false - gem 'coveralls', '~> 0.8.2', require: false + gem 'coveralls', '~> 0.8.2', require: false gem 'simplecov', '~> 0.11.0', require: false gem 'flog', require: false gem 'flay', require: false gem 'bundler-audit', require: false gem 'benchmark-ips', require: false + + gem "license_finder", require: false + gem 'knapsack' end group :test do @@ -325,7 +336,7 @@ gem "mail_room", "~> 0.7" gem 'email_reply_parser', '~> 0.5.8' ## CI -gem 'activerecord-session_store', '~> 0.1.0' +gem 'activerecord-session_store', '~> 1.0.0' gem "nested_form", '~> 0.3.2' # OAuth diff --git a/Gemfile.lock b/Gemfile.lock index b55764504c..c1c8c175b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,6 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.2) RedCloth (4.2.9) ace-rails-ap (4.0.2) actionmailer (4.2.6) @@ -33,10 +32,12 @@ GEM activemodel (= 4.2.6) activesupport (= 4.2.6) arel (~> 6.0) - activerecord-session_store (0.1.2) - actionpack (>= 4.0.0, < 5) - activerecord (>= 4.0.0, < 5) - railties (>= 4.0.0, < 5) + activerecord-session_store (1.0.0) + actionpack (>= 4.0, < 5.1) + activerecord (>= 4.0, < 5.1) + multi_json (~> 1.11, >= 1.11.2) + rack (>= 1.5.2, < 3) + railties (>= 4.0, < 5.1) activesupport (4.2.6) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) @@ -49,7 +50,7 @@ GEM after_commit_queue (1.3.0) activerecord (>= 3.0) akismet (2.0.0) - allocations (1.0.4) + allocations (1.0.5) arel (6.0.3) asana (0.4.0) faraday (~> 0.9) @@ -58,8 +59,8 @@ GEM oauth2 (~> 1.0) asciidoctor (1.5.3) ast (2.2.0) - attr_encrypted (1.3.4) - encryptor (>= 1.3.0) + attr_encrypted (3.0.1) + encryptor (~> 3.0.0) attr_required (1.0.0) autoprefixer-rails (6.2.3) execjs @@ -69,9 +70,24 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) + azure (0.7.5) + addressable (~> 2.3) + azure-core (~> 0.1) + faraday (~> 0.9) + faraday_middleware (~> 0.10) + json (~> 1.8) + mime-types (>= 1, < 3.0) + nokogiri (~> 1.6) + systemu (~> 2.6) + thor (~> 0.19) + uuid (~> 2.0) + azure-core (0.1.2) + faraday (~> 0.9) + faraday_middleware (~> 0.10) + nokogiri (~> 1.6) babosa (1.0.2) base32 (0.3.2) - bcrypt (3.1.10) + bcrypt (3.1.11) benchmark-ips (2.3.0) better_errors (1.0.1) coderay (>= 1.0.0) @@ -81,17 +97,8 @@ GEM bootstrap-sass (3.3.6) autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) - brakeman (3.2.1) - erubis (~> 2.6) - haml (>= 3.0, < 5.0) - highline (>= 1.6.20, < 2.0) - ruby2ruby (~> 2.3.0) - ruby_parser (~> 3.8.1) - safe_yaml (>= 1.0) - sass (~> 3.0) - slim (>= 1.3.6, < 4.0) - terminal-table (~> 1.4) - browser (1.0.1) + brakeman (3.3.2) + browser (2.0.3) builder (3.2.2) bullet (5.0.0) activesupport (>= 3.0.0) @@ -100,7 +107,6 @@ GEM bundler (~> 1.2) thor (~> 0.18) byebug (8.2.1) - cal-heatmap-rails (3.6.0) capybara (2.6.2) addressable mime-types (>= 1.16) @@ -118,6 +124,8 @@ GEM mime-types (>= 1.16) cause (0.1) charlock_holmes (0.7.3) + chronic_duration (0.10.6) + numerizer (~> 0.1.1) chunky_png (1.3.5) cliver (0.3.2) coderay (1.1.0) @@ -154,21 +162,18 @@ GEM activerecord (>= 3.2.0, < 5.0) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - devise (3.5.4) + devise (4.1.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) + railties (>= 4.1.0, < 5.1) responders - thread_safe (~> 0.1) warden (~> 1.2.3) - devise-async (0.9.0) - devise (~> 3.2) - devise-two-factor (2.0.1) + devise-two-factor (3.0.0) activesupport - attr_encrypted (~> 1.3.2) - devise (~> 3.5.0) + attr_encrypted (>= 1.3, < 4, != 2) + devise (~> 4.0) railties - rotp (~> 2) + rotp (~> 2.0) diff-lcs (1.2.5) diffy (3.0.7) docile (1.1.5) @@ -180,12 +185,12 @@ GEM email_spec (1.6.0) launchy (~> 2.1) mail (~> 2.2) - encryptor (1.3.0) + encryptor (3.0.0) equalizer (0.0.11) erubis (2.7.0) escape_utils (1.1.1) eventmachine (1.0.8) - excon (0.45.4) + excon (0.49.0) execjs (2.6.0) expression_parser (0.9.0) factory_girl (4.5.0) @@ -202,8 +207,6 @@ GEM multi_json ffaker (2.0.0) ffi (1.9.10) - fission (0.5.0) - CFPropertyList (~> 2.2) flay (2.6.1) ruby_parser (~> 3.0) sexp_processor (~> 4.0) @@ -213,109 +216,33 @@ GEM flowdock (0.7.1) httparty (~> 0.7) multi_json - fog (1.36.0) - fog-aliyun (>= 0.1.0) - fog-atmos - fog-aws (>= 0.6.0) - fog-brightbox (~> 0.4) - fog-core (~> 1.32) - fog-dynect (~> 0.0.2) - fog-ecloud (~> 0.1) - fog-google (<= 0.1.0) - fog-json - fog-local - fog-powerdns (>= 0.1.1) - fog-profitbricks - fog-radosgw (>= 0.0.2) - fog-riakcs - fog-sakuracloud (>= 0.0.4) - fog-serverlove - fog-softlayer - fog-storm_on_demand - fog-terremark - fog-vmfusion - fog-voxel - fog-xenserver - fog-xml (~> 0.1.1) - ipaddress (~> 0.5) - nokogiri (~> 1.5, >= 1.5.11) - fog-aliyun (0.1.0) - fog-core (~> 1.27) - fog-json (~> 1.0) - ipaddress (~> 0.8) - xml-simple (~> 1.1) - fog-atmos (0.1.0) - fog-core - fog-xml - fog-aws (0.8.1) + fog-aws (0.9.2) fog-core (~> 1.27) fog-json (~> 1.0) fog-xml (~> 0.1) ipaddress (~> 0.8) - fog-brightbox (0.10.1) - fog-core (~> 1.22) - fog-json - inflecto (~> 0.0.2) - fog-core (1.35.0) + fog-azure (0.0.2) + azure (~> 0.6) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + fog-core (1.40.0) builder - excon (~> 0.45) + excon (~> 0.49) formatador (~> 0.2) - fog-dynect (0.0.2) - fog-core - fog-json - fog-xml - fog-ecloud (0.3.0) - fog-core - fog-xml - fog-google (0.1.0) + fog-google (0.3.2) fog-core fog-json fog-xml fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) - fog-local (0.2.1) + fog-local (0.3.0) fog-core (~> 1.27) - fog-powerdns (0.1.1) - fog-core (~> 1.27) - fog-json (~> 1.0) - fog-xml (~> 0.1) - fog-profitbricks (0.0.5) - fog-core - fog-xml - nokogiri - fog-radosgw (0.0.5) - fog-core (>= 1.21.0) - fog-json - fog-xml (>= 0.0.1) - fog-riakcs (0.1.0) - fog-core - fog-json - fog-xml - fog-sakuracloud (1.7.5) - fog-core - fog-json - fog-serverlove (0.1.2) - fog-core - fog-json - fog-softlayer (1.0.3) - fog-core - fog-json - fog-storm_on_demand (0.1.1) - fog-core - fog-json - fog-terremark (0.1.0) - fog-core - fog-xml - fog-vmfusion (0.1.0) - fission - fog-core - fog-voxel (0.1.0) - fog-core - fog-xml - fog-xenserver (0.2.2) - fog-core - fog-xml + fog-openstack (0.1.6) + fog-core (>= 1.39) + fog-json (>= 1.0) + ipaddress (>= 0.8) fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) @@ -350,7 +277,7 @@ GEM posix-spawn (~> 0.3) gitlab_emoji (0.3.1) gemojione (~> 2.2, >= 2.2.1) - gitlab_git (10.1.0) + gitlab_git (10.1.3) activesupport (~> 4.0) charlock_holmes (~> 0.7.3) github-linguist (~> 4.7.0) @@ -404,7 +331,6 @@ GEM hashie (3.4.3) health_check (1.5.1) rails (>= 2.3.0) - highline (1.7.8) hipchat (1.5.2) httparty mimemagic @@ -424,11 +350,10 @@ GEM httpclient (2.7.0.1) i18n (0.7.0) ice_nine (0.11.1) - inflecto (0.0.2) influxdb (0.2.3) cause json - ipaddress (0.8.2) + ipaddress (0.8.3) jquery-atwho-rails (1.3.2) jquery-rails (4.1.1) rails-dom-testing (>= 1, < 3) @@ -441,10 +366,13 @@ GEM railties (>= 3.2.16) json (1.8.3) jwt (1.5.2) - kaminari (0.16.3) + kaminari (0.17.0) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.10.0) + knapsack (1.11.0) + rake + timecop (>= 0.1.0) launchy (2.4.3) addressable (~> 2.3) letter_opener (1.4.1) @@ -453,6 +381,12 @@ GEM actionmailer (>= 3.2) letter_opener (~> 1.0) railties (>= 3.2) + license_finder (2.1.0) + bundler + httparty + rubyzip + thor + xml-simple licensee (8.0.0) rugged (>= 0.24b) listen (3.0.5) @@ -466,9 +400,9 @@ GEM mime-types (>= 1.16, < 4) mail_room (0.7.0) method_source (0.8.2) - mime-types (2.99.1) + mime-types (2.99.2) mimemagic (0.3.0) - mini_portile2 (2.0.0) + mini_portile2 (2.1.0) minitest (5.7.0) mousetrap-rails (1.4.6) multi_json (1.11.2) @@ -479,8 +413,10 @@ GEM net-ldap (0.12.1) net-ssh (3.0.1) newrelic_rpm (3.14.1.311) - nokogiri (1.6.7.2) - mini_portile2 (~> 2.0.0.rc2) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + numerizer (0.1.1) oauth (0.4.7) oauth2 (1.0.0) faraday (>= 0.8, < 0.10) @@ -549,9 +485,10 @@ GEM orm_adapter (0.5.0) paranoia (2.1.4) activerecord (~> 4.0) - parser (2.3.0.6) + parser (2.3.1.0) ast (~> 2.2) pg (0.18.4) + pkg-config (1.1.7) poltergeist (1.9.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -627,7 +564,7 @@ GEM debugger-ruby_core_source (~> 1.3) rdoc (3.12.2) json (~> 1.4) - recaptcha (1.0.2) + recaptcha (3.0.0) json redcarpet (3.3.3) redis (3.3.0) @@ -655,8 +592,8 @@ GEM responders (2.1.1) railties (>= 4.2.0, < 5.1) rinku (1.7.3) - rotp (2.1.1) - rouge (1.10.1) + rotp (2.1.2) + rouge (1.11.0) rqrcode (0.7.0) chunky_png rqrcode-rails3 (0.1.7) @@ -684,31 +621,31 @@ GEM rspec-retry (0.4.5) rspec-core rspec-support (3.4.1) - rubocop (0.38.0) - parser (>= 2.3.0.6, < 3.0) + rubocop (0.40.0) + parser (>= 2.3.1.0, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) + rubocop-rspec (1.5.0) + rubocop (>= 0.40.0) ruby-fogbugz (0.2.1) crack (~> 0.4) - ruby-progressbar (1.7.5) + ruby-progressbar (1.8.1) ruby-saml (1.1.2) nokogiri (>= 1.5.10) uuid (~> 2.3) - ruby2ruby (2.3.0) - ruby_parser (~> 3.1) - sexp_processor (~> 4.0) - ruby_parser (3.8.1) + ruby_parser (3.8.2) sexp_processor (~> 4.1) rubyntlm (0.5.2) rubypants (0.2.0) + rubyzip (1.2.0) rufus-scheduler (3.1.10) rugged (0.24.0) safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) - sass (3.4.21) + sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) sass (~> 3.1) @@ -757,9 +694,6 @@ GEM tilt (>= 1.3, < 3) six (0.2.0) slack-notifier (1.2.1) - slim (3.0.6) - temple (~> 0.7.3) - tilt (>= 1.3.3, < 2.1) slop (3.6.0) spinach (0.8.10) colorize @@ -786,11 +720,11 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) state_machines (0.4.0) - state_machines-activemodel (0.3.0) - activemodel (~> 4.1) + state_machines-activemodel (0.4.0) + activemodel (>= 4.1, < 5.1) state_machines (>= 0.4.0) - state_machines-activerecord (0.3.0) - activerecord (~> 4.1) + state_machines-activerecord (0.4.0) + activerecord (>= 4.1, < 5.1) state_machines-activemodel (>= 0.3.0) stringex (2.5.2) systemu (2.6.5) @@ -800,10 +734,8 @@ GEM railties (>= 3.2.5, < 6) teaspoon-jasmine (2.2.0) teaspoon (>= 1.0.0) - temple (0.7.6) term-ansicolor (1.3.2) tins (~> 1.0) - terminal-table (1.5.2) test_after_commit (0.4.2) activerecord (>= 3.2) thin (1.6.4) @@ -812,7 +744,8 @@ GEM rack (~> 1.0) thor (0.19.1) thread_safe (0.3.5) - tilt (2.0.2) + tilt (2.0.5) + timecop (0.8.1) timfel-krb5-auth (0.8.3) tinder (1.10.1) eventmachine (~> 1.0) @@ -832,6 +765,7 @@ GEM simple_oauth (~> 0.1.4) tzinfo (1.2.2) thread_safe (~> 0.1) + u2f (0.2.1) uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) @@ -839,7 +773,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (1.0.2) + unicode-display_width (1.0.5) unicorn (4.9.0) kgio (~> 2.6) rack @@ -856,7 +790,7 @@ GEM coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) equalizer (~> 0.0, >= 0.0.9) - warden (1.2.4) + warden (1.2.6) rack (>= 1.0) web-console (2.3.0) activemodel (>= 4.0) @@ -883,7 +817,7 @@ PLATFORMS DEPENDENCIES RedCloth (~> 4.2.9) ace-rails-ap (~> 4.0.2) - activerecord-session_store (~> 0.1.0) + activerecord-session_store (~> 1.0.0) acts-as-taggable-on (~> 3.4) addressable (~> 2.3.8) after_commit_queue @@ -891,7 +825,7 @@ DEPENDENCIES allocations (~> 1.0) asana (~> 0.4.0) asciidoctor (~> 1.5.2) - attr_encrypted (~> 1.3.4) + attr_encrypted (~> 3.0.0) awesome_print (~> 1.2.0) babosa (~> 1.0.2) base32 (~> 0.3.0) @@ -899,27 +833,25 @@ DEPENDENCIES better_errors (~> 1.0.1) binding_of_caller (~> 0.7.2) bootstrap-sass (~> 3.3.0) - brakeman (~> 3.2.0) - browser (~> 1.0.0) + brakeman (~> 3.3.0) + browser (~> 2.0.3) bullet bundler-audit byebug - cal-heatmap-rails (~> 3.6.0) capybara (~> 2.6.2) capybara-screenshot (~> 1.0.0) carrierwave (~> 0.10.0) charlock_holmes (~> 0.7.3) + chronic_duration (~> 0.10.6) coffee-rails (~> 4.1.0) - colorize (~> 0.7.0) connection_pool (~> 2.0) coveralls (~> 0.8.2) creole (~> 0.5.0) d3_rails (~> 3.5.0) database_cleaner (~> 1.4.0) default_value_for (~> 3.0.0) - devise (~> 3.5.4) - devise-async (~> 0.9.0) - devise-two-factor (~> 2.0.0) + devise (~> 4.0) + devise-two-factor (~> 3.0.0) diffy (~> 3.0.3) doorkeeper (~> 3.1) dropzonejs-rails (~> 0.7.1) @@ -929,7 +861,12 @@ DEPENDENCIES ffaker (~> 2.0.0) flay flog - fog (~> 1.36.0) + fog-aws (~> 0.9) + fog-azure (~> 0.0) + fog-core (~> 1.40) + fog-google (~> 0.3) + fog-local (~> 0.3) + fog-openstack (~> 0.1) font-awesome-rails (~> 4.2) foreman fuubar (~> 2.0.0) @@ -957,8 +894,10 @@ DEPENDENCIES jquery-turbolinks (~> 2.1.0) jquery-ui-rails (~> 5.0.0) jwt - kaminari (~> 0.16.3) + kaminari (~> 0.17.0) + knapsack letter_opener_web (~> 1.3.0) + license_finder licensee (~> 8.0.0) loofah (~> 2.0.3) mail_room (~> 0.7) @@ -998,10 +937,11 @@ DEPENDENCIES rack-oauth2 (~> 1.2.1) rails (= 4.2.6) rails-deprecated_sanitizer (~> 1.0.3) + rainbow (~> 2.1.0) raphael-rails (~> 2.1.2) rblineprof rdoc (~> 3.6) - recaptcha + recaptcha (~> 3.0) redcarpet (~> 3.3.3) redis (~> 3.2) redis-namespace @@ -1009,11 +949,12 @@ DEPENDENCIES request_store (~> 1.3.0) rerun (~> 0.11.0) responders (~> 2.0) - rouge (~> 1.10.1) + rouge (~> 1.11) rqrcode-rails3 (~> 0.1.7) rspec-rails (~> 3.4.0) rspec-retry - rubocop (~> 0.38.0) + rubocop (~> 0.40.0) + rubocop-rspec (~> 1.5.0) ruby-fogbugz (~> 0.2.1) sanitize (~> 2.0) sass-rails (~> 5.0.0) @@ -1038,7 +979,7 @@ DEPENDENCIES spring-commands-spinach (~> 1.1.0) spring-commands-teaspoon (~> 0.0.2) sprockets (~> 3.6.0) - state_machines-activerecord (~> 0.3.0) + state_machines-activerecord (~> 0.4.0) task_list (~> 1.0.2) teaspoon (~> 1.1.0) teaspoon-jasmine (~> 2.2.0) @@ -1046,6 +987,7 @@ DEPENDENCIES thin (~> 1.6.1) tinder (~> 1.10.0) turbolinks (~> 2.5.0) + u2f (~> 0.2.1) uglifier (~> 2.7.2) underscore-rails (~> 1.8.0) unf (~> 0.1.4) @@ -1058,4 +1000,4 @@ DEPENDENCIES wikicloth (= 0.8.1) BUNDLED WITH - 1.12.3 + 1.12.5 diff --git a/README.md b/README.md index 418d06a45a..fee93d5f9c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # GitLab [![build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master) -[![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq) [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq) -[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) ## Canonical source diff --git a/Rakefile b/Rakefile index 5dd389d567..85fff2d51e 100755 --- a/Rakefile +++ b/Rakefile @@ -8,3 +8,5 @@ relative_url_conf = File.expand_path('../config/initializers/relative_url', __FI require relative_url_conf if File.exist?("#{relative_url_conf}.rb") Gitlab::Application.load_tasks + +Knapsack.load_tasks if defined?(Knapsack) diff --git a/VERSION b/VERSION index d439d82b62..141cafb8e0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.8.2 \ No newline at end of file +8.9.0-rc4 diff --git a/app/assets/images/mailers/gitlab_header_logo.png b/app/assets/images/mailers/gitlab_header_logo.png new file mode 100644 index 0000000000..35ca186088 Binary files /dev/null and b/app/assets/images/mailers/gitlab_header_logo.png differ diff --git a/app/assets/images/mailers/gitlab_tanuki_2x.png b/app/assets/images/mailers/gitlab_tanuki_2x.png new file mode 100644 index 0000000000..551dd6ce2c Binary files /dev/null and b/app/assets/images/mailers/gitlab_tanuki_2x.png differ diff --git a/app/assets/javascripts/LabelManager.js.coffee b/app/assets/javascripts/LabelManager.js.coffee new file mode 100644 index 0000000000..365a062bb8 --- /dev/null +++ b/app/assets/javascripts/LabelManager.js.coffee @@ -0,0 +1,84 @@ +class @LabelManager + errorMessage: 'Unable to update label prioritization at this time' + + constructor: (opts = {}) -> + # Defaults + { + @togglePriorityButton = $('.js-toggle-priority') + @prioritizedLabels = $('.js-prioritized-labels') + @otherLabels = $('.js-other-labels') + } = opts + + @prioritizedLabels.sortable( + items: 'li' + placeholder: 'list-placeholder' + axis: 'y' + update: @onPrioritySortUpdate.bind(@) + ) + + @bindEvents() + + bindEvents: -> + @togglePriorityButton.on 'click', @, @onTogglePriorityClick + + onTogglePriorityClick: (e) -> + e.preventDefault() + _this = e.data + $btn = $(e.currentTarget) + $label = $("##{$btn.data('domId')}") + action = if $btn.parents('.js-prioritized-labels').length then 'remove' else 'add' + _this.toggleLabelPriority($label, action) + + toggleLabelPriority: ($label, action, persistState = true) -> + _this = @ + url = $label.find('.js-toggle-priority').data 'url' + + $target = @prioritizedLabels + $from = @otherLabels + + # Optimistic update + if action is 'remove' + $target = @otherLabels + $from = @prioritizedLabels + + if $from.find('li').length is 1 + $from.find('.empty-message').show() + + if not $target.find('li').length + $target.find('.empty-message').hide() + + $label.detach().appendTo($target) + + # Return if we are not persisting state + return unless persistState + + if action is 'remove' + xhr = $.ajax url: url, type: 'DELETE' + else + xhr = @savePrioritySort($label, action) + + xhr.fail @rollbackLabelPosition.bind(@, $label, action) + + onPrioritySortUpdate: -> + xhr = @savePrioritySort() + + xhr.fail -> + new Flash(@errorMessage, 'alert') + + savePrioritySort: () -> + $.post + url: @prioritizedLabels.data('url') + data: + label_ids: @getSortedLabelsIds() + + rollbackLabelPosition: ($label, originalAction)-> + action = if originalAction is 'remove' then 'add' else 'remove' + @toggleLabelPriority($label, action, false) + + new Flash(@errorMessage, 'alert') + + getSortedLabelsIds: -> + sortedIds = [] + @prioritizedLabels.find('li').each -> + sortedIds.push $(@).data 'id' + sortedIds diff --git a/app/assets/javascripts/activities.js.coffee b/app/assets/javascripts/activities.js.coffee index 5092e824e6..ed5a5d0260 100644 --- a/app/assets/javascripts/activities.js.coffee +++ b/app/assets/javascripts/activities.js.coffee @@ -1,11 +1,14 @@ class @Activities constructor: -> - Pager.init 20, true + Pager.init 20, true, false, @updateTooltips $(".event-filter-link").on "click", (event) => event.preventDefault() @toggleFilter($(event.currentTarget)) @reloadActivities() + updateTooltips: -> + gl.utils.localTimeAgo($('.js-timeago', '#activity')) + reloadActivities: -> $(".content_list").html '' Pager.init 20, true diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index bffce5a0c0..6c16f89cef 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -4,7 +4,7 @@ # 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 jquery +#= require jquery2 #= require jquery-ui/autocomplete #= require jquery-ui/datepicker #= require jquery-ui/draggable @@ -18,8 +18,6 @@ #= require jquery.atwho #= require jquery.scrollTo #= require jquery.turbolinks -#= require d3 -#= require cal-heatmap #= require turbolinks #= require autosave #= require bootstrap/affix @@ -37,7 +35,6 @@ #= require raphael #= require g.raphael #= require g.bar -#= require Chart #= require branch-graph #= require ace/ace #= require ace/ext-searchbox @@ -52,9 +49,17 @@ #= require shortcuts_network #= require jquery.nicescroll #= require date.format -#= require_tree . +#= require_directory ./behaviors +#= require_directory ./blob +#= require_directory ./ci +#= require_directory ./commit +#= require_directory ./extensions +#= require_directory ./lib +#= require_directory ./u2f +#= require_directory . #= require fuzzaldrin-plus #= require cropper +#= require u2f window.slugify = (text) -> text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() @@ -120,6 +125,7 @@ window.onload = -> setTimeout shiftWindow, 100 $ -> + gl.utils.preventDisabledButtons() bootstrapBreakpoint = bp.getBreakpointSize() $(".nicescroll").niceScroll(cursoropacitymax: '0.4', cursorcolor: '#FFF', cursorborder: "1px solid #FFF") @@ -157,19 +163,6 @@ $ -> $el.data('placement') || 'bottom' ) - $('.header-logo .home').tooltip( - placement: (_, el) -> - $el = $(el) - if $('.page-with-sidebar').hasClass('page-sidebar-collapsed') then 'right' else 'bottom' - container: 'body' - ) - - $('.page-with-sidebar').tooltip( - selector: '.sidebar-collapsed .nav-sidebar a, .sidebar-collapsed a.sidebar-user' - placement: 'right' - container: 'body' - ) - # Form submitter $('.trigger-submit').on 'change', -> $(@).parents('form').submit() @@ -202,6 +195,7 @@ $ -> $('.navbar-toggle').on 'click', -> $('.header-content .title').toggle() + $('.header-content .header-logo').toggle() $('.header-content .navbar-collapse').toggle() $('.navbar-toggle').toggleClass('active') $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left") @@ -220,6 +214,10 @@ $ -> form = btn.closest("form") new ConfirmDangerModal(form, text) + + $(document).on 'click', 'button', -> + $(this).blur() + $('input[type="search"]').each -> $this = $(this) $this.attr 'value', $this.val() @@ -232,7 +230,6 @@ $ -> $this.attr 'value', $this.val() $sidebarGutterToggle = $('.js-sidebar-toggle') - $navIconToggle = $('.toggle-nav-collapse') $(document) .off 'breakpoint:change' @@ -242,42 +239,6 @@ $ -> if $gutterIcon.hasClass('fa-angle-double-right') $sidebarGutterToggle.trigger('click') - $navIcon = $navIconToggle.find('.fa') - if $navIcon.hasClass('fa-angle-left') - $navIconToggle.trigger('click') - - $(document) - .off 'click', '.js-sidebar-toggle' - .on 'click', '.js-sidebar-toggle', (e, triggered) -> - e.preventDefault() - $this = $(this) - $thisIcon = $this.find 'i' - $allGutterToggleIcons = $('.js-sidebar-toggle i') - if $thisIcon.hasClass('fa-angle-double-right') - $allGutterToggleIcons - .removeClass('fa-angle-double-right') - .addClass('fa-angle-double-left') - $('aside.right-sidebar') - .removeClass('right-sidebar-expanded') - .addClass('right-sidebar-collapsed') - $('.page-with-sidebar') - .removeClass('right-sidebar-expanded') - .addClass('right-sidebar-collapsed') - else - $allGutterToggleIcons - .removeClass('fa-angle-double-left') - .addClass('fa-angle-double-right') - $('aside.right-sidebar') - .removeClass('right-sidebar-collapsed') - .addClass('right-sidebar-expanded') - $('.page-with-sidebar') - .removeClass('right-sidebar-collapsed') - .addClass('right-sidebar-expanded') - if not triggered - $.cookie("collapsed_gutter", - $('.right-sidebar') - .hasClass('right-sidebar-collapsed'), { path: '/' }) - fitSidebarForSize = -> oldBootstrapBreakpoint = bootstrapBreakpoint bootstrapBreakpoint = bp.getBreakpointSize() @@ -290,9 +251,10 @@ $ -> $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) $(window) - .off "resize" - .on "resize", (e) -> + .off "resize.app" + .on "resize.app", (e) -> fitSidebarForSize() + gl.awardsHandler = new AwardsHandler() checkInitialSidebarSize() new Aside() diff --git a/app/assets/javascripts/awards_handler.coffee b/app/assets/javascripts/awards_handler.coffee index bf95e06b4e..136db8ee14 100644 --- a/app/assets/javascripts/awards_handler.coffee +++ b/app/assets/javascripts/awards_handler.coffee @@ -1,201 +1,354 @@ class @AwardsHandler - constructor: (@getEmojisUrl, @postEmojiUrl, @noteableType, @noteableId, @unicodes) -> - $('.js-add-award').on 'click', (event) => - event.stopPropagation() - event.preventDefault() - @showEmojiMenu() + constructor: -> - $('html').on 'click', (event) -> - if !$(event.target).closest('.emoji-menu').length + @aliases = gl.emojiAliases() + + $(document) + .off 'click', '.js-add-award' + .on 'click', '.js-add-award', (e) => + e.stopPropagation() + e.preventDefault() + + @showEmojiMenu $(e.currentTarget) + + $('html').on 'click', (e) -> + $target = $ e.target + + unless $target.closest('.emoji-menu-content').length + $('.js-awards-block.current').removeClass 'current' + + unless $target.closest('.emoji-menu').length if $('.emoji-menu').is(':visible') + $('.js-add-award.is-active').removeClass 'is-active' $('.emoji-menu').removeClass 'is-visible' - $('.awards') - .off 'click' - .on 'click', '.js-emoji-btn', @handleClick + $(document) + .off 'click', '.js-emoji-btn' + .on 'click', '.js-emoji-btn', (e) => + e.preventDefault() - @renderFrequentlyUsedBlock() + $target = $ e.currentTarget + emoji = $target.find('.icon').data 'emoji' - handleClick: (e) -> - e.preventDefault() - emoji = $(this) - .find('.icon') - .data 'emoji' + $target.closest('.js-awards-block').addClass 'current' + @addAward @getVotesBlock(), @getAwardUrl(), emoji - if emoji is 'thumbsup' and awardsHandler.didUserClickEmoji $(this), 'thumbsdown' - awardsHandler.addAward 'thumbsdown' - else if emoji is 'thumbsdown' and awardsHandler.didUserClickEmoji $(this), 'thumbsup' - awardsHandler.addAward 'thumbsup' + showEmojiMenu: ($addBtn) -> - awardsHandler.addAward emoji + $menu = $ '.emoji-menu' - $(this).trigger 'blur' + if $addBtn.hasClass 'js-note-emoji' + $addBtn.parents('.note').find('.js-awards-block').addClass 'current' + else + $addBtn.closest('.js-awards-block').addClass 'current' - didUserClickEmoji: (that, emoji) -> - if $(that).siblings("button:has([data-emoji=#{emoji}])").attr('data-original-title') - $(that).siblings("button:has([data-emoji=#{emoji}])").attr('data-original-title').indexOf('me') > -1 + if $menu.length + $holder = $addBtn.closest('.js-award-holder') - showEmojiMenu: -> - if $('.emoji-menu').length - if $('.emoji-menu').is '.is-visible' - $('.emoji-menu').removeClass 'is-visible' + if $menu.is '.is-visible' + $addBtn.removeClass 'is-active' + $menu.removeClass 'is-visible' $('#emoji_search').blur() else - $('.emoji-menu').addClass 'is-visible' + $addBtn.addClass 'is-active' + @positionMenu($menu, $addBtn) + + $menu.addClass 'is-visible' $('#emoji_search').focus() else - $('.js-add-award').addClass 'is-loading' - $.get @getEmojisUrl, (response) => - $('.js-add-award').removeClass 'is-loading' - $('.js-award-holder').append response + $addBtn.addClass 'is-loading is-active' + url = @getAwardMenuUrl() + + @createEmojiMenu url, => + $addBtn.removeClass 'is-loading' + $menu = $('.emoji-menu') + @positionMenu($menu, $addBtn) + @renderFrequentlyUsedBlock() unless @frequentEmojiBlockRendered + setTimeout => - $('.emoji-menu').addClass 'is-visible' + $menu.addClass 'is-visible' $('#emoji_search').focus() @setupSearch() , 200 - addAward: (emoji) -> - @postEmoji emoji, => - @addAwardToEmojiBar(emoji) + + createEmojiMenu: (awardMenuUrl, callback) -> + + $.get awardMenuUrl, (response) -> + $('body').append response + callback() + + + positionMenu: ($menu, $addBtn) -> + + 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" + + if position? and position is 'right' + css.left = "#{($addBtn.offset().left - $menu.outerWidth()) + 20}px" + $menu.addClass 'is-aligned-right' + else + css.left = "#{$addBtn.offset().left}px" + $menu.removeClass 'is-aligned-right' + + $menu.css(css) + + + addAward: (votesBlock, awardUrl, emoji, checkMutuality = true, callback) -> + + emoji = @normilizeEmojiName emoji + + @postEmoji awardUrl, emoji, => + @addAwardToEmojiBar votesBlock, emoji, checkMutuality + callback?() $('.emoji-menu').removeClass 'is-visible' - addAwardToEmojiBar: (emoji) -> - @addEmojiToFrequentlyUsedList(emoji) - if @exist(emoji) - if @isActive(emoji) - @decrementCounter(emoji) + addAwardToEmojiBar: (votesBlock, emoji, checkForMutuality = true) -> + + @checkMutuality votesBlock, emoji if checkForMutuality + @addEmojiToFrequentlyUsedList emoji + + emoji = @normilizeEmojiName emoji + $emojiButton = @findEmojiIcon(votesBlock, emoji).parent() + + if $emojiButton.length > 0 + if @isActive $emojiButton + @decrementCounter $emojiButton, emoji else - counter = @findEmojiIcon(emoji).siblings('.js-counter') - counter.text(parseInt(counter.text()) + 1) - counter.parent().addClass('active') - @addMeToAuthorList(emoji) + counter = $emojiButton.find '.js-counter' + counter.text parseInt(counter.text()) + 1 + $emojiButton.addClass 'active' + @addMeToUserList votesBlock, emoji + @animateEmoji $emojiButton else - @createEmoji(emoji) + votesBlock.removeClass 'hidden' + @createEmoji votesBlock, emoji - exist: (emoji) -> - @findEmojiIcon(emoji).length > 0 - isActive: (emoji) -> - @findEmojiIcon(emoji).parent().hasClass('active') + getVotesBlock: -> - decrementCounter: (emoji) -> - counter = @findEmojiIcon(emoji).siblings('.js-counter') - emojiIcon = counter.parent() - if parseInt(counter.text()) > 1 - counter.text(parseInt(counter.text()) - 1) - emojiIcon.removeClass('active') - @removeMeFromAuthorList(emoji) - else if emoji == 'thumbsup' || emoji == 'thumbsdown' - emojiIcon.tooltip('destroy') - counter.text(0) - emojiIcon.removeClass('active') - @removeMeFromAuthorList(emoji) + currentBlock = $ '.js-awards-block.current' + return if currentBlock.length then currentBlock else $('.js-awards-block').eq 0 + + + getAwardUrl: -> return @getVotesBlock().data 'award-url' + + + checkMutuality: (votesBlock, emoji) -> + + awardUrl = @getAwardUrl() + + if emoji in [ 'thumbsup', 'thumbsdown' ] + mutualVote = if emoji is 'thumbsup' then 'thumbsdown' else 'thumbsup' + $emojiButton = votesBlock.find("[data-emoji=#{mutualVote}]").parent() + isAlreadyVoted = $emojiButton.hasClass 'active' + + if isAlreadyVoted + @showEmojiLoader $emojiButton + @addAward votesBlock, awardUrl, mutualVote, false, -> + $emojiButton.removeClass 'is-loading' + + + showEmojiLoader: ($emojiButton) -> + + $loader = $emojiButton.find '.fa-spinner' + + unless $loader.length + $emojiButton.append '' + + $emojiButton.addClass 'is-loading' + + + isActive: ($emojiButton) -> $emojiButton.hasClass 'active' + + + decrementCounter: ($emojiButton, emoji) -> + + counter = $ '.js-counter', $emojiButton + counterNumber = parseInt counter.text(), 10 + + if counterNumber > 1 + counter.text counterNumber - 1 + @removeMeFromUserList $emojiButton, emoji + else if emoji is 'thumbsup' or emoji is 'thumbsdown' + $emojiButton.tooltip 'destroy' + counter.text '0' + @removeMeFromUserList $emojiButton, emoji + @removeEmoji $emojiButton if $emojiButton.parents('.note').length else - emojiIcon.tooltip('destroy') - emojiIcon.remove() + @removeEmoji $emojiButton + + $emojiButton.removeClass 'active' + + + removeEmoji: ($emojiButton) -> + + $emojiButton.tooltip('destroy') + $emojiButton.remove() + + $votesBlock = @getVotesBlock() + + if $votesBlock.find('.js-emoji-btn').length is 0 + $votesBlock.addClass 'hidden' + + + getAwardTooltip: ($awardBlock) -> + + return $awardBlock.attr('data-original-title') or $awardBlock.attr('data-title') or '' + + + removeMeFromUserList: ($emojiButton, emoji) -> + + awardBlock = $emojiButton + originalTitle = @getAwardTooltip awardBlock + + authors = originalTitle.split ', ' + authors.splice authors.indexOf('me'), 1 + + newAuthors = authors.join ', ' - removeMeFromAuthorList: (emoji) -> - awardBlock = @findEmojiIcon(emoji).parent() - authors = awardBlock - .attr('data-original-title') - .split(', ') - authors.splice(authors.indexOf('me'),1) awardBlock - .closest('.js-emoji-btn') - .attr('data-original-title', authors.join(', ')) - @resetTooltip(awardBlock) + .closest '.js-emoji-btn' + .removeData 'original-title' + .attr 'data-original-title', newAuthors + + @resetTooltip awardBlock + + + addMeToUserList: (votesBlock, emoji) -> + + awardBlock = @findEmojiIcon(votesBlock, emoji).parent() + origTitle = @getAwardTooltip awardBlock + users = [] - addMeToAuthorList: (emoji) -> - awardBlock = @findEmojiIcon(emoji).parent() - origTitle = awardBlock.attr('data-original-title').trim() - authors = [] if origTitle - authors = origTitle.split(', ') - authors.push('me') - awardBlock.attr('data-original-title', authors.join(', ')) - @resetTooltip(awardBlock) + users = origTitle.trim().split ', ' + + users.push 'me' + awardBlock.attr 'title', users.join ', ' + + @resetTooltip awardBlock + resetTooltip: (award) -> - award.tooltip('destroy') - # "destroy" call is asynchronous and there is no appropriate callback on it, this is why we need to set timeout. - setTimeout (-> - award.tooltip() - ), 200 + award.tooltip 'destroy' + + # 'destroy' call is asynchronous and there is no appropriate callback on it, this is why we need to set timeout. + cb = -> award.tooltip() + setTimeout cb, 200 - createEmoji: (emoji) -> - emojiCssClass = @resolveNameToCssClass(emoji) + createEmoji_: (votesBlock, emoji) -> - nodes = [] - nodes.push( - "" - ) + emojiCssClass = @resolveNameToCssClass emoji + buttonHtml = "" - $(nodes.join("\n")) - .insertBefore('.js-award-holder') - .find('.emoji-icon') - .data('emoji', emoji) + $emojiButton = $ buttonHtml + $emojiButton + .insertBefore votesBlock.find '.js-award-holder' + .find '.emoji-icon' + .data 'emoji', emoji + + @animateEmoji $emojiButton $('.award-control').tooltip() + votesBlock.removeClass 'current' + + + animateEmoji: ($emoji) -> + + className = 'pulse animated' + + $emoji.addClass className + setTimeout (-> $emoji.removeClass className), 321 + + + createEmoji: (votesBlock, emoji) -> + + if $('.emoji-menu').length + return @createEmoji_ votesBlock, emoji + + @createEmojiMenu @getAwardMenuUrl(), => @createEmoji_ votesBlock, emoji + + + getAwardMenuUrl: -> return gon.award_menu_url + resolveNameToCssClass: (emoji) -> - emojiIcon = $(".emoji-menu-content [data-emoji='#{emoji}']") + + emojiIcon = $ ".emoji-menu-content [data-emoji='#{emoji}']" if emojiIcon.length > 0 - unicodeName = emojiIcon.data('unicode-name') + unicodeName = emojiIcon.data 'unicode-name' else # Find by alias - unicodeName = $(".emoji-menu-content [data-aliases*=':#{emoji}:']").data('unicode-name') + unicodeName = $(".emoji-menu-content [data-aliases*=':#{emoji}:']").data 'unicode-name' - "emoji-#{unicodeName}" + return "emoji-#{unicodeName}" - postEmoji: (emoji, callback) -> - $.post @postEmojiUrl, { note: { - note: ":#{emoji}:" - noteable_type: @noteableType - noteable_id: @noteableId - }},(data) -> - if data.ok - callback.call() - findEmojiIcon: (emoji) -> - $(".awards > .js-emoji-btn [data-emoji='#{emoji}']") + postEmoji: (awardUrl, emoji, callback) -> + + $.post awardUrl, { name: emoji }, (data) -> + callback() if data.ok + + + findEmojiIcon: (votesBlock, emoji) -> + + return votesBlock.find ".js-emoji-btn [data-emoji='#{emoji}']" + scrollToAwards: -> - $('body, html').animate({ - scrollTop: $('.awards').offset().top - 80 - }, 200) + + options = scrollTop: $('.awards').offset().top - 110 + $('body, html').animate options, 200 + + + normilizeEmojiName: (emoji) -> return @aliases[emoji] or emoji + addEmojiToFrequentlyUsedList: (emoji) -> + frequentlyUsedEmojis = @getFrequentlyUsedEmojis() - frequentlyUsedEmojis.push(emoji) - $.cookie('frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 }) + frequentlyUsedEmojis.push emoji + $.cookie 'frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 } + getFrequentlyUsedEmojis: -> - frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') || '').split(',') - _.compact(_.uniq(frequentlyUsedEmojis)) + + frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') or '').split(',') + return _.compact _.uniq frequentlyUsedEmojis + renderFrequentlyUsedBlock: -> - if $.cookie('frequently_used_emojis') + + if $.cookie 'frequently_used_emojis' frequentlyUsedEmojis = @getFrequentlyUsedEmojis() - ul = $('