New upstream version 11.1.8+dfsg
|
@ -8,8 +8,6 @@ engines:
|
|||
languages:
|
||||
- ruby
|
||||
- javascript
|
||||
exclude_paths:
|
||||
- "lib/api/v3/*"
|
||||
ratings:
|
||||
paths:
|
||||
- Gemfile.lock
|
||||
|
|
56
.eslintrc
|
@ -1,56 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"airbnb-base",
|
||||
"plugin:vue/recommended"
|
||||
],
|
||||
"globals": {
|
||||
"__webpack_public_path__": true,
|
||||
"gl": false,
|
||||
"gon": false,
|
||||
"localStorage": false
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"plugins": [
|
||||
"filenames",
|
||||
"import",
|
||||
"html",
|
||||
"promise"
|
||||
],
|
||||
"settings": {
|
||||
"html/html-extensions": [".html", ".html.raw"],
|
||||
"import/resolver": {
|
||||
"webpack": {
|
||||
"config": "./config/webpack.config.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"filenames/match-regex": [2, "^[a-z0-9_]+$"],
|
||||
"import/no-commonjs": "error",
|
||||
"no-multiple-empty-lines": ["error", { "max": 1 }],
|
||||
"promise/catch-or-return": "error",
|
||||
"no-underscore-dangle": ["error", { "allow": ["__", "_links"] }],
|
||||
"no-mixed-operators": 0,
|
||||
"space-before-function-paren": 0,
|
||||
"curly": 0,
|
||||
"arrow-parens": 0,
|
||||
"vue/html-self-closing": [
|
||||
"error",
|
||||
{
|
||||
"html": {
|
||||
"void": "always",
|
||||
"normal": "never",
|
||||
"component": "always"
|
||||
},
|
||||
"svg": "always",
|
||||
"math": "always"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
71
.eslintrc.yml
Normal file
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
env:
|
||||
browser: true
|
||||
es6: true
|
||||
extends:
|
||||
- airbnb-base
|
||||
- plugin:vue/recommended
|
||||
globals:
|
||||
__webpack_public_path__: true
|
||||
gl: false
|
||||
gon: false
|
||||
localStorage: false
|
||||
parserOptions:
|
||||
parser: babel-eslint
|
||||
plugins:
|
||||
- filenames
|
||||
- import
|
||||
- html
|
||||
- promise
|
||||
settings:
|
||||
html/html-extensions:
|
||||
- ".html"
|
||||
- ".html.raw"
|
||||
import/resolver:
|
||||
webpack:
|
||||
config: "./config/webpack.config.js"
|
||||
rules:
|
||||
filenames/match-regex:
|
||||
- error
|
||||
- "^[a-z0-9_]+$"
|
||||
import/no-commonjs: error
|
||||
no-multiple-empty-lines:
|
||||
- error
|
||||
- max: 1
|
||||
promise/catch-or-return: error
|
||||
no-underscore-dangle:
|
||||
- error
|
||||
- allow:
|
||||
- __
|
||||
- _links
|
||||
no-mixed-operators: off
|
||||
vue/html-self-closing:
|
||||
- error
|
||||
- html:
|
||||
void: always
|
||||
normal: never
|
||||
component: always
|
||||
svg: always
|
||||
math: always
|
||||
## Conflicting rules with prettier:
|
||||
space-before-function-paren: off
|
||||
curly: off
|
||||
arrow-parens: off
|
||||
function-paren-newline: off
|
||||
object-curly-newline: off
|
||||
padded-blocks: off
|
||||
# Disabled for now, to make the eslint 3 -> eslint 4 update smoother
|
||||
## Indent rule. We are using the old for now: https://eslint.org/docs/user-guide/migrating-to-4.0.0#indent-rewrite
|
||||
indent: off
|
||||
indent-legacy:
|
||||
- error
|
||||
- 2
|
||||
- SwitchCase: 1
|
||||
VariableDeclarator: 1
|
||||
outerIIFEBody: 1
|
||||
FunctionDeclaration:
|
||||
parameters: 1
|
||||
body: 1
|
||||
FunctionExpression:
|
||||
parameters: 1
|
||||
body: 1
|
22
.flayignore
|
@ -1,12 +1,34 @@
|
|||
*.erb
|
||||
lib/gitlab/sanitizers/svg/whitelist.rb
|
||||
lib/gitlab/diff/position_tracer.rb
|
||||
app/controllers/projects/approver_groups_controller.rb
|
||||
app/controllers/projects/approvers_controller.rb
|
||||
app/controllers/projects/protected_branches/merge_access_levels_controller.rb
|
||||
app/controllers/projects/protected_branches/push_access_levels_controller.rb
|
||||
app/controllers/projects/protected_tags/create_access_levels_controller.rb
|
||||
app/policies/project_policy.rb
|
||||
app/models/concerns/relative_positioning.rb
|
||||
app/workers/stuck_merge_jobs_worker.rb
|
||||
lib/gitlab/redis/*.rb
|
||||
lib/gitlab/gitaly_client/operation_service.rb
|
||||
app/models/project_services/packagist_service.rb
|
||||
lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb
|
||||
lib/gitlab/background_migration/*
|
||||
app/models/project_services/kubernetes_service.rb
|
||||
lib/gitlab/workhorse.rb
|
||||
lib/gitlab/ci/trace/chunked_io.rb
|
||||
lib/gitlab/gitaly_client/ref_service.rb
|
||||
lib/gitlab/gitaly_client/commit_service.rb
|
||||
lib/gitlab/git/commit.rb
|
||||
lib/gitlab/git/tag.rb
|
||||
|
||||
ee/db/**/*
|
||||
ee/app/serializers/ee/merge_request_widget_entity.rb
|
||||
ee/lib/api/epics.rb
|
||||
ee/lib/api/geo_nodes.rb
|
||||
ee/lib/ee/api/group_boards.rb
|
||||
ee/lib/ee/api/boards.rb
|
||||
ee/lib/ee/gitlab/ldap/sync/admin_users.rb
|
||||
ee/app/workers/geo/file_download_dispatch_worker/job_artifact_job_finder.rb
|
||||
ee/app/workers/geo/file_download_dispatch_worker/lfs_object_job_finder.rb
|
||||
ee/spec/**/*
|
||||
|
|
3
.gitignore
vendored
|
@ -29,7 +29,7 @@ eslint-report.html
|
|||
/app/assets/javascripts/locale/**/app.js
|
||||
/backups/*
|
||||
/config/aws.yml
|
||||
/config/database.yml
|
||||
/config/database*.yml
|
||||
/config/gitlab.yml
|
||||
/config/gitlab_ci.yml
|
||||
/config/initializers/rack_attack.rb
|
||||
|
@ -76,3 +76,4 @@ eslint-report.html
|
|||
/.rspec
|
||||
/plugins/*
|
||||
/.gitlab_pages_secret
|
||||
package-lock.json
|
||||
|
|
458
.gitlab-ci.yml
|
@ -1,4 +1,4 @@
|
|||
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.7-golang-1.9-git-2.17-chrome-65.0-node-8.x-yarn-1.2-postgresql-9.6"
|
||||
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.4.4-golang-1.9-git-2.17-chrome-67.0-node-8.x-yarn-1.2-postgresql-9.6-graphicsmagick-1.3.29"
|
||||
|
||||
.dedicated-runner: &dedicated-runner
|
||||
retry: 1
|
||||
|
@ -6,7 +6,7 @@ image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.7-golang-1.9-git
|
|||
- gitlab-org
|
||||
|
||||
.default-cache: &default-cache
|
||||
key: "ruby-2.3.7-debian-stretch-with-yarn"
|
||||
key: "ruby-2.4.4-debian-stretch-with-yarn"
|
||||
paths:
|
||||
- vendor/ruby
|
||||
- .yarn-cache/
|
||||
|
@ -31,7 +31,6 @@ variables:
|
|||
GIT_SUBMODULE_STRATEGY: "none"
|
||||
GET_SOURCES_ATTEMPTS: "3"
|
||||
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
|
||||
KNAPSACK_SPINACH_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/spinach_report-master.json
|
||||
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
|
||||
|
||||
before_script:
|
||||
|
@ -127,6 +126,23 @@ stages:
|
|||
<<: *dedicated-no-docs-pull-cache-job
|
||||
<<: *except-docs-and-qa
|
||||
|
||||
.single-script-job: &single-script-job
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
cache: {}
|
||||
dependencies: []
|
||||
variables: &single-script-job-variables
|
||||
GIT_STRATEGY: none
|
||||
before_script:
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# package-and-qa job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- export SCRIPT_NAME="${SCRIPT_NAME:-$CI_JOB_NAME}"
|
||||
- apk add --update openssl
|
||||
- wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/$SCRIPT_NAME
|
||||
- chmod 755 $SCRIPT_NAME
|
||||
|
||||
.rake-exec: &rake-exec
|
||||
<<: *dedicated-no-docs-no-db-pull-cache-job
|
||||
script:
|
||||
|
@ -179,46 +195,6 @@ stages:
|
|||
<<: *rspec-metadata-mysql
|
||||
<<: *rails5
|
||||
|
||||
.spinach-metadata: &spinach-metadata
|
||||
<<: *dedicated-runner
|
||||
<<: *except-docs-and-qa
|
||||
<<: *pull-cache
|
||||
<<: *rails5-variables
|
||||
stage: test
|
||||
script:
|
||||
- JOB_NAME=( $CI_JOB_NAME )
|
||||
- export CI_NODE_INDEX=${JOB_NAME[-2]}
|
||||
- export CI_NODE_TOTAL=${JOB_NAME[-1]}
|
||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${JOB_NAME[0]}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
||||
- export KNAPSACK_GENERATE_REPORT=true
|
||||
- export CACHE_CLASSES=true
|
||||
- cp ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
||||
- scripts/gitaly-test-spawn
|
||||
- knapsack spinach "-r rerun" -b || retry '[[ -e tmp/spinach-rerun.txt ]] && bundle exec spinach -b -r rerun $(cat tmp/spinach-rerun.txt)'
|
||||
artifacts:
|
||||
expire_in: 31d
|
||||
when: always
|
||||
paths:
|
||||
- coverage/
|
||||
- knapsack/
|
||||
- tmp/capybara/
|
||||
|
||||
.spinach-metadata-pg: &spinach-metadata-pg
|
||||
<<: *spinach-metadata
|
||||
<<: *use-pg
|
||||
|
||||
.spinach-metadata-pg-rails5: &spinach-metadata-pg-rails5
|
||||
<<: *spinach-metadata-pg
|
||||
<<: *rails5
|
||||
|
||||
.spinach-metadata-mysql: &spinach-metadata-mysql
|
||||
<<: *spinach-metadata
|
||||
<<: *use-mysql
|
||||
|
||||
.spinach-metadata-mysql-rails5: &spinach-metadata-mysql-rails5
|
||||
<<: *spinach-metadata-mysql
|
||||
<<: *rails5
|
||||
|
||||
.only-canonical-masters: &only-canonical-masters
|
||||
only:
|
||||
- master@gitlab-org/gitlab-ce
|
||||
|
@ -230,7 +206,7 @@ stages:
|
|||
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
|
||||
<<: *use-pg
|
||||
variables:
|
||||
CREATE_DB_USER: "true"
|
||||
SETUP_DB: "false"
|
||||
script:
|
||||
# Manually clone gitlab-test and only seed this project in
|
||||
# db/fixtures/development/04_project.rb thanks to SIZE=1 below
|
||||
|
@ -244,27 +220,6 @@ stages:
|
|||
paths:
|
||||
- log/development.log
|
||||
|
||||
# Review docs base
|
||||
.review-docs: &review-docs
|
||||
<<: *dedicated-runner
|
||||
<<: *except-qa
|
||||
image: ruby:2.4-alpine
|
||||
before_script:
|
||||
- gem install gitlab --no-doc
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# review-docs-cleanup job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- apk add --update openssl
|
||||
- wget https://gitlab.com/gitlab-org/gitlab-ce/raw/master/scripts/trigger-build-docs
|
||||
- chmod 755 trigger-build-docs
|
||||
cache: {}
|
||||
dependencies: []
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
when: manual
|
||||
only:
|
||||
- branches
|
||||
|
||||
# DB migration, rollback, and seed jobs
|
||||
.db-migrate-reset: &db-migrate-reset
|
||||
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
|
||||
|
@ -274,7 +229,7 @@ stages:
|
|||
.migration-paths: &migration-paths
|
||||
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
|
||||
variables:
|
||||
CREATE_DB_USER: "true"
|
||||
SETUP_DB: "false"
|
||||
script:
|
||||
- git fetch https://gitlab.com/gitlab-org/gitlab-ce.git v9.3.0
|
||||
- git checkout -f FETCH_HEAD
|
||||
|
@ -283,7 +238,7 @@ stages:
|
|||
- cp config/gitlab.yml.example config/gitlab.yml
|
||||
- bundle exec rake db:drop db:create db:schema:load db:seed_fu
|
||||
- date
|
||||
- git checkout $CI_COMMIT_SHA
|
||||
- git checkout -f $CI_COMMIT_SHA
|
||||
- bundle install $BUNDLE_INSTALL_FLAGS
|
||||
- date
|
||||
- . scripts/prepare_build.sh
|
||||
|
@ -294,50 +249,88 @@ stages:
|
|||
# Trigger a package build in omnibus-gitlab repository
|
||||
#
|
||||
package-and-qa:
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
cache: {}
|
||||
when: manual
|
||||
<<: *single-script-job
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
<<: *single-script-job-variables
|
||||
SCRIPT_NAME: trigger-build
|
||||
retry: 0
|
||||
before_script:
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# package-and-qa job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- apk add --update openssl
|
||||
- wget https://gitlab.com/$CI_PROJECT_PATH/raw/$CI_COMMIT_SHA/scripts/trigger-build-omnibus
|
||||
- chmod 755 trigger-build-omnibus
|
||||
script:
|
||||
- ./trigger-build-omnibus
|
||||
- ./$SCRIPT_NAME omnibus
|
||||
when: manual
|
||||
only:
|
||||
- //@gitlab-org/gitlab-ce
|
||||
- //@gitlab-org/gitlab-ee
|
||||
|
||||
# Trigger a docs build in gitlab-docs
|
||||
# Useful to preview the docs changes live
|
||||
review-docs-deploy:
|
||||
<<: *review-docs
|
||||
stage: build
|
||||
# Review docs base
|
||||
.review-docs: &review-docs
|
||||
<<: *dedicated-runner
|
||||
<<: *single-script-job
|
||||
variables:
|
||||
<<: *single-script-job-variables
|
||||
SCRIPT_NAME: trigger-build-docs
|
||||
environment:
|
||||
name: review-docs/$CI_COMMIT_REF_NAME
|
||||
name: review-docs/$CI_COMMIT_REF_SLUG
|
||||
# DOCS_REVIEW_APPS_DOMAIN and DOCS_GITLAB_REPO_SUFFIX are secret variables
|
||||
# Discussion: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14236/diffs#note_40140693
|
||||
url: http://$DOCS_GITLAB_REPO_SUFFIX-$CI_COMMIT_REF_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
|
||||
url: http://$CI_ENVIRONMENT_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
|
||||
on_stop: review-docs-cleanup
|
||||
|
||||
# Trigger a manual docs build in gitlab-docs only on non docs-only branches.
|
||||
# Useful to preview the docs changes live.
|
||||
review-docs-deploy-manual:
|
||||
<<: *review-docs
|
||||
stage: build
|
||||
script:
|
||||
- ./trigger-build-docs deploy
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./$SCRIPT_NAME deploy
|
||||
when: manual
|
||||
only:
|
||||
- branches@gitlab-org/gitlab-ce
|
||||
- branches@gitlab-org/gitlab-ee
|
||||
<<: *except-docs-and-qa
|
||||
|
||||
# Always trigger a docs build in gitlab-docs only on docs-only branches.
|
||||
# Useful to preview the docs changes live.
|
||||
review-docs-deploy:
|
||||
<<: *review-docs
|
||||
stage: post-test
|
||||
script:
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./$SCRIPT_NAME deploy
|
||||
only:
|
||||
- /(^docs[\/-].*|.*-docs$)/@gitlab-org/gitlab-ce
|
||||
- /(^docs[\/-].*|.*-docs$)/@gitlab-org/gitlab-ee
|
||||
<<: *except-qa
|
||||
|
||||
# Cleanup remote environment of gitlab-docs
|
||||
review-docs-cleanup:
|
||||
<<: *review-docs
|
||||
stage: post-cleanup
|
||||
environment:
|
||||
name: review-docs/$CI_COMMIT_REF_NAME
|
||||
name: review-docs/$CI_COMMIT_REF_SLUG
|
||||
action: stop
|
||||
when: manual
|
||||
script:
|
||||
- ./trigger-build-docs cleanup
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./$SCRIPT_NAME cleanup
|
||||
|
||||
##
|
||||
# Trigger a docker image build in CNG (Cloud Native GitLab) repository
|
||||
#
|
||||
cloud-native-image:
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
allow_failure: true
|
||||
variables:
|
||||
GIT_DEPTH: "1"
|
||||
cache: {}
|
||||
script:
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN scripts/trigger-build cng
|
||||
only:
|
||||
- tags@gitlab-org/gitlab-ce
|
||||
- tags@gitlab-org/gitlab-ee
|
||||
|
||||
# Retrieve knapsack and rspec_flaky reports
|
||||
retrieve-tests-metadata:
|
||||
|
@ -350,9 +343,7 @@ retrieve-tests-metadata:
|
|||
script:
|
||||
- mkdir -p knapsack/${CI_PROJECT_NAME}/
|
||||
- wget -O $KNAPSACK_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_RSPEC_SUITE_REPORT_PATH || rm $KNAPSACK_RSPEC_SUITE_REPORT_PATH
|
||||
- wget -O $KNAPSACK_SPINACH_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_SPINACH_SUITE_REPORT_PATH || rm $KNAPSACK_SPINACH_SUITE_REPORT_PATH
|
||||
- '[[ -f $KNAPSACK_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
|
||||
- '[[ -f $KNAPSACK_SPINACH_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_SPINACH_SUITE_REPORT_PATH}'
|
||||
- mkdir -p rspec_flaky/
|
||||
- wget -O $FLAKY_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$FLAKY_RSPEC_SUITE_REPORT_PATH || rm $FLAKY_RSPEC_SUITE_REPORT_PATH
|
||||
- '[[ -f $FLAKY_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_SUITE_REPORT_PATH}'
|
||||
|
@ -368,12 +359,11 @@ update-tests-metadata:
|
|||
- rspec_flaky/
|
||||
policy: push
|
||||
script:
|
||||
- retry gem install fog-aws mime-types activesupport
|
||||
- retry gem install fog-aws mime-types activesupport --no-ri --no-rdoc
|
||||
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json
|
||||
- scripts/merge-reports ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/spinach-pg_node_*.json
|
||||
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json
|
||||
- FLAKY_RSPEC_GENERATE_REPORT=1 scripts/prune-old-flaky-specs ${FLAKY_RSPEC_SUITE_REPORT_PATH}
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH $KNAPSACK_SPINACH_SUITE_REPORT_PATH'
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH'
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $FLAKY_RSPEC_SUITE_REPORT_PATH'
|
||||
- rm -f knapsack/${CI_PROJECT_NAME}/*_node_*.json
|
||||
- rm -f rspec_flaky/all_*.json rspec_flaky/new_*.json
|
||||
|
@ -417,7 +407,11 @@ compile-assets:
|
|||
- date
|
||||
- yarn install --frozen-lockfile --cache-folder .yarn-cache
|
||||
- date
|
||||
- free -m
|
||||
- bundle exec rake gitlab:assets:compile
|
||||
variables:
|
||||
# we override the max_old_space_size to prevent OOM errors
|
||||
NODE_OPTIONS: --max_old_space_size=3584
|
||||
artifacts:
|
||||
expire_in: 7d
|
||||
paths:
|
||||
|
@ -434,6 +428,7 @@ setup-test-env:
|
|||
script:
|
||||
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
|
||||
- scripts/gitaly-test-build # Do not use 'bundle exec' here
|
||||
- BUNDLE_GEMFILE=Gemfile.rails5 bundle install $BUNDLE_INSTALL_FLAGS
|
||||
artifacts:
|
||||
expire_in: 7d
|
||||
paths:
|
||||
|
@ -441,133 +436,129 @@ setup-test-env:
|
|||
- config/secrets.yml
|
||||
- vendor/gitaly-ruby
|
||||
|
||||
rspec-pg 0 28: *rspec-metadata-pg
|
||||
rspec-pg 1 28: *rspec-metadata-pg
|
||||
rspec-pg 2 28: *rspec-metadata-pg
|
||||
rspec-pg 3 28: *rspec-metadata-pg
|
||||
rspec-pg 4 28: *rspec-metadata-pg
|
||||
rspec-pg 5 28: *rspec-metadata-pg
|
||||
rspec-pg 6 28: *rspec-metadata-pg
|
||||
rspec-pg 7 28: *rspec-metadata-pg
|
||||
rspec-pg 8 28: *rspec-metadata-pg
|
||||
rspec-pg 9 28: *rspec-metadata-pg
|
||||
rspec-pg 10 28: *rspec-metadata-pg
|
||||
rspec-pg 11 28: *rspec-metadata-pg
|
||||
rspec-pg 12 28: *rspec-metadata-pg
|
||||
rspec-pg 13 28: *rspec-metadata-pg
|
||||
rspec-pg 14 28: *rspec-metadata-pg
|
||||
rspec-pg 15 28: *rspec-metadata-pg
|
||||
rspec-pg 16 28: *rspec-metadata-pg
|
||||
rspec-pg 17 28: *rspec-metadata-pg
|
||||
rspec-pg 18 28: *rspec-metadata-pg
|
||||
rspec-pg 19 28: *rspec-metadata-pg
|
||||
rspec-pg 20 28: *rspec-metadata-pg
|
||||
rspec-pg 21 28: *rspec-metadata-pg
|
||||
rspec-pg 22 28: *rspec-metadata-pg
|
||||
rspec-pg 23 28: *rspec-metadata-pg
|
||||
rspec-pg 24 28: *rspec-metadata-pg
|
||||
rspec-pg 25 28: *rspec-metadata-pg
|
||||
rspec-pg 26 28: *rspec-metadata-pg
|
||||
rspec-pg 27 28: *rspec-metadata-pg
|
||||
rspec-pg 0 30: *rspec-metadata-pg
|
||||
rspec-pg 1 30: *rspec-metadata-pg
|
||||
rspec-pg 2 30: *rspec-metadata-pg
|
||||
rspec-pg 3 30: *rspec-metadata-pg
|
||||
rspec-pg 4 30: *rspec-metadata-pg
|
||||
rspec-pg 5 30: *rspec-metadata-pg
|
||||
rspec-pg 6 30: *rspec-metadata-pg
|
||||
rspec-pg 7 30: *rspec-metadata-pg
|
||||
rspec-pg 8 30: *rspec-metadata-pg
|
||||
rspec-pg 9 30: *rspec-metadata-pg
|
||||
rspec-pg 10 30: *rspec-metadata-pg
|
||||
rspec-pg 11 30: *rspec-metadata-pg
|
||||
rspec-pg 12 30: *rspec-metadata-pg
|
||||
rspec-pg 13 30: *rspec-metadata-pg
|
||||
rspec-pg 14 30: *rspec-metadata-pg
|
||||
rspec-pg 15 30: *rspec-metadata-pg
|
||||
rspec-pg 16 30: *rspec-metadata-pg
|
||||
rspec-pg 17 30: *rspec-metadata-pg
|
||||
rspec-pg 18 30: *rspec-metadata-pg
|
||||
rspec-pg 19 30: *rspec-metadata-pg
|
||||
rspec-pg 20 30: *rspec-metadata-pg
|
||||
rspec-pg 21 30: *rspec-metadata-pg
|
||||
rspec-pg 22 30: *rspec-metadata-pg
|
||||
rspec-pg 23 30: *rspec-metadata-pg
|
||||
rspec-pg 24 30: *rspec-metadata-pg
|
||||
rspec-pg 25 30: *rspec-metadata-pg
|
||||
rspec-pg 26 30: *rspec-metadata-pg
|
||||
rspec-pg 27 30: *rspec-metadata-pg
|
||||
rspec-pg 28 30: *rspec-metadata-pg
|
||||
rspec-pg 29 30: *rspec-metadata-pg
|
||||
|
||||
rspec-mysql 0 28: *rspec-metadata-mysql
|
||||
rspec-mysql 1 28: *rspec-metadata-mysql
|
||||
rspec-mysql 2 28: *rspec-metadata-mysql
|
||||
rspec-mysql 3 28: *rspec-metadata-mysql
|
||||
rspec-mysql 4 28: *rspec-metadata-mysql
|
||||
rspec-mysql 5 28: *rspec-metadata-mysql
|
||||
rspec-mysql 6 28: *rspec-metadata-mysql
|
||||
rspec-mysql 7 28: *rspec-metadata-mysql
|
||||
rspec-mysql 8 28: *rspec-metadata-mysql
|
||||
rspec-mysql 9 28: *rspec-metadata-mysql
|
||||
rspec-mysql 10 28: *rspec-metadata-mysql
|
||||
rspec-mysql 11 28: *rspec-metadata-mysql
|
||||
rspec-mysql 12 28: *rspec-metadata-mysql
|
||||
rspec-mysql 13 28: *rspec-metadata-mysql
|
||||
rspec-mysql 14 28: *rspec-metadata-mysql
|
||||
rspec-mysql 15 28: *rspec-metadata-mysql
|
||||
rspec-mysql 16 28: *rspec-metadata-mysql
|
||||
rspec-mysql 17 28: *rspec-metadata-mysql
|
||||
rspec-mysql 18 28: *rspec-metadata-mysql
|
||||
rspec-mysql 19 28: *rspec-metadata-mysql
|
||||
rspec-mysql 20 28: *rspec-metadata-mysql
|
||||
rspec-mysql 21 28: *rspec-metadata-mysql
|
||||
rspec-mysql 22 28: *rspec-metadata-mysql
|
||||
rspec-mysql 23 28: *rspec-metadata-mysql
|
||||
rspec-mysql 24 28: *rspec-metadata-mysql
|
||||
rspec-mysql 25 28: *rspec-metadata-mysql
|
||||
rspec-mysql 26 28: *rspec-metadata-mysql
|
||||
rspec-mysql 27 28: *rspec-metadata-mysql
|
||||
rspec-mysql 0 30: *rspec-metadata-mysql
|
||||
rspec-mysql 1 30: *rspec-metadata-mysql
|
||||
rspec-mysql 2 30: *rspec-metadata-mysql
|
||||
rspec-mysql 3 30: *rspec-metadata-mysql
|
||||
rspec-mysql 4 30: *rspec-metadata-mysql
|
||||
rspec-mysql 5 30: *rspec-metadata-mysql
|
||||
rspec-mysql 6 30: *rspec-metadata-mysql
|
||||
rspec-mysql 7 30: *rspec-metadata-mysql
|
||||
rspec-mysql 8 30: *rspec-metadata-mysql
|
||||
rspec-mysql 9 30: *rspec-metadata-mysql
|
||||
rspec-mysql 10 30: *rspec-metadata-mysql
|
||||
rspec-mysql 11 30: *rspec-metadata-mysql
|
||||
rspec-mysql 12 30: *rspec-metadata-mysql
|
||||
rspec-mysql 13 30: *rspec-metadata-mysql
|
||||
rspec-mysql 14 30: *rspec-metadata-mysql
|
||||
rspec-mysql 15 30: *rspec-metadata-mysql
|
||||
rspec-mysql 16 30: *rspec-metadata-mysql
|
||||
rspec-mysql 17 30: *rspec-metadata-mysql
|
||||
rspec-mysql 18 30: *rspec-metadata-mysql
|
||||
rspec-mysql 19 30: *rspec-metadata-mysql
|
||||
rspec-mysql 20 30: *rspec-metadata-mysql
|
||||
rspec-mysql 21 30: *rspec-metadata-mysql
|
||||
rspec-mysql 22 30: *rspec-metadata-mysql
|
||||
rspec-mysql 23 30: *rspec-metadata-mysql
|
||||
rspec-mysql 24 30: *rspec-metadata-mysql
|
||||
rspec-mysql 25 30: *rspec-metadata-mysql
|
||||
rspec-mysql 26 30: *rspec-metadata-mysql
|
||||
rspec-mysql 27 30: *rspec-metadata-mysql
|
||||
rspec-mysql 28 30: *rspec-metadata-mysql
|
||||
rspec-mysql 29 30: *rspec-metadata-mysql
|
||||
|
||||
spinach-pg 0 2: *spinach-metadata-pg
|
||||
spinach-pg 1 2: *spinach-metadata-pg
|
||||
rspec-pg-rails5 0 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 1 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 2 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 3 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 4 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 5 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 6 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 7 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 8 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 9 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 10 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 11 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 12 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 13 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 14 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 15 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 16 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 17 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 18 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 19 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 20 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 21 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 22 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 23 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 24 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 25 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 26 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 27 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 28 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 29 30: *rspec-metadata-pg-rails5
|
||||
|
||||
spinach-mysql 0 2: *spinach-metadata-mysql
|
||||
spinach-mysql 1 2: *spinach-metadata-mysql
|
||||
|
||||
rspec-pg-rails5 0 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 1 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 2 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 3 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 4 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 5 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 6 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 7 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 8 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 9 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 10 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 11 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 12 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 13 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 14 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 15 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 16 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 17 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 18 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 19 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 20 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 21 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 22 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 23 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 24 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 25 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 26 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 27 28: *rspec-metadata-pg-rails5
|
||||
|
||||
rspec-mysql-rails5 0 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 1 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 2 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 3 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 4 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 5 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 6 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 7 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 8 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 9 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 10 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 11 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 12 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 13 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 14 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 15 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 16 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 17 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 18 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 19 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 20 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 21 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 22 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 23 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 24 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 25 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 26 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 27 28: *rspec-metadata-mysql-rails5
|
||||
|
||||
spinach-pg-rails5 0 2: *spinach-metadata-pg-rails5
|
||||
spinach-pg-rails5 1 2: *spinach-metadata-pg-rails5
|
||||
|
||||
spinach-mysql-rails5 0 2: *spinach-metadata-mysql-rails5
|
||||
spinach-mysql-rails5 1 2: *spinach-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 0 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 1 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 2 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 3 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 4 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 5 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 6 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 7 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 8 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 9 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 10 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 11 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 12 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 13 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 14 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 15 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 16 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 17 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 18 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 19 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 20 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 21 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 22 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 23 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 24 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 25 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 26 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 27 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 28 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 29 30: *rspec-metadata-mysql-rails5
|
||||
|
||||
static-analysis:
|
||||
<<: *dedicated-no-docs-no-db-pull-cache-job
|
||||
|
@ -577,7 +568,7 @@ static-analysis:
|
|||
script:
|
||||
- scripts/static-analysis
|
||||
cache:
|
||||
key: "ruby-2.3.7-debian-stretch-with-yarn-and-rubocop"
|
||||
key: "ruby-2.4.4-debian-stretch-with-yarn-and-rubocop"
|
||||
paths:
|
||||
- vendor/ruby
|
||||
- .yarn-cache/
|
||||
|
@ -613,12 +604,18 @@ downtime_check:
|
|||
- /(^docs[\/-].*|.*-docs$)/
|
||||
- /(^qa[\/-].*|.*-qa$)/
|
||||
|
||||
rails5_gemfile_lock_check:
|
||||
<<: *dedicated-no-docs-no-db-pull-cache-job
|
||||
<<: *except-docs-and-qa
|
||||
script:
|
||||
- scripts/rails5-gemfile-lock-check
|
||||
|
||||
ee_compat_check:
|
||||
<<: *rake-exec
|
||||
except:
|
||||
- master
|
||||
- tags
|
||||
- /^[\d-]+-stable(-ee)?/
|
||||
- /[\d-]+-stable(-ee)?/
|
||||
- /^security-/
|
||||
- branches@gitlab-org/gitlab-ee
|
||||
- branches@gitlab/gitlab-ee
|
||||
|
@ -685,10 +682,13 @@ gitlab:assets:compile:
|
|||
SKIP_STORAGE_VALIDATION: "true"
|
||||
WEBPACK_REPORT: "true"
|
||||
NO_COMPRESSION: "true"
|
||||
# we override the max_old_space_size to prevent OOM errors
|
||||
NODE_OPTIONS: --max_old_space_size=3584
|
||||
script:
|
||||
- date
|
||||
- yarn install --frozen-lockfile --production --cache-folder .yarn-cache
|
||||
- date
|
||||
- free -m
|
||||
- bundle exec rake gitlab:assets:compile
|
||||
artifacts:
|
||||
name: webpack-report
|
||||
|
@ -828,8 +828,6 @@ lint:javascript:report:
|
|||
- setup-test-env
|
||||
before_script: []
|
||||
script:
|
||||
- date
|
||||
- find app/ spec/ -name '*.js' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files
|
||||
- date
|
||||
- yarn run eslint-report || true # ignore exit code
|
||||
artifacts:
|
||||
|
@ -884,3 +882,15 @@ gitlab_git_test:
|
|||
cache: {}
|
||||
script:
|
||||
- spec/support/prepare-gitlab-git-test-for-commit --check-for-changes
|
||||
|
||||
no_ee_check:
|
||||
<<: *dedicated-runner
|
||||
<<: *except-docs-and-qa
|
||||
variables:
|
||||
SETUP_DB: "false"
|
||||
before_script: []
|
||||
cache: {}
|
||||
script:
|
||||
- scripts/no-ee-check
|
||||
only:
|
||||
- //@gitlab-org/gitlab-ce
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
### Description
|
||||
|
||||
(Include problem, use cases, benefits, and/or goals)
|
||||
|
||||
### Proposal
|
||||
|
||||
### Links / references
|
||||
|
||||
/label ~"feature proposal"
|
15
.gitlab/issue_templates/Feature proposal.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
### Problem to solve
|
||||
|
||||
### Further details
|
||||
|
||||
(Include use cases, benefits, and/or goals)
|
||||
|
||||
### Proposal
|
||||
|
||||
### What does success look like, and how can we measure that?
|
||||
|
||||
(If no way to measure success, link to an issue that will implement a way to measure this)
|
||||
|
||||
### Links / references
|
||||
|
||||
/label ~"feature proposal"
|
|
@ -39,6 +39,7 @@ Set the title to: `[Security] Description of the original issue`
|
|||
- [ ] Add the nickname of the external user who found the issue (and/or HackerOne profile) to the Thanks row in the [details section](#details)
|
||||
|
||||
### Summary
|
||||
|
||||
#### Links
|
||||
|
||||
| Description | Link |
|
|
@ -1,7 +1,7 @@
|
|||
Add a description of your merge request here. Merge requests without an adequate
|
||||
description will not be reviewed until one is added.
|
||||
|
||||
## Database Checklist
|
||||
## Database checklist
|
||||
|
||||
When adding migrations:
|
||||
|
||||
|
@ -31,18 +31,20 @@ When removing columns, tables, indexes or other structures:
|
|||
- [ ] Removed these in a post-deployment migration
|
||||
- [ ] Made sure the application no longer uses (or ignores) these structures
|
||||
|
||||
## General Checklist
|
||||
## General checklist
|
||||
|
||||
- [ ] [Changelog entry](https://docs.gitlab.com/ee/development/changelog.html) added, if necessary
|
||||
- [ ] [Documentation created/updated](https://docs.gitlab.com/ee/development/doc_styleguide.html)
|
||||
- [ ] API support added
|
||||
- [ ] Tests added for this feature/bug
|
||||
- Review
|
||||
- [ ] Has been reviewed by Backend
|
||||
- [ ] Has been reviewed by Database
|
||||
- Conform by the [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
|
||||
- [ ] Has been reviewed by a Backend maintainer
|
||||
- [ ] Has been reviewed by a Database specialist
|
||||
- [ ] Conform by the [merge request performance guides](https://docs.gitlab.com/ee/development/merge_request_performance_guidelines.html)
|
||||
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/CONTRIBUTING.md#style-guides)
|
||||
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
|
||||
- [ ] If you have multiple commits, please combine them into a few logically organized commits by [squashing them](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
|
||||
- [ ] Internationalization required/considered
|
||||
- [ ] If paid feature, have we considered GitLab.com plan and how it works for groups and is there a design for promoting it to users who aren't on the correct plan
|
||||
- [ ] End-to-end tests pass (`package-and-qa` manual pipeline job)
|
||||
|
||||
/label ~database
|
2
.nvmrc
|
@ -1 +1 @@
|
|||
9.0.0
|
||||
8.11.3
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
Capybara/CurrentPathExpectation:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 956
|
||||
Capybara/FeatureMethods:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 23
|
||||
FactoryBot/DynamicAttributeDefinedStatically:
|
||||
Exclude:
|
||||
|
@ -173,7 +169,6 @@ Lint/UriEscapeUnescape:
|
|||
- 'spec/requests/api/files_spec.rb'
|
||||
- 'spec/requests/api/internal_spec.rb'
|
||||
- 'spec/requests/api/issues_spec.rb'
|
||||
- 'spec/requests/api/v3/issues_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
|
@ -333,8 +328,6 @@ RSpec/ScatteredSetup:
|
|||
- 'spec/lib/gitlab/bitbucket_import/importer_spec.rb'
|
||||
- 'spec/lib/gitlab/git/env_spec.rb'
|
||||
- 'spec/requests/api/jobs_spec.rb'
|
||||
- 'spec/requests/api/v3/builds_spec.rb'
|
||||
- 'spec/requests/api/v3/projects_spec.rb'
|
||||
- 'spec/services/projects/create_service_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
|
@ -490,7 +483,7 @@ Style/EmptyLiteral:
|
|||
- 'lib/gitlab/fogbugz_import/importer.rb'
|
||||
- 'lib/gitlab/git/diff_collection.rb'
|
||||
- 'lib/gitlab/gitaly_client.rb'
|
||||
- 'scripts/trigger-build-omnibus'
|
||||
- 'scripts/trigger-build'
|
||||
- 'spec/features/merge_requests/versions_spec.rb'
|
||||
- 'spec/helpers/merge_requests_helper_spec.rb'
|
||||
- 'spec/lib/gitlab/request_context_spec.rb'
|
||||
|
@ -618,7 +611,6 @@ Style/OrAssignment:
|
|||
Exclude:
|
||||
- 'app/models/concerns/token_authenticatable.rb'
|
||||
- 'lib/api/commit_statuses.rb'
|
||||
- 'lib/api/v3/members.rb'
|
||||
- 'lib/gitlab/project_transfer.rb'
|
||||
|
||||
# Offense count: 50
|
||||
|
@ -781,7 +773,6 @@ Style/TernaryParentheses:
|
|||
- 'app/finders/projects_finder.rb'
|
||||
- 'app/helpers/namespaces_helper.rb'
|
||||
- 'features/support/capybara.rb'
|
||||
- 'lib/api/v3/projects.rb'
|
||||
- 'lib/gitlab/ci/build/artifacts/metadata/entry.rb'
|
||||
- 'spec/requests/api/pipeline_schedules_spec.rb'
|
||||
- 'spec/support/capybara.rb'
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.3.7
|
||||
2.4.4
|
||||
|
|
|
@ -46,8 +46,9 @@ linters:
|
|||
# - properties
|
||||
# - @include declarations with inner @content
|
||||
# - nested rule sets.
|
||||
# Disabled to minimize Bootstrap migration footprint
|
||||
DeclarationOrder:
|
||||
enabled: true
|
||||
enabled: false
|
||||
|
||||
# `scss-lint:disable` control comments should be preceded by a comment
|
||||
# explaining why these linters are being disabled for this file.
|
||||
|
|
654
CHANGELOG.md
|
@ -2,26 +2,626 @@
|
|||
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||
entry.
|
||||
|
||||
## 10.8.7 (2018-07-26)
|
||||
## 11.1.8 (2018-10-05)
|
||||
|
||||
### Security (3 changes)
|
||||
|
||||
- Filter user sensitive data from discussions JSON. !2539
|
||||
- Properly filter private references from system notes.
|
||||
- Markdown API no longer displays confidential title references unless authorized.
|
||||
|
||||
|
||||
## 11.1.7 (2018-09-26)
|
||||
|
||||
### Security (6 changes)
|
||||
|
||||
- Redact confidential events in the API.
|
||||
- Set timeout for syntax highlighting.
|
||||
- Sanitize JSON data properly to fix XSS on Issue details page.
|
||||
- Fix stored XSS in merge requests from imported repository.
|
||||
- Fix xss vulnerability sourced from package.json.
|
||||
- Block loopback addresses in UrlBlocker.
|
||||
|
||||
|
||||
## 11.1.6 (2018-08-28)
|
||||
|
||||
- No changes.
|
||||
|
||||
## 11.1.5 (2018-08-27)
|
||||
|
||||
### Security (3 changes)
|
||||
|
||||
- Fixed persistent XSS rendering/escaping of diff location lines.
|
||||
- Adding CSRF protection to Hooks resend action.
|
||||
- Block link-local addresses in URLBlocker.
|
||||
|
||||
### Fixed (1 change, 1 of them is from the community)
|
||||
|
||||
- Sanitize git URL in import errors. (Jamie Schembri)
|
||||
|
||||
|
||||
## 11.1.4 (2018-07-30)
|
||||
|
||||
- No changes.
|
||||
|
||||
## 11.1.3 (2018-07-27)
|
||||
|
||||
### Fixed (8 changes, 1 of them is from the community)
|
||||
|
||||
- Rework some projects table indexes around repository_storage field. !20377
|
||||
- Fix navigation to First and Next discussion on MR Changes tab. !20434
|
||||
- Fix showing outdated discussions on Changes tab. !20445
|
||||
- Fix autosave and ESC confirmation issues for MR discussions. !20569
|
||||
- Fix rendering of the context lines in MR diffs page. !20642
|
||||
- Don't overflow project/group dropdown results. !20704 (gfyoung)
|
||||
- Fixed IDE not opening JSON files. !20798
|
||||
- Disable Gitaly timeouts when creating or restoring backups. !20810
|
||||
|
||||
### Performance (1 change)
|
||||
|
||||
- Reduces the client side memory footprint on merge requests. !20744
|
||||
|
||||
|
||||
## 11.1.2 (2018-07-26)
|
||||
|
||||
### Security (4 changes)
|
||||
|
||||
- Don't expose project names in various counters.
|
||||
- Don't expose project names in GitHub counters.
|
||||
- Adding CSRF protection to Hooks test action.
|
||||
- Don't expose project names in GitHub counters.
|
||||
- Don't expose project names in various counters.
|
||||
- Fixed XSS in branch name in Web IDE.
|
||||
|
||||
### Fixed (1 change)
|
||||
|
||||
- Escapes milestone and label's names on flash notice when promoting them.
|
||||
|
||||
### Performance (1 change)
|
||||
|
||||
## 10.8.6 (2018-07-17)
|
||||
- Fix slow Markdown rendering. !20820
|
||||
|
||||
### Security (2 changes)
|
||||
|
||||
## 11.1.1 (2018-07-23)
|
||||
|
||||
### Fixed (2 changes)
|
||||
|
||||
- Add missing Gitaly branch_update nil checks. !20711
|
||||
- Fix filename for accelerated uploads.
|
||||
|
||||
### Added (1 change)
|
||||
|
||||
- Add uploader support to Import/Export uploads. !20484
|
||||
|
||||
|
||||
## 11.1.0 (2018-07-22)
|
||||
|
||||
### Security (6 changes)
|
||||
|
||||
- Fix XSS vulnerability for table of content generation.
|
||||
- Update sanitize gem to 4.6.5 to fix HTML injection vulnerability.
|
||||
- HTML escape branch name in project graphs page.
|
||||
- HTML escape the name of the user in ProjectsHelper#link_to_member.
|
||||
- Don't show events from internal projects for anonymous users in public feed.
|
||||
- Fix symlink vulnerability in project import.
|
||||
- Merge branch 'fix-mr-widget-border' into 'master'.
|
||||
|
||||
### Removed (1 change)
|
||||
|
||||
- Remove deprecated object_storage_upload queue.
|
||||
|
||||
### Fixed (98 changes, 52 of them are from the community)
|
||||
|
||||
- Keep lists ordered when copying only list items. !18522 (Jan Beckmann)
|
||||
- Fix bug where maintainer would not be allowed to push to forks with merge requests that have `Allow maintainer edits` enabled. !18968
|
||||
- mergeError message has been binded using v-html directive. !19058 (Murat Dogan)
|
||||
- Set MR target branch to default branch if target branch is not valid. !19067
|
||||
- Fix CSS for buttons not to be hidden on issues/MR title. !19176 (Takuya Noguchi)
|
||||
- Use same gem versions for rails5 as for rails4 where possible. !19498 (Jasper Maes)
|
||||
- Fix extra blank line at start of rendered reStructuredText code block. !19596
|
||||
- Fix username validation order on signup, resolves #45575. !19610 (Jan Beckmann)
|
||||
- Make quick commands case insensitive. !19614 (Jan Beckmann)
|
||||
- Remove incorrect CI doc re: PowerShell. !19622 (gfyoung)
|
||||
- Fixes Microsoft Teams notifications for pipeline events. !19632 (Jeff Brown)
|
||||
- Fix branch name encoding for dropdown on issue page. !19634
|
||||
- Rails5 fix expected `issuable.reload.updated_at` to have changed. !19733 (Jasper Maes)
|
||||
- Rails5 fix stack level too deep. !19762 (Jasper Maes)
|
||||
- Rails5 ActionController::ParameterMissing: param is missing or the value is empty: application_setting. !19763 (Jasper Maes)
|
||||
- Invalidate cache with project details when repository is updated. !19774
|
||||
- Rails5 fix no implicit conversion of Hash into String. ActionController::Parameters no longer returns an hash in Rails 5. !19792 (Jasper Maes)
|
||||
- [Rails5] Fix snippets_finder arel queries. !19796 (@blackst0ne)
|
||||
- Fix fields for author & assignee in MR API docs. !19798 (gfyoung)
|
||||
- Remove scrollbar in Safari in repo settings page. !19809 (gfyoung)
|
||||
- Omits operartions and kubernetes item from project sidebar when repository or builds are disabled. !19835
|
||||
- Rails5 fix passing Group objects array into for_projects_and_groups milestone scope. !19863 (Jasper Maes)
|
||||
- Fix chat service tag notifications not sending when only default branch enabled. !19864
|
||||
- Only show new issue / new merge request on group page when issues / merge requests are enabled. !19869 (Jan Beckmann)
|
||||
- [Rails5] Explicitly set request.format for blob_controller. !19876 (@blackst0ne)
|
||||
- [Rails5] Fix optimistic lock value. !19878 (@blackst0ne)
|
||||
- Rails5 fix update_attribute usage not causing a save. !19881 (Jasper Maes)
|
||||
- Rails5 fix connection execute return integer instead of string. !19901 (Jasper Maes)
|
||||
- Rails5 fix format in uploads actions. !19907 (Jasper Maes)
|
||||
- [Rails5] Fix "-1 is not a valid data_store". !19917 (@blackst0ne)
|
||||
- [Rails5] Invalid single-table inheritance type: Group is not a subclass of Namespace. !19918 (@blackst0ne)
|
||||
- [Rails5] Fix pipeline_schedules_controller_spec. !19919 (@blackst0ne)
|
||||
- Rails5 fix passing Group objects array into for_projects_and_groups milestone scope. !19920 (Jasper Maes)
|
||||
- Rails5 update Gemfile.rails5.lock. !19921 (Jasper Maes)
|
||||
- [Rails5] Fix sessions_controller_spec. !19936 (@blackst0ne)
|
||||
- [Rails5] Set request.format for artifacts_controller. !19937 (@blackst0ne)
|
||||
- Fix webhook error when password is not present. !19945 (Jan Beckmann)
|
||||
- Fix label and milestone duplicated records and IID errors. !19961
|
||||
- Rails5 fix expected: 1 time with arguments: (97, anything, {"squash"=>false}) received: 0 times. !20004 (Jasper Maes)
|
||||
- Rails5 fix Projects::PagesController spec. !20007 (Jasper Maes)
|
||||
- [Rails5] Fix ActionCable '/cable' mountpoint conflict. !20015 (@blackst0ne)
|
||||
- Fix branches are not shown in Merge Request dropdown when preferred language is not English. !20016 (Hiroyuki Sato)
|
||||
- Rails5 fix Admin::HooksController. !20017 (Jasper Maes)
|
||||
- Rails5 fix expected: 0 times with any arguments received: 1 time with arguments: DashboardController. !20018 (Jasper Maes)
|
||||
- [Rails5] Set request.format in commits_controller. !20023 (@blackst0ne)
|
||||
- Keeps the label on an issue when the issue is moved. !20036
|
||||
- Cleanup Prometheus ruby metrics. !20039 (Ben Kochie)
|
||||
- Rails 5 fix Capybara::ElementNotFound: Unable to find visible css #modal-revert-commit and expected: "/bar" got: "/foo". !20044 (Jasper Maes)
|
||||
- [Rails5] Force the callback run first. !20055 (@blackst0ne)
|
||||
- Add readme button to non-empty project page. !20104
|
||||
- Fixed bug when editing a comment in an issue,the preview mode is toggled in the main textarea. !20112 (Constance Okoghenun)
|
||||
- Ignore unknown OAuth sources in ApplicationSetting. !20129
|
||||
- Fix paragraph line height for emoji. !20137 (George Tsiolis)
|
||||
- Fixes issue with uploading same image to Profile Avatar twice. !20161 (Chirag Bhatia)
|
||||
- Rails5 fix arel from in mysql_median_datetime_sql. !20167 (Jasper Maes)
|
||||
- Adds the `locked` state to the merge request API so that it can be used as a search filter. !20186
|
||||
- Enable Doorkeeper option to avoid generating new tokens when users login via oauth. !20200
|
||||
- Fix OAuth Application Authorization screen to appear with each access. !20216
|
||||
- Rails5 fix MySQL milliseconds problem in specs. !20221 (Jasper Maes)
|
||||
- Rails5 fix Mysql comparison failure caused by milliseconds problem. !20222 (Jasper Maes)
|
||||
- Updated last commit link color. !20234 (Constance Okoghenun)
|
||||
- Fixed Merge request changes dropdown displays incorrectly. !20237 (Constance Okoghenun)
|
||||
- Show jobs from same pipeline in sidebar in job details view. !20243
|
||||
- [Rails5] Fix milestone GROUP BY query. !20256 (@blackst0ne)
|
||||
- Line separator to the left of the 'Admin area' wrench icon had vanished. !20282 (bitsapien)
|
||||
- Check if archived trace exist before archive it. !20297
|
||||
- Load Devise with Omniauth when auto_sign_in_with_provider is configured. !20302
|
||||
- Fix link to job when creating a new issue from a failed job. !20328
|
||||
- Fix double "in" in time to artifact deletion message. !20357 (@bbodenmiller)
|
||||
- Fix wrong role badge displayed in projects dashboard. !20374
|
||||
- Stop relying on migrations in the CacheableAttributes cache key and cache attributes for 1 minute instead. !20389
|
||||
- Fixes toggle discussion button not expanding collapsed discussions. !20452
|
||||
- Resolve compatibility issues with node 6. !20461
|
||||
- Fixes base command used in Helm installations. !20471
|
||||
- Fix RSS button interaction on Dashboard, Project and Group activities. !20549
|
||||
- Use appropriate timeout on Gitaly server info checks, avoid error on timeout. !20552
|
||||
- Remove healthchecks from prometheus endpoint. !20565
|
||||
- Render MR page when diffs cannot be fetched from the database or the git repository. !20680
|
||||
- Expire correct method caches after HEAD changed.
|
||||
- Ensure MR diffs always exist in the PR importer.
|
||||
- Fix overlapping file title and file actions in MR changes tag.
|
||||
- Mark MR as merged regardless of errors when closing issues.
|
||||
- Fix performance bar modal visibility in Safari.
|
||||
- Prevent browser autocomplete for milestone date fields.
|
||||
- Limit the action suffixes in transaction metrics.
|
||||
- Add /uploads subdirectory to allowed upload paths.
|
||||
- Fix cross-project label references.
|
||||
- Invalidate merge request diffs cache if diff data change.
|
||||
- Don't show context button for diffs of deleted files.
|
||||
- Structure getters for diff Store properly and adds specs.
|
||||
- Bump rugged to 0.27.2.
|
||||
- Fix Bamboo CI status not showing for branch plans.
|
||||
- Fixed bug that allowed to remove other wiki pages if the title had wildcard characters.
|
||||
- Disabled Web IDE autocomplete suggestions for Markdown files. (Isaac Smith)
|
||||
- Fix merge request diffs when created with gitaly_diff_between enabled.
|
||||
- Properly detect label reference if followed by period or question mark.
|
||||
- Deactivate new KubernetesService created from active template to prevent project creation from failing.
|
||||
- Allow trailing whitespace on blockquote fence lines.
|
||||
|
||||
### Deprecated (1 change)
|
||||
|
||||
- Removes unused bootstrap 4 scss files. !19423
|
||||
|
||||
### Changed (33 changes, 16 of them are from the community)
|
||||
|
||||
- Change label link vertical alignment property. !18777 (George Tsiolis)
|
||||
- Updated the icon for expand buttons to ellipsis. !18793 (Constance Okoghenun)
|
||||
- Create new or add existing Kubernetes cluster from a single page. !18963
|
||||
- Use object storage as the first class persistable store for new live trace architecture. !19515
|
||||
- Hide project name if searching against a project. !19595
|
||||
- Allows you to create another deploy token dimmediately after creating one. !19639
|
||||
- Removes the environment scope field for users that cannot edit it. !19643
|
||||
- Don't hash user ID in OIDC subject claim. !19784 (Markus Koller)
|
||||
- Milestone page list redesign. !19832 (Constance Okoghenun)
|
||||
- Add environment dropdown for the metrics page. !19833
|
||||
- Allow querying a single merge request within a project. !19853
|
||||
- Update WebIDE to show file in tree on load. !19887
|
||||
- Remove small container width. !19893 (George Tsiolis)
|
||||
- Improve U2F workflow when using unsupported browsers. !19938 (Jan Beckmann)
|
||||
- Update Web IDE file tree styles. !19969
|
||||
- Highlight cluster settings message. !19996 (George Tsiolis)
|
||||
- Fade uneditable area in Web IDE. !20008
|
||||
- Update pipeline icon in web ide sidebar. !20058 (George Tsiolis)
|
||||
- Revert merge request discussion buttons padding. !20060 (George Tsiolis)
|
||||
- Fix boards issue highlight. !20063 (George Tsiolis)
|
||||
- Update external link icon in header user dropdown. !20150 (George Tsiolis)
|
||||
- Update external link icon in merge request widget. !20154 (George Tsiolis)
|
||||
- Update environments nav controls icons. !20199 (George Tsiolis)
|
||||
- Update integrations external link icons. !20205 (George Tsiolis)
|
||||
- Fixes an issue where migrations instead of schema loading were run. !20227
|
||||
- Add title placeholder for new issues. !20271 (George Tsiolis)
|
||||
- Close revoke deploy token modal on escape keypress. !20347 (George Tsiolis)
|
||||
- Change environment scope text depending on number of project clusters. Update form to only include form-groups.
|
||||
- Improve Web IDE commit flow.
|
||||
- Add machine type and pricing documentation links, add class to labels to make bold.
|
||||
- Remove remaining traces of the Allocations Gem.
|
||||
- Use one column form layout on Admin Area Settings page.
|
||||
- Add back copy for existing gcp accounts within offer banner.
|
||||
|
||||
### Performance (16 changes, 4 of them are from the community)
|
||||
|
||||
- Fully migrate pipeline stages position. !19369
|
||||
- Use Tooltip component in MrWidgetAuthorTime vue comonent. !19635 (George Tsiolis)
|
||||
- Move boards modal EmptyState vue component. !20068 (George Tsiolis)
|
||||
- Bump carrierwave gem verion to 1.2.3. !20287
|
||||
- Remove redundant query when removing trace. !20324
|
||||
- Improves performance of mr code, by fixing the state being mutated outside of the store in the util function trimFirstCharOfLineContent and in map operations. Avoids map operation in an empty array. Adds specs to the trimFirstCharOfLineContent function. !20380 (filipa)
|
||||
- Reduce the number of queries when searching for groups. !20398
|
||||
- Improve render performance of large wiki pages. !20465 (Peter Leitzen)
|
||||
- Improves performance on Merge Request diff tab by removing the scroll event listeners being added to every file.
|
||||
- Remove the ci_job_request_with_tags_matcher.
|
||||
- Updated Gitaly fail-fast timeout values.
|
||||
- Add index on deployable_type/id for deployments.
|
||||
- Eliminate N+1 queries in LFS file locks checks during a push.
|
||||
- Fix performance problem of accessing tag list for projects api endpoints.
|
||||
- Improve performance of listing users without projects.
|
||||
- Fixed pagination of web hook logs.
|
||||
|
||||
### Added (29 changes, 9 of them are from the community)
|
||||
|
||||
- Add dropdown to Groups link in top bar. !18280
|
||||
- Web IDE supports now Image + Download Diff Viewing. !18768
|
||||
- Use CommonMark syntax and rendering for new Markdown content. !19331
|
||||
- Add SHA256 and HEAD on File API. !19439 (ahmet2mir)
|
||||
- Add filename filtering to code search. !19509
|
||||
- Add CI_PIPELINE_URL and CI_JOB_URL. !19618
|
||||
- Expose visibility via Snippets API. !19620 (Jan Beckmann)
|
||||
- Fixed pagination of groups API. !19665 (Marko, Peter)
|
||||
- Added id sorting option to GET groups and subgroups API. !19665 (Marko, Peter)
|
||||
- Add a link to the contributing page in the user dropdown. !19708
|
||||
- Add Object Storage to project export. !20105
|
||||
- Change avatar image in the header when user updates their avatar. !20119 (Jamie Schembri)
|
||||
- Allow straight diff in Compare API. !20120 (Maciej Nowak)
|
||||
- Add transfer project API endpoint. !20122 (Aram Visser)
|
||||
- Expose permissions of the current user on resources in GraphQL. !20152
|
||||
- Run repository checks in parallel for each shard. !20179
|
||||
- Add pipeline lists to GraphQL. !20249
|
||||
- Add option to add README when creating a project. !20335
|
||||
- Add option to hide third party offers in admin application settings. !20379
|
||||
- Add /confidential quick action. (Jan Beckmann)
|
||||
- Support direct_upload for generic uploads.
|
||||
- Display merge request title & description in Web IDE.
|
||||
- Prune web hook logs older than 90 days.
|
||||
- Add Web Terminal for Ci Builds. (Vicky Chijwani)
|
||||
- Expose whether current user can push into a branch on branches API.
|
||||
- Present state indication on GFM preview.
|
||||
- migrate backup rake task to gitaly.
|
||||
- Add Gitlab::SQL:CTE for easily building CTE statements.
|
||||
- Added with_statsoption for GET /projects/:id/repository/commits.
|
||||
|
||||
### Other (28 changes, 11 of them are from the community)
|
||||
|
||||
- Move some Gitaly RPC's to opt-out. !19591
|
||||
- Bump grape-path-helpers to 1.0.5. !19604 (@blackst0ne)
|
||||
- Add CI job to check Gemfile.rails5.lock. !19605 (@blackst0ne)
|
||||
- Move Gitaly branch/tag/ref RPC's to opt-out. !19644
|
||||
- CE port gitlab-ee!6112. !19714
|
||||
- Enable no-multi-assignment in JS files. !19808 (gfyoung)
|
||||
- Enable no-restricted globals in JS files. !19877 (gfyoung)
|
||||
- Improve no-multi-assignment fixes after enabling rule. !19915 (gfyoung)
|
||||
- Enable prefer-structuring in JS files. !19943 (gfyoung)
|
||||
- Enable frozen string in app/workers/*.rb. !19944 (gfyoung)
|
||||
- Uses long sha version of the merged commit in MR widget copy to clipboard button. !19955
|
||||
- Update new group page to better explain what groups are. !19991
|
||||
- Update new SSH key page to improve copy. !19994
|
||||
- Update new SSH key page to improve key input validation. !19997
|
||||
- Gitaly metrics check for read/writeability. !20022
|
||||
- Add ellispsis to web ide commit button. !20030
|
||||
- Minor style changes to personal access token form and scope checkboxes. !20052
|
||||
- Finish enabling frozen string for app/workers/*.rb. !20197 (gfyoung)
|
||||
- Allows settings sections to expand by default when linking to them. !20211
|
||||
- Enable frozen string in apps/validators/*.rb. !20220 (gfyoung)
|
||||
- update bcrypt to also support libxcrypt. !20260 (muhammadn)
|
||||
- Enable frozen string in apps/validators/*.rb. !20382 (gfyoung)
|
||||
- Removes unused vuex code in mr refactor and removes unneeded dependencies. !20499
|
||||
- Delete non-latest merge request diff files upon merge.
|
||||
- Schedule workers to delete non-latest diffs in post-migration.
|
||||
- Remove the use of `is_shared` of `Ci::Runner`.
|
||||
- Add more detailed logging to githost.log when rebasing.
|
||||
- Use monospaced font for MR diff commit link ref on GFM.
|
||||
|
||||
|
||||
## 11.0.3 (2018-07-05)
|
||||
|
||||
### Fixed (14 changes, 1 of them is from the community)
|
||||
|
||||
- Revert merge request widget button max height. !20175 (George Tsiolis)
|
||||
- Implement upload copy when moving an issue with upload on object storage. !20191
|
||||
- Fix broken '!' support to autocomplete MRs in GFM fields. !20204
|
||||
- Restore showing Elasticsearch and Geo status on dashboard. !20276
|
||||
- Fix merge request page rendering error when its target/source branch is missing. !20280
|
||||
- Fix sidebar collapse breapoints for job and wiki pages.
|
||||
- fix size of code blocks in headings.
|
||||
- Fix loading screen for search autocomplete dropdown.
|
||||
- Fix ambiguous due_date column for Issue scopes.
|
||||
- Always serve favicon from main GitLab domain so that CI badge can be drawn over it.
|
||||
- Fix tooltip flickering bug.
|
||||
- Fix refreshing cache keys for open issues count.
|
||||
- Replace deprecated bs.affix in merge request tabs with sticky polyfill.
|
||||
- Prevent pipeline job tooltip from scrolling off dropdown container.
|
||||
|
||||
|
||||
## 11.0.2 (2018-06-26)
|
||||
|
||||
### Fixed (8 changes, 1 of them is from the community)
|
||||
|
||||
- Serve favicon image always from the main GitLab domain to avoid issues with CORS. !19810 (Alexis Reigel)
|
||||
- Specify chart version when installing applications on Clusters. !20010
|
||||
- Fix invalid fuzzy translations being generated during installation. !20048
|
||||
- Fix incremental rollouts for Auto DevOps. !20061
|
||||
- Notify conflict for only open merge request. !20125
|
||||
- Only load Omniauth if enabled. !20132
|
||||
- Fix sorting by name on explore projects page. !20162
|
||||
- Fix alert button styling so that they don't show up white.
|
||||
|
||||
### Performance (1 change)
|
||||
|
||||
- Remove performance bottleneck preventing large wiki pages from displaying. !20174
|
||||
|
||||
### Added (1 change)
|
||||
|
||||
- Add support for verifying remote uploads, artifacts, and LFS objects in check rake tasks. !19501
|
||||
|
||||
|
||||
## 11.0.1 (2018-06-21)
|
||||
|
||||
### Security (5 changes)
|
||||
|
||||
- Fix XSS vulnerability for table of content generation.
|
||||
- Update sanitize gem to 4.6.5 to fix HTML injection vulnerability.
|
||||
- HTML escape branch name in project graphs page.
|
||||
- HTML escape the name of the user in ProjectsHelper#link_to_member.
|
||||
- Don't show events from internal projects for anonymous users in public feed.
|
||||
|
||||
|
||||
## 11.0.0 (2018-06-22)
|
||||
|
||||
### Security (3 changes)
|
||||
|
||||
- Fix API to remove deploy key from project instead of deleting it entirely.
|
||||
- Fixed bug that allowed importing arbitrary project attributes.
|
||||
- Prevent user passwords from being changed without providing the previous password.
|
||||
|
||||
### Removed (2 changes)
|
||||
|
||||
- Removed API v3 from the codebase. !18970
|
||||
- Removes outdated `g t` shortcut for TODO in favor of `Shift+T`. !19002
|
||||
|
||||
### Fixed (69 changes, 23 of them are from the community)
|
||||
|
||||
- Optimize the upload migration proces. !15947
|
||||
- Import bitbucket issues that are reported by an anonymous user. !18199 (bartl)
|
||||
- Fix an issue where the notification email address would be set to an unconfirmed email address. !18474
|
||||
- Stop logging email information when emails are disabled. !18521 (Marc Shaw)
|
||||
- Fix double-brackets being linkified in wiki markdown. !18524 (brewingcode)
|
||||
- Use case in-sensitive ordering by name for dashboard. !18553 (@vedharish)
|
||||
- Fix width of contributors graphs. !18639 (Paul Vorbach)
|
||||
- Fix modal width of shorcuts help page. !18766 (Lars Greiss)
|
||||
- Add missing tooltip to creation date on container registry overview. !18767 (Lars Greiss)
|
||||
- Add missing migration for minimal Project build_timeout. !18775
|
||||
- Update commit status from external CI services less aggressively. !18802
|
||||
- Fix Runner contacted at tooltip cache. !18810
|
||||
- Added support for LFS Download in the importing process. !18871
|
||||
- Fix issue board bug with long strings in titles. !18924
|
||||
- Does not log failed sign-in attempts when the database is in read-only mode. !18957
|
||||
- Fixes 500 error on /estimate BIG_VALUE. !18964 (Jacopo Beschi @jacopo-beschi)
|
||||
- Forbid to patch traces for finished jobs. !18969
|
||||
- Do not allow to trigger manual actions that were skipped. !18985
|
||||
- Renamed 'Overview' to 'Project' in collapsed contextual navigation at a project level. !18996 (Constance Okoghenun)
|
||||
- Fixed bug where generated api urls didn't add the base url if set. !19003
|
||||
- Fixed badge api endpoint route when relative url is set. !19004
|
||||
- Fixes: Runners search input placeholder is cut off. !19015 (Jacopo Beschi @jacopo-beschi)
|
||||
- Exclude CI_PIPELINE_ID from variables supported in dynamic environment name. !19032
|
||||
- Updates updated_at on label changes. !19065 (Jacopo Beschi @jacopo-beschi)
|
||||
- Disallow updating job status if the job is not running. !19101
|
||||
- Fix FreeBSD can not upload artifacts due to wrong tmp path. !19148
|
||||
- Check for nil AutoDevOps when saving project CI/CD settings. !19190
|
||||
- Missing timeout value in object storage pre-authorization. !19201
|
||||
- Use strings as properties key in kubernetes service spec. !19265 (Jasper Maes)
|
||||
- Fixed HTTP_PROXY environment not honored when reading remote traces. !19282 (NLR)
|
||||
- Updates ReactiveCaching clear_reactive_caching method to clear both data and alive caching. !19311
|
||||
- Fixes the styling on the modal headers. !19312 (samdbeckham)
|
||||
- Fixes a spelling error on the new label page. !19316 (samdbeckham)
|
||||
- Rails5 fix arel from. !19340 (Jasper Maes)
|
||||
- Support rails5 in postgres indexes function and fix some migrations. !19400 (Jasper Maes)
|
||||
- Fix repository archive generation when hashed storage is enabled. !19441
|
||||
- Rails 5 fix unknown keywords: changes, key_id, project, gl_repository, action, secret_token, protocol. !19466 (Jasper Maes)
|
||||
- Rails 5 fix glob spec. !19469 (Jasper Maes)
|
||||
- Showing project import_status in a humanized form no longer gives an error. !19470
|
||||
- Make avatars/icons hidden on mobile. !19585 (Takuya Noguchi)
|
||||
- Fix active tab highlight when creating new merge request. !19781 (Jan Beckmann)
|
||||
- Fixes Web IDE button on merge requests when GitLab is installed with relative URL.
|
||||
- Unverified hover state color changed to black.
|
||||
- Fix after sign-in with Google button.
|
||||
- Don't trim incoming emails that create new issues. (Cameron Crockett)
|
||||
- Wrapping problem on the issues page has been fixed.
|
||||
- Fix resolvable check if note's commit could not be found.
|
||||
- Fix filename matching when processing file or blob search results.
|
||||
- Allow maintainers to retry pipelines on forked projects (if allowed in merge request).
|
||||
- Fix deletion of Object Store uploads.
|
||||
- Fix overflowing Failed Jobs table in sm viewports on IE11.
|
||||
- Adjust insufficient diff hunks being persisted on NoteDiffFile.
|
||||
- Render calendar feed inline when accessed from GitLab.
|
||||
- Line height fixed. (Murat Dogan)
|
||||
- Use upload ID for creating lease key for file uploaders.
|
||||
- Use Github repo visibility during import while respecting restricted visibility levels.
|
||||
- Adjust permitted params filtering on merge scheduling.
|
||||
- Fix unscrollable Markdown preview of WebIDE on Firefox.
|
||||
- Enforce UTF-8 encoding on user input in LogrageWithTimestamp formatter and filter out file content from logs.
|
||||
- Fix project destruction failing due to idle in transaction timeouts.
|
||||
- Add a unique and not null constraint on the project_features.project_id column.
|
||||
- Expire Wiki content cache after importing a repository.
|
||||
- Fix admin counters not working when PostgreSQL has secondaries.
|
||||
- Fix backup creation and restore for specific Rake tasks.
|
||||
- Fix cross-origin errors when attempting to download JavaScript attachments.
|
||||
- Fix api_json.log not always reporting the right HTTP status code.
|
||||
- Fix attr_encryption key settings.
|
||||
- Remove gray button styles.
|
||||
- Fix print styles for markdown pages.
|
||||
|
||||
### Deprecated (4 changes)
|
||||
|
||||
- Deprecate Gemnasium project service. !18954
|
||||
- Rephrasing Merge Request's 'allow edits from maintainer' functionality. !19061
|
||||
- Rename issue scope created-by-me to created_by_me, and assigned-to-me to assigned_to_me. !44799
|
||||
- Migrate any remaining jobs from deprecated `object_storage_upload` queue.
|
||||
|
||||
### Changed (42 changes, 11 of them are from the community)
|
||||
|
||||
- Add support for smarter system notes. !17164
|
||||
- Automatically accepts project/group invite by email after user signup. !17634 (Jacopo Beschi @jacopo-beschi)
|
||||
- Dynamically fetch GCP cluster creation parameters. !17806
|
||||
- Label list page redesign. !18466
|
||||
- Move discussion actions to the right for small viewports. !18476 (George Tsiolis)
|
||||
- Add 2FA filter to the group members page. !18483
|
||||
- made listing and showing public issue apis available without authentication. !18638 (haseebeqx)
|
||||
- Refactoring UrlValidators to include url blocking. !18686
|
||||
- Removed "(Beta)" from "Auto DevOps" messages. !18759
|
||||
- Expose runner ip address to runners API. !18799 (Lars Greiss)
|
||||
- Moves MR widget external link icon to the right. !18828 (Jacopo Beschi @jacopo-beschi)
|
||||
- Add support for 'active' setting on Runner Registration API endpoint. !18848
|
||||
- Add dot to separate system notes content. !18864
|
||||
- Remove modalbox confirmation when retrying a pipeline. !18879
|
||||
- Remove docker pull prefix from registry clipboard feature. !18933 (Lars Greiss)
|
||||
- Move project sidebar sub-entries 'Environments' and 'Kubernetes' from 'CI/CD' to a new entry 'Operations'. !18941
|
||||
- Updated icons for branch and tag names in commit details. !18953 (Constance Okoghenun)
|
||||
- Expose readme url in Project API. !18960 (Imre Farkas)
|
||||
- Changes keyboard shortcut of Activity feed to `g v`. !19002
|
||||
- Updated Mattermost integration to use API v4 and only allow creation of Mattermost slash commands in the current user's teams. !19043 (Harrison Healey)
|
||||
- Add shortcuts to Web IDE docs and modal. !19044
|
||||
- Rename merge request widget author component. !19079 (George Tsiolis)
|
||||
- Rename the Master role to Maintainer. !19080
|
||||
- Use "right now" for short time periods. !19095
|
||||
- Update 404 and 403 pages with helpful actions. !19096
|
||||
- Add username to terms message in git and API calls. !19126
|
||||
- Change the IDE file buttons for an "Open in file view" button. !19129 (Sam Beckham)
|
||||
- Removes redundant script failure message from Job page. !19138
|
||||
- Add flash notice if user has already accepted terms and allow users to continue to root path. !19156
|
||||
- Redesign group settings page into expandable sections. !19184
|
||||
- Hashed Storage: migration rake task now can be executed to specific project. !19268
|
||||
- Make CI job update entrypoint to work as keep-alive endpoint. !19543
|
||||
- Avoid checking the user format in every url validation. !19575
|
||||
- Apply notification settings level of groups to all child objects.
|
||||
- Support restoring repositories into gitaly.
|
||||
- Bump omniauth-gitlab to 1.0.3.
|
||||
- Move API group deletion to Sidekiq.
|
||||
- Improve Failed Jobs tab in the Pipeline detail page.
|
||||
- Add additional theme color options.
|
||||
- Include milestones from parent groups when assigning a milestone to an issue or merge request.
|
||||
- Restore API v3 user endpoint.
|
||||
- Hide merge request option in IDE when disabled.
|
||||
|
||||
### Performance (28 changes, 1 of them is from the community)
|
||||
|
||||
- Add backgound migration for filling nullfied file_store columns. !18557
|
||||
- Add a cronworker to rescue stale live traces. !18680
|
||||
- Move SquashBeforeMerge vue component. !18813 (George Tsiolis)
|
||||
- Add index on runner_type for ci_runners. !18897
|
||||
- Fix CarrierWave reads local files into memoery when migrates to ObjectStorage. !19102
|
||||
- Remove double-checked internal id generation. !19181
|
||||
- Throttle updates to Project#last_repository_updated_at. !19183
|
||||
- Add background migrations for archiving legacy job traces. !19194
|
||||
- Use NPM provided version of SortableJS. !19274
|
||||
- Improve performance of group issues filtering on GitLab.com. !19429
|
||||
- Improve performance of LFS integrity check. !19494
|
||||
- Fix an N+1 when loading user avatars.
|
||||
- Only preload member records for the relevant projects/groups/user in projects API.
|
||||
- Fix some sources of excessive query counts when calculating notification recipients.
|
||||
- Optimise PagesWorker usage.
|
||||
- Optimise paused runners to reduce amount of used requests.
|
||||
- Update runner cached informations without performing validations.
|
||||
- Improve performance of project pipelines pages.
|
||||
- Persist truncated note diffs on a new table.
|
||||
- Remove unused running_or_pending_build_count.
|
||||
- Remove N+1 query for author in issues API.
|
||||
- Eliminate N+1 queries with authors and push_data_payload in Events API.
|
||||
- Eliminate cached N+1 queries for projects in Issue API.
|
||||
- Eliminate N+1 queries for CI job artifacts in /api/prjoects/:id/pipelines/:pipeline_id/jobs.
|
||||
- Fix N+1 with source_projects in merge requests API.
|
||||
- Replace grape-route-helpers with our own grape-path-helpers.
|
||||
- Move PR IO operations out of a transaction.
|
||||
- Improve performance of GroupsController#show.
|
||||
|
||||
### Added (25 changes, 10 of them are from the community)
|
||||
|
||||
- Closes MR check out branch modal with escape. (19050)
|
||||
- Allow changing the default favicon to a custom icon. !14497 (Alexis Reigel)
|
||||
- Export assigned issues in iCalendar feed. !17783 (Imre Farkas)
|
||||
- When MR becomes unmergeable, notify and create todo for author and merge user. !18042
|
||||
- Display help text below auto devops domain with nip.io domain name (#45561). !18496
|
||||
- Add per-project pipeline id. !18558
|
||||
- New design for wiki page deletion confirmation. !18712 (Constance Okoghenun)
|
||||
- Updates updated_at on issuable when setting time spent. !18757 (Jacopo Beschi @jacopo-beschi)
|
||||
- Expose artifacts_expire_at field for job entity in api. !18872 (Semyon Pupkov)
|
||||
- Add support for variables expression pattern matching syntax. !18902
|
||||
- Add API endpoint to render markdown text. !18926 (@blackst0ne)
|
||||
- Add `Squash and merge` to GitLab Core (CE). !18956 (@blackst0ne)
|
||||
- Adds keyboard shortcut `g k` for Kubernetes on Project pages. !19002
|
||||
- Adds keyboard shortcut `g e` for Environments on Project pages. !19002
|
||||
- Setup graphql with initial project & merge request query. !19008
|
||||
- Adds JupyterHub to cluster applications. !19019
|
||||
- Added ability to search by wiki titles. !19112
|
||||
- Add Avatar API. !19121 (Imre Farkas)
|
||||
- Add variables to POST api/v4/projects/:id/pipeline. !19124 (Jacopo Beschi @jacopo-beschi)
|
||||
- Add deploy strategies to the Auto DevOps settings. !19172
|
||||
- Automatize Deploy Token creation for Auto Devops. !19507
|
||||
- Add anchor for incoming email regex.
|
||||
- Support direct_upload with S3 Multipart uploads.
|
||||
- Add Open in Xcode link for xcode repositories.
|
||||
- Add pipeline status to the status bar of the Web IDE.
|
||||
|
||||
### Other (40 changes, 17 of them are from the community)
|
||||
|
||||
- Expand documentation for Runners API. !16484
|
||||
- Order UsersController#projects.json by updated_at. !18227 (Takuya Noguchi)
|
||||
- Replace the `project/issues/references.feature` spinach test with an rspec analog. !18769 (@blackst0ne)
|
||||
- Replace the `project/merge_requests/references.feature` spinach test with an rspec analog. !18794 (@blackst0ne)
|
||||
- Replace the `project/deploy_keys.feature` spinach test with an rspec analog. !18796 (@blackst0ne)
|
||||
- Replace the `project/ff_merge_requests.feature` spinach test with an rspec analog. !18800 (@blackst0ne)
|
||||
- Apply NestingDepth (level 5) (pages/pipelines.scss). !18830 (Takuya Noguchi)
|
||||
- Replace the `project/forked_merge_requests.feature` spinach test with an rspec analog. !18867 (@blackst0ne)
|
||||
- Remove Spinach. !18869 (@blackst0ne)
|
||||
- Add NOT NULL constraints to project_authorizations. !18980
|
||||
- Add helpful messages to empty wiki view. !19007
|
||||
- Increase text limit for GPG keys (mysql only). !19069
|
||||
- Take two for MR metrics population background migration. !19097
|
||||
- Remove Gemnasium badge from project README.md. !19136 (Takuya Noguchi)
|
||||
- Update awesome_print to 1.8.0. !19163 (Takuya Noguchi)
|
||||
- Update email_spec to 2.2.0. !19164 (Takuya Noguchi)
|
||||
- Update redis-namespace to 1.6.0. !19166 (Takuya Noguchi)
|
||||
- Update rdoc to 6.0.4. !19167 (Takuya Noguchi)
|
||||
- Updates the version of kubeclient from 3.0 to 3.1.0. !19199
|
||||
- Fix UI broken in line profiling modal due to Bootstrap 4. !19253 (Takuya Noguchi)
|
||||
- Add migration to disable the usage of DSA keys. !19299
|
||||
- Use the default strings of timeago.js for timeago. !19350 (Takuya Noguchi)
|
||||
- Update selenium-webdriver to 3.12.0. !19351 (Takuya Noguchi)
|
||||
- Include username in output when testing SSH to GitLab. !19358
|
||||
- Update screenshot in Gitlab.com integration documentation. !19433 (Tuğçe Nur Taş)
|
||||
- Users can accept terms during registration. !19583
|
||||
- Fix issue count on sidebar.
|
||||
- Add merge requests list endpoint for groups.
|
||||
- Upgrade GitLab from Bootstrap 3 to 4.
|
||||
- Make ActiveRecordSubscriber rails 5 compatible.
|
||||
- Show a more helpful error for import status.
|
||||
- Log response body to production_json.log when a controller responds with a 422 status.
|
||||
- Log Workhorse queue duration for Grape API calls.
|
||||
- Adjust SQL and transaction Prometheus buckets.
|
||||
- Adding branches through the WebUI is handled by Gitaly.
|
||||
- Remove shellout implementation for Repository checksums.
|
||||
- Refs containting sha checks are done by Gitaly.
|
||||
- Finding a wiki page is done by Gitaly by default.
|
||||
- Workhorse will use Gitaly to create archives.
|
||||
- Workhorse to send raw diff and patch for commits.
|
||||
|
||||
|
||||
## 10.8.5 (2018-06-21)
|
||||
|
@ -253,6 +853,38 @@ entry.
|
|||
- Gitaly handles repository forks by default.
|
||||
|
||||
|
||||
## 10.7.6 (2018-06-21)
|
||||
|
||||
### Security (6 changes)
|
||||
|
||||
- Fix XSS vulnerability for table of content generation.
|
||||
- Update sanitize gem to 4.6.5 to fix HTML injection vulnerability.
|
||||
- HTML escape branch name in project graphs page.
|
||||
- HTML escape the name of the user in ProjectsHelper#link_to_member.
|
||||
- Don't show events from internal projects for anonymous users in public feed.
|
||||
- XSS fix to use safe_params instead of params in url_for helpers.
|
||||
|
||||
### Other (1 change)
|
||||
|
||||
- Replacing gollum libraries for gitlab custom libs. !18343
|
||||
|
||||
|
||||
## 10.7.5 (2018-05-28)
|
||||
|
||||
### Security (3 changes)
|
||||
|
||||
- Prevent user passwords from being changed without providing the previous password.
|
||||
- Fix API to remove deploy key from project instead of deleting it entirely.
|
||||
- Fixed bug that allowed importing arbitrary project attributes.
|
||||
|
||||
|
||||
## 10.7.4 (2018-05-21)
|
||||
|
||||
### Fixed (1 change)
|
||||
|
||||
- Fix error when deleting an empty list of refs.
|
||||
|
||||
|
||||
## 10.7.3 (2018-05-02)
|
||||
|
||||
### Fixed (8 changes)
|
||||
|
@ -510,6 +1142,16 @@ entry.
|
|||
- Upgrade Gitaly to upgrade its charlock_holmes.
|
||||
|
||||
|
||||
## 10.6.6 (2018-05-28)
|
||||
|
||||
### Security (4 changes)
|
||||
|
||||
- Do not allow non-members to create MRs via forked projects when MRs are private.
|
||||
- Prevent user passwords from being changed without providing the previous password.
|
||||
- Fix API to remove deploy key from project instead of deleting it entirely.
|
||||
- Fixed bug that allowed importing arbitrary project attributes.
|
||||
|
||||
|
||||
## 10.6.5 (2018-04-24)
|
||||
|
||||
### Security (1 change)
|
||||
|
|
147
CONTRIBUTING.md
|
@ -27,25 +27,26 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
|
|||
- [Helping others](#helping-others)
|
||||
- [I want to contribute!](#i-want-to-contribute)
|
||||
- [Workflow labels](#workflow-labels)
|
||||
- [Type labels (~"feature proposal", ~bug, ~customer, etc.)](#type-labels-feature-proposal-bug-customer-etc)
|
||||
- [Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.)](#subject-labels-wiki-container-registry-ldap-api-etc)
|
||||
- [Team labels (~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.)](#team-labels-cicd-discussion-quality-platform-etc)
|
||||
- [Milestone labels (~Deliverable, ~Stretch, ~"Next Patch Release")](#milestone-labels-deliverable-stretch-next-patch-release)
|
||||
- [Priority labels (~Deliverable, ~Stretch, ~"Next Patch Release")](#bug-priority-labels-p1-p2-p3-etc)
|
||||
- [Severity labels (~Deliverable, ~Stretch, ~"Next Patch Release")](#bug-severity-labels-s1-s2-s3-etc)
|
||||
- [Label for community contributors (~"Accepting Merge Requests")](#label-for-community-contributors-accepting-merge-requests)
|
||||
- [Implement design & UI elements](#implement-design--ui-elements)
|
||||
- [Type labels](#type-labels)
|
||||
- [Subject labels](#subject-labels)
|
||||
- [Team labels](#team-labels)
|
||||
- [Release Scoping labels](#release-scoping-labels)
|
||||
- [Bug Priority labels](#bug-priority-labels)
|
||||
- [Bug Severity labels](#bug-severity-labels)
|
||||
- [Severity impact guidance](#severity-impact-guidance)
|
||||
- [Label for community contributors](#label-for-community-contributors)
|
||||
- [Implement design & UI elements](#implement-design-ui-elements)
|
||||
- [Issue tracker](#issue-tracker)
|
||||
- [Issue triaging](#issue-triaging)
|
||||
- [Feature proposals](#feature-proposals)
|
||||
- [Issue tracker guidelines](#issue-tracker-guidelines)
|
||||
- [Issue weight](#issue-weight)
|
||||
- [Regression issues](#regression-issues)
|
||||
- [Technical and UX debt](#technical-and-ux-debt)
|
||||
- [Stewardship](#stewardship)
|
||||
- [Issue triaging](#issue-triaging)
|
||||
- [Feature proposals](#feature-proposals)
|
||||
- [Issue tracker guidelines](#issue-tracker-guidelines)
|
||||
- [Issue weight](#issue-weight)
|
||||
- [Regression issues](#regression-issues)
|
||||
- [Technical and UX debt](#technical-and-ux-debt)
|
||||
- [Stewardship](#stewardship)
|
||||
- [Merge requests](#merge-requests)
|
||||
- [Merge request guidelines](#merge-request-guidelines)
|
||||
- [Contribution acceptance criteria](#contribution-acceptance-criteria)
|
||||
- [Merge request guidelines](#merge-request-guidelines)
|
||||
- [Contribution acceptance criteria](#contribution-acceptance-criteria)
|
||||
- [Definition of done](#definition-of-done)
|
||||
- [Style guides](#style-guides)
|
||||
- [Code of conduct](#code-of-conduct)
|
||||
|
@ -132,7 +133,7 @@ Most issues will have labels for at least one of the following:
|
|||
- Type: ~"feature proposal", ~bug, ~customer, etc.
|
||||
- Subject: ~wiki, ~"container registry", ~ldap, ~api, ~frontend, etc.
|
||||
- Team: ~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.
|
||||
- Milestone: ~Deliverable, ~Stretch, ~"Next Patch Release"
|
||||
- Release Scoping: ~Deliverable, ~Stretch, ~"Next Patch Release"
|
||||
- Priority: ~P1, ~P2, ~P3, ~P4
|
||||
- Severity: ~S1, ~S2, ~S3, ~S4
|
||||
|
||||
|
@ -145,7 +146,7 @@ labels, you can _always_ add the team and type, and often also the subject.
|
|||
[milestones-page]: https://gitlab.com/gitlab-org/gitlab-ce/milestones
|
||||
[labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels
|
||||
|
||||
### Type labels (~"feature proposal", ~bug, ~customer, etc.)
|
||||
### Type labels
|
||||
|
||||
Type labels are very important. They define what kind of issue this is. Every
|
||||
issue should have one or more.
|
||||
|
@ -161,28 +162,41 @@ already reserved for subject labels).
|
|||
|
||||
The descriptions on the [labels page][labels-page] explain what falls under each type label.
|
||||
|
||||
### Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.)
|
||||
### Subject labels
|
||||
|
||||
Subject labels are labels that define what area or feature of GitLab this issue
|
||||
hits. They are not always necessary, but very convenient.
|
||||
|
||||
Examples of subject labels are ~wiki, ~ldap, ~api,
|
||||
~issues, ~"merge requests", ~labels, and ~"container registry".
|
||||
|
||||
If you are an expert in a particular area, it makes it easier to find issues to
|
||||
work on. You can also subscribe to those labels to receive an email each time an
|
||||
issue is labelled with a subject label corresponding to your expertise.
|
||||
|
||||
Examples of subject labels are ~wiki, ~"container registry", ~ldap, ~api,
|
||||
~issues, ~"merge requests", ~labels, and ~"container registry".
|
||||
issue is labeled with a subject label corresponding to your expertise.
|
||||
|
||||
Subject labels are always all-lowercase.
|
||||
|
||||
### Team labels (~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.)
|
||||
### Team labels
|
||||
|
||||
Team labels specify what team is responsible for this issue.
|
||||
Assigning a team label makes sure issues get the attention of the appropriate
|
||||
people.
|
||||
|
||||
The current team labels are ~Build, ~"CI/CD", ~Discussion, ~Documentation, ~Quality,
|
||||
~Geo, ~Gitaly, ~Monitoring, ~Platform, ~Release, ~"Security Products" and ~"UX".
|
||||
The current team labels are:
|
||||
|
||||
- ~Configuration
|
||||
- ~"CI/CD"
|
||||
- ~Discussion
|
||||
- ~Distribution
|
||||
- ~Documentation
|
||||
- ~Geo
|
||||
- ~Gitaly
|
||||
- ~Monitoring
|
||||
- ~Platform
|
||||
- ~Quality
|
||||
- ~Release
|
||||
- ~"Security Products"
|
||||
- ~UX
|
||||
|
||||
The descriptions on the [labels page][labels-page] explain what falls under the
|
||||
responsibility of each team.
|
||||
|
@ -193,10 +207,10 @@ indicate if an issue needs backend work, frontend work, or both.
|
|||
Team labels are always capitalized so that they show up as the first label for
|
||||
any issue.
|
||||
|
||||
### Milestone labels (~Deliverable, ~Stretch, ~"Next Patch Release")
|
||||
### Release Scoping labels
|
||||
|
||||
Milestone labels help us clearly communicate expectations of the work for the
|
||||
release. There are three levels of Milestone labels:
|
||||
Release Scoping labels help us clearly communicate expectations of the work for the
|
||||
release. There are three levels of Release Scoping labels:
|
||||
|
||||
- ~Deliverable: Issues that are expected to be delivered in the current
|
||||
milestone.
|
||||
|
@ -211,9 +225,10 @@ Each issue scheduled for the current milestone should be labeled ~Deliverable
|
|||
or ~"Stretch". Any open issue for a previous milestone should be labeled
|
||||
~"Next Patch Release", or otherwise rescheduled to a different milestone.
|
||||
|
||||
### Bug Priority labels (~P1, ~P2, ~P3 & etc.)
|
||||
### Bug Priority labels
|
||||
|
||||
Bug Priority labels help us define the time a ~bug fix should be completed. Priority determines how quickly the defect turnaround time must be. If there are multiple defects, the priority decides which defect has to be fixed immediately versus later.
|
||||
Bug Priority labels help us define the time a ~bug fix should be completed. Priority determines how quickly the defect turnaround time must be.
|
||||
If there are multiple defects, the priority decides which defect has to be fixed immediately versus later.
|
||||
This label documents the planned timeline & urgency which is used to measure against our actual SLA on delivering ~bug fixes.
|
||||
|
||||
| Label | Meaning | Estimate time to fix | Guidance |
|
||||
|
@ -223,16 +238,7 @@ This label documents the planned timeline & urgency which is used to measure aga
|
|||
| ~P3 | Medium Priority | Within the next 3 releases (approx one quarter) | |
|
||||
| ~P4 | Low Priority | Anything outside the next 3 releases (approx beyond one quarter) | The issue is prominent but does not impact user workflow and a workaround is documented |
|
||||
|
||||
#### Specific Priority guidance
|
||||
|
||||
| Label | Availability / Performance |
|
||||
|-------|--------------------------------------------------------------|
|
||||
| ~P1 | |
|
||||
| ~P2 | The issue is (almost) guaranteed to occur in the near future |
|
||||
| ~P3 | The issue is likely to occur in the near future |
|
||||
| ~P4 | The issue _may_ occur but it's not likely |
|
||||
|
||||
### Bug Severity labels (~S1, ~S2, ~S3 & etc.)
|
||||
### Bug Severity labels
|
||||
|
||||
Severity labels help us clearly communicate the impact of a ~bug on users.
|
||||
|
||||
|
@ -243,16 +249,16 @@ Severity labels help us clearly communicate the impact of a ~bug on users.
|
|||
| ~S3 | Major Severity | Broken Feature, workaround acceptable | Can create merge requests only from the Merge Requests page, not through the Issue. |
|
||||
| ~S4 | Low Severity | Functionality inconvenience or cosmetic issue | Label colors are incorrect / not being displayed. |
|
||||
|
||||
#### Specific Severity guidance
|
||||
#### Severity impact guidance
|
||||
|
||||
| Label | Security Impact |
|
||||
|-------|-------------------------------------------------------------------|
|
||||
| ~S1 | >50% customers impacted (possible company extinction level event) |
|
||||
| ~S2 | Multiple customers impacted (but not apocalyptic) |
|
||||
| ~S3 | A single customer impacted |
|
||||
| ~S4 | No customer impact, or expected impact within 30 days |
|
||||
| Label | Security Impact | Availability / Performance Impact |
|
||||
|-------|---------------------------------------------------------------------|--------------------------------------------------------------|
|
||||
| ~S1 | >50% users impacted (possible company extinction level event) | |
|
||||
| ~S2 | Many users or multiple paid customers impacted (but not apocalyptic)| The issue is (almost) guaranteed to occur in the near future |
|
||||
| ~S3 | A few users or a single paid customer impacted | The issue is likely to occur in the near future |
|
||||
| ~S4 | No paid users/customer impacted, or expected impact within 30 days | The issue _may_ occur but it's not likely |
|
||||
|
||||
### Label for community contributors (~"Accepting Merge Requests")
|
||||
### Label for community contributors
|
||||
|
||||
Issues that are beneficial to our users, 'nice to haves', that we currently do
|
||||
not have the capacity for or want to give the priority to, are labeled as
|
||||
|
@ -304,7 +310,33 @@ any potential community contributor to @-mention per above.
|
|||
|
||||
## Implement design & UI elements
|
||||
|
||||
Please see the [UX Guide for GitLab].
|
||||
For guidance on UX implementation at GitLab, please refer to our [Design System](https://design.gitlab.com/).
|
||||
|
||||
The UX team uses labels to manage their workflow.
|
||||
|
||||
The ~"UX" label on an issue is a signal to the UX team that it will need UX attention.
|
||||
To better understand the priority by which UX tackles issues, see the [UX section](https://about.gitlab.com/handbook/engineering/ux) of the handbook.
|
||||
|
||||
Once an issue has been worked on and is ready for development, a UXer removes the ~"UX" label and applies the ~"UX ready" label to that issue.
|
||||
|
||||
The UX team has a special type label called ~"design artifact". This label indicates that the final output
|
||||
for an issue is a UX solution/design. The solution will be developed by frontend and/or backend in a subsequent milestone.
|
||||
Any issue labeled ~"design artifact" should not also be labeled ~"frontend" or ~"backend" since no development is
|
||||
needed until the solution has been decided.
|
||||
|
||||
~"design artifact" issues are like any other issue and should contain a milestone label, ~"Deliverable" or ~"Stretch", when scheduled in the current milestone.
|
||||
|
||||
To prevent the misunderstanding that a feature will be be delivered in the
|
||||
assigned milestone, when only UX design is planned for that milestone, the
|
||||
Product Manager should create a separate issue for the ~"design artifact",
|
||||
assign the ~UX, ~"design artifact" and ~"Deliverable" labels, add a milestone
|
||||
and use a title that makes it clear that the scheduled issue is design only
|
||||
(e.g. `Design exploration for XYZ`).
|
||||
|
||||
When the ~"design artifact" issue has been completed, the UXer removes the ~UX
|
||||
label, adds the ~"UX ready" label and closes the issue. This indicates the
|
||||
design artifact is complete. The UXer will also copy the designs to related
|
||||
issues for implementation in an upcoming milestone.
|
||||
|
||||
## Issue tracker
|
||||
|
||||
|
@ -340,7 +372,7 @@ on those issues. Please select someone with relevant experience from the
|
|||
[GitLab team][team]. If there is nobody mentioned with that expertise look in
|
||||
the commit history for the affected files to find someone.
|
||||
|
||||
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issues/issue-triage-policies/
|
||||
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issue-triage/
|
||||
[issue bash events]: https://gitlab.com/gitlab-org/gitlab-ce/issues/17815
|
||||
|
||||
### Feature proposals
|
||||
|
@ -503,7 +535,7 @@ request is as follows:
|
|||
1. Write [tests](https://docs.gitlab.com/ee/development/rake_tasks.html#run-tests) and code
|
||||
1. [Generate a changelog entry with `bin/changelog`][changelog]
|
||||
1. If you are writing documentation, make sure to follow the
|
||||
[documentation styleguide][doc-styleguide]
|
||||
[documentation guidelines][doc-guidelines]
|
||||
1. If you have multiple commits please combine them into a few logically
|
||||
organized commits by [squashing them][git-squash]
|
||||
1. Push the commit(s) to your fork
|
||||
|
@ -618,7 +650,7 @@ the feature you contribute through all of these steps.
|
|||
1. Working and clean code that is commented where needed
|
||||
1. [Unit, integration, and system tests][testing] that pass on the CI server
|
||||
1. Performance/scalability implications have been considered, addressed, and tested
|
||||
1. [Documented][doc-styleguide] in the `/doc` directory
|
||||
1. [Documented][doc-guidelines] in the `/doc` directory
|
||||
1. [Changelog entry added][changelog], if necessary
|
||||
1. Reviewed and any concerns are addressed
|
||||
1. Merged by a project maintainer
|
||||
|
@ -655,7 +687,7 @@ merge request:
|
|||
contributors to enhance security
|
||||
1. [Database Migrations](doc/development/migration_style_guide.md)
|
||||
1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
|
||||
1. [Documentation styleguide][doc-styleguide]
|
||||
1. [Documentation styleguide](https://docs.gitlab.com/ee/development/documentation/styleguide.html)
|
||||
1. Interface text should be written subjectively instead of objectively. It
|
||||
should be the GitLab core team addressing a person. It should be written in
|
||||
present time and never use past tense (has been/was). For example instead
|
||||
|
@ -718,7 +750,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
|
|||
[rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout
|
||||
[rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming
|
||||
[changelog]: doc/development/changelog.md "Generate a changelog entry"
|
||||
[doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide"
|
||||
[doc-guidelines]: doc/development/documentation/index.md "Documentation guidelines"
|
||||
[js-styleguide]: doc/development/fe_guide/style_guide_js.md "JavaScript styleguide"
|
||||
[scss-styleguide]: doc/development/fe_guide/style_guide_scss.md "SCSS styleguide"
|
||||
[newlines-styleguide]: doc/development/newlines_styleguide.md "Newlines styleguide"
|
||||
|
@ -728,6 +760,3 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
|
|||
[polling-etag]: https://docs.gitlab.com/ce/development/polling.html
|
||||
[testing]: doc/development/testing_guide/index.md
|
||||
[us-english]: https://en.wikipedia.org/wiki/American_English
|
||||
|
||||
[^1]: Please note that specs other than JavaScript specs are considered backend
|
||||
code.
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.100.1
|
||||
0.111.4
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.9.1
|
||||
1.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
7.1.2
|
||||
7.1.4
|
||||
|
|
|
@ -1 +1 @@
|
|||
4.2.1
|
||||
5.0.0
|
||||
|
|
62
Gemfile
|
@ -6,7 +6,7 @@ end
|
|||
gem_versions = {}
|
||||
gem_versions['activerecord_sane_schema_dumper'] = rails5? ? '1.0' : '0.2'
|
||||
gem_versions['default_value_for'] = rails5? ? '~> 3.0.5' : '~> 3.0.0'
|
||||
gem_versions['rails'] = rails5? ? '5.0.6' : '4.2.10'
|
||||
gem_versions['rails'] = rails5? ? '5.0.7' : '4.2.10'
|
||||
gem_versions['rails-i18n'] = rails5? ? '~> 5.1' : '~> 4.0.9'
|
||||
# --- The end of special code for migrating to Rails 5.0 ---
|
||||
|
||||
|
@ -28,14 +28,14 @@ gem 'mysql2', '~> 0.4.10', group: :mysql
|
|||
gem 'pg', '~> 0.18.2', group: :postgres
|
||||
|
||||
gem 'rugged', '~> 0.27'
|
||||
gem 'grape-route-helpers', '~> 2.1.0'
|
||||
gem 'grape-path-helpers', '~> 1.0'
|
||||
|
||||
gem 'faraday', '~> 0.12'
|
||||
|
||||
# Authentication libraries
|
||||
gem 'devise', '~> 4.4'
|
||||
gem 'doorkeeper', '~> 4.3'
|
||||
gem 'doorkeeper-openid_connect', '~> 1.3'
|
||||
gem 'doorkeeper-openid_connect', '~> 1.5'
|
||||
gem 'omniauth', '~> 1.8'
|
||||
gem 'omniauth-auth0', '~> 2.0.0'
|
||||
gem 'omniauth-azure-oauth2', '~> 0.0.9'
|
||||
|
@ -47,10 +47,10 @@ gem 'omniauth-google-oauth2', '~> 0.5.3'
|
|||
gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos
|
||||
gem 'omniauth-oauth2-generic', '~> 0.2.2'
|
||||
gem 'omniauth-saml', '~> 1.10'
|
||||
gem 'omniauth-shibboleth', '~> 1.2.0'
|
||||
gem 'omniauth-shibboleth', '~> 1.3.0'
|
||||
gem 'omniauth-twitter', '~> 1.4'
|
||||
gem 'omniauth_crowd', '~> 2.2.0'
|
||||
gem 'omniauth-authentiq', '~> 0.3.1'
|
||||
gem 'omniauth-authentiq', '~> 0.3.3'
|
||||
gem 'rack-oauth2', '~> 1.2.1'
|
||||
gem 'jwt', '~> 1.5.6'
|
||||
|
||||
|
@ -93,6 +93,10 @@ gem 'grape', '~> 1.0'
|
|||
gem 'grape-entity', '~> 0.7.1'
|
||||
gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
|
||||
|
||||
# GraphQL API
|
||||
gem 'graphql', '~> 1.8.0'
|
||||
gem 'graphiql-rails', '~> 1.4.10'
|
||||
|
||||
# Disable strong_params so that Mash does not respond to :permitted?
|
||||
gem 'hashie-forbidden_attributes'
|
||||
|
||||
|
@ -104,6 +108,7 @@ gem 'hamlit', '~> 2.6.1'
|
|||
|
||||
# Files attachments
|
||||
gem 'carrierwave', '~> 1.2'
|
||||
gem 'mini_magick'
|
||||
|
||||
# Drag and Drop UI
|
||||
gem 'dropzonejs-rails', '~> 0.7.1'
|
||||
|
@ -127,13 +132,13 @@ gem 'unf', '~> 0.1.4'
|
|||
gem 'seed-fu', '~> 2.3.7'
|
||||
|
||||
# Markdown and HTML processing
|
||||
gem 'html-pipeline', '~> 2.7.1'
|
||||
gem 'html-pipeline', '~> 2.8'
|
||||
gem 'deckar01-task_list', '2.0.0'
|
||||
gem 'gitlab-markup', '~> 1.6.2'
|
||||
gem 'gitlab-markup', '~> 1.6.4'
|
||||
gem 'redcarpet', '~> 3.4'
|
||||
gem 'commonmarker', '~> 0.17'
|
||||
gem 'RedCloth', '~> 4.3.2'
|
||||
gem 'rdoc', '~> 4.2'
|
||||
gem 'rdoc', '~> 6.0'
|
||||
gem 'org-ruby', '~> 0.9.12'
|
||||
gem 'creole', '~> 0.5.0'
|
||||
gem 'wikicloth', '0.8.1'
|
||||
|
@ -144,6 +149,9 @@ gem 'truncato', '~> 0.7.9'
|
|||
gem 'bootstrap_form', '~> 2.7.0'
|
||||
gem 'nokogiri', '~> 1.8.2'
|
||||
|
||||
# Calendar rendering
|
||||
gem 'icalendar'
|
||||
|
||||
# Diffs
|
||||
gem 'diffy', '~> 3.1.0'
|
||||
|
||||
|
@ -160,9 +168,9 @@ gem 'state_machines-activerecord', '~> 0.5.1'
|
|||
gem 'acts-as-taggable-on', '~> 5.0'
|
||||
|
||||
# Background jobs
|
||||
gem 'sidekiq', '~> 5.0'
|
||||
gem 'sidekiq', '~> 5.1'
|
||||
gem 'sidekiq-cron', '~> 0.6.0'
|
||||
gem 'redis-namespace', '~> 1.5.2'
|
||||
gem 'redis-namespace', '~> 1.6.0'
|
||||
gem 'sidekiq-limit_fetch', '~> 3.4', require: false
|
||||
|
||||
# Cron Parser
|
||||
|
@ -174,6 +182,9 @@ gem 'httparty', '~> 0.13.3'
|
|||
# Colored output to console
|
||||
gem 'rainbow', '~> 2.2'
|
||||
|
||||
# Progress bar
|
||||
gem 'ruby-progressbar'
|
||||
|
||||
# GitLab settings
|
||||
gem 'settingslogic', '~> 2.0.9'
|
||||
|
||||
|
@ -216,10 +227,7 @@ gem 'asana', '~> 0.6.0'
|
|||
gem 'ruby-fogbugz', '~> 0.2.1'
|
||||
|
||||
# Kubernetes integration
|
||||
gem 'kubeclient', '~> 3.0'
|
||||
|
||||
# d3
|
||||
gem 'd3_rails', '~> 3.5.0'
|
||||
gem 'kubeclient', '~> 3.1.0'
|
||||
|
||||
# Sanitize user input
|
||||
gem 'sanitize', '~> 4.6.5'
|
||||
|
@ -257,10 +265,9 @@ gem 'sass-rails', '~> 5.0.6'
|
|||
gem 'uglifier', '~> 2.7.2'
|
||||
|
||||
gem 'addressable', '~> 2.5.2'
|
||||
gem 'bootstrap-sass', '~> 3.3.0'
|
||||
gem 'font-awesome-rails', '~> 4.7'
|
||||
gem 'gemojione', '~> 3.3'
|
||||
gem 'gon', '~> 6.1.0'
|
||||
gem 'gon', '~> 6.2'
|
||||
gem 'jquery-atwho-rails', '~> 1.3.2'
|
||||
gem 'request_store', '~> 1.3'
|
||||
gem 'select2-rails', '~> 3.5.9'
|
||||
|
@ -292,7 +299,6 @@ gem 'peek-sidekiq', '~> 1.0.3'
|
|||
|
||||
# Metrics
|
||||
group :metrics do
|
||||
gem 'allocations', '~> 1.0', require: false, platform: :mri
|
||||
gem 'method_source', '~> 0.8', require: false
|
||||
gem 'influxdb', '~> 0.2', require: false
|
||||
|
||||
|
@ -321,15 +327,13 @@ group :development, :test do
|
|||
gem 'pry-byebug', '~> 3.4.1', platform: :mri
|
||||
gem 'pry-rails', '~> 0.3.4'
|
||||
|
||||
gem 'awesome_print', '~> 1.2.0', require: false
|
||||
gem 'awesome_print', require: false
|
||||
gem 'fuubar', '~> 2.2.0'
|
||||
|
||||
gem 'database_cleaner', '~> 1.5.0'
|
||||
gem 'factory_bot_rails', '~> 4.8.2'
|
||||
gem 'rspec-rails', '~> 3.6.0'
|
||||
gem 'rspec-rails', '~> 3.7.0'
|
||||
gem 'rspec-retry', '~> 0.4.5'
|
||||
gem 'spinach-rails', '~> 0.2.1'
|
||||
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
||||
gem 'rspec_profiling', '~> 0.0.5'
|
||||
gem 'rspec-set', '~> 0.1.3'
|
||||
gem 'rspec-parameterized', require: false
|
||||
|
@ -342,11 +346,10 @@ group :development, :test do
|
|||
|
||||
gem 'capybara', '~> 2.15'
|
||||
gem 'capybara-screenshot', '~> 1.0.0'
|
||||
gem 'selenium-webdriver', '~> 3.5'
|
||||
gem 'selenium-webdriver', '~> 3.12'
|
||||
|
||||
gem 'spring', '~> 2.0.0'
|
||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||
gem 'spring-commands-spinach', '~> 1.1.0'
|
||||
|
||||
gem 'gitlab-styles', '~> 2.3', require: false
|
||||
# Pin these dependencies, otherwise a new rule could break the CI pipelines
|
||||
|
@ -375,7 +378,7 @@ end
|
|||
|
||||
group :test do
|
||||
gem 'shoulda-matchers', '~> 3.1.2', require: false
|
||||
gem 'email_spec', '~> 1.6.0'
|
||||
gem 'email_spec', '~> 2.2.0'
|
||||
gem 'json-schema', '~> 2.8.0'
|
||||
gem 'webmock', '~> 2.3.2'
|
||||
gem 'rails-controller-testing' if rails5? # Rails5 only gem.
|
||||
|
@ -385,7 +388,7 @@ group :test do
|
|||
gem 'test-prof', '~> 0.2.5'
|
||||
end
|
||||
|
||||
gem 'octokit', '~> 4.8'
|
||||
gem 'octokit', '~> 4.9'
|
||||
|
||||
gem 'mail_room', '~> 0.9.1'
|
||||
|
||||
|
@ -405,18 +408,17 @@ gem 'vmstat', '~> 2.3.0'
|
|||
gem 'sys-filesystem', '~> 1.1.6'
|
||||
|
||||
# SSH host key support
|
||||
gem 'net-ssh', '~> 4.2.0'
|
||||
gem 'net-ssh', '~> 5.0'
|
||||
gem 'sshkey', '~> 1.9.0'
|
||||
|
||||
# Required for ED25519 SSH host key support
|
||||
group :ed25519 do
|
||||
gem 'rbnacl-libsodium'
|
||||
gem 'rbnacl', '~> 4.0'
|
||||
gem 'ed25519', '~> 1.2'
|
||||
gem 'bcrypt_pbkdf', '~> 1.0'
|
||||
end
|
||||
|
||||
# Gitaly GRPC client
|
||||
gem 'gitaly-proto', '~> 0.99.0', require: 'gitaly'
|
||||
gem 'gitaly-proto', '~> 0.105.0', require: 'gitaly'
|
||||
gem 'grpc', '~> 1.11.0'
|
||||
|
||||
# Locked until https://github.com/google/protobuf/issues/4210 is closed
|
||||
|
@ -434,4 +436,4 @@ gem 'lograge', '~> 0.5'
|
|||
gem 'grape_logging', '~> 1.7'
|
||||
|
||||
# Asset synchronization
|
||||
gem 'asset_sync', '~> 2.2.0'
|
||||
gem 'asset_sync', '~> 2.4'
|
||||
|
|
209
Gemfile.lock
|
@ -49,7 +49,6 @@ GEM
|
|||
public_suffix (>= 2.0.2, < 4.0)
|
||||
aes_key_wrap (1.0.1)
|
||||
akismet (2.0.0)
|
||||
allocations (1.0.5)
|
||||
arel (6.0.4)
|
||||
asana (0.6.0)
|
||||
faraday (~> 0.9)
|
||||
|
@ -59,7 +58,7 @@ GEM
|
|||
asciidoctor (1.5.6.2)
|
||||
asciidoctor-plantuml (0.0.8)
|
||||
asciidoctor (~> 1.5)
|
||||
asset_sync (2.2.0)
|
||||
asset_sync (2.4.0)
|
||||
activemodel (>= 4.1.0)
|
||||
fog-core
|
||||
mime-types (>= 2.99)
|
||||
|
@ -69,10 +68,7 @@ GEM
|
|||
attr_encrypted (3.1.0)
|
||||
encryptor (~> 3.0.0)
|
||||
attr_required (1.0.0)
|
||||
autoprefixer-rails (6.2.3)
|
||||
execjs
|
||||
json
|
||||
awesome_print (1.2.0)
|
||||
awesome_print (1.8.0)
|
||||
axiom-types (0.1.1)
|
||||
descendants_tracker (~> 0.0.4)
|
||||
ice_nine (~> 0.11.0)
|
||||
|
@ -80,7 +76,7 @@ GEM
|
|||
babosa (1.0.2)
|
||||
base32 (0.3.2)
|
||||
batch-loader (1.2.1)
|
||||
bcrypt (3.1.11)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt_pbkdf (1.0.0)
|
||||
benchmark-ips (2.3.0)
|
||||
better_errors (2.1.1)
|
||||
|
@ -91,9 +87,6 @@ GEM
|
|||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
blankslate (2.1.2.4)
|
||||
bootstrap-sass (3.3.6)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sass (>= 3.3.4)
|
||||
bootstrap_form (2.7.0)
|
||||
brakeman (4.2.1)
|
||||
browser (2.2.0)
|
||||
|
@ -115,13 +108,13 @@ GEM
|
|||
capybara-screenshot (1.0.14)
|
||||
capybara (>= 1.0, < 3)
|
||||
launchy
|
||||
carrierwave (1.2.1)
|
||||
carrierwave (1.2.3)
|
||||
activemodel (>= 4.0.0)
|
||||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
cause (0.1)
|
||||
charlock_holmes (0.7.6)
|
||||
childprocess (0.7.0)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chronic (0.10.2)
|
||||
chronic_duration (0.10.6)
|
||||
|
@ -131,7 +124,6 @@ GEM
|
|||
coderay (1.1.1)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
colorize (0.7.7)
|
||||
commonmarker (0.17.8)
|
||||
ruby-enum (~> 0.5)
|
||||
concord (0.1.5)
|
||||
|
@ -147,8 +139,6 @@ GEM
|
|||
creole (0.5.0)
|
||||
css_parser (1.5.0)
|
||||
addressable
|
||||
d3_rails (3.5.11)
|
||||
railties (>= 3.1.0)
|
||||
daemons (1.2.3)
|
||||
database_cleaner (1.5.3)
|
||||
debug_inspector (0.0.2)
|
||||
|
@ -177,19 +167,21 @@ GEM
|
|||
diff-lcs (1.3)
|
||||
diffy (3.1.0)
|
||||
docile (1.1.5)
|
||||
domain_name (0.5.20170404)
|
||||
domain_name (0.5.20180417)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
doorkeeper (4.3.2)
|
||||
railties (>= 4.2)
|
||||
doorkeeper-openid_connect (1.3.0)
|
||||
doorkeeper-openid_connect (1.5.0)
|
||||
doorkeeper (~> 4.3)
|
||||
json-jwt (~> 1.6)
|
||||
dropzonejs-rails (0.7.2)
|
||||
rails (> 3.1)
|
||||
ed25519 (1.2.4)
|
||||
email_reply_trimmer (0.1.6)
|
||||
email_spec (1.6.0)
|
||||
email_spec (2.2.0)
|
||||
htmlentities (~> 4.3.3)
|
||||
launchy (~> 2.1)
|
||||
mail (~> 2.2)
|
||||
mail (~> 2.7)
|
||||
encryptor (3.0.0)
|
||||
equalizer (0.0.11)
|
||||
erubis (2.7.0)
|
||||
|
@ -197,7 +189,7 @@ GEM
|
|||
et-orbi (1.0.3)
|
||||
tzinfo
|
||||
eventmachine (1.0.8)
|
||||
excon (0.60.0)
|
||||
excon (0.62.0)
|
||||
execjs (2.6.0)
|
||||
expression_parser (0.9.0)
|
||||
factory_bot (4.8.2)
|
||||
|
@ -290,8 +282,7 @@ GEM
|
|||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly-proto (0.99.0)
|
||||
gitaly-proto (0.105.0)
|
||||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.10)
|
||||
github-linguist (5.3.3)
|
||||
|
@ -312,7 +303,7 @@ GEM
|
|||
rouge (~> 3.1)
|
||||
sanitize (~> 4.6.4)
|
||||
stringex (~> 2.6)
|
||||
gitlab-gollum-rugged_adapter (0.4.4)
|
||||
gitlab-gollum-rugged_adapter (0.4.4.1)
|
||||
mime-types (>= 1.15)
|
||||
rugged (~> 0.25)
|
||||
gitlab-grit (2.8.2)
|
||||
|
@ -320,7 +311,7 @@ GEM
|
|||
diff-lcs (~> 1.1)
|
||||
mime-types (>= 1.16)
|
||||
posix-spawn (~> 0.3)
|
||||
gitlab-markup (1.6.3)
|
||||
gitlab-markup (1.6.4)
|
||||
gitlab-styles (2.3.2)
|
||||
rubocop (~> 0.51)
|
||||
rubocop-gitlab-security (~> 0.1.0)
|
||||
|
@ -334,9 +325,8 @@ GEM
|
|||
activesupport (>= 4.2.0)
|
||||
gollum-grit_adapter (1.0.1)
|
||||
gitlab-grit (~> 2.7, >= 2.7.1)
|
||||
gon (6.1.0)
|
||||
gon (6.2.0)
|
||||
actionpack (>= 3.0)
|
||||
json
|
||||
multi_json
|
||||
request_store (>= 1.0)
|
||||
google-api-client (0.19.8)
|
||||
|
@ -359,7 +349,7 @@ GEM
|
|||
signet (~> 0.7)
|
||||
gpgme (2.0.13)
|
||||
mini_portile2 (~> 2.1)
|
||||
grape (1.0.2)
|
||||
grape (1.0.3)
|
||||
activesupport
|
||||
builder
|
||||
mustermann-grape (~> 1.0.0)
|
||||
|
@ -369,12 +359,16 @@ GEM
|
|||
grape-entity (0.7.1)
|
||||
activesupport (>= 4.0)
|
||||
multi_json (>= 1.3.2)
|
||||
grape-route-helpers (2.1.0)
|
||||
activesupport
|
||||
grape (>= 0.16.0)
|
||||
rake
|
||||
grape-path-helpers (1.0.5)
|
||||
activesupport (>= 4, < 5.1)
|
||||
grape (~> 1.0)
|
||||
rake (~> 12)
|
||||
grape_logging (1.7.0)
|
||||
grape
|
||||
graphiql-rails (1.4.10)
|
||||
railties
|
||||
sprockets-rails
|
||||
graphql (1.8.1)
|
||||
grpc (1.11.0)
|
||||
google-protobuf (~> 3.1)
|
||||
googleapis-common-protos-types (~> 1.0.0)
|
||||
|
@ -400,7 +394,7 @@ GEM
|
|||
hipchat (1.5.2)
|
||||
httparty
|
||||
mimemagic
|
||||
html-pipeline (2.7.1)
|
||||
html-pipeline (2.8.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
html2text (0.2.0)
|
||||
|
@ -421,6 +415,7 @@ GEM
|
|||
httpclient (2.8.3)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
icalendar (2.4.1)
|
||||
ice_nine (0.11.2)
|
||||
influxdb (0.2.3)
|
||||
cause
|
||||
|
@ -432,12 +427,10 @@ GEM
|
|||
oauth (~> 0.5, >= 0.5.0)
|
||||
jquery-atwho-rails (1.3.2)
|
||||
json (1.8.6)
|
||||
json-jwt (1.9.2)
|
||||
json-jwt (1.9.4)
|
||||
activesupport
|
||||
aes_key_wrap
|
||||
bindata
|
||||
securecompare
|
||||
url_safe_base64
|
||||
json-schema (2.8.0)
|
||||
addressable (>= 2.4)
|
||||
jwt (1.5.6)
|
||||
|
@ -456,10 +449,9 @@ GEM
|
|||
kgio (2.10.0)
|
||||
knapsack (1.16.0)
|
||||
rake
|
||||
timecop (>= 0.1.0)
|
||||
kubeclient (3.0.0)
|
||||
kubeclient (3.1.0)
|
||||
http (~> 2.2.2)
|
||||
recursive-open-struct (~> 1.0.4)
|
||||
recursive-open-struct (~> 1.0, >= 1.0.4)
|
||||
rest-client (~> 2.0)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
|
@ -503,6 +495,7 @@ GEM
|
|||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.0)
|
||||
mini_magick (4.8.0)
|
||||
mini_mime (1.0.0)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.7.0)
|
||||
|
@ -515,9 +508,9 @@ GEM
|
|||
mustermann (~> 1.0.0)
|
||||
mysql2 (0.4.10)
|
||||
net-ldap (0.16.0)
|
||||
net-ssh (4.2.0)
|
||||
net-ssh (5.0.1)
|
||||
netrc (0.11.0)
|
||||
nokogiri (1.8.2)
|
||||
nokogiri (1.8.3)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nokogumbo (1.5.0)
|
||||
nokogiri
|
||||
|
@ -529,15 +522,16 @@ GEM
|
|||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
octokit (4.8.0)
|
||||
octokit (4.9.0)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
omniauth (1.8.1)
|
||||
hashie (>= 3.4.6, < 3.6.0)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-auth0 (2.0.0)
|
||||
omniauth-oauth2 (~> 1.4)
|
||||
omniauth-authentiq (0.3.1)
|
||||
omniauth-oauth2 (~> 1.3, >= 1.3.1)
|
||||
omniauth-authentiq (0.3.3)
|
||||
jwt (>= 1.5)
|
||||
omniauth-oauth2 (>= 1.5)
|
||||
omniauth-azure-oauth2 (0.0.9)
|
||||
jwt (~> 1.0)
|
||||
omniauth (~> 1.0)
|
||||
|
@ -551,7 +545,7 @@ GEM
|
|||
omniauth-github (1.3.0)
|
||||
omniauth (~> 1.5)
|
||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
||||
omniauth-gitlab (1.0.2)
|
||||
omniauth-gitlab (1.0.3)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (~> 1.0)
|
||||
omniauth-google-oauth2 (0.5.3)
|
||||
|
@ -574,7 +568,7 @@ GEM
|
|||
omniauth-saml (1.10.0)
|
||||
omniauth (~> 1.3, >= 1.3.2)
|
||||
ruby-saml (~> 1.7)
|
||||
omniauth-shibboleth (1.2.1)
|
||||
omniauth-shibboleth (1.3.0)
|
||||
omniauth (>= 1.0.0)
|
||||
omniauth-twitter (1.4.0)
|
||||
omniauth-oauth (~> 1.1)
|
||||
|
@ -702,16 +696,11 @@ GEM
|
|||
ffi (>= 0.5.0, < 2)
|
||||
rblineprof (0.3.6)
|
||||
debugger-ruby_core_source (~> 1.3)
|
||||
rbnacl (4.0.2)
|
||||
ffi
|
||||
rbnacl-libsodium (1.0.11)
|
||||
rbnacl (>= 3.0.1)
|
||||
rdoc (4.2.2)
|
||||
json (~> 1.4)
|
||||
rdoc (6.0.4)
|
||||
re2 (1.1.1)
|
||||
recaptcha (3.0.0)
|
||||
json
|
||||
recursive-open-struct (1.0.5)
|
||||
recursive-open-struct (1.1.0)
|
||||
redcarpet (3.4.0)
|
||||
redis (3.3.5)
|
||||
redis-actionpack (5.0.2)
|
||||
|
@ -721,8 +710,8 @@ GEM
|
|||
redis-activesupport (5.0.4)
|
||||
activesupport (>= 3, < 6)
|
||||
redis-store (>= 1.3, < 2)
|
||||
redis-namespace (1.5.2)
|
||||
redis (~> 3.0, >= 3.0.4)
|
||||
redis-namespace (1.6.0)
|
||||
redis (>= 3.0.4)
|
||||
redis-rack (2.0.4)
|
||||
rack (>= 1.5, < 3)
|
||||
redis-store (>= 1.2, < 2)
|
||||
|
@ -752,36 +741,36 @@ GEM
|
|||
chunky_png
|
||||
rqrcode-rails3 (0.1.7)
|
||||
rqrcode (>= 0.4.2)
|
||||
rspec (3.6.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-core (3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-expectations (3.6.0)
|
||||
rspec (3.7.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-core (3.7.1)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-mocks (3.6.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-mocks (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-parameterized (0.4.0)
|
||||
binding_of_caller
|
||||
parser
|
||||
proc_to_ast
|
||||
rspec (>= 2.13, < 4)
|
||||
unparser
|
||||
rspec-rails (3.6.0)
|
||||
rspec-rails (3.7.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-retry (0.4.5)
|
||||
rspec-core
|
||||
rspec-set (0.1.3)
|
||||
rspec-support (3.6.0)
|
||||
rspec-support (3.7.1)
|
||||
rspec_profiling (0.0.5)
|
||||
activerecord
|
||||
pg
|
||||
|
@ -813,7 +802,7 @@ GEM
|
|||
rubyzip (1.2.1)
|
||||
rufus-scheduler (3.4.0)
|
||||
et-orbi (~> 1.0)
|
||||
rugged (0.27.1)
|
||||
rugged (0.27.2)
|
||||
safe_yaml (1.0.4)
|
||||
sanitize (4.6.5)
|
||||
crass (~> 1.0.2)
|
||||
|
@ -836,15 +825,14 @@ GEM
|
|||
scss_lint (0.56.0)
|
||||
rake (>= 0.9, < 13)
|
||||
sass (~> 3.5.3)
|
||||
securecompare (1.0.0)
|
||||
seed-fu (2.3.7)
|
||||
activerecord (>= 3.1)
|
||||
activesupport (>= 3.1)
|
||||
select2-rails (3.5.9.3)
|
||||
thor (~> 0.14)
|
||||
selenium-webdriver (3.5.0)
|
||||
selenium-webdriver (3.12.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.0)
|
||||
rubyzip (~> 1.2)
|
||||
sentry-raven (2.7.2)
|
||||
faraday (>= 0.7.6, < 1.0)
|
||||
settingslogic (2.0.9)
|
||||
|
@ -853,11 +841,11 @@ GEM
|
|||
rack
|
||||
shoulda-matchers (3.1.2)
|
||||
activesupport (>= 4.0.0)
|
||||
sidekiq (5.0.5)
|
||||
sidekiq (5.1.3)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (>= 3.3.4, < 5)
|
||||
redis (>= 3.3.5, < 5)
|
||||
sidekiq-cron (0.6.0)
|
||||
rufus-scheduler (>= 3.3.0)
|
||||
sidekiq (>= 4.2.1)
|
||||
|
@ -876,23 +864,11 @@ GEM
|
|||
simplecov-html (0.10.0)
|
||||
slack-notifier (1.5.1)
|
||||
slop (3.6.0)
|
||||
spinach (0.8.10)
|
||||
colorize
|
||||
gherkin-ruby (>= 0.3.2)
|
||||
json
|
||||
spinach-rails (0.2.1)
|
||||
capybara (>= 2.0.0)
|
||||
railties (>= 3)
|
||||
spinach (>= 0.4)
|
||||
spinach-rerun-reporter (0.0.2)
|
||||
spinach (~> 0.8)
|
||||
spring (2.0.1)
|
||||
activesupport (>= 4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-spinach (1.1.0)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.1)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
|
@ -960,7 +936,6 @@ GEM
|
|||
equalizer (~> 0.0.9)
|
||||
parser (>= 2.3.1.2, < 2.6)
|
||||
procto (~> 0.0.2)
|
||||
url_safe_base64 (0.2.2)
|
||||
validates_hostname (1.0.6)
|
||||
activerecord (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
|
@ -998,13 +973,12 @@ DEPENDENCIES
|
|||
acts-as-taggable-on (~> 5.0)
|
||||
addressable (~> 2.5.2)
|
||||
akismet (~> 2.0)
|
||||
allocations (~> 1.0)
|
||||
asana (~> 0.6.0)
|
||||
asciidoctor (~> 1.5.6)
|
||||
asciidoctor-plantuml (= 0.0.8)
|
||||
asset_sync (~> 2.2.0)
|
||||
asset_sync (~> 2.4)
|
||||
attr_encrypted (~> 3.1.0)
|
||||
awesome_print (~> 1.2.0)
|
||||
awesome_print
|
||||
babosa (~> 1.0.2)
|
||||
base32 (~> 0.3.0)
|
||||
batch-loader (~> 1.2.1)
|
||||
|
@ -1012,7 +986,6 @@ DEPENDENCIES
|
|||
benchmark-ips (~> 2.3.0)
|
||||
better_errors (~> 2.1.0)
|
||||
binding_of_caller (~> 0.7.2)
|
||||
bootstrap-sass (~> 3.3.0)
|
||||
bootstrap_form (~> 2.7.0)
|
||||
brakeman (~> 4.2)
|
||||
browser (~> 2.2)
|
||||
|
@ -1028,7 +1001,6 @@ DEPENDENCIES
|
|||
concurrent-ruby (~> 1.0.5)
|
||||
connection_pool (~> 2.0)
|
||||
creole (~> 0.5.0)
|
||||
d3_rails (~> 3.5.0)
|
||||
database_cleaner (~> 1.5.0)
|
||||
deckar01-task_list (= 2.0.0)
|
||||
default_value_for (~> 3.0.0)
|
||||
|
@ -1037,10 +1009,11 @@ DEPENDENCIES
|
|||
devise-two-factor (~> 3.0.0)
|
||||
diffy (~> 3.1.0)
|
||||
doorkeeper (~> 4.3)
|
||||
doorkeeper-openid_connect (~> 1.3)
|
||||
doorkeeper-openid_connect (~> 1.5)
|
||||
dropzonejs-rails (~> 0.7.1)
|
||||
ed25519 (~> 1.2)
|
||||
email_reply_trimmer (~> 0.1)
|
||||
email_spec (~> 1.6.0)
|
||||
email_spec (~> 2.2.0)
|
||||
factory_bot_rails (~> 4.8.2)
|
||||
faraday (~> 0.12)
|
||||
fast_blank
|
||||
|
@ -1064,31 +1037,34 @@ DEPENDENCIES
|
|||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly-proto (~> 0.99.0)
|
||||
gitaly-proto (~> 0.105.0)
|
||||
github-linguist (~> 5.3.3)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-gollum-lib (~> 4.2)
|
||||
gitlab-gollum-rugged_adapter (~> 0.4.4)
|
||||
gitlab-markup (~> 1.6.2)
|
||||
gitlab-markup (~> 1.6.4)
|
||||
gitlab-styles (~> 2.3)
|
||||
gitlab_omniauth-ldap (~> 2.0.4)
|
||||
gon (~> 6.1.0)
|
||||
gon (~> 6.2)
|
||||
google-api-client (~> 0.19.8)
|
||||
google-protobuf (= 3.5.1)
|
||||
gpgme
|
||||
grape (~> 1.0)
|
||||
grape-entity (~> 0.7.1)
|
||||
grape-route-helpers (~> 2.1.0)
|
||||
grape-path-helpers (~> 1.0)
|
||||
grape_logging (~> 1.7)
|
||||
graphiql-rails (~> 1.4.10)
|
||||
graphql (~> 1.8.0)
|
||||
grpc (~> 1.11.0)
|
||||
haml_lint (~> 0.26.0)
|
||||
hamlit (~> 2.6.1)
|
||||
hashie-forbidden_attributes
|
||||
health_check (~> 2.6.0)
|
||||
hipchat (~> 1.5.0)
|
||||
html-pipeline (~> 2.7.1)
|
||||
html-pipeline (~> 2.8)
|
||||
html2text
|
||||
httparty (~> 0.13.3)
|
||||
icalendar
|
||||
influxdb (~> 0.2)
|
||||
jira-ruby (~> 1.4)
|
||||
jquery-atwho-rails (~> 1.3.2)
|
||||
|
@ -1096,7 +1072,7 @@ DEPENDENCIES
|
|||
jwt (~> 1.5.6)
|
||||
kaminari (~> 1.0)
|
||||
knapsack (~> 1.16)
|
||||
kubeclient (~> 3.0)
|
||||
kubeclient (~> 3.1.0)
|
||||
letter_opener_web (~> 1.3.0)
|
||||
license_finder (~> 3.1)
|
||||
licensee (~> 8.9)
|
||||
|
@ -1104,17 +1080,18 @@ DEPENDENCIES
|
|||
loofah (~> 2.2)
|
||||
mail_room (~> 0.9.1)
|
||||
method_source (~> 0.8)
|
||||
mini_magick
|
||||
minitest (~> 5.7.0)
|
||||
mousetrap-rails (~> 1.4.6)
|
||||
mysql2 (~> 0.4.10)
|
||||
net-ldap
|
||||
net-ssh (~> 4.2.0)
|
||||
net-ssh (~> 5.0)
|
||||
nokogiri (~> 1.8.2)
|
||||
oauth2 (~> 1.4)
|
||||
octokit (~> 4.8)
|
||||
octokit (~> 4.9)
|
||||
omniauth (~> 1.8)
|
||||
omniauth-auth0 (~> 2.0.0)
|
||||
omniauth-authentiq (~> 0.3.1)
|
||||
omniauth-authentiq (~> 0.3.3)
|
||||
omniauth-azure-oauth2 (~> 0.0.9)
|
||||
omniauth-cas3 (~> 1.1.4)
|
||||
omniauth-facebook (~> 4.0.0)
|
||||
|
@ -1124,7 +1101,7 @@ DEPENDENCIES
|
|||
omniauth-kerberos (~> 0.3.0)
|
||||
omniauth-oauth2-generic (~> 0.2.2)
|
||||
omniauth-saml (~> 1.10)
|
||||
omniauth-shibboleth (~> 1.2.0)
|
||||
omniauth-shibboleth (~> 1.3.0)
|
||||
omniauth-twitter (~> 1.4)
|
||||
omniauth_crowd (~> 2.2.0)
|
||||
org-ruby (~> 0.9.12)
|
||||
|
@ -1150,21 +1127,19 @@ DEPENDENCIES
|
|||
rainbow (~> 2.2)
|
||||
raindrops (~> 0.18)
|
||||
rblineprof (~> 0.3.6)
|
||||
rbnacl (~> 4.0)
|
||||
rbnacl-libsodium
|
||||
rdoc (~> 4.2)
|
||||
rdoc (~> 6.0)
|
||||
re2 (~> 1.1.1)
|
||||
recaptcha (~> 3.0)
|
||||
redcarpet (~> 3.4)
|
||||
redis (~> 3.2)
|
||||
redis-namespace (~> 1.5.2)
|
||||
redis-namespace (~> 1.6.0)
|
||||
redis-rails (~> 5.0.2)
|
||||
request_store (~> 1.3)
|
||||
responders (~> 2.0)
|
||||
rouge (~> 3.1)
|
||||
rqrcode-rails3 (~> 0.1.7)
|
||||
rspec-parameterized
|
||||
rspec-rails (~> 3.6.0)
|
||||
rspec-rails (~> 3.7.0)
|
||||
rspec-retry (~> 0.4.5)
|
||||
rspec-set (~> 0.1.3)
|
||||
rspec_profiling (~> 0.0.5)
|
||||
|
@ -1172,6 +1147,7 @@ DEPENDENCIES
|
|||
rubocop-rspec (~> 1.22.1)
|
||||
ruby-fogbugz (~> 0.2.1)
|
||||
ruby-prof (~> 0.17.0)
|
||||
ruby-progressbar
|
||||
ruby_parser (~> 3.8)
|
||||
rufus-scheduler (~> 3.4)
|
||||
rugged (~> 0.27)
|
||||
|
@ -1180,22 +1156,19 @@ DEPENDENCIES
|
|||
scss_lint (~> 0.56.0)
|
||||
seed-fu (~> 2.3.7)
|
||||
select2-rails (~> 3.5.9)
|
||||
selenium-webdriver (~> 3.5)
|
||||
selenium-webdriver (~> 3.12)
|
||||
sentry-raven (~> 2.7)
|
||||
settingslogic (~> 2.0.9)
|
||||
sham_rack (~> 1.3.6)
|
||||
shoulda-matchers (~> 3.1.2)
|
||||
sidekiq (~> 5.0)
|
||||
sidekiq (~> 5.1)
|
||||
sidekiq-cron (~> 0.6.0)
|
||||
sidekiq-limit_fetch (~> 3.4)
|
||||
simple_po_parser (~> 1.1.2)
|
||||
simplecov (~> 0.14.0)
|
||||
slack-notifier (~> 1.5.1)
|
||||
spinach-rails (~> 0.2.1)
|
||||
spinach-rerun-reporter (~> 0.0.2)
|
||||
spring (~> 2.0.0)
|
||||
spring-commands-rspec (~> 1.0.4)
|
||||
spring-commands-spinach (~> 1.1.0)
|
||||
sprockets (~> 3.7.0)
|
||||
sshkey (~> 1.9.0)
|
||||
stackprof (~> 0.2.10)
|
||||
|
@ -1221,4 +1194,4 @@ DEPENDENCIES
|
|||
wikicloth (= 0.8.1)
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.1
|
||||
1.16.2
|
||||
|
|
1
INSTALLATION_TYPE
Normal file
|
@ -0,0 +1 @@
|
|||
source
|
7
LICENSE
|
@ -4,9 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
All Documentation content that resides under the doc/ directory of this
|
||||
repository is licensed under Creative Commons: CC BY-SA 4.0.
|
||||
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.
|
59
PROCESS.md
|
@ -15,6 +15,8 @@
|
|||
- [Between the 1st and the 7th](#between-the-1st-and-the-7th)
|
||||
- [On the 7th](#on-the-7th)
|
||||
- [After the 7th](#after-the-7th)
|
||||
- [Regressions](#regressions)
|
||||
- [How to manage a regression](#how-to-manage-a-regression)
|
||||
- [Release retrospective and kickoff](#release-retrospective-and-kickoff)
|
||||
- [Retrospective](#retrospective)
|
||||
- [Kickoff](#kickoff)
|
||||
|
@ -168,6 +170,8 @@ the stable branch are:
|
|||
|
||||
* Fixes for [regressions](#regressions)
|
||||
* Fixes for security issues
|
||||
* Fixes or improvements to automated QA scenarios
|
||||
* Documentation updates for changes in the same release
|
||||
* New or updated translations (as long as they do not touch application code)
|
||||
|
||||
During the feature freeze all merge requests that are meant to go into the
|
||||
|
@ -184,11 +188,7 @@ next patch release.
|
|||
|
||||
If a merge request is to be picked into more than one release it will need one
|
||||
`Pick into X.Y` label per release where the merge request should be back-ported
|
||||
to.
|
||||
|
||||
For example, if the current patch release is `10.1.1` and a regression fix needs
|
||||
to be backported down to the `9.5` release, you will need to assign it the
|
||||
`10.1` milestone and the following labels:
|
||||
to. For example:
|
||||
|
||||
- `Pick into 10.1`
|
||||
- `Pick into 10.0`
|
||||
|
@ -199,26 +199,9 @@ to be backported down to the `9.5` release, you will need to assign it the
|
|||
If you think a merge request should go into an RC or patch even though it does not meet these requirements,
|
||||
you can ask for an exception to be made.
|
||||
|
||||
Go to [Release tasks issue tracker](https://gitlab.com/gitlab-org/release/tasks/issues/new) and create an issue
|
||||
using the `Exception-request` issue template.
|
||||
Check [this guide](https://gitlab.com/gitlab-org/release/docs/blob/master/general/exception-request/process.md) about how to open an exception request before opening one.
|
||||
|
||||
**Do not** set the relevant `Pick into X.Y` label (see above) before request an
|
||||
exception; this should be done after the exception is approved.
|
||||
|
||||
You can find who is who on the [team page](https://about.gitlab.com/team/).
|
||||
|
||||
Whether an exception is made is determined by weighing the benefit and urgency of the change
|
||||
(how important it is to the company that this is released _right now_ instead of in a month)
|
||||
against the potential negative impact
|
||||
(things breaking without enough time to comfortably find and fix them before the release on the 22nd).
|
||||
When in doubt, we err on the side of _not_ cherry-picking.
|
||||
|
||||
For example, it is likely that an exception will be made for a trivial 1-5 line performance improvement
|
||||
(e.g. adding a database index or adding `includes` to a query), but not for a new feature, no matter how relatively small or thoroughly tested.
|
||||
|
||||
All MRs which have had exceptions granted must be merged by the 15th.
|
||||
|
||||
### Regressions
|
||||
## Regressions
|
||||
|
||||
A regression for a particular monthly release is a bug that exists in that
|
||||
release, but wasn't present in the release before. This includes bugs in
|
||||
|
@ -236,10 +219,30 @@ month. When we say 'the most recent monthly release', this can refer to either
|
|||
the version currently running on GitLab.com, or the most recent version
|
||||
available in the package repositories.
|
||||
|
||||
A regression issue should be labeled with the appropriate [subject label](../CONTRIBUTING.md#subject-labels-wiki-container-registry-ldap-api-etc)
|
||||
and [team label](../CONTRIBUTING.md#team-labels-ci-discussion-edge-platform-etc),
|
||||
just like any other issue, to help GitLab team members focus on issues that are
|
||||
relevant to [their area of responsibility](https://about.gitlab.com/handbook/engineering/workflow/#choosing-something-to-work-on).
|
||||
### How to manage a regression
|
||||
|
||||
Regressions are very important, and they should be considered high priority
|
||||
issues that should be solved as soon as possible, especially if they affect
|
||||
users. Despite that, ~regression label itself does not imply when the issue
|
||||
will be scheduled.
|
||||
|
||||
When a regression is found:
|
||||
1. Create an issue describing the problem in the most detailed way possible
|
||||
1. If possible, provide links to real examples and how to reproduce the problem
|
||||
1. Label the issue properly, using the [team label](../CONTRIBUTING.md#team-labels),
|
||||
the [subject label](../CONTRIBUTING.md#subject-labels)
|
||||
and any other label that may apply in the specific case
|
||||
1. Add the ~bug and ~regression labels
|
||||
1. Notify the respective Engineering Manager to evaluate the Severity of the regression and add a [Severity label](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#bug-severity-labels). The counterpart Product Manager is included to weigh-in on prioritization as needed to set the [Priority label](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#bug-priority-labels).
|
||||
1. If the regression is either an ~S1, ~S2 or ~S3 severity, label the regression with the current milestone as it should be fixed in the current milestone.
|
||||
1. If the regression was introduced in an RC of the current release, label with ~Deliverable
|
||||
1. If the regression was introduced in the previous release, label with ~"Next Patch Release"
|
||||
1. If the regression is an ~S4 severity, the regression may be scheduled for later milestones at the discretion of Engineering Manager and Product Manager.
|
||||
|
||||
When a new issue is found, the fix should start as soon as possible. You can
|
||||
ping the Engineering Manager or the Product Manager for the relative area to
|
||||
make them aware of the issue earlier. They will analyze the priority and change
|
||||
it if needed.
|
||||
|
||||
## Release retrospective and kickoff
|
||||
|
||||
|
|
11
README.md
|
@ -2,7 +2,6 @@
|
|||
|
||||
[![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
|
||||
[![Overall test coverage](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-ce/pipelines)
|
||||
[![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.svg)](https://gemnasium.com/gitlabhq/gitlabhq)
|
||||
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
|
||||
[![Gitter](https://badges.gitter.im/gitlabhq/gitlabhq.svg)](https://gitter.im/gitlabhq/gitlabhq?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
@ -36,7 +35,7 @@ We're hiring developers, support people, and production engineers all the time,
|
|||
There are two editions of GitLab:
|
||||
|
||||
- GitLab Community Edition (CE) is available freely under the MIT Expat license.
|
||||
- GitLab Enterprise Edition (EE) includes [extra features](https://about.gitlab.com/products/#compare-options) that are more useful for organizations with more than 100 users. To use EE and get official support please [become a subscriber](https://about.gitlab.com/products/).
|
||||
- GitLab Enterprise Edition (EE) includes [extra features](https://about.gitlab.com/pricing/#compare-options) that are more useful for organizations with more than 100 users. To use EE and get official support please [become a subscriber](https://about.gitlab.com/pricing/).
|
||||
|
||||
## Website
|
||||
|
||||
|
@ -73,6 +72,8 @@ GitLab Community Edition (CE) is available freely under the MIT Expat license.
|
|||
|
||||
All third party components incorporated into the GitLab Software are licensed under the original license provided by the owner of the applicable component.
|
||||
|
||||
All Documentation content that resides under the doc/ directory of this repository is licensed under Creative Commons: CC BY-SA 4.0.
|
||||
|
||||
## Install a development environment
|
||||
|
||||
To work on GitLab itself, we recommend setting up your development environment with [the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit).
|
||||
|
@ -119,11 +120,15 @@ All documentation can be found on [docs.gitlab.com/ce/](https://docs.gitlab.com/
|
|||
|
||||
Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on our website for the many options to get help.
|
||||
|
||||
## Why?
|
||||
|
||||
[Read here](https://about.gitlab.com/why/)
|
||||
|
||||
## Is it any good?
|
||||
|
||||
[Yes](https://news.ycombinator.com/item?id=3067434)
|
||||
|
||||
## Is it awesome?
|
||||
|
||||
Thanks for [asking this question](https://twitter.com/supersloth/status/489462789384056832) Joshua.
|
||||
[These people](https://twitter.com/gitlab/likes) seem to like it.
|
||||
|
||||
|
|
2
VERSION
|
@ -1 +1 @@
|
|||
10.8.7
|
||||
11.1.8
|
||||
|
|
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_canceled.png
Normal file
After Width: | Height: | Size: 864 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_created.png
Normal file
After Width: | Height: | Size: 889 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_failed.png
Normal file
After Width: | Height: | Size: 1,015 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_manual.png
Normal file
After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_not_found.png
Normal file
After Width: | Height: | Size: 945 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_pending.png
Normal file
After Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_running.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_skipped.png
Normal file
After Width: | Height: | Size: 923 B |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_success.png
Normal file
After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_warning.png
Normal file
After Width: | Height: | Size: 830 B |
Before Width: | Height: | Size: 5.3 KiB |
BIN
app/assets/images/favicon-blue.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 5.3 KiB |
BIN
app/assets/images/favicon-yellow.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 5.3 KiB |
BIN
app/assets/images/favicon.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable no-param-reassign, class-methods-use-this */
|
||||
/* eslint-disable class-methods-use-this */
|
||||
|
||||
import $ from 'jquery';
|
||||
import Cookies from 'js-cookie';
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class AjaxLoadingSpinner {
|
|||
}
|
||||
|
||||
static toggleLoadingIcon(iconElement) {
|
||||
const classList = iconElement.classList;
|
||||
const { classList } = iconElement;
|
||||
classList.toggle(iconElement.dataset.icon);
|
||||
classList.toggle('fa-spinner');
|
||||
classList.toggle('fa-spin');
|
||||
|
|
|
@ -11,6 +11,7 @@ const Api = {
|
|||
projectPath: '/api/:version/projects/:id',
|
||||
projectLabelsPath: '/:namespace_path/:project_path/labels',
|
||||
mergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid',
|
||||
mergeRequestsPath: '/api/:version/merge_requests',
|
||||
mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes',
|
||||
mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions',
|
||||
groupLabelsPath: '/groups/:namespace_path/-/labels',
|
||||
|
@ -21,6 +22,7 @@ const Api = {
|
|||
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
||||
usersPath: '/api/:version/users.json',
|
||||
commitPath: '/api/:version/projects/:id/repository/commits',
|
||||
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
|
||||
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
|
||||
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
||||
|
||||
|
@ -98,12 +100,18 @@ const Api = {
|
|||
},
|
||||
|
||||
// Return Merge Request for project
|
||||
mergeRequest(projectPath, mergeRequestId) {
|
||||
mergeRequest(projectPath, mergeRequestId, params = {}) {
|
||||
const url = Api.buildUrl(Api.mergeRequestPath)
|
||||
.replace(':id', encodeURIComponent(projectPath))
|
||||
.replace(':mrid', mergeRequestId);
|
||||
|
||||
return axios.get(url);
|
||||
return axios.get(url, { params });
|
||||
},
|
||||
|
||||
mergeRequests(params = {}) {
|
||||
const url = Api.buildUrl(Api.mergeRequestsPath);
|
||||
|
||||
return axios.get(url, { params });
|
||||
},
|
||||
|
||||
mergeRequestChanges(projectPath, mergeRequestId) {
|
||||
|
@ -142,14 +150,15 @@ const Api = {
|
|||
},
|
||||
|
||||
// Return group projects list. Filtered by query
|
||||
groupProjects(groupId, query, callback) {
|
||||
groupProjects(groupId, query, options, callback) {
|
||||
const url = Api.buildUrl(Api.groupProjectsPath).replace(':id', groupId);
|
||||
const defaults = {
|
||||
search: query,
|
||||
per_page: 20,
|
||||
};
|
||||
return axios
|
||||
.get(url, {
|
||||
params: {
|
||||
search: query,
|
||||
per_page: 20,
|
||||
},
|
||||
params: Object.assign({}, defaults, options),
|
||||
})
|
||||
.then(({ data }) => callback(data));
|
||||
},
|
||||
|
@ -164,6 +173,19 @@ const Api = {
|
|||
});
|
||||
},
|
||||
|
||||
commitPipelines(projectId, sha) {
|
||||
const encodedProjectId = projectId
|
||||
.split('/')
|
||||
.map(fragment => encodeURIComponent(fragment))
|
||||
.join('/');
|
||||
|
||||
const url = Api.buildUrl(Api.commitPipelinesPath)
|
||||
.replace(':project_id', encodedProjectId)
|
||||
.replace(':sha', encodeURIComponent(sha));
|
||||
|
||||
return axios.get(url);
|
||||
},
|
||||
|
||||
branchSingle(id, branch) {
|
||||
const url = Api.buildUrl(Api.branchSinglePath)
|
||||
.replace(':id', encodeURIComponent(id))
|
||||
|
@ -222,6 +244,15 @@ const Api = {
|
|||
});
|
||||
},
|
||||
|
||||
createBranch(id, { ref, branch }) {
|
||||
const url = Api.buildUrl(this.createBranchPath).replace(':id', encodeURIComponent(id));
|
||||
|
||||
return axios.post(url, {
|
||||
ref,
|
||||
branch,
|
||||
});
|
||||
},
|
||||
|
||||
buildUrl(url) {
|
||||
let urlRoot = '';
|
||||
if (gon.relative_url_root != null) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable no-param-reassign, prefer-template, no-var, no-void, consistent-return */
|
||||
/* eslint-disable no-param-reassign, prefer-template, no-void, consistent-return */
|
||||
|
||||
import AccessorUtilities from './lib/utils/accessor';
|
||||
|
||||
|
@ -31,7 +31,9 @@ export default class Autosave {
|
|||
// https://github.com/vuejs/vue/issues/2804#issuecomment-216968137
|
||||
const event = new Event('change', { bubbles: true, cancelable: false });
|
||||
const field = this.field.get(0);
|
||||
field.dispatchEvent(event);
|
||||
if (field) {
|
||||
field.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
save() {
|
||||
|
|
|
@ -11,7 +11,8 @@ import axios from './lib/utils/axios_utils';
|
|||
|
||||
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
||||
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
|
||||
const requestAnimationFrame = window.requestAnimationFrame ||
|
||||
const requestAnimationFrame =
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.setTimeout;
|
||||
|
@ -37,21 +38,28 @@ class AwardsHandler {
|
|||
this.emoji = emoji;
|
||||
this.eventListeners = [];
|
||||
// If the user shows intent let's pre-build the menu
|
||||
this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => {
|
||||
const $menu = $('.emoji-menu');
|
||||
if ($menu.length === 0) {
|
||||
requestAnimationFrame(() => {
|
||||
this.createEmojiMenu();
|
||||
});
|
||||
}
|
||||
});
|
||||
this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => {
|
||||
this.registerEventListener(
|
||||
'one',
|
||||
$(document),
|
||||
'mouseenter focus',
|
||||
'.js-add-award',
|
||||
'mouseenter focus',
|
||||
() => {
|
||||
const $menu = $('.emoji-menu');
|
||||
if ($menu.length === 0) {
|
||||
requestAnimationFrame(() => {
|
||||
this.createEmojiMenu();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
this.registerEventListener('on', $(document), 'click', '.js-add-award', e => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.showEmojiMenu($(e.currentTarget));
|
||||
});
|
||||
|
||||
this.registerEventListener('on', $('html'), 'click', (e) => {
|
||||
this.registerEventListener('on', $('html'), 'click', e => {
|
||||
const $target = $(e.target);
|
||||
if (!$target.closest('.emoji-menu').length) {
|
||||
$('.js-awards-block.current').removeClass('current');
|
||||
|
@ -61,12 +69,14 @@ class AwardsHandler {
|
|||
}
|
||||
}
|
||||
});
|
||||
this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => {
|
||||
this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
const $glEmojiElement = $target.find('gl-emoji');
|
||||
const $spriteIconElement = $target.find('.icon');
|
||||
const emojiName = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name');
|
||||
const emojiName = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data(
|
||||
'name',
|
||||
);
|
||||
|
||||
$target.closest('.js-awards-block').addClass('current');
|
||||
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emojiName);
|
||||
|
@ -83,7 +93,10 @@ class AwardsHandler {
|
|||
|
||||
showEmojiMenu($addBtn) {
|
||||
if ($addBtn.hasClass('js-note-emoji')) {
|
||||
$addBtn.closest('.note').find('.js-awards-block').addClass('current');
|
||||
$addBtn
|
||||
.closest('.note')
|
||||
.find('.js-awards-block')
|
||||
.addClass('current');
|
||||
} else {
|
||||
$addBtn.closest('.js-awards-block').addClass('current');
|
||||
}
|
||||
|
@ -177,32 +190,38 @@ class AwardsHandler {
|
|||
const remainingCategories = Object.keys(categoryMap).slice(1);
|
||||
const allCategoriesAddedPromise = remainingCategories.reduce(
|
||||
(promiseChain, categoryNameKey) =>
|
||||
promiseChain.then(() =>
|
||||
new Promise((resolve) => {
|
||||
const emojisInCategory = categoryMap[categoryNameKey];
|
||||
const categoryMarkup = this.renderCategory(
|
||||
categoryLabelMap[categoryNameKey],
|
||||
emojisInCategory,
|
||||
);
|
||||
requestAnimationFrame(() => {
|
||||
emojiContentElement.insertAdjacentHTML('beforeend', categoryMarkup);
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
),
|
||||
promiseChain.then(
|
||||
() =>
|
||||
new Promise(resolve => {
|
||||
const emojisInCategory = categoryMap[categoryNameKey];
|
||||
const categoryMarkup = this.renderCategory(
|
||||
categoryLabelMap[categoryNameKey],
|
||||
emojisInCategory,
|
||||
);
|
||||
requestAnimationFrame(() => {
|
||||
emojiContentElement.insertAdjacentHTML('beforeend', categoryMarkup);
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
),
|
||||
Promise.resolve(),
|
||||
);
|
||||
|
||||
allCategoriesAddedPromise.then(() => {
|
||||
// Used for tests
|
||||
// We check for the menu in case it was destroyed in the meantime
|
||||
if (menu) {
|
||||
menu.dispatchEvent(new CustomEvent('build-emoji-menu-finish'));
|
||||
}
|
||||
}).catch((err) => {
|
||||
emojiContentElement.insertAdjacentHTML('beforeend', '<p>We encountered an error while adding the remaining categories</p>');
|
||||
throw new Error(`Error occurred in addRemainingEmojiMenuCategories: ${err.message}`);
|
||||
});
|
||||
allCategoriesAddedPromise
|
||||
.then(() => {
|
||||
// Used for tests
|
||||
// We check for the menu in case it was destroyed in the meantime
|
||||
if (menu) {
|
||||
menu.dispatchEvent(new CustomEvent('build-emoji-menu-finish'));
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
emojiContentElement.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
'<p>We encountered an error while adding the remaining categories</p>',
|
||||
);
|
||||
throw new Error(`Error occurred in addRemainingEmojiMenuCategories: ${err.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
renderCategory(name, emojiList, opts = {}) {
|
||||
|
@ -211,7 +230,9 @@ class AwardsHandler {
|
|||
${name}
|
||||
</h5>
|
||||
<ul class="clearfix emoji-menu-list ${opts.menuListClass || ''}">
|
||||
${emojiList.map(emojiName => `
|
||||
${emojiList
|
||||
.map(
|
||||
emojiName => `
|
||||
<li class="emoji-menu-list-item">
|
||||
<button class="emoji-menu-btn text-center js-emoji-btn" type="button">
|
||||
${this.emoji.glEmojiTag(emojiName, {
|
||||
|
@ -219,7 +240,9 @@ class AwardsHandler {
|
|||
})}
|
||||
</button>
|
||||
</li>
|
||||
`).join('\n')}
|
||||
`,
|
||||
)
|
||||
.join('\n')}
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
@ -232,7 +255,7 @@ class AwardsHandler {
|
|||
top: `${$addBtn.offset().top + $addBtn.outerHeight()}px`,
|
||||
};
|
||||
if (position === 'right') {
|
||||
css.left = `${($addBtn.offset().left - $menu.outerWidth()) + 20}px`;
|
||||
css.left = `${$addBtn.offset().left - $menu.outerWidth() + 20}px`;
|
||||
$menu.addClass('is-aligned-right');
|
||||
} else {
|
||||
css.left = `${$addBtn.offset().left}px`;
|
||||
|
@ -345,7 +368,7 @@ class AwardsHandler {
|
|||
counter.text(counterNumber - 1);
|
||||
this.removeYouFromUserList($emojiButton);
|
||||
} else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
|
||||
$emojiButton.tooltip('destroy');
|
||||
$emojiButton.tooltip('dispose');
|
||||
counter.text('0');
|
||||
this.removeYouFromUserList($emojiButton);
|
||||
if ($emojiButton.parents('.note').length) {
|
||||
|
@ -358,7 +381,7 @@ class AwardsHandler {
|
|||
}
|
||||
|
||||
removeEmoji($emojiButton) {
|
||||
$emojiButton.tooltip('destroy');
|
||||
$emojiButton.tooltip('dispose');
|
||||
$emojiButton.remove();
|
||||
const $votesBlock = this.getVotesBlock();
|
||||
if ($votesBlock.find('.js-emoji-btn').length === 0) {
|
||||
|
@ -392,7 +415,7 @@ class AwardsHandler {
|
|||
.removeAttr('data-title')
|
||||
.removeAttr('data-original-title')
|
||||
.attr('title', this.toSentence(authors))
|
||||
.tooltip('fixTitle');
|
||||
.tooltip('_fixTitle');
|
||||
}
|
||||
|
||||
addYouToUserList(votesBlock, emoji) {
|
||||
|
@ -405,7 +428,7 @@ class AwardsHandler {
|
|||
users.unshift('You');
|
||||
return awardBlock
|
||||
.attr('title', this.toSentence(users))
|
||||
.tooltip('fixTitle');
|
||||
.tooltip('_fixTitle');
|
||||
}
|
||||
|
||||
createAwardButtonForVotesBlock(votesBlock, emojiName) {
|
||||
|
@ -416,7 +439,10 @@ class AwardsHandler {
|
|||
</button>
|
||||
`;
|
||||
const $emojiButton = $(buttonHtml);
|
||||
$emojiButton.insertBefore(votesBlock.find('.js-award-holder')).find('.emoji-icon').data('name', emojiName);
|
||||
$emojiButton
|
||||
.insertBefore(votesBlock.find('.js-award-holder'))
|
||||
.find('.emoji-icon')
|
||||
.data('name', emojiName);
|
||||
this.animateEmoji($emojiButton);
|
||||
$('.award-control').tooltip();
|
||||
votesBlock.removeClass('current');
|
||||
|
@ -426,7 +452,7 @@ class AwardsHandler {
|
|||
const className = 'pulse animated once short';
|
||||
$emoji.addClass(className);
|
||||
|
||||
this.registerEventListener('on', $emoji, animationEndEventString, (e) => {
|
||||
this.registerEventListener('on', $emoji, animationEndEventString, e => {
|
||||
$(e.currentTarget).removeClass(className);
|
||||
});
|
||||
}
|
||||
|
@ -444,15 +470,16 @@ class AwardsHandler {
|
|||
if (this.isUserAuthored($emojiButton)) {
|
||||
this.userAuthored($emojiButton);
|
||||
} else {
|
||||
axios.post(awardUrl, {
|
||||
name: emoji,
|
||||
})
|
||||
.then(({ data }) => {
|
||||
if (data.ok) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.catch(() => flash(__('Something went wrong on our end.')));
|
||||
axios
|
||||
.post(awardUrl, {
|
||||
name: emoji,
|
||||
})
|
||||
.then(({ data }) => {
|
||||
if (data.ok) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.catch(() => flash(__('Something went wrong on our end.')));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,26 +513,33 @@ class AwardsHandler {
|
|||
}
|
||||
|
||||
getFrequentlyUsedEmojis() {
|
||||
return this.frequentlyUsedEmojis || (() => {
|
||||
const frequentlyUsedEmojis = _.uniq((Cookies.get('frequently_used_emojis') || '').split(','));
|
||||
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(
|
||||
inputName => this.emoji.isEmojiNameValid(inputName),
|
||||
);
|
||||
return (
|
||||
this.frequentlyUsedEmojis ||
|
||||
(() => {
|
||||
const frequentlyUsedEmojis = _.uniq(
|
||||
(Cookies.get('frequently_used_emojis') || '').split(','),
|
||||
);
|
||||
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter(inputName =>
|
||||
this.emoji.isEmojiNameValid(inputName),
|
||||
);
|
||||
|
||||
return this.frequentlyUsedEmojis;
|
||||
})();
|
||||
return this.frequentlyUsedEmojis;
|
||||
})()
|
||||
);
|
||||
}
|
||||
|
||||
setupSearch() {
|
||||
const $search = $('.js-emoji-menu-search');
|
||||
|
||||
this.registerEventListener('on', $search, 'input', (e) => {
|
||||
const term = $(e.target).val().trim();
|
||||
this.registerEventListener('on', $search, 'input', e => {
|
||||
const term = $(e.target)
|
||||
.val()
|
||||
.trim();
|
||||
this.searchEmojis(term);
|
||||
});
|
||||
|
||||
const $menu = $('.emoji-menu');
|
||||
this.registerEventListener('on', $menu, transitionEndEventString, (e) => {
|
||||
this.registerEventListener('on', $menu, transitionEndEventString, e => {
|
||||
if (e.target === e.currentTarget) {
|
||||
// Clear the search
|
||||
this.searchEmojis('');
|
||||
|
@ -523,19 +557,26 @@ class AwardsHandler {
|
|||
// Generate a search result block
|
||||
const h5 = $('<h5 class="emoji-search-title"/>').text('Search results');
|
||||
const foundEmojis = this.findMatchingEmojiElements(term).show();
|
||||
const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);
|
||||
const ul = $('<ul>')
|
||||
.addClass('emoji-menu-list emoji-menu-search')
|
||||
.append(foundEmojis);
|
||||
$('.emoji-menu-content ul, .emoji-menu-content h5').hide();
|
||||
$('.emoji-menu-content').append(h5).append(ul);
|
||||
$('.emoji-menu-content')
|
||||
.append(h5)
|
||||
.append(ul);
|
||||
} else {
|
||||
$('.emoji-menu-content').children().show();
|
||||
$('.emoji-menu-content')
|
||||
.children()
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
findMatchingEmojiElements(query) {
|
||||
const emojiMatches = this.emoji.filterEmojiNamesByAlias(query);
|
||||
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
|
||||
const $matchingElements = $emojiElements
|
||||
.filter((i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0);
|
||||
const $matchingElements = $emojiElements.filter(
|
||||
(i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0,
|
||||
);
|
||||
return $matchingElements.closest('li').clone();
|
||||
}
|
||||
|
||||
|
@ -550,16 +591,13 @@ class AwardsHandler {
|
|||
$emojiMenu.addClass(IS_RENDERED);
|
||||
|
||||
// enqueues animation as a microtask, so it begins ASAP once IS_RENDERED added
|
||||
return Promise.resolve()
|
||||
.then(() => $emojiMenu.addClass(IS_VISIBLE));
|
||||
return Promise.resolve().then(() => $emojiMenu.addClass(IS_VISIBLE));
|
||||
}
|
||||
|
||||
hideMenuElement($emojiMenu) {
|
||||
$emojiMenu.on(transitionEndEventString, (e) => {
|
||||
$emojiMenu.on(transitionEndEventString, e => {
|
||||
if (e.currentTarget === e.target) {
|
||||
$emojiMenu
|
||||
.removeClass(IS_RENDERED)
|
||||
.off(transitionEndEventString);
|
||||
$emojiMenu.removeClass(IS_RENDERED).off(transitionEndEventString);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -567,7 +605,7 @@ class AwardsHandler {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
this.eventListeners.forEach((entry) => {
|
||||
this.eventListeners.forEach(entry => {
|
||||
entry.element.off.call(entry.element, ...entry.args);
|
||||
});
|
||||
$('.emoji-menu').remove();
|
||||
|
@ -577,8 +615,9 @@ class AwardsHandler {
|
|||
let awardsHandlerPromise = null;
|
||||
export default function loadAwardsHandler(reload = false) {
|
||||
if (!awardsHandlerPromise || reload) {
|
||||
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji')
|
||||
.then(Emoji => new AwardsHandler(Emoji));
|
||||
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(
|
||||
Emoji => new AwardsHandler(Emoji),
|
||||
);
|
||||
}
|
||||
return awardsHandlerPromise;
|
||||
}
|
||||
|
|
|
@ -72,11 +72,11 @@ export default {
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<img
|
||||
class="project-badge"
|
||||
:src="imageUrlWithRetries"
|
||||
class="project-badge"
|
||||
aria-hidden="true"
|
||||
@load="onLoad"
|
||||
@error="onError"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</a>
|
||||
|
||||
|
@ -89,32 +89,32 @@ export default {
|
|||
v-show="hasError"
|
||||
class="btn-group"
|
||||
>
|
||||
<div class="btn btn-default btn-xs disabled">
|
||||
<div class="btn btn-default btn-sm disabled">
|
||||
<icon
|
||||
:size="16"
|
||||
class="prepend-left-8 append-right-8"
|
||||
name="doc_image"
|
||||
:size="16"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="btn btn-default btn-xs disabled"
|
||||
class="btn btn-default btn-sm disabled"
|
||||
>
|
||||
<span class="prepend-left-8 append-right-8">{{ s__('Badges|No badge image') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-show="hasError"
|
||||
class="btn btn-transparent btn-xs text-primary"
|
||||
type="button"
|
||||
v-tooltip
|
||||
v-show="hasError"
|
||||
:title="s__('Badges|Reload badge image')"
|
||||
class="btn btn-transparent btn-sm text-primary"
|
||||
type="button"
|
||||
@click="reloadImage"
|
||||
>
|
||||
<icon
|
||||
name="retry"
|
||||
:size="16"
|
||||
name="retry"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -153,14 +153,14 @@ export default {
|
|||
<label for="badge-link-url">{{ s__('Badges|Link') }}</label>
|
||||
<input
|
||||
id="badge-link-url"
|
||||
type="text"
|
||||
class="form-control"
|
||||
v-model="linkUrl"
|
||||
:placeholder="$options.badgeLinkUrlPlaceholder"
|
||||
type="text"
|
||||
class="form-control"
|
||||
@input="debouncedPreview"
|
||||
/>
|
||||
<span
|
||||
class="help-block"
|
||||
class="form-text text-muted"
|
||||
v-html="helpText"
|
||||
></span>
|
||||
</div>
|
||||
|
@ -169,14 +169,14 @@ export default {
|
|||
<label for="badge-image-url">{{ s__('Badges|Badge image URL') }}</label>
|
||||
<input
|
||||
id="badge-image-url"
|
||||
type="text"
|
||||
class="form-control"
|
||||
v-model="imageUrl"
|
||||
:placeholder="$options.badgeImageUrlPlaceholder"
|
||||
type="text"
|
||||
class="form-control"
|
||||
@input="debouncedPreview"
|
||||
/>
|
||||
<span
|
||||
class="help-block"
|
||||
class="form-text text-muted"
|
||||
v-html="helpText"
|
||||
></span>
|
||||
</div>
|
||||
|
@ -184,8 +184,8 @@ export default {
|
|||
<div class="form-group">
|
||||
<label for="badge-preview">{{ s__('Badges|Badge image preview') }}</label>
|
||||
<badge
|
||||
id="badge-preview"
|
||||
v-show="renderedBadge && !isRendering"
|
||||
id="badge-preview"
|
||||
:image-url="renderedImageUrl"
|
||||
:link-url="renderedLinkUrl"
|
||||
/>
|
||||
|
@ -202,16 +202,16 @@ export default {
|
|||
|
||||
<div class="row-content-block">
|
||||
<loading-button
|
||||
type="submit"
|
||||
container-class="btn btn-success"
|
||||
:disabled="!canSubmit"
|
||||
:loading="isSaving"
|
||||
:label="submitButtonLabel"
|
||||
type="submit"
|
||||
container-class="btn btn-success"
|
||||
/>
|
||||
<button
|
||||
v-if="isEditing"
|
||||
class="btn btn-cancel"
|
||||
type="button"
|
||||
v-if="isEditing"
|
||||
@click="onCancel"
|
||||
>{{ __('Cancel') }}</button>
|
||||
</div>
|
||||
|
|
|
@ -23,8 +23,8 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{{ s__('Badges|Your badges') }}
|
||||
<span
|
||||
v-show="!isLoading"
|
||||
|
@ -33,19 +33,19 @@ export default {
|
|||
</div>
|
||||
<loading-icon
|
||||
v-show="isLoading"
|
||||
class="panel-body"
|
||||
class="card-body"
|
||||
size="2"
|
||||
/>
|
||||
<div
|
||||
v-if="hasNoBadges"
|
||||
class="panel-body"
|
||||
class="card-body"
|
||||
>
|
||||
<span v-if="isGroupBadge">{{ s__('Badges|This group has no badges') }}</span>
|
||||
<span v-else>{{ s__('Badges|This project has no badges') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="panel-body"
|
||||
class="card-body"
|
||||
>
|
||||
<badge-list-row
|
||||
v-for="badge in badges"
|
||||
|
|
|
@ -41,9 +41,9 @@ export default {
|
|||
<template>
|
||||
<div class="gl-responsive-table-row-layout gl-responsive-table-row">
|
||||
<badge
|
||||
class="table-section section-30"
|
||||
:image-url="badge.renderedImageUrl"
|
||||
:link-url="badge.renderedLinkUrl"
|
||||
class="table-section section-30"
|
||||
/>
|
||||
<span class="table-section section-50 str-truncated">{{ badge.linkUrl }}</span>
|
||||
<div class="table-section section-10">
|
||||
|
@ -54,29 +54,29 @@ export default {
|
|||
v-if="canEditBadge"
|
||||
class="table-action-buttons">
|
||||
<button
|
||||
:disabled="badge.isDeleting"
|
||||
class="btn btn-default append-right-8"
|
||||
type="button"
|
||||
:disabled="badge.isDeleting"
|
||||
@click="editBadge(badge)"
|
||||
>
|
||||
<icon
|
||||
name="pencil"
|
||||
:size="16"
|
||||
:aria-label="__('Edit')"
|
||||
name="pencil"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
:disabled="badge.isDeleting"
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
data-toggle="modal"
|
||||
data-target="#delete-badge-modal"
|
||||
:disabled="badge.isDeleting"
|
||||
@click="updateBadgeInModal(badge)"
|
||||
>
|
||||
<icon
|
||||
name="remove"
|
||||
:size="16"
|
||||
:aria-label="__('Delete')"
|
||||
name="remove"
|
||||
/>
|
||||
</button>
|
||||
<loading-icon
|
||||
|
|
|
@ -44,8 +44,8 @@ export default {
|
|||
<gl-modal
|
||||
id="delete-badge-modal"
|
||||
:header-title-text="s__('Badges|Delete badge?')"
|
||||
footer-primary-button-variant="danger"
|
||||
:footer-primary-button-text="s__('Badges|Delete badge')"
|
||||
footer-primary-button-variant="danger"
|
||||
@submit="onSubmitModal">
|
||||
<div class="well">
|
||||
<badge
|
||||
|
|
|
@ -8,10 +8,10 @@ function showTooltip(target, title) {
|
|||
if (!$target.data('hideTooltip')) {
|
||||
$target
|
||||
.attr('title', title)
|
||||
.tooltip('fixTitle')
|
||||
.tooltip('_fixTitle')
|
||||
.tooltip('show')
|
||||
.attr('title', originalTitle)
|
||||
.tooltip('fixTitle');
|
||||
.tooltip('_fixTitle');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ export default function initCopyToClipboard() {
|
|||
* data types to the intended values.
|
||||
*/
|
||||
$(document).on('copy', 'body > textarea[readonly]', (e) => {
|
||||
const clipboardData = e.originalEvent.clipboardData;
|
||||
const { clipboardData } = e.originalEvent;
|
||||
if (!clipboardData) return;
|
||||
|
||||
const text = e.target.value;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */
|
||||
/* eslint-disable object-shorthand, no-unused-vars, no-use-before-define, max-len, no-restricted-syntax, guard-for-in, no-continue */
|
||||
|
||||
import $ from 'jquery';
|
||||
import _ from 'underscore';
|
||||
|
@ -119,7 +119,7 @@ const gfmRules = {
|
|||
return el.outerHTML;
|
||||
},
|
||||
'dl'(el, text) {
|
||||
let lines = text.trim().split('\n');
|
||||
let lines = text.replace(/\n\n/g, '\n').trim().split('\n');
|
||||
// Add two spaces to the front of subsequent list items lines,
|
||||
// or leave the line entirely blank.
|
||||
lines = lines.map((l) => {
|
||||
|
@ -129,9 +129,13 @@ const gfmRules = {
|
|||
return ` ${line}`;
|
||||
});
|
||||
|
||||
return `<dl>\n${lines.join('\n')}\n</dl>`;
|
||||
return `<dl>\n${lines.join('\n')}\n</dl>\n`;
|
||||
},
|
||||
'sub, dt, dd, kbd, q, samp, var, ruby, rt, rp, abbr, summary, details'(el, text) {
|
||||
'dt, dd, summary, details'(el, text) {
|
||||
const tag = el.nodeName.toLowerCase();
|
||||
return `<${tag}>${text}</${tag}>\n`;
|
||||
},
|
||||
'sup, sub, kbd, q, samp, var, ruby, rt, rp, abbr'(el, text) {
|
||||
const tag = el.nodeName.toLowerCase();
|
||||
return `<${tag}>${text}</${tag}>`;
|
||||
},
|
||||
|
@ -215,22 +219,22 @@ const gfmRules = {
|
|||
return text.replace(/^- /mg, '1. ');
|
||||
},
|
||||
'h1'(el, text) {
|
||||
return `# ${text.trim()}`;
|
||||
return `# ${text.trim()}\n`;
|
||||
},
|
||||
'h2'(el, text) {
|
||||
return `## ${text.trim()}`;
|
||||
return `## ${text.trim()}\n`;
|
||||
},
|
||||
'h3'(el, text) {
|
||||
return `### ${text.trim()}`;
|
||||
return `### ${text.trim()}\n`;
|
||||
},
|
||||
'h4'(el, text) {
|
||||
return `#### ${text.trim()}`;
|
||||
return `#### ${text.trim()}\n`;
|
||||
},
|
||||
'h5'(el, text) {
|
||||
return `##### ${text.trim()}`;
|
||||
return `##### ${text.trim()}\n`;
|
||||
},
|
||||
'h6'(el, text) {
|
||||
return `###### ${text.trim()}`;
|
||||
return `###### ${text.trim()}\n`;
|
||||
},
|
||||
'strong'(el, text) {
|
||||
return `**${text}**`;
|
||||
|
@ -241,11 +245,13 @@ const gfmRules = {
|
|||
'del'(el, text) {
|
||||
return `~~${text}~~`;
|
||||
},
|
||||
'sup'(el, text) {
|
||||
return `^${text}`;
|
||||
},
|
||||
'hr'(el) {
|
||||
return '-----';
|
||||
// extra leading \n is to ensure that there is a blank line between
|
||||
// a list followed by an hr, otherwise this breaks old redcarpet rendering
|
||||
return '\n-----\n';
|
||||
},
|
||||
'p'(el, text) {
|
||||
return `${text.trim()}\n`;
|
||||
},
|
||||
'table'(el) {
|
||||
const theadEl = el.querySelector('thead');
|
||||
|
@ -263,7 +269,9 @@ const gfmRules = {
|
|||
|
||||
let before = '';
|
||||
let after = '';
|
||||
switch (cell.style.textAlign) {
|
||||
const alignment = cell.align || cell.style.textAlign;
|
||||
|
||||
switch (alignment) {
|
||||
case 'center':
|
||||
before = ':';
|
||||
after = ':';
|
||||
|
@ -313,7 +321,7 @@ export class CopyAsGFM {
|
|||
}
|
||||
|
||||
static copyAsGFM(e, transformer) {
|
||||
const clipboardData = e.originalEvent.clipboardData;
|
||||
const { clipboardData } = e.originalEvent;
|
||||
if (!clipboardData) return;
|
||||
|
||||
const documentFragment = getSelectedFragment();
|
||||
|
@ -330,7 +338,7 @@ export class CopyAsGFM {
|
|||
}
|
||||
|
||||
static pasteGFM(e) {
|
||||
const clipboardData = e.originalEvent.clipboardData;
|
||||
const { clipboardData } = e.originalEvent;
|
||||
if (!clipboardData) return;
|
||||
|
||||
const text = clipboardData.getData('text/plain');
|
||||
|
|
|
@ -69,7 +69,7 @@ $(document).on('keyup.quick_submit', '.js-quick-submit input[type=submit], .js-q
|
|||
$this.tooltip({
|
||||
container: 'body',
|
||||
html: 'true',
|
||||
placement: 'auto top',
|
||||
placement: 'top',
|
||||
title,
|
||||
trigger: 'manual',
|
||||
});
|
||||
|
|
|
@ -42,9 +42,9 @@ $.fn.requiresInput = function requiresInput() {
|
|||
function hideOrShowHelpBlock(form) {
|
||||
const selected = $('.js-select-namespace option:selected');
|
||||
if (selected.length && selected.data('optionsParent') === 'groups') {
|
||||
form.find('.help-block').hide();
|
||||
form.find('.form-text.text-muted').hide();
|
||||
} else if (selected.length) {
|
||||
form.find('.help-block').show();
|
||||
form.find('.form-text.text-muted').show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ import sqljs from 'sql.js';
|
|||
import { template as _template } from 'underscore';
|
||||
|
||||
const PREVIEW_TEMPLATE = _template(`
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><%- name %></div>
|
||||
<div class="panel-body">
|
||||
<div class="card">
|
||||
<div class="card-header"><%- name %></div>
|
||||
<div class="card-body">
|
||||
<img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -84,7 +84,7 @@ class BalsamiqViewer {
|
|||
renderTemplate(preview) {
|
||||
const resource = this.getResource(preview.resourceID);
|
||||
const name = BalsamiqViewer.parseTitle(resource);
|
||||
const image = preview.image;
|
||||
const { image } = preview;
|
||||
|
||||
const template = PREVIEW_TEMPLATE({
|
||||
name,
|
||||
|
|
|
@ -12,7 +12,7 @@ export default function loadBalsamiqFile() {
|
|||
|
||||
if (!(viewer instanceof Element)) return;
|
||||
|
||||
const endpoint = viewer.dataset.endpoint;
|
||||
const { endpoint } = viewer.dataset;
|
||||
|
||||
const balsamiqViewer = new BalsamiqViewer(viewer);
|
||||
balsamiqViewer.loadFile(endpoint).catch(onError);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable no-new */
|
||||
import Vue from 'vue';
|
||||
import pdfLab from '../../pdf/index.vue';
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class SketchLoader {
|
|||
previewLink.href = previewUrl;
|
||||
previewLink.target = '_blank';
|
||||
previewImage.src = previewUrl;
|
||||
previewImage.className = 'img-responsive';
|
||||
previewImage.className = 'img-fluid';
|
||||
|
||||
previewLink.appendChild(previewImage);
|
||||
this.container.appendChild(previewLink);
|
||||
|
|
|
@ -5,7 +5,7 @@ export default () => {
|
|||
|
||||
[].slice.call(document.querySelectorAll('.js-material-changer')).forEach((el) => {
|
||||
el.addEventListener('click', (e) => {
|
||||
const target = e.target;
|
||||
const { target } = e;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ export default class BlobViewer {
|
|||
const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)');
|
||||
let initialViewerName = initialViewer.getAttribute('data-type');
|
||||
|
||||
if (this.switcher && location.hash.indexOf('#L') === 0) {
|
||||
if (this.switcher && window.location.hash.indexOf('#L') === 0) {
|
||||
initialViewerName = 'simple';
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ export default class BlobViewer {
|
|||
this.copySourceBtn.classList.add('disabled');
|
||||
}
|
||||
|
||||
$(this.copySourceBtn).tooltip('fixTitle');
|
||||
$(this.copySourceBtn).tooltip('_fixTitle');
|
||||
}
|
||||
|
||||
switchToViewer(name) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var, quotes, vars-on-top, no-unused-vars, no-new, max-len */
|
||||
/* global EditBlob */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
import $ from 'jquery';
|
||||
import NewCommitForm from '../new_commit_form';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable comma-dangle, space-before-function-paren, one-var */
|
||||
/* eslint-disable comma-dangle */
|
||||
|
||||
import $ from 'jquery';
|
||||
import Sortable from 'vendor/Sortable';
|
||||
import Sortable from 'sortablejs';
|
||||
import Vue from 'vue';
|
||||
import AccessorUtilities from '../../lib/utils/accessor';
|
||||
import boardList from './board_list.vue';
|
||||
|
@ -14,17 +13,28 @@ window.gl = window.gl || {};
|
|||
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||
|
||||
gl.issueBoards.Board = Vue.extend({
|
||||
template: '#js-board-template',
|
||||
components: {
|
||||
boardList,
|
||||
'board-delete': gl.issueBoards.BoardDelete,
|
||||
BoardBlankState,
|
||||
},
|
||||
props: {
|
||||
list: Object,
|
||||
disabled: Boolean,
|
||||
issueLinkBase: String,
|
||||
rootPath: String,
|
||||
list: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
boardId: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
@ -46,56 +56,8 @@ gl.issueBoards.Board = Vue.extend({
|
|||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
detailIssue: {
|
||||
handler () {
|
||||
if (!Object.keys(this.detailIssue.issue).length) return;
|
||||
|
||||
const issue = this.list.findIssue(this.detailIssue.issue.id);
|
||||
|
||||
if (issue) {
|
||||
const offsetLeft = this.$el.offsetLeft;
|
||||
const boardsList = document.querySelectorAll('.boards-list')[0];
|
||||
const left = boardsList.scrollLeft - offsetLeft;
|
||||
let right = (offsetLeft + this.$el.offsetWidth);
|
||||
|
||||
if (window.innerWidth > 768 && boardsList.classList.contains('is-compact')) {
|
||||
// -290 here because width of boardsList is animating so therefore
|
||||
// getting the width here is incorrect
|
||||
// 290 is the width of the sidebar
|
||||
right -= (boardsList.offsetWidth - 290);
|
||||
} else {
|
||||
right -= boardsList.offsetWidth;
|
||||
}
|
||||
|
||||
if (right - boardsList.scrollLeft > 0) {
|
||||
$(boardsList).animate({
|
||||
scrollLeft: right
|
||||
}, this.sortableOptions.animation);
|
||||
} else if (left > 0) {
|
||||
$(boardsList).animate({
|
||||
scrollLeft: offsetLeft
|
||||
}, this.sortableOptions.animation);
|
||||
}
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showNewIssueForm() {
|
||||
this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
|
||||
},
|
||||
toggleExpanded(e) {
|
||||
if (this.list.isExpandable && !e.target.classList.contains('js-no-trigger-collapse')) {
|
||||
this.list.isExpanded = !this.list.isExpanded;
|
||||
|
||||
if (AccessorUtilities.isLocalStorageAccessSafe()) {
|
||||
localStorage.setItem(`boards.${this.boardId}.${this.list.type}.expanded`, this.list.isExpanded);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.sortableOptions = gl.issueBoards.getBoardSortableDefaultOptions({
|
||||
disabled: this.disabled,
|
||||
|
@ -125,4 +87,19 @@ gl.issueBoards.Board = Vue.extend({
|
|||
this.list.isExpanded = !isCollapsed;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showNewIssueForm() {
|
||||
this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
|
||||
},
|
||||
toggleExpanded(e) {
|
||||
if (this.list.isExpandable && !e.target.classList.contains('js-no-trigger-collapse')) {
|
||||
this.list.isExpanded = !this.list.isExpanded;
|
||||
|
||||
if (AccessorUtilities.isLocalStorageAccessSafe()) {
|
||||
localStorage.setItem(`boards.${this.boardId}.${this.list.type}.expanded`, this.list.isExpanded);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
template: '#js-board-template',
|
||||
});
|
||||
|
|
|
@ -72,8 +72,8 @@ export default {
|
|||
:key="index"
|
||||
>
|
||||
<span
|
||||
class="label-color"
|
||||
:style="{ backgroundColor: label.color }">
|
||||
:style="{ backgroundColor: label.color }"
|
||||
class="label-color">
|
||||
</span>
|
||||
{{ label.title }}
|
||||
</li>
|
||||
|
|
|
@ -1,83 +1,82 @@
|
|||
<script>
|
||||
/* eslint-disable vue/require-default-prop */
|
||||
import './issue_card_inner';
|
||||
import eventHub from '../eventhub';
|
||||
/* eslint-disable vue/require-default-prop */
|
||||
import IssueCardInner from './issue_card_inner.vue';
|
||||
import eventHub from '../eventhub';
|
||||
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
|
||||
export default {
|
||||
name: 'BoardsIssueCard',
|
||||
components: {
|
||||
'issue-card-inner': gl.issueBoards.IssueCardInner,
|
||||
},
|
||||
props: {
|
||||
list: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
export default {
|
||||
name: 'BoardsIssueCard',
|
||||
components: {
|
||||
IssueCardInner,
|
||||
},
|
||||
issue: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
props: {
|
||||
list: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
issue: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
groupId: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
default: '',
|
||||
data() {
|
||||
return {
|
||||
showDetail: false,
|
||||
detailIssue: Store.detail,
|
||||
};
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
computed: {
|
||||
issueDetailVisible() {
|
||||
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
|
||||
},
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
groupId: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDetail: false,
|
||||
detailIssue: Store.detail,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
issueDetailVisible() {
|
||||
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
mouseDown() {
|
||||
this.showDetail = true;
|
||||
},
|
||||
mouseMove() {
|
||||
this.showDetail = false;
|
||||
},
|
||||
showIssue(e) {
|
||||
if (e.target.classList.contains('js-no-trigger')) return;
|
||||
|
||||
if (this.showDetail) {
|
||||
methods: {
|
||||
mouseDown() {
|
||||
this.showDetail = true;
|
||||
},
|
||||
mouseMove() {
|
||||
this.showDetail = false;
|
||||
},
|
||||
showIssue(e) {
|
||||
if (e.target.classList.contains('js-no-trigger')) return;
|
||||
|
||||
if (Store.detail.issue && Store.detail.issue.id === this.issue.id) {
|
||||
eventHub.$emit('clearDetailIssue');
|
||||
} else {
|
||||
eventHub.$emit('newDetailIssue', this.issue);
|
||||
Store.detail.list = this.list;
|
||||
if (this.showDetail) {
|
||||
this.showDetail = false;
|
||||
|
||||
if (Store.detail.issue && Store.detail.issue.id === this.issue.id) {
|
||||
eventHub.$emit('clearDetailIssue');
|
||||
} else {
|
||||
eventHub.$emit('newDetailIssue', this.issue);
|
||||
Store.detail.list = this.list;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
class="card"
|
||||
:class="{
|
||||
'user-can-drag': !disabled && issue.id,
|
||||
'is-disabled': disabled || !issue.id,
|
||||
|
@ -85,6 +84,7 @@ export default {
|
|||
}"
|
||||
:index="index"
|
||||
:data-issue-id="issue.id"
|
||||
class="board-card"
|
||||
@mousedown="mouseDown"
|
||||
@mousemove="mouseMove"
|
||||
@mouseup="showIssue($event)">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable comma-dangle, space-before-function-paren, no-alert */
|
||||
/* eslint-disable comma-dangle, no-alert */
|
||||
|
||||
import $ from 'jquery';
|
||||
import Vue from 'vue';
|
||||
|
@ -8,13 +8,16 @@ window.gl.issueBoards = window.gl.issueBoards || {};
|
|||
|
||||
gl.issueBoards.BoardDelete = Vue.extend({
|
||||
props: {
|
||||
list: Object
|
||||
list: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
deleteBoard () {
|
||||
$(this.$el).tooltip('hide');
|
||||
|
||||
if (confirm('Are you sure you want to delete this list?')) {
|
||||
if (window.confirm('Are you sure you want to delete this list?')) {
|
||||
this.list.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import Sortable from 'vendor/Sortable';
|
||||
import Sortable from 'sortablejs';
|
||||
import boardNewIssue from './board_new_issue.vue';
|
||||
import boardCard from './board_card.vue';
|
||||
import eventHub from '../eventhub';
|
||||
|
@ -87,10 +87,46 @@ export default {
|
|||
mounted() {
|
||||
const options = gl.issueBoards.getBoardSortableDefaultOptions({
|
||||
scroll: true,
|
||||
group: 'issues',
|
||||
disabled: this.disabled,
|
||||
filter: '.board-list-count, .is-disabled',
|
||||
dataIdAttr: 'data-issue-id',
|
||||
group: {
|
||||
name: 'issues',
|
||||
/**
|
||||
* Dynamically determine between which containers
|
||||
* items can be moved or copied as
|
||||
* Assignee lists (EE feature) require this behavior
|
||||
*/
|
||||
pull: (to, from, dragEl, e) => {
|
||||
// As per Sortable's docs, `to` should provide
|
||||
// reference to exact sortable container on which
|
||||
// we're trying to drag element, but either it is
|
||||
// a library's bug or our markup structure is too complex
|
||||
// that `to` never points to correct container
|
||||
// See https://github.com/RubaXa/Sortable/issues/1037
|
||||
//
|
||||
// So we use `e.target` which is always accurate about
|
||||
// which element we're currently dragging our card upon
|
||||
// So from there, we can get reference to actual container
|
||||
// and thus the container type to enable Copy or Move
|
||||
if (e.target) {
|
||||
const containerEl = e.target.closest('.js-board-list') || e.target.querySelector('.js-board-list');
|
||||
const toBoardType = containerEl.dataset.boardType;
|
||||
|
||||
if (toBoardType) {
|
||||
const fromBoardType = this.list.type;
|
||||
|
||||
if ((fromBoardType === 'assignee' && toBoardType === 'label') ||
|
||||
(fromBoardType === 'label' && toBoardType === 'assignee')) {
|
||||
return 'clone';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
revertClone: true,
|
||||
},
|
||||
onStart: (e) => {
|
||||
const card = this.$refs.issue[e.oldIndex];
|
||||
|
||||
|
@ -169,21 +205,22 @@ export default {
|
|||
<template>
|
||||
<div class="board-list-component">
|
||||
<div
|
||||
v-if="loading"
|
||||
class="board-list-loading text-center"
|
||||
aria-label="Loading issues"
|
||||
v-if="loading">
|
||||
aria-label="Loading issues">
|
||||
<loading-icon />
|
||||
</div>
|
||||
<board-new-issue
|
||||
v-if="list.type !== 'closed' && showIssueForm"
|
||||
:group-id="groupId"
|
||||
:list="list"
|
||||
v-if="list.type !== 'closed' && showIssueForm"/>
|
||||
:list="list"/>
|
||||
<ul
|
||||
class="board-list"
|
||||
v-show="!loading"
|
||||
ref="list"
|
||||
:data-board="list.id"
|
||||
:class="{ 'is-smaller': showIssueForm }">
|
||||
:data-board-type="list.type"
|
||||
:class="{ 'is-smaller': showIssueForm }"
|
||||
class="board-list js-board-list">
|
||||
<board-card
|
||||
v-for="(issue, index) in issues"
|
||||
ref="issue"
|
||||
|
@ -196,8 +233,8 @@ export default {
|
|||
:disabled="disabled"
|
||||
:key="issue.id" />
|
||||
<li
|
||||
class="board-list-count text-center"
|
||||
v-if="showCount"
|
||||
class="board-list-count text-center"
|
||||
data-issue-id="-1">
|
||||
<loading-icon
|
||||
v-show="list.loadingMore"
|
||||
|
|
|
@ -49,11 +49,12 @@ export default {
|
|||
this.error = false;
|
||||
|
||||
const labels = this.list.label ? [this.list.label] : [];
|
||||
const assignees = this.list.assignee ? [this.list.assignee] : [];
|
||||
const issue = new ListIssue({
|
||||
title: this.title,
|
||||
labels,
|
||||
subscribed: true,
|
||||
assignees: [],
|
||||
assignees,
|
||||
project_id: this.selectedProject.id,
|
||||
});
|
||||
|
||||
|
@ -92,29 +93,29 @@ export default {
|
|||
|
||||
<template>
|
||||
<div class="board-new-issue-form">
|
||||
<div class="card">
|
||||
<div class="board-card">
|
||||
<form @submit="submit($event)">
|
||||
<div
|
||||
class="flash-container"
|
||||
v-if="error"
|
||||
class="flash-container"
|
||||
>
|
||||
<div class="flash-alert">
|
||||
An error occurred. Please try again.
|
||||
</div>
|
||||
</div>
|
||||
<label
|
||||
class="label-light"
|
||||
:for="list.id + '-title'"
|
||||
class="label-light"
|
||||
>
|
||||
Title
|
||||
</label>
|
||||
<input
|
||||
ref="input"
|
||||
v-model="title"
|
||||
:id="list.id + '-title'"
|
||||
class="form-control"
|
||||
type="text"
|
||||
v-model="title"
|
||||
ref="input"
|
||||
autocomplete="off"
|
||||
:id="list.id + '-title'"
|
||||
/>
|
||||
<project-select
|
||||
v-if="groupId"
|
||||
|
@ -122,15 +123,15 @@ export default {
|
|||
/>
|
||||
<div class="clearfix prepend-top-10">
|
||||
<button
|
||||
class="btn btn-success pull-left"
|
||||
type="submit"
|
||||
:disabled="disabled"
|
||||
ref="submit-button"
|
||||
:disabled="disabled"
|
||||
class="btn btn-success float-left"
|
||||
type="submit"
|
||||
>
|
||||
Submit issue
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-default pull-right"
|
||||
class="btn btn-default float-right"
|
||||
type="button"
|
||||
@click="cancel"
|
||||
>
|
||||
|
@ -141,4 +142,3 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable comma-dangle, space-before-function-paren, no-new */
|
||||
/* eslint-disable comma-dangle, no-new */
|
||||
|
||||
import $ from 'jquery';
|
||||
import Vue from 'vue';
|
||||
|
@ -6,13 +6,13 @@ import Flash from '../../flash';
|
|||
import { __ } from '../../locale';
|
||||
import Sidebar from '../../right_sidebar';
|
||||
import eventHub from '../../sidebar/event_hub';
|
||||
import assigneeTitle from '../../sidebar/components/assignees/assignee_title.vue';
|
||||
import assignees from '../../sidebar/components/assignees/assignees.vue';
|
||||
import AssigneeTitle from '../../sidebar/components/assignees/assignee_title.vue';
|
||||
import Assignees from '../../sidebar/components/assignees/assignees.vue';
|
||||
import DueDateSelectors from '../../due_date_select';
|
||||
import './sidebar/remove_issue';
|
||||
import RemoveBtn from './sidebar/remove_issue.vue';
|
||||
import IssuableContext from '../../issuable_context';
|
||||
import LabelsSelect from '../../labels_select';
|
||||
import subscriptions from '../../sidebar/components/subscriptions/subscriptions.vue';
|
||||
import Subscriptions from '../../sidebar/components/subscriptions/subscriptions.vue';
|
||||
import MilestoneSelect from '../../milestone_select';
|
||||
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
|
@ -21,8 +21,17 @@ window.gl = window.gl || {};
|
|||
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||
|
||||
gl.issueBoards.BoardSidebar = Vue.extend({
|
||||
components: {
|
||||
AssigneeTitle,
|
||||
Assignees,
|
||||
RemoveBtn,
|
||||
Subscriptions,
|
||||
},
|
||||
props: {
|
||||
currentUser: Object
|
||||
currentUser: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -64,6 +73,26 @@ gl.issueBoards.BoardSidebar = Vue.extend({
|
|||
deep: true
|
||||
},
|
||||
},
|
||||
created () {
|
||||
// Get events from glDropdown
|
||||
eventHub.$on('sidebar.removeAssignee', this.removeAssignee);
|
||||
eventHub.$on('sidebar.addAssignee', this.addAssignee);
|
||||
eventHub.$on('sidebar.removeAllAssignees', this.removeAllAssignees);
|
||||
eventHub.$on('sidebar.saveAssignees', this.saveAssignees);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('sidebar.removeAssignee', this.removeAssignee);
|
||||
eventHub.$off('sidebar.addAssignee', this.addAssignee);
|
||||
eventHub.$off('sidebar.removeAllAssignees', this.removeAllAssignees);
|
||||
eventHub.$off('sidebar.saveAssignees', this.saveAssignees);
|
||||
},
|
||||
mounted () {
|
||||
new IssuableContext(this.currentUser);
|
||||
new MilestoneSelect();
|
||||
new DueDateSelectors();
|
||||
new LabelsSelect();
|
||||
new Sidebar();
|
||||
},
|
||||
methods: {
|
||||
closeSidebar () {
|
||||
this.detail.issue = {};
|
||||
|
@ -97,30 +126,4 @@ gl.issueBoards.BoardSidebar = Vue.extend({
|
|||
});
|
||||
},
|
||||
},
|
||||
created () {
|
||||
// Get events from glDropdown
|
||||
eventHub.$on('sidebar.removeAssignee', this.removeAssignee);
|
||||
eventHub.$on('sidebar.addAssignee', this.addAssignee);
|
||||
eventHub.$on('sidebar.removeAllAssignees', this.removeAllAssignees);
|
||||
eventHub.$on('sidebar.saveAssignees', this.saveAssignees);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('sidebar.removeAssignee', this.removeAssignee);
|
||||
eventHub.$off('sidebar.addAssignee', this.addAssignee);
|
||||
eventHub.$off('sidebar.removeAllAssignees', this.removeAllAssignees);
|
||||
eventHub.$off('sidebar.saveAssignees', this.saveAssignees);
|
||||
},
|
||||
mounted () {
|
||||
new IssuableContext(this.currentUser);
|
||||
new MilestoneSelect();
|
||||
new DueDateSelectors();
|
||||
new LabelsSelect();
|
||||
new Sidebar();
|
||||
},
|
||||
components: {
|
||||
assigneeTitle,
|
||||
assignees,
|
||||
removeBtn: gl.issueBoards.RemoveIssueBtn,
|
||||
subscriptions,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
import $ from 'jquery';
|
||||
import Vue from 'vue';
|
||||
import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import eventHub from '../eventhub';
|
||||
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
|
||||
window.gl = window.gl || {};
|
||||
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||
|
||||
gl.issueBoards.IssueCardInner = Vue.extend({
|
||||
props: {
|
||||
issue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
list: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
updateFilters: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
groupId: {
|
||||
type: Number,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
limitBeforeCounter: 3,
|
||||
maxRender: 4,
|
||||
maxCounter: 99,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
UserAvatarLink,
|
||||
},
|
||||
computed: {
|
||||
numberOverLimit() {
|
||||
return this.issue.assignees.length - this.limitBeforeCounter;
|
||||
},
|
||||
assigneeCounterTooltip() {
|
||||
return `${this.assigneeCounterLabel} more`;
|
||||
},
|
||||
assigneeCounterLabel() {
|
||||
if (this.numberOverLimit > this.maxCounter) {
|
||||
return `${this.maxCounter}+`;
|
||||
}
|
||||
|
||||
return `+${this.numberOverLimit}`;
|
||||
},
|
||||
shouldRenderCounter() {
|
||||
if (this.issue.assignees.length <= this.maxRender) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.issue.assignees.length > this.numberOverLimit;
|
||||
},
|
||||
issueId() {
|
||||
if (this.issue.iid) {
|
||||
return `#${this.issue.iid}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
showLabelFooter() {
|
||||
return this.issue.labels.find(l => this.showLabel(l)) !== undefined;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isIndexLessThanlimit(index) {
|
||||
return index < this.limitBeforeCounter;
|
||||
},
|
||||
shouldRenderAssignee(index) {
|
||||
// Eg. maxRender is 4,
|
||||
// Render up to all 4 assignees if there are only 4 assigness
|
||||
// Otherwise render up to the limitBeforeCounter
|
||||
if (this.issue.assignees.length <= this.maxRender) {
|
||||
return index < this.maxRender;
|
||||
}
|
||||
|
||||
return index < this.limitBeforeCounter;
|
||||
},
|
||||
assigneeUrl(assignee) {
|
||||
return `${this.rootPath}${assignee.username}`;
|
||||
},
|
||||
assigneeUrlTitle(assignee) {
|
||||
return `Assigned to ${assignee.name}`;
|
||||
},
|
||||
avatarUrlTitle(assignee) {
|
||||
return `Avatar for ${assignee.name}`;
|
||||
},
|
||||
showLabel(label) {
|
||||
if (!label.id) return false;
|
||||
return true;
|
||||
},
|
||||
filterByLabel(label, e) {
|
||||
if (!this.updateFilters) return;
|
||||
|
||||
const filterPath = gl.issueBoards.BoardsStore.filter.path.split('&');
|
||||
const labelTitle = encodeURIComponent(label.title);
|
||||
const param = `label_name[]=${labelTitle}`;
|
||||
const labelIndex = filterPath.indexOf(param);
|
||||
$(e.currentTarget).tooltip('hide');
|
||||
|
||||
if (labelIndex === -1) {
|
||||
filterPath.push(param);
|
||||
} else {
|
||||
filterPath.splice(labelIndex, 1);
|
||||
}
|
||||
|
||||
gl.issueBoards.BoardsStore.filter.path = filterPath.join('&');
|
||||
|
||||
Store.updateFiltersUrl();
|
||||
|
||||
eventHub.$emit('updateTokens');
|
||||
},
|
||||
labelStyle(label) {
|
||||
return {
|
||||
backgroundColor: label.color,
|
||||
color: label.textColor,
|
||||
};
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">
|
||||
<i
|
||||
class="fa fa-eye-slash confidential-icon"
|
||||
v-if="issue.confidential"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<a
|
||||
class="js-no-trigger"
|
||||
:href="issue.path"
|
||||
:title="issue.title">{{ issue.title }}</a>
|
||||
<span
|
||||
class="card-number"
|
||||
v-if="issueId"
|
||||
>
|
||||
{{ issue.referencePath }}
|
||||
</span>
|
||||
</h4>
|
||||
<div class="card-assignee">
|
||||
<user-avatar-link
|
||||
v-for="(assignee, index) in issue.assignees"
|
||||
:key="assignee.id"
|
||||
v-if="shouldRenderAssignee(index)"
|
||||
class="js-no-trigger"
|
||||
:link-href="assigneeUrl(assignee)"
|
||||
:img-alt="avatarUrlTitle(assignee)"
|
||||
:img-src="assignee.avatar"
|
||||
:tooltip-text="assigneeUrlTitle(assignee)"
|
||||
tooltip-placement="bottom"
|
||||
/>
|
||||
<span
|
||||
class="avatar-counter has-tooltip"
|
||||
:title="assigneeCounterTooltip"
|
||||
v-if="shouldRenderCounter"
|
||||
>
|
||||
{{ assigneeCounterLabel }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="card-footer"
|
||||
v-if="showLabelFooter"
|
||||
>
|
||||
<button
|
||||
class="label color-label has-tooltip"
|
||||
v-for="label in issue.labels"
|
||||
type="button"
|
||||
v-if="showLabel(label)"
|
||||
@click="filterByLabel(label, $event)"
|
||||
:style="labelStyle(label)"
|
||||
:title="label.description"
|
||||
data-container="body">
|
||||
{{ label.title }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
});
|
202
app/assets/javascripts/boards/components/issue_card_inner.vue
Normal file
|
@ -0,0 +1,202 @@
|
|||
<script>
|
||||
import $ from 'jquery';
|
||||
import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import eventHub from '../eventhub';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserAvatarLink,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
props: {
|
||||
issue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
list: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
updateFilters: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
groupId: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
limitBeforeCounter: 3,
|
||||
maxRender: 4,
|
||||
maxCounter: 99,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
numberOverLimit() {
|
||||
return this.issue.assignees.length - this.limitBeforeCounter;
|
||||
},
|
||||
assigneeCounterTooltip() {
|
||||
return `${this.assigneeCounterLabel} more`;
|
||||
},
|
||||
assigneeCounterLabel() {
|
||||
if (this.numberOverLimit > this.maxCounter) {
|
||||
return `${this.maxCounter}+`;
|
||||
}
|
||||
|
||||
return `+${this.numberOverLimit}`;
|
||||
},
|
||||
shouldRenderCounter() {
|
||||
if (this.issue.assignees.length <= this.maxRender) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.issue.assignees.length > this.numberOverLimit;
|
||||
},
|
||||
issueId() {
|
||||
if (this.issue.iid) {
|
||||
return `#${this.issue.iid}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
showLabelFooter() {
|
||||
return this.issue.labels.find(l => this.showLabel(l)) !== undefined;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isIndexLessThanlimit(index) {
|
||||
return index < this.limitBeforeCounter;
|
||||
},
|
||||
shouldRenderAssignee(index) {
|
||||
// Eg. maxRender is 4,
|
||||
// Render up to all 4 assignees if there are only 4 assigness
|
||||
// Otherwise render up to the limitBeforeCounter
|
||||
if (this.issue.assignees.length <= this.maxRender) {
|
||||
return index < this.maxRender;
|
||||
}
|
||||
|
||||
return index < this.limitBeforeCounter;
|
||||
},
|
||||
assigneeUrl(assignee) {
|
||||
return `${this.rootPath}${assignee.username}`;
|
||||
},
|
||||
assigneeUrlTitle(assignee) {
|
||||
return `Assigned to ${assignee.name}`;
|
||||
},
|
||||
avatarUrlTitle(assignee) {
|
||||
return `Avatar for ${assignee.name}`;
|
||||
},
|
||||
showLabel(label) {
|
||||
if (!label.id) return false;
|
||||
return true;
|
||||
},
|
||||
filterByLabel(label, e) {
|
||||
if (!this.updateFilters) return;
|
||||
|
||||
const filterPath = gl.issueBoards.BoardsStore.filter.path.split('&');
|
||||
const labelTitle = encodeURIComponent(label.title);
|
||||
const param = `label_name[]=${labelTitle}`;
|
||||
const labelIndex = filterPath.indexOf(param);
|
||||
$(e.currentTarget).tooltip('hide');
|
||||
|
||||
if (labelIndex === -1) {
|
||||
filterPath.push(param);
|
||||
} else {
|
||||
filterPath.splice(labelIndex, 1);
|
||||
}
|
||||
|
||||
gl.issueBoards.BoardsStore.filter.path = filterPath.join('&');
|
||||
|
||||
Store.updateFiltersUrl();
|
||||
|
||||
eventHub.$emit('updateTokens');
|
||||
},
|
||||
labelStyle(label) {
|
||||
return {
|
||||
backgroundColor: label.color,
|
||||
color: label.textColor,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="board-card-header">
|
||||
<h4 class="board-card-title">
|
||||
<i
|
||||
v-if="issue.confidential"
|
||||
class="fa fa-eye-slash confidential-icon"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<a
|
||||
:href="issue.path"
|
||||
:title="issue.title"
|
||||
class="js-no-trigger">{{ issue.title }}</a>
|
||||
<span
|
||||
v-if="issueId"
|
||||
class="board-card-number"
|
||||
>
|
||||
{{ issue.referencePath }}
|
||||
</span>
|
||||
</h4>
|
||||
<div class="board-card-assignee">
|
||||
<user-avatar-link
|
||||
v-for="(assignee, index) in issue.assignees"
|
||||
v-if="shouldRenderAssignee(index)"
|
||||
:key="assignee.id"
|
||||
:link-href="assigneeUrl(assignee)"
|
||||
:img-alt="avatarUrlTitle(assignee)"
|
||||
:img-src="assignee.avatar"
|
||||
:tooltip-text="assigneeUrlTitle(assignee)"
|
||||
class="js-no-trigger"
|
||||
tooltip-placement="bottom"
|
||||
/>
|
||||
<span
|
||||
v-tooltip
|
||||
v-if="shouldRenderCounter"
|
||||
:title="assigneeCounterTooltip"
|
||||
class="avatar-counter"
|
||||
>
|
||||
{{ assigneeCounterLabel }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="showLabelFooter"
|
||||
class="board-card-footer"
|
||||
>
|
||||
<button
|
||||
v-tooltip
|
||||
v-for="label in issue.labels"
|
||||
v-if="showLabel(label)"
|
||||
:key="label.id"
|
||||
:style="labelStyle(label)"
|
||||
:title="label.description"
|
||||
class="badge color-label"
|
||||
type="button"
|
||||
data-container="body"
|
||||
@click="filterByLabel(label, $event)"
|
||||
>
|
||||
{{ label.title }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,12 +1,9 @@
|
|||
import Vue from 'vue';
|
||||
<script>
|
||||
import ModalStore from '../../stores/modal_store';
|
||||
import modalMixin from '../../mixins/modal_mixins';
|
||||
|
||||
gl.issueBoards.ModalEmptyState = Vue.extend({
|
||||
export default {
|
||||
mixins: [modalMixin],
|
||||
data() {
|
||||
return ModalStore.store;
|
||||
},
|
||||
props: {
|
||||
newIssuePath: {
|
||||
type: String,
|
||||
|
@ -17,6 +14,9 @@ gl.issueBoards.ModalEmptyState = Vue.extend({
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return ModalStore.store;
|
||||
},
|
||||
computed: {
|
||||
contents() {
|
||||
const obj = {
|
||||
|
@ -38,32 +38,36 @@ gl.issueBoards.ModalEmptyState = Vue.extend({
|
|||
return obj;
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<section class="empty-state">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6 col-sm-push-6">
|
||||
<aside class="svg-content"><img :src="emptyStateSvg"/></aside>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-sm-pull-6">
|
||||
<div class="text-content">
|
||||
<h4>{{ contents.title }}</h4>
|
||||
<p v-html="contents.content"></p>
|
||||
<a
|
||||
:href="newIssuePath"
|
||||
class="btn btn-success btn-inverted"
|
||||
v-if="activeTab === 'all'">
|
||||
New issue
|
||||
</a>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
@click="changeTab('all')"
|
||||
v-if="activeTab === 'selected'">
|
||||
Open issues
|
||||
</button>
|
||||
</div>
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="empty-state">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 order-md-last">
|
||||
<aside class="svg-content"><img :src="emptyStateSvg"/></aside>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 order-md-first">
|
||||
<div class="text-content">
|
||||
<h4>{{ contents.title }}</h4>
|
||||
<p v-html="contents.content"></p>
|
||||
<a
|
||||
v-if="activeTab === 'all'"
|
||||
:href="newIssuePath"
|
||||
class="btn btn-success btn-inverted"
|
||||
>
|
||||
New issue
|
||||
</a>
|
||||
<button
|
||||
v-if="activeTab === 'selected'"
|
||||
class="btn btn-default"
|
||||
type="button"
|
||||
@click="changeTab('all')"
|
||||
>
|
||||
Open issues
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
`,
|
||||
});
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
|
@ -1,12 +1,15 @@
|
|||
import Vue from 'vue';
|
||||
<script>
|
||||
import Flash from '../../../flash';
|
||||
import { __ } from '../../../locale';
|
||||
import './lists_dropdown';
|
||||
import ListsDropdown from './lists_dropdown.vue';
|
||||
import { pluralize } from '../../../lib/utils/text_utility';
|
||||
import ModalStore from '../../stores/modal_store';
|
||||
import modalMixin from '../../mixins/modal_mixins';
|
||||
|
||||
gl.issueBoards.ModalFooter = Vue.extend({
|
||||
export default {
|
||||
components: {
|
||||
ListsDropdown,
|
||||
},
|
||||
mixins: [modalMixin],
|
||||
data() {
|
||||
return {
|
||||
|
@ -25,23 +28,29 @@ gl.issueBoards.ModalFooter = Vue.extend({
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
buildUpdateRequest(list) {
|
||||
return {
|
||||
add_label_ids: [list.label.id],
|
||||
};
|
||||
},
|
||||
addIssues() {
|
||||
const firstListIndex = 1;
|
||||
const list = this.modal.selectedList || this.state.lists[firstListIndex];
|
||||
const selectedIssues = ModalStore.getSelectedIssues();
|
||||
const issueIds = selectedIssues.map(issue => issue.id);
|
||||
const req = this.buildUpdateRequest(list);
|
||||
|
||||
// Post the data to the backend
|
||||
gl.boardService.bulkUpdate(issueIds, {
|
||||
add_label_ids: [list.label.id],
|
||||
}).catch(() => {
|
||||
Flash(__('Failed to update issues, please try again.'));
|
||||
gl.boardService
|
||||
.bulkUpdate(issueIds, req)
|
||||
.catch(() => {
|
||||
Flash(__('Failed to update issues, please try again.'));
|
||||
|
||||
selectedIssues.forEach((issue) => {
|
||||
list.removeIssue(issue);
|
||||
list.issuesSize -= 1;
|
||||
selectedIssues.forEach((issue) => {
|
||||
list.removeIssue(issue);
|
||||
list.issuesSize -= 1;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Add the issues on the frontend
|
||||
selectedIssues.forEach((issue) => {
|
||||
|
@ -52,31 +61,32 @@ gl.issueBoards.ModalFooter = Vue.extend({
|
|||
this.toggleModal(false);
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'lists-dropdown': gl.issueBoards.ModalFooterListsDropdown,
|
||||
},
|
||||
template: `
|
||||
<footer
|
||||
class="form-actions add-issues-footer">
|
||||
<div class="pull-left">
|
||||
<button
|
||||
class="btn btn-success"
|
||||
type="button"
|
||||
:disabled="submitDisabled"
|
||||
@click="addIssues">
|
||||
{{ submitText }}
|
||||
</button>
|
||||
<span class="inline add-issues-footer-to-list">
|
||||
to list
|
||||
</span>
|
||||
<lists-dropdown></lists-dropdown>
|
||||
</div>
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<footer
|
||||
class="form-actions add-issues-footer"
|
||||
>
|
||||
<div class="float-left">
|
||||
<button
|
||||
class="btn btn-default pull-right"
|
||||
:disabled="submitDisabled"
|
||||
class="btn btn-success"
|
||||
type="button"
|
||||
@click="toggleModal(false)">
|
||||
Cancel
|
||||
@click="addIssues"
|
||||
>
|
||||
{{ submitText }}
|
||||
</button>
|
||||
</footer>
|
||||
`,
|
||||
});
|
||||
<span class="inline add-issues-footer-to-list">
|
||||
to list
|
||||
</span>
|
||||
<lists-dropdown/>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-default float-right"
|
||||
type="button"
|
||||
@click="toggleModal(false)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</footer>
|
||||
</template>
|
|
@ -1,79 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import modalFilters from './filters';
|
||||
import './tabs';
|
||||
import ModalStore from '../../stores/modal_store';
|
||||
import modalMixin from '../../mixins/modal_mixins';
|
||||
|
||||
gl.issueBoards.ModalHeader = Vue.extend({
|
||||
mixins: [modalMixin],
|
||||
props: {
|
||||
projectId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
milestonePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
labelPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return ModalStore.store;
|
||||
},
|
||||
computed: {
|
||||
selectAllText() {
|
||||
if (ModalStore.selectedCount() !== this.issues.length || this.issues.length === 0) {
|
||||
return 'Select all';
|
||||
}
|
||||
|
||||
return 'Deselect all';
|
||||
},
|
||||
showSearch() {
|
||||
return this.activeTab === 'all' && !this.loading && this.issuesCount > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleAll() {
|
||||
this.$refs.selectAllBtn.blur();
|
||||
|
||||
ModalStore.toggleAll();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'modal-tabs': gl.issueBoards.ModalTabs,
|
||||
modalFilters,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<header class="add-issues-header form-actions">
|
||||
<h2>
|
||||
Add issues
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
@click="toggleModal(false)">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</h2>
|
||||
</header>
|
||||
<modal-tabs v-if="!loading && issuesCount > 0"></modal-tabs>
|
||||
<div
|
||||
class="add-issues-search append-bottom-10"
|
||||
v-if="showSearch">
|
||||
<modal-filters :store="filter" />
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-inverted prepend-left-10"
|
||||
ref="selectAllBtn"
|
||||
@click="toggleAll">
|
||||
{{ selectAllText }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
});
|
82
app/assets/javascripts/boards/components/modal/header.vue
Normal file
|
@ -0,0 +1,82 @@
|
|||
<script>
|
||||
import ModalFilters from './filters';
|
||||
import ModalTabs from './tabs.vue';
|
||||
import ModalStore from '../../stores/modal_store';
|
||||
import modalMixin from '../../mixins/modal_mixins';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalTabs,
|
||||
ModalFilters,
|
||||
},
|
||||
mixins: [modalMixin],
|
||||
props: {
|
||||
projectId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
milestonePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
labelPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return ModalStore.store;
|
||||
},
|
||||
computed: {
|
||||
selectAllText() {
|
||||
if (ModalStore.selectedCount() !== this.issues.length || this.issues.length === 0) {
|
||||
return 'Select all';
|
||||
}
|
||||
|
||||
return 'Deselect all';
|
||||
},
|
||||
showSearch() {
|
||||
return this.activeTab === 'all' && !this.loading && this.issuesCount > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleAll() {
|
||||
this.$refs.selectAllBtn.blur();
|
||||
|
||||
ModalStore.toggleAll();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<header class="add-issues-header form-actions">
|
||||
<h2>
|
||||
Add issues
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
@click="toggleModal(false)"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</h2>
|
||||
</header>
|
||||
<modal-tabs v-if="!loading && issuesCount > 0"/>
|
||||
<div
|
||||
v-if="showSearch"
|
||||
class="add-issues-search append-bottom-10">
|
||||
<modal-filters :store="filter" />
|
||||
<button
|
||||
ref="selectAllBtn"
|
||||
type="button"
|
||||
class="btn btn-success btn-inverted prepend-left-10"
|
||||
@click="toggleAll"
|
||||
>
|
||||
{{ selectAllText }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,171 +0,0 @@
|
|||
/* global ListIssue */
|
||||
|
||||
import Vue from 'vue';
|
||||
import queryData from '~/boards/utils/query_data';
|
||||
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
|
||||
import './header';
|
||||
import './list';
|
||||
import './footer';
|
||||
import './empty_state';
|
||||
import ModalStore from '../../stores/modal_store';
|
||||
|
||||
gl.issueBoards.IssuesModal = Vue.extend({
|
||||
props: {
|
||||
newIssuePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
emptyStateSvg: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
issueLinkBase: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
rootPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
milestonePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
labelPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return ModalStore.store;
|
||||
},
|
||||
watch: {
|
||||
page() {
|
||||
this.loadIssues();
|
||||
},
|
||||
showAddIssuesModal() {
|
||||
if (this.showAddIssuesModal && !this.issues.length) {
|
||||
this.loading = true;
|
||||
const loadingDone = () => {
|
||||
this.loading = false;
|
||||
};
|
||||
|
||||
this.loadIssues()
|
||||
.then(loadingDone)
|
||||
.catch(loadingDone);
|
||||
} else if (!this.showAddIssuesModal) {
|
||||
this.issues = [];
|
||||
this.selectedIssues = [];
|
||||
this.issuesCount = false;
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
handler() {
|
||||
if (this.$el.tagName) {
|
||||
this.page = 1;
|
||||
this.filterLoading = true;
|
||||
const loadingDone = () => {
|
||||
this.filterLoading = false;
|
||||
};
|
||||
|
||||
this.loadIssues(true)
|
||||
.then(loadingDone)
|
||||
.catch(loadingDone);
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadIssues(clearIssues = false) {
|
||||
if (!this.showAddIssuesModal) return false;
|
||||
|
||||
return gl.boardService.getBacklog(queryData(this.filter.path, {
|
||||
page: this.page,
|
||||
per: this.perPage,
|
||||
}))
|
||||
.then(res => res.data)
|
||||
.then((data) => {
|
||||
if (clearIssues) {
|
||||
this.issues = [];
|
||||
}
|
||||
|
||||
data.issues.forEach((issueObj) => {
|
||||
const issue = new ListIssue(issueObj);
|
||||
const foundSelectedIssue = ModalStore.findSelectedIssue(issue);
|
||||
issue.selected = !!foundSelectedIssue;
|
||||
|
||||
this.issues.push(issue);
|
||||
});
|
||||
|
||||
this.loadingNewPage = false;
|
||||
|
||||
if (!this.issuesCount) {
|
||||
this.issuesCount = data.size;
|
||||
}
|
||||
}).catch(() => {
|
||||
// TODO: handle request error
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showList() {
|
||||
if (this.activeTab === 'selected') {
|
||||
return this.selectedIssues.length > 0;
|
||||
}
|
||||
|
||||
return this.issuesCount > 0;
|
||||
},
|
||||
showEmptyState() {
|
||||
if (!this.loading && this.issuesCount === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.activeTab === 'selected' && this.selectedIssues.length === 0;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.page = 1;
|
||||
},
|
||||
components: {
|
||||
'modal-header': gl.issueBoards.ModalHeader,
|
||||
'modal-list': gl.issueBoards.ModalList,
|
||||
'modal-footer': gl.issueBoards.ModalFooter,
|
||||
'empty-state': gl.issueBoards.ModalEmptyState,
|
||||
loadingIcon,
|
||||
},
|
||||
template: `
|
||||
<div
|
||||
class="add-issues-modal"
|
||||
v-if="showAddIssuesModal">
|
||||
<div class="add-issues-container">
|
||||
<modal-header
|
||||
:project-id="projectId"
|
||||
:milestone-path="milestonePath"
|
||||
:label-path="labelPath">
|
||||
</modal-header>
|
||||
<modal-list
|
||||
:issue-link-base="issueLinkBase"
|
||||
:root-path="rootPath"
|
||||
:empty-state-svg="emptyStateSvg"
|
||||
v-if="!loading && showList && !filterLoading"></modal-list>
|
||||
<empty-state
|
||||
v-if="showEmptyState"
|
||||
:new-issue-path="newIssuePath"
|
||||
:empty-state-svg="emptyStateSvg"></empty-state>
|
||||
<section
|
||||
class="add-issues-list text-center"
|
||||
v-if="loading || filterLoading">
|
||||
<div class="add-issues-list-loading">
|
||||
<loading-icon />
|
||||
</div>
|
||||
</section>
|
||||
<modal-footer></modal-footer>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
});
|