New upstream version 12.4.6
This commit is contained in:
parent
317968c865
commit
3a6a82fa42
5378 changed files with 256257 additions and 50675 deletions
|
@ -6,6 +6,7 @@
|
||||||
# - ./config/initializers/0_inject_enterprise_edition_module.rb
|
# - ./config/initializers/0_inject_enterprise_edition_module.rb
|
||||||
# - ./ee/app/models/license.rb
|
# - ./ee/app/models/license.rb
|
||||||
# - ./lib/gitlab.rb
|
# - ./lib/gitlab.rb
|
||||||
|
# - ./lib/gitlab/utils.rb
|
||||||
# - ./qa/
|
# - ./qa/
|
||||||
# - ./INSTALLATION_TYPE
|
# - ./INSTALLATION_TYPE
|
||||||
# - ./VERSION
|
# - ./VERSION
|
||||||
|
@ -49,7 +50,6 @@
|
||||||
/lib/flowdock/
|
/lib/flowdock/
|
||||||
/lib/generators/
|
/lib/generators/
|
||||||
/lib/gitaly/
|
/lib/gitaly/
|
||||||
/lib/gitlab/
|
|
||||||
/lib/api/
|
/lib/api/
|
||||||
/lib/token/
|
/lib/token/
|
||||||
/lib/mattermost/
|
/lib/mattermost/
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
extends:
|
extends:
|
||||||
- '@gitlab'
|
- '@gitlab'
|
||||||
|
- plugin:promise/recommended
|
||||||
globals:
|
globals:
|
||||||
__webpack_public_path__: true
|
__webpack_public_path__: true
|
||||||
gl: false
|
gl: false
|
||||||
|
@ -10,6 +11,7 @@ plugins:
|
||||||
- import
|
- import
|
||||||
- "@gitlab/i18n"
|
- "@gitlab/i18n"
|
||||||
- "@gitlab/vue-i18n"
|
- "@gitlab/vue-i18n"
|
||||||
|
- no-jquery
|
||||||
settings:
|
settings:
|
||||||
import/resolver:
|
import/resolver:
|
||||||
webpack:
|
webpack:
|
||||||
|
@ -36,6 +38,13 @@ rules:
|
||||||
vue/no-use-v-if-with-v-for: off
|
vue/no-use-v-if-with-v-for: off
|
||||||
vue/no-v-html: off
|
vue/no-v-html: off
|
||||||
vue/use-v-on-exact: off
|
vue/use-v-on-exact: off
|
||||||
|
no-jquery/no-ajax: error
|
||||||
|
no-jquery/no-ajax-events: error
|
||||||
|
no-jquery/no-load: error
|
||||||
|
no-jquery/no-load-shorthand: error
|
||||||
|
no-jquery/no-serialize: error
|
||||||
|
promise/always-return: off
|
||||||
|
promise/no-callback-in-promise: off
|
||||||
overrides:
|
overrides:
|
||||||
files:
|
files:
|
||||||
- '**/spec/**/*'
|
- '**/spec/**/*'
|
||||||
|
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1,3 +1,2 @@
|
||||||
VERSION merge=ours
|
VERSION merge=ours
|
||||||
Dangerfile gitlab-language=ruby
|
Dangerfile gitlab-language=ruby
|
||||||
db/schema.rb merge=merge_db_schema
|
|
||||||
|
|
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,3 +1,3 @@
|
||||||
We’re closing our issue tracker on GitHub so we can focus on the GitLab.com project and respond to issues more quickly.
|
We’re closing our issue tracker on GitHub so we can focus on the GitLab.com project and respond to issues more quickly.
|
||||||
|
|
||||||
We encourage you to open an issue on the [GitLab.com issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues). You can log into GitLab.com using your GitHub account.
|
We encourage you to open an issue on the [GitLab.com issue tracker](https://gitlab.com/gitlab-org/gitlab/issues). You can log into GitLab.com using your GitHub account.
|
||||||
|
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,3 +1,3 @@
|
||||||
Thank you for taking the time to contribute back to GitLab!
|
Thank you for taking the time to contribute back to GitLab!
|
||||||
|
|
||||||
Please open a merge request [on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests), we look forward to reviewing your contribution! You can log into GitLab.com using your GitHub account.
|
Please open a merge request [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/merge_requests), we look forward to reviewing your contribution! You can log into GitLab.com using your GitHub account.
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -81,3 +81,4 @@ package-lock.json
|
||||||
jsdoc/
|
jsdoc/
|
||||||
**/tmp/rubocop_cache/**
|
**/tmp/rubocop_cache/**
|
||||||
.overcommit.yml
|
.overcommit.yml
|
||||||
|
.projections.json
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33"
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- prepare
|
- prepare
|
||||||
|
@ -8,17 +8,17 @@ stages:
|
||||||
- review
|
- review
|
||||||
- qa
|
- qa
|
||||||
- post-test
|
- post-test
|
||||||
|
- notification
|
||||||
- pages
|
- pages
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
RAILS_ENV: "test"
|
RAILS_ENV: "test"
|
||||||
NODE_ENV: "test"
|
NODE_ENV: "test"
|
||||||
SIMPLECOV: "true"
|
SIMPLECOV: "true"
|
||||||
GIT_DEPTH: "20"
|
GIT_DEPTH: "50"
|
||||||
GIT_SUBMODULE_STRATEGY: "none"
|
GIT_SUBMODULE_STRATEGY: "none"
|
||||||
GET_SOURCES_ATTEMPTS: "3"
|
GET_SOURCES_ATTEMPTS: "3"
|
||||||
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
|
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/report-master.json
|
||||||
EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master-ee.json
|
|
||||||
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
|
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
|
||||||
BUILD_ASSETS_IMAGE: "false"
|
BUILD_ASSETS_IMAGE: "false"
|
||||||
ES_JAVA_OPTS: "-Xms256m -Xmx256m"
|
ES_JAVA_OPTS: "-Xms256m -Xmx256m"
|
||||||
|
@ -28,11 +28,12 @@ after_script:
|
||||||
- date
|
- date
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- local: .gitlab/ci/global.gitlab-ci.yml
|
|
||||||
- local: .gitlab/ci/cng.gitlab-ci.yml
|
- local: .gitlab/ci/cng.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/docs.gitlab-ci.yml
|
- local: .gitlab/ci/docs.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/frontend.gitlab-ci.yml
|
- local: .gitlab/ci/frontend.gitlab-ci.yml
|
||||||
|
- local: .gitlab/ci/global.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/memory.gitlab-ci.yml
|
- local: .gitlab/ci/memory.gitlab-ci.yml
|
||||||
|
- local: .gitlab/ci/notifications.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/pages.gitlab-ci.yml
|
- local: .gitlab/ci/pages.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/qa.gitlab-ci.yml
|
- local: .gitlab/ci/qa.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/reports.gitlab-ci.yml
|
- local: .gitlab/ci/reports.gitlab-ci.yml
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
/doc/ @axil @marcia @eread @mikelewis
|
/doc/ @axil @marcia @eread @mikelewis
|
||||||
|
|
||||||
# Frontend maintainers should see everything in `app/assets/`
|
# Frontend maintainers should see everything in `app/assets/`
|
||||||
app/assets/ @ClemMakesApps @fatihacet @filipa @mikegreiling @timzallmann @kushalpandya @pslaughter
|
app/assets/ @ClemMakesApps @fatihacet @filipa @mikegreiling @timzallmann @kushalpandya @pslaughter @wortschi @ntepluhina
|
||||||
*.scss @annabeldunstone @ClemMakesApps @fatihacet @filipa @mikegreiling @timzallmann @kushalpandya @pslaughter
|
*.scss @annabeldunstone @ClemMakesApps @fatihacet @filipa @mikegreiling @timzallmann @kushalpandya @pslaughter @wortschi @ntepluhina
|
||||||
|
|
||||||
# Database maintainers should review changes in `db/`
|
# Database maintainers should review changes in `db/`
|
||||||
db/ @gitlab-org/maintainers/database
|
db/ @gitlab-org/maintainers/database
|
||||||
|
@ -23,6 +23,13 @@ lib/gitlab/github_import/ @gitlab-org/maintainers/database
|
||||||
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
||||||
/lib/gitlab/ci/templates/ @nolith @zj
|
/lib/gitlab/ci/templates/ @nolith @zj
|
||||||
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
|
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
|
||||||
/lib/gitlab/ci/templates/Security/ @plafoucriere @gonzoyumo @twoodham
|
/lib/gitlab/ci/templates/Security/ @plafoucriere @gonzoyumo @twoodham @sethgitlab
|
||||||
/ee/app/models/project_alias.rb @patrickbajao
|
/ee/app/models/project_alias.rb @patrickbajao
|
||||||
/ee/lib/api/project_aliases.rb @patrickbajao
|
/ee/lib/api/project_aliases.rb @patrickbajao
|
||||||
|
|
||||||
|
# Engineering Productivity owned files
|
||||||
|
/.gitlab-ci.yml @gl-quality/eng-prod
|
||||||
|
/.gitlab/ci/ @gl-quality/eng-prod
|
||||||
|
Dangerfile @gl-quality/eng-prod
|
||||||
|
/danger/ @gl-quality/eng-prod
|
||||||
|
/scripts/ @gl-quality/eng-prod
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none
|
GIT_STRATEGY: none
|
||||||
environment:
|
environment:
|
||||||
name: review-docs/$CI_COMMIT_REF_SLUG
|
name: review-docs/$DOCS_GITLAB_REPO_SUFFIX-$CI_MERGE_REQUEST_IID
|
||||||
# DOCS_REVIEW_APPS_DOMAIN and DOCS_GITLAB_REPO_SUFFIX are CI variables
|
# DOCS_REVIEW_APPS_DOMAIN and DOCS_GITLAB_REPO_SUFFIX are CI variables
|
||||||
# Discussion: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/14236/diffs#note_40140693
|
# Discussion: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/14236/diffs#note_40140693
|
||||||
url: http://$CI_ENVIRONMENT_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
|
url: http://docs-preview-$DOCS_GITLAB_REPO_SUFFIX-$CI_MERGE_REQUEST_IID.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
|
||||||
on_stop: review-docs-cleanup
|
on_stop: review-docs-cleanup
|
||||||
before_script:
|
before_script:
|
||||||
# We don't clone the repo by using GIT_STRATEGY: none and only download the
|
# We don't clone the repo by using GIT_STRATEGY: none and only download the
|
||||||
|
@ -39,7 +39,7 @@ review-docs-deploy:
|
||||||
review-docs-cleanup:
|
review-docs-cleanup:
|
||||||
extends: .review-docs
|
extends: .review-docs
|
||||||
environment:
|
environment:
|
||||||
name: review-docs/$CI_COMMIT_REF_SLUG
|
name: review-docs/$DOCS_GITLAB_REPO_SUFFIX-$CI_MERGE_REQUEST_IID
|
||||||
action: stop
|
action: stop
|
||||||
script:
|
script:
|
||||||
- ./trigger-build-docs cleanup
|
- ./trigger-build-docs cleanup
|
||||||
|
@ -67,3 +67,19 @@ docs lint:
|
||||||
- bundle exec nanoc check internal_links
|
- bundle exec nanoc check internal_links
|
||||||
# Check the internal anchor links
|
# Check the internal anchor links
|
||||||
- bundle exec nanoc check internal_anchors
|
- bundle exec nanoc check internal_anchors
|
||||||
|
|
||||||
|
graphql-docs-verify:
|
||||||
|
extends:
|
||||||
|
- .only-ee
|
||||||
|
- .default-tags
|
||||||
|
- .default-retry
|
||||||
|
- .default-cache
|
||||||
|
- .default-only
|
||||||
|
- .default-before_script
|
||||||
|
- .only-graphql-changes
|
||||||
|
variables:
|
||||||
|
SETUP_DB: "false"
|
||||||
|
stage: test
|
||||||
|
needs: ["setup-test-env"]
|
||||||
|
script:
|
||||||
|
- bundle exec rake gitlab:graphql:check_docs
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .assets-compile-cache
|
- .assets-compile-cache
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
image: dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-git-2.22-chrome-73.0-node-12.x-yarn-1.16-graphicsmagick-1.3.33-docker-18.06.1
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-git-2.22-chrome-73.0-node-12.x-yarn-1.16-graphicsmagick-1.3.33-docker-18.06.1
|
||||||
stage: test
|
stage: test
|
||||||
dependencies: ["setup-test-env"]
|
dependencies: ["setup-test-env"]
|
||||||
needs: ["setup-test-env"]
|
needs: ["setup-test-env"]
|
||||||
|
@ -47,13 +47,13 @@
|
||||||
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
|
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
|
||||||
only:
|
only:
|
||||||
variables:
|
variables:
|
||||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ # Matches the gitlab-org group and its subgroups
|
||||||
- $CI_SERVER_HOST == "dev.gitlab.org"
|
- $CI_SERVER_HOST == "dev.gitlab.org"
|
||||||
tags:
|
tags:
|
||||||
- gitlab-org
|
- gitlab-org
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
gitlab:assets:compile:
|
gitlab:assets:compile pull-push-cache:
|
||||||
extends: .gitlab:assets:compile-metadata
|
extends: .gitlab:assets:compile-metadata
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
|
@ -63,9 +63,6 @@ gitlab:assets:compile:
|
||||||
|
|
||||||
gitlab:assets:compile pull-cache:
|
gitlab:assets:compile pull-cache:
|
||||||
extends: .gitlab:assets:compile-metadata
|
extends: .gitlab:assets:compile-metadata
|
||||||
except:
|
|
||||||
refs:
|
|
||||||
- master
|
|
||||||
cache:
|
cache:
|
||||||
policy: pull
|
policy: pull
|
||||||
|
|
||||||
|
@ -77,7 +74,7 @@ gitlab:assets:compile pull-cache:
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .assets-compile-cache
|
- .assets-compile-cache
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
- .use-pg
|
- .use-pg9
|
||||||
stage: prepare
|
stage: prepare
|
||||||
script:
|
script:
|
||||||
- node --version
|
- node --version
|
||||||
|
@ -89,14 +86,14 @@ gitlab:assets:compile pull-cache:
|
||||||
# we override the max_old_space_size to prevent OOM errors
|
# we override the max_old_space_size to prevent OOM errors
|
||||||
NODE_OPTIONS: --max_old_space_size=3584
|
NODE_OPTIONS: --max_old_space_size=3584
|
||||||
cache:
|
cache:
|
||||||
key: "assets-compile:test:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:v6"
|
key: "assets-compile:v7"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
paths:
|
paths:
|
||||||
- node_modules
|
- node_modules
|
||||||
- public/assets
|
- public/assets
|
||||||
|
|
||||||
compile-assets:
|
compile-assets pull-push-cache:
|
||||||
extends: .compile-assets-metadata
|
extends: .compile-assets-metadata
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
|
@ -104,14 +101,26 @@ compile-assets:
|
||||||
cache:
|
cache:
|
||||||
policy: pull-push
|
policy: pull-push
|
||||||
|
|
||||||
compile-assets pull-cache:
|
compile-assets pull-push-cache foss:
|
||||||
extends: .compile-assets-metadata
|
extends: [".compile-assets-metadata", ".only-ee-as-if-foss"]
|
||||||
except:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- master
|
- master
|
||||||
|
cache:
|
||||||
|
policy: pull-push
|
||||||
|
key: "assets-compile:v7:foss"
|
||||||
|
|
||||||
|
compile-assets pull-cache:
|
||||||
|
extends: .compile-assets-metadata
|
||||||
cache:
|
cache:
|
||||||
policy: pull
|
policy: pull
|
||||||
|
|
||||||
|
compile-assets pull-cache foss:
|
||||||
|
extends: [".compile-assets-metadata", ".only-ee-as-if-foss"]
|
||||||
|
cache:
|
||||||
|
policy: pull
|
||||||
|
key: "assets-compile:v7:foss"
|
||||||
|
|
||||||
.only-code-frontend-job-base:
|
.only-code-frontend-job-base:
|
||||||
extends:
|
extends:
|
||||||
- .default-tags
|
- .default-tags
|
||||||
|
@ -120,10 +129,12 @@ compile-assets pull-cache:
|
||||||
- .default-only
|
- .default-only
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .only-code-changes
|
- .only-code-changes
|
||||||
- .use-pg
|
- .use-pg9
|
||||||
dependencies: ["compile-assets", "compile-assets pull-cache", "setup-test-env"]
|
stage: test
|
||||||
|
needs: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
|
dependencies: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
|
|
||||||
karma:
|
.karma-base:
|
||||||
extends: .only-code-frontend-job-base
|
extends: .only-code-frontend-job-base
|
||||||
variables:
|
variables:
|
||||||
# we override the max_old_space_size to prevent OOM errors
|
# we override the max_old_space_size to prevent OOM errors
|
||||||
|
@ -134,6 +145,9 @@ karma:
|
||||||
- scripts/gitaly-test-spawn
|
- scripts/gitaly-test-spawn
|
||||||
- date
|
- date
|
||||||
- bundle exec rake karma
|
- bundle exec rake karma
|
||||||
|
|
||||||
|
karma:
|
||||||
|
extends: .karma-base
|
||||||
coverage: '/^Statements *: (\d+\.\d+%)/'
|
coverage: '/^Statements *: (\d+\.\d+%)/'
|
||||||
artifacts:
|
artifacts:
|
||||||
name: coverage-javascript
|
name: coverage-javascript
|
||||||
|
@ -146,7 +160,12 @@ karma:
|
||||||
reports:
|
reports:
|
||||||
junit: junit_karma.xml
|
junit: junit_karma.xml
|
||||||
|
|
||||||
jest:
|
karma-foss:
|
||||||
|
extends:
|
||||||
|
- .karma-base
|
||||||
|
- .only-ee-as-if-foss
|
||||||
|
|
||||||
|
.jest-base:
|
||||||
extends: .only-code-frontend-job-base
|
extends: .only-code-frontend-job-base
|
||||||
script:
|
script:
|
||||||
- scripts/gitaly-test-spawn
|
- scripts/gitaly-test-spawn
|
||||||
|
@ -154,6 +173,14 @@ jest:
|
||||||
- bundle exec rake frontend:fixtures
|
- bundle exec rake frontend:fixtures
|
||||||
- date
|
- date
|
||||||
- yarn jest --ci --coverage
|
- yarn jest --ci --coverage
|
||||||
|
cache:
|
||||||
|
key: jest
|
||||||
|
paths:
|
||||||
|
- tmp/jest/jest/
|
||||||
|
policy: pull-push
|
||||||
|
|
||||||
|
jest:
|
||||||
|
extends: .jest-base
|
||||||
artifacts:
|
artifacts:
|
||||||
name: coverage-frontend
|
name: coverage-frontend
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
|
@ -164,34 +191,13 @@ jest:
|
||||||
- tmp/tests/frontend/
|
- tmp/tests/frontend/
|
||||||
reports:
|
reports:
|
||||||
junit: junit_jest.xml
|
junit: junit_jest.xml
|
||||||
cache:
|
|
||||||
key: jest
|
|
||||||
paths:
|
|
||||||
- tmp/jest/jest/
|
|
||||||
policy: pull-push
|
|
||||||
|
|
||||||
.qa-job-base:
|
jest-foss:
|
||||||
extends:
|
extends:
|
||||||
- .default-tags
|
- .jest-base
|
||||||
- .default-retry
|
- .only-ee-as-if-foss
|
||||||
- .default-cache
|
cache:
|
||||||
- .default-only
|
policy: pull
|
||||||
- .only-code-qa-changes
|
|
||||||
dependencies: []
|
|
||||||
stage: test
|
|
||||||
before_script:
|
|
||||||
- cd qa/
|
|
||||||
- bundle install
|
|
||||||
|
|
||||||
qa:internal:
|
|
||||||
extends: .qa-job-base
|
|
||||||
script:
|
|
||||||
- bundle exec rspec
|
|
||||||
|
|
||||||
qa:selectors:
|
|
||||||
extends: .qa-job-base
|
|
||||||
script:
|
|
||||||
- bundle exec bin/qa Test::Sanity::Selectors
|
|
||||||
|
|
||||||
.qa-frontend-node:
|
.qa-frontend-node:
|
||||||
extends:
|
extends:
|
||||||
|
@ -200,6 +206,7 @@ qa:selectors:
|
||||||
- .default-cache
|
- .default-cache
|
||||||
- .default-only
|
- .default-only
|
||||||
- .only-code-changes
|
- .only-code-changes
|
||||||
|
stage: test
|
||||||
dependencies: []
|
dependencies: []
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
|
@ -232,7 +239,9 @@ webpack-dev-server:
|
||||||
- .default-cache
|
- .default-cache
|
||||||
- .default-only
|
- .default-only
|
||||||
- .only-code-changes
|
- .only-code-changes
|
||||||
dependencies: ["setup-test-env", "compile-assets", "compile-assets pull-cache"]
|
stage: test
|
||||||
|
needs: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
|
dependencies: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
variables:
|
variables:
|
||||||
WEBPACK_MEMORY_TEST: "true"
|
WEBPACK_MEMORY_TEST: "true"
|
||||||
script:
|
script:
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
.default-before_script:
|
.default-before_script:
|
||||||
before_script:
|
before_script:
|
||||||
- date
|
- date
|
||||||
|
- export GOPATH=$CI_PROJECT_DIR/.go
|
||||||
|
- mkdir -p $GOPATH
|
||||||
- source scripts/utils.sh
|
- source scripts/utils.sh
|
||||||
- source scripts/prepare_build.sh
|
- source scripts/prepare_build.sh
|
||||||
- date
|
- date
|
||||||
|
@ -22,6 +24,7 @@
|
||||||
cache:
|
cache:
|
||||||
key: "debian-stretch-ruby-2.6.3-node-12.x"
|
key: "debian-stretch-ruby-2.6.3-node-12.x"
|
||||||
paths:
|
paths:
|
||||||
|
- .go/pkg/mod
|
||||||
- vendor/ruby
|
- vendor/ruby
|
||||||
- .yarn-cache/
|
- .yarn-cache/
|
||||||
- vendor/gitaly-ruby
|
- vendor/gitaly-ruby
|
||||||
|
@ -33,6 +36,7 @@
|
||||||
- master
|
- master
|
||||||
- /^[\d-]+-stable(-ee)?$/
|
- /^[\d-]+-stable(-ee)?$/
|
||||||
- /^\d+-\d+-auto-deploy-\d+$/
|
- /^\d+-\d+-auto-deploy-\d+$/
|
||||||
|
- /^security\//
|
||||||
- merge_requests
|
- merge_requests
|
||||||
- tags
|
- tags
|
||||||
|
|
||||||
|
@ -51,7 +55,7 @@
|
||||||
- "{babel.config,jest.config}.js"
|
- "{babel.config,jest.config}.js"
|
||||||
- "config.ru"
|
- "config.ru"
|
||||||
- "{package.json,yarn.lock}"
|
- "{package.json,yarn.lock}"
|
||||||
- "{app,bin,config,danger,db,ee,fixtures,haml_lint,lib,public,rubocop,scripts,spec,symbol,vendor}/**/*"
|
- "{app,bin,config,danger,db,ee,fixtures,haml_lint,lib,locale,public,rubocop,scripts,spec,symbol,vendor}/**/*"
|
||||||
- "doc/README.md" # Some RSpec test rely on this file
|
- "doc/README.md" # Some RSpec test rely on this file
|
||||||
|
|
||||||
.only-qa-changes:
|
.only-qa-changes:
|
||||||
|
@ -67,6 +71,12 @@
|
||||||
- "doc/**/*"
|
- "doc/**/*"
|
||||||
- ".markdownlint.json"
|
- ".markdownlint.json"
|
||||||
|
|
||||||
|
.only-graphql-changes:
|
||||||
|
only:
|
||||||
|
changes:
|
||||||
|
- "{,ee/}app/graphql/**/*"
|
||||||
|
- "{,ee/}lib/gitlab/graphql/**/*"
|
||||||
|
|
||||||
.only-code-qa-changes:
|
.only-code-qa-changes:
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
|
@ -82,7 +92,7 @@
|
||||||
- "{babel.config,jest.config}.js"
|
- "{babel.config,jest.config}.js"
|
||||||
- "config.ru"
|
- "config.ru"
|
||||||
- "{package.json,yarn.lock}"
|
- "{package.json,yarn.lock}"
|
||||||
- "{app,bin,config,danger,db,ee,fixtures,haml_lint,lib,public,rubocop,scripts,spec,symbol,vendor}/**/*"
|
- "{app,bin,config,danger,db,ee,fixtures,haml_lint,lib,locale,public,rubocop,scripts,spec,symbol,vendor}/**/*"
|
||||||
- "doc/README.md" # Some RSpec test rely on this file
|
- "doc/README.md" # Some RSpec test rely on this file
|
||||||
- ".dockerignore"
|
- ".dockerignore"
|
||||||
- "qa/**/*"
|
- "qa/**/*"
|
||||||
|
@ -96,30 +106,57 @@
|
||||||
refs:
|
refs:
|
||||||
- master
|
- master
|
||||||
- /^\d+-\d+-auto-deploy-\d+$/
|
- /^\d+-\d+-auto-deploy-\d+$/
|
||||||
|
- /^[\d-]+-stable(-ee)?$/
|
||||||
|
|
||||||
.only-review-schedules:
|
.only-review-schedules:
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- schedules
|
- schedules
|
||||||
variables:
|
variables:
|
||||||
- $REVIEW_APP_CLEANUP && $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
||||||
kubernetes: active
|
kubernetes: active
|
||||||
|
|
||||||
.use-pg:
|
.only-canonical-schedules:
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- schedules@gitlab-org/gitlab
|
||||||
|
- schedules@gitlab-org/gitlab-foss
|
||||||
|
|
||||||
|
.use-pg9:
|
||||||
services:
|
services:
|
||||||
- name: postgres:9.6.14
|
- name: postgres:9.6
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
|
|
||||||
.use-pg-10:
|
.use-pg10:
|
||||||
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
|
||||||
services:
|
services:
|
||||||
- name: postgres:10.9
|
- name: postgres:10.9
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
|
|
||||||
|
.use-pg9-ee:
|
||||||
|
services:
|
||||||
|
- name: postgres:9.6
|
||||||
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
- name: redis:alpine
|
||||||
|
- name: docker.elastic.co/elasticsearch/elasticsearch:5.6.12
|
||||||
|
|
||||||
|
.use-pg10-ee:
|
||||||
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
|
||||||
|
services:
|
||||||
|
- name: postgres:10.9
|
||||||
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
- name: redis:alpine
|
||||||
|
- name: docker.elastic.co/elasticsearch/elasticsearch:5.6.12
|
||||||
|
|
||||||
.only-ee:
|
.only-ee:
|
||||||
only:
|
only:
|
||||||
variables:
|
variables:
|
||||||
- $CI_PROJECT_NAME == "gitlab"
|
- $CI_PROJECT_NAME == "gitlab"
|
||||||
- $CI_PROJECT_NAME == "gitlab-ee" # Support former project name for forks/mirrors
|
- $CI_PROJECT_NAME == "gitlab-ee" # Support former project name for forks/mirrors
|
||||||
|
|
||||||
|
.only-ee-as-if-foss:
|
||||||
|
extends: .only-ee
|
||||||
|
variables:
|
||||||
|
FOSS_ONLY: '1'
|
||||||
|
|
|
@ -36,7 +36,7 @@ memory-static:
|
||||||
memory-on-boot:
|
memory-on-boot:
|
||||||
extends:
|
extends:
|
||||||
- .only-code-memory-job-base
|
- .only-code-memory-job-base
|
||||||
- .use-pg-10
|
- .use-pg10
|
||||||
variables:
|
variables:
|
||||||
NODE_ENV: "production"
|
NODE_ENV: "production"
|
||||||
RAILS_ENV: "production"
|
RAILS_ENV: "production"
|
||||||
|
|
29
.gitlab/ci/notifications.gitlab-ci.yml
Normal file
29
.gitlab/ci/notifications.gitlab-ci.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.notify:
|
||||||
|
image: alpine
|
||||||
|
stage: notification
|
||||||
|
dependencies: []
|
||||||
|
cache: {}
|
||||||
|
before_script:
|
||||||
|
- apk update && apk add git curl bash
|
||||||
|
|
||||||
|
schedule:package-and-qa:notify-success:
|
||||||
|
extends:
|
||||||
|
- .only-canonical-schedules
|
||||||
|
- .notify
|
||||||
|
variables:
|
||||||
|
COMMIT_NOTES_URL: "https://$CI_SERVER_HOST/$CI_PROJECT_PATH/commit/$CI_COMMIT_SHA#notes-list"
|
||||||
|
script:
|
||||||
|
- 'scripts/notify-slack qa-master ":tada: Scheduled QA against master passed! :tada: See $CI_PIPELINE_URL. For downstream pipelines, see $COMMIT_NOTES_URL" ci_passing'
|
||||||
|
needs: ["schedule:package-and-qa"]
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
schedule:package-and-qa:notify-failure:
|
||||||
|
extends:
|
||||||
|
- .only-canonical-schedules
|
||||||
|
- .notify
|
||||||
|
variables:
|
||||||
|
COMMIT_NOTES_URL: "https://$CI_SERVER_HOST/$CI_PROJECT_PATH/commit/$CI_COMMIT_SHA#notes-list"
|
||||||
|
script:
|
||||||
|
- 'scripts/notify-slack qa-master ":skull_and_crossbones: Scheduled QA against master failed! :skull_and_crossbones: See $CI_PIPELINE_URL. For downstream pipelines, see $COMMIT_NOTES_URL" ci_failing'
|
||||||
|
needs: ["schedule:package-and-qa"]
|
||||||
|
when: on_failure
|
|
@ -11,7 +11,7 @@ pages:
|
||||||
variables:
|
variables:
|
||||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
||||||
stage: pages
|
stage: pages
|
||||||
dependencies: ["coverage", "karma", "gitlab:assets:compile"]
|
dependencies: ["coverage", "karma", "gitlab:assets:compile pull-cache"]
|
||||||
script:
|
script:
|
||||||
- mv public/ .public/
|
- mv public/ .public/
|
||||||
- mkdir public/
|
- mkdir public/
|
||||||
|
|
|
@ -1,10 +1,40 @@
|
||||||
|
.qa-job-base:
|
||||||
|
extends:
|
||||||
|
- .default-tags
|
||||||
|
- .default-retry
|
||||||
|
- .default-only
|
||||||
|
- .only-code-qa-changes
|
||||||
|
stage: test
|
||||||
|
dependencies: []
|
||||||
|
cache:
|
||||||
|
key: "qa-framework-jobs:v1"
|
||||||
|
paths:
|
||||||
|
- vendor/ruby
|
||||||
|
before_script:
|
||||||
|
- cd qa/
|
||||||
|
- bundle install --clean --jobs=$(nproc) --path=vendor --retry=3 --quiet
|
||||||
|
- bundle check
|
||||||
|
|
||||||
|
qa:internal:
|
||||||
|
extends: .qa-job-base
|
||||||
|
script:
|
||||||
|
- bundle exec rspec
|
||||||
|
|
||||||
|
qa:selectors:
|
||||||
|
extends: .qa-job-base
|
||||||
|
script:
|
||||||
|
- bundle exec bin/qa Test::Sanity::Selectors
|
||||||
|
|
||||||
|
qa:selectors-foss:
|
||||||
|
extends:
|
||||||
|
- qa:selectors
|
||||||
|
- .only-ee-as-if-foss
|
||||||
|
|
||||||
.package-and-qa-base:
|
.package-and-qa-base:
|
||||||
extends: .default-only
|
extends: .default-only
|
||||||
image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
stage: qa
|
stage: qa
|
||||||
dependencies: []
|
dependencies: []
|
||||||
variables:
|
|
||||||
GIT_DEPTH: "1"
|
|
||||||
retry: 0
|
retry: 0
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- source scripts/utils.sh
|
||||||
|
@ -12,7 +42,7 @@
|
||||||
- ./scripts/trigger-build omnibus
|
- ./scripts/trigger-build omnibus
|
||||||
only:
|
only:
|
||||||
variables:
|
variables:
|
||||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ # Matches the gitlab-org group or its subgroups
|
||||||
|
|
||||||
package-and-qa-manual:
|
package-and-qa-manual:
|
||||||
extends:
|
extends:
|
||||||
|
@ -21,20 +51,10 @@ package-and-qa-manual:
|
||||||
except:
|
except:
|
||||||
refs:
|
refs:
|
||||||
- master
|
- master
|
||||||
|
- /^\d+-\d+-auto-deploy-\d+$/
|
||||||
when: manual
|
when: manual
|
||||||
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
||||||
|
|
||||||
package-and-qa-manual:master:
|
|
||||||
extends:
|
|
||||||
- .package-and-qa-base
|
|
||||||
- .only-code-qa-changes
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- master@gitlab-org/gitlab-foss
|
|
||||||
- master@gitlab-org/gitlab
|
|
||||||
when: manual
|
|
||||||
needs: ["build-qa-image", "gitlab:assets:compile"]
|
|
||||||
|
|
||||||
package-and-qa:
|
package-and-qa:
|
||||||
extends:
|
extends:
|
||||||
- .package-and-qa-base
|
- .package-and-qa-base
|
||||||
|
@ -42,5 +62,13 @@ package-and-qa:
|
||||||
except:
|
except:
|
||||||
refs:
|
refs:
|
||||||
- master
|
- master
|
||||||
|
- /^\d+-\d+-auto-deploy-\d+$/
|
||||||
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
schedule:package-and-qa:
|
||||||
|
extends:
|
||||||
|
- .package-and-qa-base
|
||||||
|
- .only-code-qa-changes
|
||||||
|
- .only-canonical-schedules
|
||||||
|
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
||||||
|
|
|
@ -33,31 +33,31 @@
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
|
|
||||||
|
setup-test-env:
|
||||||
|
extends:
|
||||||
|
- .only-code-qa-rails-job-base
|
||||||
|
- .use-pg9
|
||||||
|
stage: prepare
|
||||||
|
script:
|
||||||
|
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
|
||||||
|
- scripts/gitaly-test-build # Do not use 'bundle exec' here
|
||||||
|
artifacts:
|
||||||
|
expire_in: 7d
|
||||||
|
paths:
|
||||||
|
- tmp/tests
|
||||||
|
- config/secrets.yml
|
||||||
|
- vendor/gitaly-ruby
|
||||||
|
cache:
|
||||||
|
policy: pull-push
|
||||||
|
|
||||||
.rspec-base:
|
.rspec-base:
|
||||||
extends: .only-code-rails-job-base
|
extends: .only-code-rails-job-base
|
||||||
stage: test
|
stage: test
|
||||||
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache"]
|
||||||
|
dependencies: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache"]
|
||||||
script:
|
script:
|
||||||
- JOB_NAME=( $CI_JOB_NAME )
|
- source scripts/rspec_helpers.sh
|
||||||
- TEST_TOOL=${JOB_NAME[0]}
|
- rspec_paralellized_job "--tag ~quarantine --tag ~geo"
|
||||||
- TEST_LEVEL=${JOB_NAME[1]}
|
|
||||||
- DATABASE=${JOB_NAME[2]}
|
|
||||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${TEST_TOOL}_${TEST_LEVEL}_${DATABASE}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
|
||||||
- export KNAPSACK_GENERATE_REPORT=true KNAPSACK_LOG_LEVEL=debug KNAPSACK_TEST_DIR=spec
|
|
||||||
- export SUITE_FLAKY_RSPEC_REPORT_PATH=${FLAKY_RSPEC_SUITE_REPORT_PATH}
|
|
||||||
- export FLAKY_RSPEC_REPORT_PATH=rspec_flaky/all_${TEST_TOOL}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
|
||||||
- export NEW_FLAKY_RSPEC_REPORT_PATH=rspec_flaky/new_${TEST_TOOL}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
|
||||||
- export FLAKY_RSPEC_GENERATE_REPORT=true
|
|
||||||
- export CACHE_CLASSES=true
|
|
||||||
- cp ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
|
||||||
- '[[ -f $FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_REPORT_PATH}'
|
|
||||||
- '[[ -f $NEW_FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${NEW_FLAKY_RSPEC_REPORT_PATH}'
|
|
||||||
- scripts/gitaly-test-spawn
|
|
||||||
- date
|
|
||||||
- 'export KNAPSACK_TEST_FILE_PATTERN=$(ruby -r./lib/quality/test_level.rb -e "puts Quality::TestLevel.new.pattern(:${TEST_LEVEL})")'
|
|
||||||
- mkdir -p tmp/memory_test
|
|
||||||
- export MEMORY_TEST_PATH="tmp/memory_test/${TEST_TOOL}_${TEST_LEVEL}_${DATABASE}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_memory.csv"
|
|
||||||
- knapsack rspec "--color --format documentation --format RspecJunitFormatter --out junit_rspec.xml --tag level:${TEST_LEVEL} --tag ~geo"
|
|
||||||
- date
|
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
when: always
|
when: always
|
||||||
|
@ -71,79 +71,172 @@
|
||||||
reports:
|
reports:
|
||||||
junit: junit_rspec.xml
|
junit: junit_rspec.xml
|
||||||
|
|
||||||
.rspec-base-pg:
|
.rspec-base-foss:
|
||||||
|
extends: [".rspec-base", ".only-ee-as-if-foss"]
|
||||||
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache foss"]
|
||||||
|
dependencies: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache foss"]
|
||||||
|
|
||||||
|
.rspec-base-pg9:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base
|
- .rspec-base
|
||||||
- .use-pg
|
- .use-pg9
|
||||||
|
|
||||||
.rspec-base-pg-10:
|
.rspec-base-pg9-foss:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-foss
|
||||||
|
- .use-pg9
|
||||||
|
|
||||||
|
.rspec-base-pg10:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base
|
- .rspec-base
|
||||||
- .use-pg-10
|
- .use-pg10
|
||||||
|
- .only-master
|
||||||
|
|
||||||
setup-test-env:
|
rspec unit pg9:
|
||||||
extends:
|
extends: .rspec-base-pg9
|
||||||
- .only-code-qa-rails-job-base
|
|
||||||
- .use-pg
|
|
||||||
stage: prepare
|
|
||||||
script:
|
|
||||||
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
|
|
||||||
- scripts/gitaly-test-build # Do not use 'bundle exec' here
|
|
||||||
artifacts:
|
|
||||||
expire_in: 7d
|
|
||||||
paths:
|
|
||||||
- tmp/tests
|
|
||||||
- config/secrets.yml
|
|
||||||
- vendor/gitaly-ruby
|
|
||||||
|
|
||||||
rspec unit pg:
|
|
||||||
extends: .rspec-base-pg
|
|
||||||
parallel: 20
|
parallel: 20
|
||||||
|
|
||||||
rspec integration pg:
|
rspec unit pg9-foss:
|
||||||
extends: .rspec-base-pg
|
extends: .rspec-base-pg9-foss
|
||||||
parallel: 6
|
|
||||||
|
|
||||||
rspec system pg:
|
|
||||||
extends: .rspec-base-pg
|
|
||||||
parallel: 24
|
|
||||||
|
|
||||||
rspec unit pg-10:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-pg-10
|
|
||||||
- .only-master
|
|
||||||
parallel: 20
|
parallel: 20
|
||||||
|
|
||||||
rspec integration pg-10:
|
rspec integration pg9:
|
||||||
extends:
|
extends: .rspec-base-pg9
|
||||||
- .rspec-base-pg-10
|
|
||||||
- .only-master
|
|
||||||
parallel: 6
|
parallel: 6
|
||||||
|
|
||||||
rspec system pg-10:
|
rspec integration pg9-foss:
|
||||||
extends:
|
extends: .rspec-base-pg9-foss
|
||||||
- .rspec-base-pg-10
|
parallel: 6
|
||||||
- .only-master
|
|
||||||
|
rspec system pg9:
|
||||||
|
extends: .rspec-base-pg9
|
||||||
parallel: 24
|
parallel: 24
|
||||||
|
|
||||||
rspec-fast-spec-helper:
|
rspec system pg9-foss:
|
||||||
extends: .rspec-base-pg
|
extends: .rspec-base-pg9-foss
|
||||||
script:
|
parallel: 24
|
||||||
- bundle exec rspec spec/fast_spec_helper.rb
|
|
||||||
|
|
||||||
rspec quarantine pg:
|
rspec unit pg10:
|
||||||
|
extends: .rspec-base-pg10
|
||||||
|
parallel: 20
|
||||||
|
|
||||||
|
rspec integration pg10:
|
||||||
|
extends: .rspec-base-pg10
|
||||||
|
parallel: 6
|
||||||
|
|
||||||
|
rspec system pg10:
|
||||||
|
extends: .rspec-base-pg10
|
||||||
|
parallel: 24
|
||||||
|
|
||||||
|
.rspec-ee-base-pg9:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base-pg
|
- .rspec-base
|
||||||
|
- .only-ee
|
||||||
|
- .use-pg9-ee
|
||||||
|
|
||||||
|
.rspec-ee-base-pg10:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .only-ee
|
||||||
|
- .use-pg10-ee
|
||||||
|
|
||||||
|
rspec-ee unit pg9:
|
||||||
|
extends: .rspec-ee-base-pg9
|
||||||
|
parallel: 7
|
||||||
|
|
||||||
|
rspec-ee integration pg9:
|
||||||
|
extends: .rspec-ee-base-pg9
|
||||||
|
parallel: 3
|
||||||
|
|
||||||
|
rspec-ee system pg9:
|
||||||
|
extends: .rspec-ee-base-pg9
|
||||||
|
parallel: 5
|
||||||
|
|
||||||
|
rspec-ee unit pg10:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg10
|
||||||
- .only-master
|
- .only-master
|
||||||
|
parallel: 7
|
||||||
|
|
||||||
|
rspec-ee integration pg10:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg10
|
||||||
|
- .only-master
|
||||||
|
parallel: 3
|
||||||
|
|
||||||
|
rspec-ee system pg10:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg10
|
||||||
|
- .only-master
|
||||||
|
parallel: 5
|
||||||
|
|
||||||
|
.rspec-ee-base-geo:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .only-ee
|
||||||
script:
|
script:
|
||||||
- export NO_KNAPSACK=1 CACHE_CLASSES=true
|
- source scripts/rspec_helpers.sh
|
||||||
- scripts/gitaly-test-spawn
|
- scripts/prepare_postgres_fdw.sh
|
||||||
- bin/rspec --color --format documentation --tag quarantine -- spec/
|
- rspec_paralellized_job "--tag ~quarantine --tag geo"
|
||||||
|
|
||||||
|
.rspec-ee-base-geo-pg9:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo
|
||||||
|
- .use-pg9-ee
|
||||||
|
|
||||||
|
.rspec-ee-base-geo-pg10:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo
|
||||||
|
- .use-pg10-ee
|
||||||
|
|
||||||
|
rspec-ee unit pg9 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg9
|
||||||
|
parallel: 2
|
||||||
|
|
||||||
|
rspec-ee integration pg9 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg9
|
||||||
|
|
||||||
|
rspec-ee system pg9 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg9
|
||||||
|
|
||||||
|
rspec-ee unit pg10 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg10
|
||||||
|
parallel: 2
|
||||||
|
|
||||||
|
rspec-ee integration pg10 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg10
|
||||||
|
|
||||||
|
rspec-ee system pg10 geo:
|
||||||
|
extends: .rspec-ee-base-geo-pg10
|
||||||
|
|
||||||
|
rspec quarantine pg9:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-pg9
|
||||||
|
- .only-master
|
||||||
|
variables:
|
||||||
|
RSPEC_OPTS: "--tag quarantine -- spec/"
|
||||||
|
script:
|
||||||
|
- source scripts/rspec_helpers.sh
|
||||||
|
- rspec_simple_job "${RSPEC_OPTS}"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
rspec-ee quarantine pg9:
|
||||||
|
extends:
|
||||||
|
- rspec quarantine pg9
|
||||||
|
- .only-ee
|
||||||
|
variables:
|
||||||
|
RSPEC_OPTS: "--tag quarantine -- ee/spec/"
|
||||||
|
|
||||||
|
rspec fast_spec_helper:
|
||||||
|
extends: .rspec-base-pg9
|
||||||
|
script:
|
||||||
|
- bin/rspec spec/fast_spec_helper.rb
|
||||||
|
|
||||||
static-analysis:
|
static-analysis:
|
||||||
extends: .only-code-qa-rails-job-base
|
extends: .only-code-qa-rails-job-base
|
||||||
dependencies: ["setup-test-env", "compile-assets", "compile-assets pull-cache"]
|
stage: test
|
||||||
|
needs: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
|
dependencies: ["setup-test-env", "compile-assets pull-cache"]
|
||||||
variables:
|
variables:
|
||||||
SETUP_DB: "false"
|
SETUP_DB: "false"
|
||||||
script:
|
script:
|
||||||
|
@ -166,16 +259,16 @@ downtime_check:
|
||||||
variables:
|
variables:
|
||||||
- $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/
|
- $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/
|
||||||
stage: test
|
stage: test
|
||||||
dependencies: ["setup-test-env"]
|
|
||||||
needs: ["setup-test-env"]
|
needs: ["setup-test-env"]
|
||||||
|
dependencies: ["setup-test-env"]
|
||||||
|
|
||||||
.db-job-base:
|
.db-job-base:
|
||||||
extends:
|
extends:
|
||||||
- .only-code-rails-job-base
|
- .only-code-rails-job-base
|
||||||
- .use-pg
|
- .use-pg9
|
||||||
stage: test
|
stage: test
|
||||||
dependencies: ["setup-test-env"]
|
|
||||||
needs: ["setup-test-env"]
|
needs: ["setup-test-env"]
|
||||||
|
dependencies: ["setup-test-env"]
|
||||||
|
|
||||||
# DB migration, rollback, and seed jobs
|
# DB migration, rollback, and seed jobs
|
||||||
db:migrate:reset:
|
db:migrate:reset:
|
||||||
|
@ -256,108 +349,6 @@ coverage:
|
||||||
- coverage/assets/
|
- coverage/assets/
|
||||||
- tmp/memory_test/
|
- tmp/memory_test/
|
||||||
|
|
||||||
## EE-specific content
|
|
||||||
.rspec-base-ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base
|
|
||||||
- .only-ee
|
|
||||||
script:
|
|
||||||
- JOB_NAME=( $CI_JOB_NAME )
|
|
||||||
- TEST_TOOL=${JOB_NAME[0]}
|
|
||||||
- TEST_LEVEL=${JOB_NAME[1]}
|
|
||||||
- DATABASE=${JOB_NAME[2]}
|
|
||||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${TEST_TOOL}_${TEST_LEVEL}_${DATABASE}_ee_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
|
||||||
- export KNAPSACK_GENERATE_REPORT=true KNAPSACK_LOG_LEVEL=debug KNAPSACK_TEST_DIR=spec
|
|
||||||
- export CACHE_CLASSES=true
|
|
||||||
- cp ${EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
|
||||||
- scripts/gitaly-test-spawn
|
|
||||||
- date
|
|
||||||
- 'export KNAPSACK_TEST_FILE_PATTERN=$(ruby -r./lib/quality/test_level.rb -e "puts Quality::TestLevel.new(%(ee/)).pattern(:${TEST_LEVEL})")'
|
|
||||||
- mkdir -p tmp/memory_test
|
|
||||||
- export MEMORY_TEST_PATH="tmp/memory_test/ee_${TEST_TOOL}_${TEST_LEVEL}_${DATABASE}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_memory.csv"
|
|
||||||
- knapsack rspec "--color --format documentation --format RspecJunitFormatter --out junit_rspec.xml --tag level:${TEST_LEVEL} --tag ~geo"
|
|
||||||
- date
|
|
||||||
|
|
||||||
.rspec-base-pg-ee:
|
|
||||||
extends: .rspec-base-ee
|
|
||||||
services:
|
|
||||||
- name: postgres:9.6
|
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
|
||||||
- name: redis:alpine
|
|
||||||
- name: docker.elastic.co/elasticsearch/elasticsearch:5.6.12
|
|
||||||
|
|
||||||
rspec unit pg ee:
|
|
||||||
extends: .rspec-base-pg-ee
|
|
||||||
parallel: 7
|
|
||||||
|
|
||||||
rspec integration pg ee:
|
|
||||||
extends: .rspec-base-pg-ee
|
|
||||||
parallel: 3
|
|
||||||
|
|
||||||
rspec system pg ee:
|
|
||||||
extends: .rspec-base-pg-ee
|
|
||||||
parallel: 5
|
|
||||||
|
|
||||||
.rspec-base-geo:
|
|
||||||
extends: .rspec-base-ee
|
|
||||||
parallel: 3
|
|
||||||
script:
|
|
||||||
- JOB_NAME=( $CI_JOB_NAME )
|
|
||||||
- TEST_TOOL=${JOB_NAME[0]}
|
|
||||||
- TEST_LEVEL=${JOB_NAME[1]}
|
|
||||||
- DATABASE=${JOB_NAME[2]}
|
|
||||||
- export KNAPSACK_TEST_FILE_PATTERN="ee/spec/**{,/*/**}/*_spec.rb" KNAPSACK_GENERATE_REPORT=true CACHE_CLASSES=true
|
|
||||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${TEST_TOOL}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
|
||||||
- cp ${EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
|
||||||
- source scripts/prepare_postgres_fdw.sh
|
|
||||||
- scripts/gitaly-test-spawn
|
|
||||||
- mkdir -p tmp/memory_test
|
|
||||||
- export MEMORY_TEST_PATH="tmp/memory_test/ee_${TEST_TOOL}_${TEST_LEVEL}_${DATABASE}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_memory.csv"
|
|
||||||
- knapsack rspec "-Ispec --color --format documentation --format RspecJunitFormatter --out junit_rspec.xml --tag geo"
|
|
||||||
|
|
||||||
rspec geo pg ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-geo
|
|
||||||
- .use-pg
|
|
||||||
except:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_REF_NAME =~ /(^geo[\/-].*|.*-geo$)/
|
|
||||||
|
|
||||||
rspec geo pg-10 ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-geo
|
|
||||||
- .use-pg-10
|
|
||||||
except:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_REF_NAME =~ /(^geo[\/-].*|.*-geo$)/
|
|
||||||
|
|
||||||
quick-rspec geo pg ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-geo
|
|
||||||
- .use-pg
|
|
||||||
stage: quick-test
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_REF_NAME =~ /(^geo[\/-].*|.*-geo$)/
|
|
||||||
|
|
||||||
quick-rspec geo pg-10 ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-geo
|
|
||||||
- .use-pg-10
|
|
||||||
stage: quick-test
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_REF_NAME =~ /(^geo[\/-].*|.*-geo$)/
|
|
||||||
|
|
||||||
rspec quarantine pg ee:
|
|
||||||
extends:
|
|
||||||
- rspec quarantine pg
|
|
||||||
- .only-ee
|
|
||||||
script:
|
|
||||||
- export NO_KNAPSACK=1 CACHE_CLASSES=true
|
|
||||||
- scripts/gitaly-test-spawn
|
|
||||||
- bin/rspec --color --format documentation --format RspecJunitFormatter --out junit_rspec.xml --tag quarantine -- ee/spec/
|
|
||||||
|
|
||||||
db:rollback geo:
|
db:rollback geo:
|
||||||
extends:
|
extends:
|
||||||
- db:rollback
|
- db:rollback
|
||||||
|
@ -365,5 +356,3 @@ db:rollback geo:
|
||||||
script:
|
script:
|
||||||
- bundle exec rake geo:db:migrate VERSION=20170627195211
|
- bundle exec rake geo:db:migrate VERSION=20170627195211
|
||||||
- bundle exec rake geo:db:migrate
|
- bundle exec rake geo:db:migrate
|
||||||
|
|
||||||
## END of EE-specific content
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ code_quality:
|
||||||
# We need to duplicate this job's definition because it seems it's impossible to
|
# We need to duplicate this job's definition because it seems it's impossible to
|
||||||
# override an included `only.refs`.
|
# override an included `only.refs`.
|
||||||
# See https://gitlab.com/gitlab-org/gitlab/issues/31371.
|
# See https://gitlab.com/gitlab-org/gitlab/issues/31371.
|
||||||
|
# Once https://gitlab.com/gitlab-org/gitlab/merge_requests/16487 will be deployed
|
||||||
|
# to GitLab.com, we should be able to use the template and set SAST_DISABLE_DIND: "true".
|
||||||
sast:
|
sast:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
|
@ -196,6 +198,7 @@ dast:
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
- .only-review
|
- .only-review
|
||||||
stage: qa
|
stage: qa
|
||||||
|
needs: ["review-deploy"]
|
||||||
dependencies: ["review-deploy"]
|
dependencies: ["review-deploy"]
|
||||||
before_script:
|
before_script:
|
||||||
- export DAST_WEBSITE="$(cat review_app_url.txt)"
|
- export DAST_WEBSITE="$(cat review_app_url.txt)"
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
.review-base:
|
.except-deploys:
|
||||||
extends:
|
except:
|
||||||
- .default-tags
|
refs:
|
||||||
- .default-retry
|
- /^\d+-\d+-auto-deploy-\d+$/
|
||||||
- .default-only
|
|
||||||
- .only-review
|
|
||||||
- .only-code-qa-changes
|
|
||||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
|
|
||||||
dependencies: []
|
|
||||||
before_script:
|
|
||||||
- source scripts/utils.sh
|
|
||||||
|
|
||||||
.review-docker:
|
.review-docker:
|
||||||
extends:
|
extends:
|
||||||
- .default-tags
|
- .default-tags
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .default-only
|
- .default-only
|
||||||
|
- .except-deploys
|
||||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine
|
||||||
services:
|
services:
|
||||||
- docker:19.03.0-dind
|
- docker:19.03.0-dind
|
||||||
|
@ -41,10 +35,31 @@ build-qa-image:
|
||||||
- echo "${CI_JOB_TOKEN}" | docker login --username gitlab-ci-token --password-stdin ${CI_REGISTRY}
|
- echo "${CI_JOB_TOKEN}" | docker login --username gitlab-ci-token --password-stdin ${CI_REGISTRY}
|
||||||
- time docker push ${QA_IMAGE}
|
- time docker push ${QA_IMAGE}
|
||||||
|
|
||||||
|
schedule:review-cleanup:
|
||||||
|
extends:
|
||||||
|
- .default-tags
|
||||||
|
- .default-retry
|
||||||
|
- .default-only
|
||||||
|
- .only-code-qa-changes
|
||||||
|
- .only-review-schedules
|
||||||
|
- .except-deploys
|
||||||
|
stage: prepare
|
||||||
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
|
||||||
|
allow_failure: true
|
||||||
|
environment:
|
||||||
|
name: review/auto-cleanup
|
||||||
|
action: stop
|
||||||
|
before_script:
|
||||||
|
- source scripts/utils.sh
|
||||||
|
- install_gitlab_gem
|
||||||
|
script:
|
||||||
|
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
||||||
|
|
||||||
.review-build-cng-base:
|
.review-build-cng-base:
|
||||||
extends:
|
extends:
|
||||||
- .default-only
|
- .default-only
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
|
- .except-deploys
|
||||||
image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
stage: review-prepare
|
stage: review-prepare
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -65,16 +80,23 @@ schedule:review-build-cng:
|
||||||
extends:
|
extends:
|
||||||
- .review-build-cng-base
|
- .review-build-cng-base
|
||||||
- .only-review-schedules
|
- .only-review-schedules
|
||||||
needs: ["gitlab:assets:compile"]
|
needs: ["gitlab:assets:compile pull-cache"]
|
||||||
|
|
||||||
.review-deploy-base:
|
.review-deploy-base:
|
||||||
extends: .review-base
|
extends:
|
||||||
allow_failure: true
|
- .default-tags
|
||||||
|
- .default-retry
|
||||||
|
- .default-only
|
||||||
|
- .only-code-qa-changes
|
||||||
|
- .except-deploys
|
||||||
stage: review
|
stage: review
|
||||||
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
|
||||||
|
dependencies: []
|
||||||
|
allow_failure: true
|
||||||
variables:
|
variables:
|
||||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||||
GITLAB_HELM_CHART_REF: "master"
|
GITLAB_HELM_CHART_REF: "v2.3.7"
|
||||||
GITLAB_EDITION: "ce"
|
GITLAB_EDITION: "ce"
|
||||||
environment:
|
environment:
|
||||||
name: review/${CI_COMMIT_REF_NAME}
|
name: review/${CI_COMMIT_REF_NAME}
|
||||||
|
@ -90,13 +112,21 @@ schedule:review-build-cng:
|
||||||
- install_api_client_dependencies_with_apk
|
- install_api_client_dependencies_with_apk
|
||||||
- source scripts/review_apps/review-apps.sh
|
- source scripts/review_apps/review-apps.sh
|
||||||
script:
|
script:
|
||||||
|
- date
|
||||||
- check_kube_domain
|
- check_kube_domain
|
||||||
|
- date
|
||||||
- ensure_namespace
|
- ensure_namespace
|
||||||
|
- date
|
||||||
- install_tiller
|
- install_tiller
|
||||||
|
- date
|
||||||
- install_external_dns
|
- install_external_dns
|
||||||
|
- date
|
||||||
- download_chart
|
- download_chart
|
||||||
|
- date
|
||||||
- deploy || (display_deployment_debug && exit 1)
|
- deploy || (display_deployment_debug && exit 1)
|
||||||
|
- date
|
||||||
- add_license
|
- add_license
|
||||||
|
- date
|
||||||
artifacts:
|
artifacts:
|
||||||
paths: [review_app_url.txt]
|
paths: [review_app_url.txt]
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
|
@ -105,6 +135,7 @@ schedule:review-build-cng:
|
||||||
review-deploy:
|
review-deploy:
|
||||||
extends:
|
extends:
|
||||||
- .review-deploy-base
|
- .review-deploy-base
|
||||||
|
- .only-review
|
||||||
needs: ["review-build-cng"]
|
needs: ["review-build-cng"]
|
||||||
|
|
||||||
schedule:review-deploy:
|
schedule:review-deploy:
|
||||||
|
@ -116,6 +147,7 @@ schedule:review-deploy:
|
||||||
review-stop:
|
review-stop:
|
||||||
extends:
|
extends:
|
||||||
- .review-deploy-base
|
- .review-deploy-base
|
||||||
|
- .only-review
|
||||||
when: manual
|
when: manual
|
||||||
environment:
|
environment:
|
||||||
action: stop
|
action: stop
|
||||||
|
@ -148,6 +180,7 @@ review-cleanup-failed-deployment:
|
||||||
- .only-review
|
- .only-review
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
stage: qa
|
stage: qa
|
||||||
|
allow_failure: true
|
||||||
variables:
|
variables:
|
||||||
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
|
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
|
||||||
QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
|
QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
|
||||||
|
@ -158,6 +191,7 @@ review-cleanup-failed-deployment:
|
||||||
GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
||||||
GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
|
GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
|
||||||
EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
|
EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
|
||||||
|
needs: ["review-deploy"]
|
||||||
dependencies: ["review-deploy"]
|
dependencies: ["review-deploy"]
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
|
@ -176,26 +210,76 @@ review-cleanup-failed-deployment:
|
||||||
|
|
||||||
review-qa-smoke:
|
review-qa-smoke:
|
||||||
extends: .review-qa-base
|
extends: .review-qa-base
|
||||||
allow_failure: true
|
|
||||||
script:
|
script:
|
||||||
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
|
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
|
||||||
|
|
||||||
review-qa-all:
|
review-qa-all:
|
||||||
extends: .review-qa-base
|
extends: .review-qa-base
|
||||||
allow_failure: true
|
|
||||||
when: manual
|
when: manual
|
||||||
parallel: 5
|
parallel: 5
|
||||||
script:
|
script:
|
||||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/review-qa-all_master_report.json
|
- export KNAPSACK_REPORT_PATH=knapsack/master_report.json
|
||||||
- export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
|
- export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
|
||||||
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
|
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
|
||||||
|
|
||||||
|
.review-performance-base:
|
||||||
|
extends:
|
||||||
|
- .review-docker
|
||||||
|
- .only-code-qa-changes
|
||||||
|
stage: qa
|
||||||
|
allow_failure: true
|
||||||
|
before_script:
|
||||||
|
- export CI_ENVIRONMENT_URL="$(cat review_app_url.txt)"
|
||||||
|
- echo "${CI_ENVIRONMENT_URL}"
|
||||||
|
- mkdir -p gitlab-exporter
|
||||||
|
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
|
||||||
|
- mkdir -p sitespeed-results
|
||||||
|
script:
|
||||||
|
- docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
|
||||||
|
after_script:
|
||||||
|
- mv sitespeed-results/data/performance.json performance.json
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- sitespeed-results/
|
||||||
|
reports:
|
||||||
|
performance: performance.json
|
||||||
|
|
||||||
|
review-performance:
|
||||||
|
extends:
|
||||||
|
- .review-performance-base
|
||||||
|
- .only-review
|
||||||
|
needs: ["review-deploy"]
|
||||||
|
dependencies: ["review-deploy"]
|
||||||
|
before_script:
|
||||||
|
- export CI_ENVIRONMENT_URL="$(cat review_app_url.txt)"
|
||||||
|
- echo "${CI_ENVIRONMENT_URL}"
|
||||||
|
- mkdir -p gitlab-exporter
|
||||||
|
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
|
||||||
|
- mkdir -p sitespeed-results
|
||||||
|
script:
|
||||||
|
- docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
|
||||||
|
after_script:
|
||||||
|
- mv sitespeed-results/data/performance.json performance.json
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- sitespeed-results/
|
||||||
|
reports:
|
||||||
|
performance: performance.json
|
||||||
|
|
||||||
|
schedule:review-performance:
|
||||||
|
extends:
|
||||||
|
- .review-performance-base
|
||||||
|
- .only-review-schedules
|
||||||
|
needs: ["schedule:review-deploy"]
|
||||||
|
dependencies: ["schedule:review-deploy"]
|
||||||
|
|
||||||
parallel-spec-reports:
|
parallel-spec-reports:
|
||||||
extends:
|
extends:
|
||||||
- .default-tags
|
- .default-tags
|
||||||
- .default-only
|
- .default-only
|
||||||
- .only-code-qa-changes
|
- .only-code-qa-changes
|
||||||
- .only-review
|
- .only-review
|
||||||
|
- .except-deploys
|
||||||
image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
stage: post-test
|
stage: post-test
|
||||||
dependencies: ["review-qa-all"]
|
dependencies: ["review-qa-all"]
|
||||||
|
@ -220,46 +304,6 @@ parallel-spec-reports:
|
||||||
- '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
|
- '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
|
||||||
- scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
|
- scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
|
||||||
|
|
||||||
review-performance:
|
|
||||||
extends: .review-qa-base
|
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
|
||||||
- export CI_ENVIRONMENT_URL="$(cat review_app_url.txt)"
|
|
||||||
- echo "${CI_ENVIRONMENT_URL}"
|
|
||||||
- mkdir -p gitlab-exporter
|
|
||||||
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
|
|
||||||
- mkdir -p sitespeed-results
|
|
||||||
script:
|
|
||||||
- docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
|
|
||||||
after_script:
|
|
||||||
- mv sitespeed-results/data/performance.json performance.json
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- sitespeed-results/
|
|
||||||
reports:
|
|
||||||
performance: performance.json
|
|
||||||
|
|
||||||
schedule:review-performance:
|
|
||||||
extends:
|
|
||||||
- review-performance
|
|
||||||
- .only-review-schedules
|
|
||||||
dependencies: ["schedule:review-deploy"]
|
|
||||||
|
|
||||||
schedule:review-cleanup:
|
|
||||||
extends:
|
|
||||||
- .review-base
|
|
||||||
- .only-review-schedules
|
|
||||||
stage: prepare
|
|
||||||
allow_failure: true
|
|
||||||
environment:
|
|
||||||
name: review/auto-cleanup
|
|
||||||
action: stop
|
|
||||||
before_script:
|
|
||||||
- source scripts/utils.sh
|
|
||||||
- install_gitlab_gem
|
|
||||||
script:
|
|
||||||
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
|
||||||
|
|
||||||
danger-review:
|
danger-review:
|
||||||
extends:
|
extends:
|
||||||
- .default-tags
|
- .default-tags
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
.tests-metadata-state:
|
.tests-metadata-state:
|
||||||
extends:
|
extends:
|
||||||
- .default-only
|
- .default-only
|
||||||
|
- .only-code-changes
|
||||||
variables:
|
variables:
|
||||||
TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache"
|
TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache"
|
||||||
before_script:
|
before_script:
|
||||||
- source scripts/utils.sh
|
- source scripts/utils.sh
|
||||||
|
cache:
|
||||||
|
key: tests_metadata
|
||||||
|
paths:
|
||||||
|
- knapsack/
|
||||||
|
- rspec_flaky/
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
paths:
|
paths:
|
||||||
|
@ -13,55 +19,29 @@
|
||||||
- rspec_profiling/
|
- rspec_profiling/
|
||||||
|
|
||||||
retrieve-tests-metadata:
|
retrieve-tests-metadata:
|
||||||
extends:
|
extends: .tests-metadata-state
|
||||||
- .tests-metadata-state
|
|
||||||
- .only-code-changes
|
|
||||||
stage: prepare
|
stage: prepare
|
||||||
cache:
|
cache:
|
||||||
key: tests_metadata
|
|
||||||
policy: pull
|
policy: pull
|
||||||
script:
|
script:
|
||||||
- mkdir -p knapsack/${CI_PROJECT_NAME}/
|
- source scripts/rspec_helpers.sh
|
||||||
- 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
|
- retrieve_tests_metadata
|
||||||
- '[[ -f $KNAPSACK_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
|
|
||||||
- mkdir -p rspec_flaky/
|
|
||||||
- mkdir -p rspec_profiling/
|
|
||||||
- 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}'
|
|
||||||
- '[[ ! -d "ee/" ]] || wget -O $EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH || rm $EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH'
|
|
||||||
- '[[ ! -d "ee/" ]] || [[ -f $EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
|
|
||||||
|
|
||||||
update-tests-metadata:
|
update-tests-metadata:
|
||||||
extends:
|
extends: .tests-metadata-state
|
||||||
- .tests-metadata-state
|
|
||||||
- .only-code-changes
|
|
||||||
stage: post-test
|
stage: post-test
|
||||||
cache:
|
cache:
|
||||||
key: tests_metadata
|
|
||||||
paths:
|
|
||||||
- knapsack/
|
|
||||||
- rspec_flaky/
|
|
||||||
policy: push
|
policy: push
|
||||||
script:
|
script:
|
||||||
- retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document
|
- retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document
|
||||||
- echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}
|
- source scripts/rspec_helpers.sh
|
||||||
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec_*_pg_node_*.json
|
- update_tests_metadata
|
||||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH'
|
|
||||||
- '[[ ! -d "ee/" ]] || echo "{}" > ${EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
|
|
||||||
- '[[ ! -d "ee/" ]] || scripts/merge-reports ${EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec_*_pg_ee_*node_*.json'
|
|
||||||
- '[[ ! -d "ee/" ]] || [[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH'
|
|
||||||
- rm -f knapsack/${CI_PROJECT_NAME}/*_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 $FLAKY_RSPEC_SUITE_REPORT_PATH'
|
|
||||||
- rm -f rspec_flaky/all_*.json rspec_flaky/new_*.json
|
|
||||||
- scripts/insert-rspec-profiling-data
|
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- master
|
- schedules
|
||||||
variables:
|
variables:
|
||||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
# Only update the Knapsack metadata on GitLab.com/gitlab-org/gitlab
|
||||||
- $CI_SERVER_HOST == "dev.gitlab.org"
|
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab"
|
||||||
|
|
||||||
flaky-examples-check:
|
flaky-examples-check:
|
||||||
extends:
|
extends:
|
||||||
|
|
|
@ -25,7 +25,7 @@ Then leave running while monitoring and performing some testing through web, api
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Dev Sentry](https://sentry.gitlap.com/gitlab/devgitlaborg/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Dev Sentry](https://sentry.gitlab.net/gitlab/devgitlaborg/?query=is%3Aunresolved)
|
||||||
|
|
||||||
## 2. Staging Trial
|
## 2. Staging Trial
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ Then leave running while monitoring for at least **15 minutes** while performing
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlap.com/gitlab/gitlabcom/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlab.net/gitlab/gitlabcom/?query=is%3Aunresolved)
|
||||||
|
|
||||||
## 4. Production Server Version Check
|
## 4. Production Server Version Check
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ Then leave running while monitoring for at least **15 minutes** while performing
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlap.com/gitlab/gitlabcom/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlab.net/gitlab/gitlabcom/?query=is%3Aunresolved)
|
||||||
|
|
||||||
## 6. Low Impact Check
|
## 6. Low Impact Check
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ Then leave running while monitoring for at least **30 minutes** while performing
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlap.com/gitlab/gitlabcom/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlab.net/gitlab/gitlabcom/?query=is%3Aunresolved)
|
||||||
|
|
||||||
## 7. Mid Impact Trial
|
## 7. Mid Impact Trial
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ Then leave running while monitoring for at least **12 hours** while performing s
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlap.com/gitlab/gitlabcom/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Sentry](https://sentry.gitlab.net/gitlab/gitlabcom/?query=is%3Aunresolved)
|
||||||
|
|
||||||
## 8. Full Impact Trial
|
## 8. Full Impact Trial
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ Then leave running while monitoring for at least **1 week**.
|
||||||
|
|
||||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||||
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
- [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana)
|
||||||
- [ ] [Check for errors in GitLab Dev Sentry](https://sentry.gitlap.com/gitlab/devgitlaborg/?query=is%3Aunresolved)
|
- [ ] [Check for errors in GitLab Dev Sentry](https://sentry.gitlab.net/gitlab/devgitlaborg/?query=is%3Aunresolved)
|
||||||
|
|
||||||
#### Success?
|
#### Success?
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,10 @@
|
||||||
Please read this!
|
Please read this!
|
||||||
|
|
||||||
Before opening a new issue, make sure to search for keywords in the issues
|
Before opening a new issue, make sure to search for keywords in the issues
|
||||||
filtered by the "regression" or "bug" label.
|
filtered by the "regression" or "bug" label:
|
||||||
|
|
||||||
For the Community Edition issue tracker:
|
- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=regression
|
||||||
|
- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=bug
|
||||||
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=regression
|
|
||||||
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=bug
|
|
||||||
|
|
||||||
For the Enterprise Edition issue tracker:
|
|
||||||
|
|
||||||
- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=regression
|
|
||||||
- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=bug
|
|
||||||
|
|
||||||
and verify the issue you're about to submit isn't a duplicate.
|
and verify the issue you're about to submit isn't a duplicate.
|
||||||
--->
|
--->
|
||||||
|
|
|
@ -11,6 +11,6 @@ Please describe the proposal and add a link to the source (for example, http://w
|
||||||
|
|
||||||
/label ~"development guidelines"
|
/label ~"development guidelines"
|
||||||
/label ~"Style decision"
|
/label ~"Style decision"
|
||||||
/label ~Documentation
|
/label ~documentation
|
||||||
|
|
||||||
/cc @gitlab-org/maintainers/rails-backend
|
/cc @gitlab-org/maintainers/rails-backend
|
||||||
|
|
|
@ -17,4 +17,4 @@ Related issue(s):
|
||||||
<!-- Any additional context, questions, or notes for the technical writer. -->
|
<!-- Any additional context, questions, or notes for the technical writer. -->
|
||||||
|
|
||||||
|
|
||||||
/label ~Documentation ~docs-review
|
/label ~documentation ~"Technical Writing"
|
||||||
|
|
|
@ -9,16 +9,6 @@
|
||||||
* For information about documentation content and process, see
|
* For information about documentation content and process, see
|
||||||
https://docs.gitlab.com/ee/development/documentation/ -->
|
https://docs.gitlab.com/ee/development/documentation/ -->
|
||||||
|
|
||||||
<!-- Type of issue -->
|
|
||||||
|
|
||||||
<!-- Un-comment the line for the applicable doc issue type to add its label.
|
|
||||||
Note that all text on that line is deleted upon issue creation. -->
|
|
||||||
<!-- /label ~"docs:fix" - Correction or clarification needed. -->
|
|
||||||
<!-- /label ~"docs:new" - New doc needed to cover a new topic or use case. -->
|
|
||||||
<!-- /label ~"docs:improvement" - Improving an existing doc; e.g. adding a diagram, adding or rewording text, resolving redundancies, cross-linking, etc. -->
|
|
||||||
<!-- /label ~"docs:revamp" - Review a page or group of pages in order to plan and implement major improvements/rewrites. -->
|
|
||||||
<!-- /label ~"docs:other" - Anything else. -->
|
|
||||||
|
|
||||||
### Problem to solve
|
### Problem to solve
|
||||||
|
|
||||||
<!-- Include the following detail as necessary:
|
<!-- Include the following detail as necessary:
|
||||||
|
@ -50,4 +40,4 @@
|
||||||
|
|
||||||
<!-- E.g. related GitLab issues/MRs -->
|
<!-- E.g. related GitLab issues/MRs -->
|
||||||
|
|
||||||
/label ~Documentation
|
/label ~documentation
|
||||||
|
|
|
@ -24,7 +24,7 @@ Remove the `:feature_name` feature flag ...
|
||||||
|
|
||||||
If applicable, any groups/projects that are happy to have this feature turned on early. Some organizations may wish to test big changes they are interested in with a small subset of users ahead of time for example.
|
If applicable, any groups/projects that are happy to have this feature turned on early. Some organizations may wish to test big changes they are interested in with a small subset of users ahead of time for example.
|
||||||
|
|
||||||
- `gitlab-org/gitlab-ce`/`gitlab-org/gitlab-ee` projects
|
- `gitlab-org/gitlab` project
|
||||||
- `gitlab-org`/`gitlab-com` groups
|
- `gitlab-org`/`gitlab-com` groups
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ If applicable, any groups/projects that are happy to have this feature turned on
|
||||||
- [ ] Test on staging
|
- [ ] Test on staging
|
||||||
- [ ] Ensure that documentation has been updated
|
- [ ] Ensure that documentation has been updated
|
||||||
- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour
|
- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour
|
||||||
|
- [ ] Coordinate a time to enable the flag with `#production` and `#g_delivery` on slack.
|
||||||
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
|
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
|
||||||
- [ ] Enable on GitLab.com by running chatops command in `#production`
|
- [ ] Enable on GitLab.com by running chatops command in `#production`
|
||||||
- [ ] Cross post chatops slack command to `#support_gitlab-com` and in your team channel
|
- [ ] Cross post chatops slack command to `#support_gitlab-com` and in your team channel
|
||||||
|
|
|
@ -38,4 +38,4 @@
|
||||||
|
|
||||||
For example, if the solution will take a product manager, designer, and engineer two weeks of effort - you may quantify this as 1.5 (based on 0.5 months x 3 people). -->
|
For example, if the solution will take a product manager, designer, and engineer two weeks of effort - you may quantify this as 1.5 (based on 0.5 months x 3 people). -->
|
||||||
|
|
||||||
/label ~"workflow::problem backlog"
|
/label ~"workflow::validation backlog" ~devops:: ~category: ~group::
|
||||||
|
|
|
@ -18,13 +18,7 @@ Set the title to: `Security Release: 12.2.X, 12.1.X, and 12.0.X`
|
||||||
|
|
||||||
## Security Issues:
|
## Security Issues:
|
||||||
|
|
||||||
### CE
|
* {https://gitlab.com/gitlab-org/gitlab/issues link}
|
||||||
|
|
||||||
* {https://gitlab.com/gitlab-org/gitlab-ce/issues link}
|
|
||||||
|
|
||||||
### EE
|
|
||||||
|
|
||||||
* {https://gitlab.com/gitlab-org/gitlab-ee/issues link}
|
|
||||||
|
|
||||||
## Security Issues in dev.gitlab.org:
|
## Security Issues in dev.gitlab.org:
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<!-- This issue outlines testing activities related to a particular issue or epic.
|
<!-- This issue outlines testing activities related to a particular issue or epic.
|
||||||
|
|
||||||
[Here is an example test plan](https://gitlab.com/gitlab-org/gitlab-ce/issues/50353)
|
[Here is an example test plan](https://gitlab.com/gitlab-org/gitlab-foss/issues/50353)
|
||||||
|
|
||||||
This and other comments should be removed as you write the plan -->
|
This and other comments should be removed as you write the plan -->
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ intersection of Components and Attributes.
|
||||||
Some features might be simple enough that they only involve one Component, while
|
Some features might be simple enough that they only involve one Component, while
|
||||||
more complex features could involve multiple or even all.
|
more complex features could involve multiple or even all.
|
||||||
|
|
||||||
Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353):
|
Example (from https://gitlab.com/gitlab-org/gitlab-foss/issues/50353):
|
||||||
* Repository is
|
* Repository is
|
||||||
* Intuitive
|
* Intuitive
|
||||||
* It's easy to select the desired file template
|
* It's easy to select the desired file template
|
||||||
|
|
|
@ -15,7 +15,7 @@ Closes
|
||||||
## Moving docs to a new location?
|
## Moving docs to a new location?
|
||||||
|
|
||||||
Read the guidelines:
|
Read the guidelines:
|
||||||
https://docs.gitlab.com/ce/development/documentation/index.html#changing-document-location
|
https://docs.gitlab.com/ee/development/documentation/index.html#changing-document-location
|
||||||
|
|
||||||
- [ ] Make sure the old link is not removed and has its contents replaced with
|
- [ ] Make sure the old link is not removed and has its contents replaced with
|
||||||
a link to the new location.
|
a link to the new location.
|
||||||
|
@ -29,4 +29,4 @@ https://docs.gitlab.com/ce/development/documentation/index.html#changing-documen
|
||||||
with the changes as well (https://docs.gitlab.com/ce/development/documentation/index.html#cherry-picking-from-ce-to-ee).
|
with the changes as well (https://docs.gitlab.com/ce/development/documentation/index.html#cherry-picking-from-ce-to-ee).
|
||||||
- [ ] Ping one of the technical writers for review.
|
- [ ] Ping one of the technical writers for review.
|
||||||
|
|
||||||
/label ~Documentation
|
/label ~documentation
|
||||||
|
|
|
@ -24,6 +24,7 @@ When adding migrations:
|
||||||
- [ ] Added a `down` method so the migration can be reverted
|
- [ ] Added a `down` method so the migration can be reverted
|
||||||
- [ ] Added the output of the migration(s) to the MR body
|
- [ ] Added the output of the migration(s) to the MR body
|
||||||
- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when migrating data)
|
- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when migrating data)
|
||||||
|
- [ ] Added rollback procedure. Include either a rollback procedure or description how to rollback changes
|
||||||
|
|
||||||
When adding or modifying queries to improve performance:
|
When adding or modifying queries to improve performance:
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ When adding foreign keys to existing tables:
|
||||||
|
|
||||||
When adding tables:
|
When adding tables:
|
||||||
|
|
||||||
- [ ] Ordered columns based on the [Ordering Table Columns](https://docs.gitlab.com/ee/development/ordering_table_columns.html#ordering-table-columns) guidelines
|
- [ ] Ordered columns based on the [Ordering Table Columns](https://docs.gitlab.com/ee/development/ordering_table_columns.html) guidelines
|
||||||
- [ ] Added foreign keys to any columns pointing to data in other tables
|
- [ ] Added foreign keys to any columns pointing to data in other tables
|
||||||
- [ ] Added indexes for fields that are used in statements such as `WHERE`, `ORDER BY`, `GROUP BY`, and `JOIN`s
|
- [ ] Added indexes for fields that are used in statements such as `WHERE`, `ORDER BY`, `GROUP BY`, and `JOIN`s
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
- [ ] Follow the [Documentation Guidelines](https://docs.gitlab.com/ee/development/documentation/) and [Style Guide](https://docs.gitlab.com/ee/development/documentation/styleguide.html).
|
- [ ] Follow the [Documentation Guidelines](https://docs.gitlab.com/ee/development/documentation/) and [Style Guide](https://docs.gitlab.com/ee/development/documentation/styleguide.html).
|
||||||
- [ ] If applicable, update the [permissions table](https://docs.gitlab.com/ee/user/permissions.html).
|
- [ ] If applicable, update the [permissions table](https://docs.gitlab.com/ee/user/permissions.html).
|
||||||
- [ ] Link docs to and from the higher-level index page, plus other related docs where helpful.
|
- [ ] Link docs to and from the higher-level index page, plus other related docs where helpful.
|
||||||
- [ ] Apply the ~Documentation label.
|
- [ ] Apply the ~documentation label.
|
||||||
|
|
||||||
## Review checklist
|
## Review checklist
|
||||||
|
|
||||||
|
@ -35,6 +35,6 @@ All reviewers can help ensure accuracy, clarity, completeness, and adherence to
|
||||||
|
|
||||||
1. [ ] Review by assigned maintainer, who can always request/require the above reviews. Maintainer's review can occur before or after a technical writer review.
|
1. [ ] Review by assigned maintainer, who can always request/require the above reviews. Maintainer's review can occur before or after a technical writer review.
|
||||||
1. [ ] Ensure a release milestone is set and that you merge the equivalent EE MR before the CE MR if both exist.
|
1. [ ] Ensure a release milestone is set and that you merge the equivalent EE MR before the CE MR if both exist.
|
||||||
1. [ ] If there has not been a technical writer review, [create an issue for one using the Doc Review template](https://gitlab.com/gitlab-org/gitlab-ce/issues/new?issuable_template=Doc%20Review).
|
1. [ ] If there has not been a technical writer review, [create an issue for one using the Doc Review template](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review).
|
||||||
|
|
||||||
/label ~Documentation
|
/label ~documentation
|
||||||
|
|
|
@ -208,6 +208,8 @@ linters:
|
||||||
- 'app/views/projects/_md_preview.html.haml'
|
- 'app/views/projects/_md_preview.html.haml'
|
||||||
- 'app/views/projects/_new_project_fields.html.haml'
|
- 'app/views/projects/_new_project_fields.html.haml'
|
||||||
- 'app/views/projects/_readme.html.haml'
|
- 'app/views/projects/_readme.html.haml'
|
||||||
|
- 'app/views/projects/artifacts/_artifact.html.haml'
|
||||||
|
- 'app/views/projects/artifacts/_search_bar.html.haml'
|
||||||
- 'app/views/projects/artifacts/_tree_file.html.haml'
|
- 'app/views/projects/artifacts/_tree_file.html.haml'
|
||||||
- 'app/views/projects/artifacts/browse.html.haml'
|
- 'app/views/projects/artifacts/browse.html.haml'
|
||||||
- 'app/views/projects/blame/_age_map_legend.html.haml'
|
- 'app/views/projects/blame/_age_map_legend.html.haml'
|
||||||
|
@ -354,6 +356,7 @@ linters:
|
||||||
- 'app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml'
|
- 'app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml'
|
||||||
- 'app/views/shared/_commit_message_container.html.haml'
|
- 'app/views/shared/_commit_message_container.html.haml'
|
||||||
- 'app/views/shared/_confirm_modal.html.haml'
|
- 'app/views/shared/_confirm_modal.html.haml'
|
||||||
|
- 'app/views/shared/_confirm_fork_modal.html.haml'
|
||||||
- 'app/views/shared/_delete_label_modal.html.haml'
|
- 'app/views/shared/_delete_label_modal.html.haml'
|
||||||
- 'app/views/shared/_group_form.html.haml'
|
- 'app/views/shared/_group_form.html.haml'
|
||||||
- 'app/views/shared/_group_tips.html.haml'
|
- 'app/views/shared/_group_tips.html.haml'
|
||||||
|
|
36
.projections.json.example
Normal file
36
.projections.json.example
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"app/*.rb": {
|
||||||
|
"alternate": "spec/{}_spec.rb",
|
||||||
|
"type": "source"
|
||||||
|
},
|
||||||
|
"spec/*_spec.rb": {
|
||||||
|
"alternate": "app/{}.rb",
|
||||||
|
"type": "test"
|
||||||
|
},
|
||||||
|
"lib/*.rb": {
|
||||||
|
"alternate": "spec/lib/{}_spec.rb",
|
||||||
|
"type": "source"
|
||||||
|
},
|
||||||
|
"spec/lib/*_spec.rb": {
|
||||||
|
"alternate": "lib/{}.rb",
|
||||||
|
"type": "test"
|
||||||
|
},
|
||||||
|
"ee/app/*.rb": {
|
||||||
|
"alternate": "ee/spec/{}_spec.rb",
|
||||||
|
"type": "source"
|
||||||
|
},
|
||||||
|
"ee/spec/*_spec.rb": {
|
||||||
|
"alternate": "ee/app/{}.rb",
|
||||||
|
"type": "test"
|
||||||
|
},
|
||||||
|
"ee/lib/*.rb": {
|
||||||
|
"alternate": "ee/spec/lib/{}_spec.rb",
|
||||||
|
"type": "source"
|
||||||
|
},
|
||||||
|
"ee/spec/lib/*_spec.rb": {
|
||||||
|
"alternate": "ee/lib/{}.rb",
|
||||||
|
"type": "test"
|
||||||
|
},
|
||||||
|
"*.rb": {"dispatch": "bundle exec rubocop {file}"},
|
||||||
|
"*_spec.rb": {"dispatch": "bundle exec rspec {file}"}
|
||||||
|
}
|
12
.rubocop.yml
12
.rubocop.yml
|
@ -51,7 +51,6 @@ Style/FrozenStringLiteralComment:
|
||||||
- 'danger/**/*'
|
- 'danger/**/*'
|
||||||
- 'db/**/*'
|
- 'db/**/*'
|
||||||
- 'ee/db/**/*'
|
- 'ee/db/**/*'
|
||||||
- 'ee/spec/**/*'
|
|
||||||
- 'ee/lib/tasks/**/*'
|
- 'ee/lib/tasks/**/*'
|
||||||
- 'lib/tasks/**/*'
|
- 'lib/tasks/**/*'
|
||||||
- 'qa/**/*'
|
- 'qa/**/*'
|
||||||
|
@ -179,6 +178,11 @@ Gitlab/ModuleWithInstanceVariables:
|
||||||
- spec/support/**/*.rb
|
- spec/support/**/*.rb
|
||||||
- features/steps/**/*.rb
|
- features/steps/**/*.rb
|
||||||
|
|
||||||
|
Gitlab/ConstGetInheritFalse:
|
||||||
|
Enabled: true
|
||||||
|
Exclude:
|
||||||
|
- 'qa/bin/*'
|
||||||
|
|
||||||
Gitlab/HTTParty:
|
Gitlab/HTTParty:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Exclude:
|
Exclude:
|
||||||
|
@ -218,6 +222,12 @@ ActiveRecordAssociationReload:
|
||||||
- 'spec/**/*'
|
- 'spec/**/*'
|
||||||
- 'ee/spec/**/*'
|
- 'ee/spec/**/*'
|
||||||
|
|
||||||
|
Naming/PredicateName:
|
||||||
|
Enabled: true
|
||||||
|
Exclude:
|
||||||
|
- 'spec/**/*'
|
||||||
|
- 'ee/spec/**/*'
|
||||||
|
|
||||||
RSpec/FactoriesInMigrationSpecs:
|
RSpec/FactoriesInMigrationSpecs:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Include:
|
Include:
|
||||||
|
|
|
@ -273,11 +273,6 @@ RSpec/ContextWording:
|
||||||
RSpec/EmptyLineAfterFinalLet:
|
RSpec/EmptyLineAfterFinalLet:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 232
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
RSpec/EmptyLineAfterSubject:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 719
|
# Offense count: 719
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
@ -442,19 +437,6 @@ Rails/LinkToBlank:
|
||||||
- 'ee/app/helpers/ee/user_callouts_helper.rb'
|
- 'ee/app/helpers/ee/user_callouts_helper.rb'
|
||||||
- 'ee/app/helpers/license_helper.rb'
|
- 'ee/app/helpers/license_helper.rb'
|
||||||
|
|
||||||
# Offense count: 11
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Rails/Presence:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/ci/pipeline.rb'
|
|
||||||
- 'app/models/concerns/mentionable.rb'
|
|
||||||
- 'app/models/project_services/hipchat_service.rb'
|
|
||||||
- 'app/models/project_services/irker_service.rb'
|
|
||||||
- 'app/models/project_services/jira_service.rb'
|
|
||||||
- 'app/models/project_services/packagist_service.rb'
|
|
||||||
- 'app/models/wiki_page.rb'
|
|
||||||
- 'lib/gitlab/github_import/importer/releases_importer.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: Include.
|
# Configuration parameters: Include.
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
title: Render xml artifact files in GitLab
|
|
||||||
merge_request: 16790
|
|
||||||
author:
|
|
||||||
type: added
|
|
189
CHANGELOG-EE.md
189
CHANGELOG-EE.md
|
@ -1,10 +1,10 @@
|
||||||
Please view this file on the master branch, on stable branches it's out of date.
|
Please view this file on the master branch, on stable branches it's out of date.
|
||||||
|
|
||||||
## 12.3.8
|
## 12.4.5
|
||||||
|
|
||||||
- No changes.
|
- No changes.
|
||||||
|
|
||||||
## 12.3.7
|
## 12.4.4
|
||||||
|
|
||||||
### Security (6 changes)
|
### Security (6 changes)
|
||||||
|
|
||||||
|
@ -16,19 +16,143 @@ Please view this file on the master branch, on stable branches it's out of date.
|
||||||
- Prevent IDOR when adding users to protected environments.
|
- Prevent IDOR when adding users to protected environments.
|
||||||
|
|
||||||
|
|
||||||
## 12.3.6
|
## 12.4.3
|
||||||
|
|
||||||
### Security (4 changes)
|
### Fixed (2 changes)
|
||||||
|
|
||||||
|
- Fix admin welcome image not found. !19676
|
||||||
|
- Revert ES support for public/internal project snippets. !19715
|
||||||
|
|
||||||
|
|
||||||
|
## 12.4.2
|
||||||
|
|
||||||
|
### Fixed (1 change)
|
||||||
|
|
||||||
|
- Fix feature flag check for productivity analytics. !19025
|
||||||
|
|
||||||
|
|
||||||
|
## 12.4.1
|
||||||
|
|
||||||
|
### Security (6 changes)
|
||||||
|
|
||||||
|
- Do not display project labels that are not visible for user accessing group labels.
|
||||||
- Do not index system notes for issue update.
|
- Do not index system notes for issue update.
|
||||||
- Redact search results based on Ability.allowed?.
|
- Redact search results based on Ability.allowed?.
|
||||||
- Do not show private cross references in epic notes.
|
- Do not show private cross references in epic notes.
|
||||||
- Filter out packages the user does'nt have permission to see at group level.
|
- Filter out packages the user does'nt have permission to see at group level.
|
||||||
|
- Fixes a Open Redirect issue in `InternalRedirect`.
|
||||||
|
|
||||||
|
|
||||||
## 12.3.5
|
## 12.4.0
|
||||||
|
|
||||||
|
### Security (2 changes)
|
||||||
|
|
||||||
|
- Prevent IDOR when adding groups to protected environments.
|
||||||
|
- Hide approvers if a rule has any hidden groups.
|
||||||
|
|
||||||
|
### Removed (1 change)
|
||||||
|
|
||||||
|
- Remove db_load_balancing_index gauge metric. !17561
|
||||||
|
|
||||||
|
### Fixed (26 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Admin settings errors now shown in the correct panel. !14374
|
||||||
|
- Add missing error handling for epic quick actions. !15648
|
||||||
|
- Fix project exports clobbering concurrent export paths. !16280
|
||||||
|
- Fixes scroll handle icon in time series. !16354
|
||||||
|
- Remove hardcoded Medium confidence for Container Scanning vulnerabilities. !16395
|
||||||
|
- Fixed renaming changed files. !16539
|
||||||
|
- Fix project-defined metrics dashboards not rendering. !16589
|
||||||
|
- Remove duplication of Licenses in Dependency List page. !16946
|
||||||
|
- Backfill SPDX identifiers in software_licenses table. !17004
|
||||||
|
- Monitor charts: Validate form for creating an alert before submitting. !17109
|
||||||
|
- Hide Push rules link when you dont have a license installed. !17530
|
||||||
|
- Operations Dashboard: fix minimum query message. !17574
|
||||||
|
- Fix page layout for sidebar on designs view. !17579
|
||||||
|
- Display error for invalid insights config. !17589
|
||||||
|
- Display appropriate approval status icon next to license. !17613
|
||||||
|
- Fix deduplication of WASC vulnerabilities in the Security dashboard. !17778
|
||||||
|
- Fix burndown negative count edge case. !18053
|
||||||
|
- Change design management empty state button style. !18060 (George Tsiolis)
|
||||||
|
- Decouple dependency list parser from v1.0 license scanning report. !18103
|
||||||
|
- Respect Group SSO Enforcement on projects where the user is an owner. !18154
|
||||||
|
- Scoped labels do not remove old label in board sidebar. !18313
|
||||||
|
- Restrict number of users input to positive numbers. !18381
|
||||||
|
- Fix undefined method log_geo_deleted_event for MergeRequestDiff. !18405
|
||||||
|
- Add default empty values to prevent parser errors from approving the Vulnerability-Check rule. !18423
|
||||||
|
- Fix time tracking info when the sidebar is collapsed.
|
||||||
|
- Fix Discussion tab counter on Issues.
|
||||||
|
|
||||||
|
### Changed (18 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Style burndown charts with gitlab-ui. !15463
|
||||||
|
- Add epic_iid parameter to issues API. !15640
|
||||||
|
- Use a single badge to show number of active alerts on metrics dashboards. !15789
|
||||||
|
- Allow files with .svg extensions to be uploaded as designs for Design Management. !16160
|
||||||
|
- Implement dismissal behaviour when dismissed vulnerabilities are hidden. !16207
|
||||||
|
- Remove environment_metrics_show_multiple_dashboards feature flag. !16640
|
||||||
|
- Make name an optional parameter of releases. !16647
|
||||||
|
- Expose epics closed_at on API. !17156
|
||||||
|
- Add static_context API param when editing GitHub project service. !17397
|
||||||
|
- Support variable expansion in branch property of bridge jobs. !17430
|
||||||
|
- Add environment dropdown to pod logs screen. !17532
|
||||||
|
- Parse v2 license scanning reports. !17646
|
||||||
|
- Remove broken HTML5 routing behaviour from Pipeline Security Dashboard. !17767
|
||||||
|
- Change Prometheus Alert details list from bulleted to description list. !18116 (Vitali Tatarintev)
|
||||||
|
- Check for software license violations using SPDX identifiers. !18300
|
||||||
|
- Move 'Advanced search' message to search page title. !18349
|
||||||
|
- Add alert message for feature 'require approval from code owners' being moved. !18715
|
||||||
|
- Enable Productivity Analytics feature by default. !18754
|
||||||
|
|
||||||
|
### Performance (1 change)
|
||||||
|
|
||||||
|
- Reduce excessive GC on pull mirrors. !17931
|
||||||
|
|
||||||
|
### Added (35 changes)
|
||||||
|
|
||||||
|
- Allow Design Management files and data to be included in the project exporter/importer. !14702
|
||||||
|
- Create system notes for design events. !14791
|
||||||
|
- Paginate SCIM responses using count and startIndex. !14892
|
||||||
|
- Front-End UI for design deletion. !15034
|
||||||
|
- Add max issue count to lists. !15116
|
||||||
|
- Sign in / sign up step for trial. !15289
|
||||||
|
- Add notification for updated privacy policy. !15435
|
||||||
|
- Show Billing Plan as Cards in profile and groups. !15437
|
||||||
|
- Add Audit Event API. !15698
|
||||||
|
- Add configurable Code Owner approvals for protected branches. !15862
|
||||||
|
- Add Alerts Service to Projects. !16117
|
||||||
|
- Add Conan check_credentials API endpoint. !16215
|
||||||
|
- Initial endpoint for exposing Cycle Analytics stages for the new frontend. !16240
|
||||||
|
- Add ability to multi select issue board cards. !16317
|
||||||
|
- Add License-Check approval UI. !16371
|
||||||
|
- Add links to associated releases on Tags page. !16479
|
||||||
|
- Frontend implementation for improved trial sign-up experience for GitLab.com (SaaS) users. !16732
|
||||||
|
- Return Todos for Designs via the REST API. !16885
|
||||||
|
- Set active insights dashboard tab from hash fragment. !16904
|
||||||
|
- Extend group IP restriction to Git activity. !16980
|
||||||
|
- Inactivate pipeline retries for Merge Trains. !17065
|
||||||
|
- Expose time when the build was generated. !17113
|
||||||
|
- Add new table for recording commit counts per file. !17277
|
||||||
|
- Add vendored template for Browser Performance Testing. !17319
|
||||||
|
- Link Gitlab managed Prometheus alerts and issues. !17477
|
||||||
|
- Disable insights tab navigation whilst current page loads. !17678
|
||||||
|
- Drop all merge requests from merge trains when the project-level setting is disabled. !17774
|
||||||
|
- Implement DAST for default branches. !17789
|
||||||
|
- Add rack attack settings for prometheus and generic alert endpoint. !17859
|
||||||
|
- Add Licenses list backend usage ping. !17925
|
||||||
|
- Associate self-managed Prometheus Alerts and Issues. !18046
|
||||||
|
- Operator can see all projects using an instance level cluster. !18173
|
||||||
|
- Expose subscribed attribute for Epics in GraphQL. !18607
|
||||||
|
- Expose epic participants on GraphQL. !18691
|
||||||
|
- Adds a generic alert integration which can accept alerts from any source via a generic webhook receiver.
|
||||||
|
|
||||||
|
### Other (4 changes)
|
||||||
|
|
||||||
|
- Productivity analytics: Add scatterplot. !15569
|
||||||
|
- Updated sidebar navigation icons to be horizontally centered when bar is condensed. !16820
|
||||||
|
- Pin major version of SAST analyzers. !17110
|
||||||
|
- Docs for protected branch code owner approval API. !17132
|
||||||
|
|
||||||
- No changes.
|
|
||||||
|
|
||||||
## 12.3.4
|
## 12.3.4
|
||||||
|
|
||||||
|
@ -38,13 +162,6 @@ Please view this file on the master branch, on stable branches it's out of date.
|
||||||
- Geo: LFS not being synced. !17633
|
- Geo: LFS not being synced. !17633
|
||||||
|
|
||||||
|
|
||||||
## 12.3.3
|
|
||||||
|
|
||||||
### Security (1 change)
|
|
||||||
|
|
||||||
- Restrict access for security reports in MR widget.
|
|
||||||
|
|
||||||
|
|
||||||
## 12.3.2
|
## 12.3.2
|
||||||
|
|
||||||
### Security (2 changes)
|
### Security (2 changes)
|
||||||
|
@ -240,6 +357,29 @@ Please view this file on the master branch, on stable branches it's out of date.
|
||||||
- Fixes style-lint errors and warnings for EE builds.scss file.
|
- Fixes style-lint errors and warnings for EE builds.scss file.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.8
|
||||||
|
|
||||||
|
### Fixed (1 change)
|
||||||
|
|
||||||
|
- Geo: LFS not being synced. !17633
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.7
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Restrict access for security reports in MR widget.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.6
|
||||||
|
|
||||||
|
### Security (3 changes)
|
||||||
|
|
||||||
|
- Hide approvers if a rule has any hidden groups.
|
||||||
|
- Fix Gitaly SearchBlobs flag RPC injection [Gitaly v1.59.3].
|
||||||
|
- Prevent IDOR when adding groups to protected environments.
|
||||||
|
|
||||||
|
|
||||||
## 12.2.5
|
## 12.2.5
|
||||||
|
|
||||||
### Security (1 change)
|
### Security (1 change)
|
||||||
|
@ -492,6 +632,27 @@ Please view this file on the master branch, on stable branches it's out of date.
|
||||||
- Fix alignment of activity dropdown in epic tabs; add counter to discussion tab.
|
- Fix alignment of activity dropdown in epic tabs; add counter to discussion tab.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.14
|
||||||
|
|
||||||
|
### Fixed (1 change)
|
||||||
|
|
||||||
|
- Geo: LFS not being synced. !17633
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.12
|
||||||
|
|
||||||
|
### Security (4 changes)
|
||||||
|
|
||||||
|
- Hide approvers if a rule has any hidden groups.
|
||||||
|
- Fix Gitaly SearchBlobs flag RPC injection [Gitaly v1.53.4].
|
||||||
|
- Prevent IDOR when adding groups to protected environments.
|
||||||
|
- Upgrade mermaid to prevent XSS.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.10
|
||||||
|
|
||||||
|
- No changes.
|
||||||
|
|
||||||
## 12.1.5
|
## 12.1.5
|
||||||
|
|
||||||
- No changes.
|
- No changes.
|
||||||
|
@ -4264,7 +4425,7 @@ Please view this file on the master branch, on stable branches it's out of date.
|
||||||
## 8.14.0 (2016-11-22)
|
## 8.14.0 (2016-11-22)
|
||||||
|
|
||||||
- Added Backfill service for Geo. !861
|
- Added Backfill service for Geo. !861
|
||||||
- Fix for autosuggested approvers(https://gitlab.com/gitlab-org/gitlab-ee/issues/1273).
|
- Fix for autosuggested approvers(https://gitlab.com/gitlab-org/gitlab/issues/1273).
|
||||||
- Gracefully recover from previously failed rebase.
|
- Gracefully recover from previously failed rebase.
|
||||||
- Disable retries for remote mirror update worker. !848
|
- Disable retries for remote mirror update worker. !848
|
||||||
- Fix Approvals API documentation.
|
- Fix Approvals API documentation.
|
||||||
|
|
427
CHANGELOG.md
427
CHANGELOG.md
|
@ -2,15 +2,15 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
## 12.3.9
|
## 12.4.6
|
||||||
|
|
||||||
- No changes.
|
- No changes.
|
||||||
|
|
||||||
## 12.3.8
|
## 12.4.5
|
||||||
|
|
||||||
- No changes.
|
- No changes.
|
||||||
|
|
||||||
## 12.3.7
|
## 12.4.4
|
||||||
|
|
||||||
### Security (12 changes)
|
### Security (12 changes)
|
||||||
|
|
||||||
|
@ -28,13 +28,43 @@ entry.
|
||||||
- Add authorization to using filter vulnerable in Dependency List.
|
- Add authorization to using filter vulnerable in Dependency List.
|
||||||
|
|
||||||
|
|
||||||
## 12.3.6
|
## 12.4.3
|
||||||
|
|
||||||
### Security (15 changes)
|
### Fixed (2 changes)
|
||||||
|
|
||||||
|
- Only enable protected paths for POST requests. !19184
|
||||||
|
- Fix Bitbucket Cloud importer pull request state. !19734
|
||||||
|
|
||||||
|
|
||||||
|
## 12.4.2
|
||||||
|
|
||||||
|
### Fixed (10 changes)
|
||||||
|
|
||||||
|
- Increase timeout for FetchInternalRemote RPC call. !18908
|
||||||
|
- Clean up duplicate indexes on ci_trigger_requests. !19053
|
||||||
|
- Fix project imports not working with serialized data. !19124
|
||||||
|
- Fixed welcome screen icons not showing. !19148
|
||||||
|
- Disable protected path throttling by default. !19185
|
||||||
|
- Fix Prometheus duplicate metrics. !19327
|
||||||
|
- Fix ref switcher not working on Microsoft Edge. !19335
|
||||||
|
- Extend gRPC timeouts for Rake tasks. !19461
|
||||||
|
- Disable upload HTTP caching to fix case when object storage is enabled and proxy_download is disabled. !19494
|
||||||
|
- Removes arrow icons for old collapsible sections.
|
||||||
|
|
||||||
|
### Changed (2 changes)
|
||||||
|
|
||||||
|
- Increased deactivation threshold to 180 days. !18902
|
||||||
|
- Add extra sentence about registry to AutoDevOps popup. !19092
|
||||||
|
|
||||||
|
|
||||||
|
## 12.4.1
|
||||||
|
|
||||||
|
### Security (14 changes)
|
||||||
|
|
||||||
- Standardize error response when route is missing.
|
- Standardize error response when route is missing.
|
||||||
- Do not display project labels that are not visible for user accessing group labels.
|
- Do not display project labels that are not visible for user accessing group labels.
|
||||||
- Show cross-referenced label and milestones in issues' activities only to authorized users.
|
- Show cross-referenced label and milestones in issues' activities only to authorized users.
|
||||||
|
- Show cross-referenced label and milestones in issues' activities only to authorized users.
|
||||||
- Analyze incoming GraphQL queries and check for recursion.
|
- Analyze incoming GraphQL queries and check for recursion.
|
||||||
- Disallow unprivileged users from commenting on private repository commits.
|
- Disallow unprivileged users from commenting on private repository commits.
|
||||||
- Don't allow maintainers of a target project to delete the source branch of a merge request from a fork.
|
- Don't allow maintainers of a target project to delete the source branch of a merge request from a fork.
|
||||||
|
@ -44,16 +74,326 @@ entry.
|
||||||
- Mask sentry auth token in Error Tracking dashboard.
|
- Mask sentry auth token in Error Tracking dashboard.
|
||||||
- Fixes a Open Redirect issue in `InternalRedirect`.
|
- Fixes a Open Redirect issue in `InternalRedirect`.
|
||||||
- Remove deploy access level when project/group link is deleted.
|
- Remove deploy access level when project/group link is deleted.
|
||||||
- Sanitize search text to prevent XSS.
|
|
||||||
- Sanitize all wiki markup formats with GitLab sanitization pipelines.
|
- Sanitize all wiki markup formats with GitLab sanitization pipelines.
|
||||||
- Fix stored XSS issue for grafana_url.
|
|
||||||
|
|
||||||
|
|
||||||
## 12.3.5
|
## 12.4.0
|
||||||
|
|
||||||
### Security (1 change)
|
### Security (14 changes)
|
||||||
|
|
||||||
|
- HTML-escape search term in empty message. !18319
|
||||||
|
- Fix private feature Elasticsearch leak.
|
||||||
|
- Prevent bypassing email verification using Salesforce.
|
||||||
|
- Fix new project path being disclosed through unsubscribe link of issue/merge requests.
|
||||||
|
- Do not show resource label events referencing not accessible labels.
|
||||||
|
- Check permissions before showing head pipeline blocking merge requests.
|
||||||
|
- Cancel all running CI jobs triggered by the user who is just blocked.
|
||||||
|
- Do not disclose project milestones on group milestones page when project milestones access is disabled in project settings.
|
||||||
|
- Display only participants that user has permission to see on milestone page.
|
||||||
|
- Fix Gitaly SearchBlobs flag RPC injection.
|
||||||
|
- Add a policy check for system notes that may not be visible due to cross references to private items.
|
||||||
- Limit search for IID to a type to avoid leaking records with the same IID that the user does not have access to.
|
- Limit search for IID to a type to avoid leaking records with the same IID that the user does not have access to.
|
||||||
|
- Prevent GitLab accounts takeover if SAML is configured.
|
||||||
|
- Only render fixed number of mermaid blocks.
|
||||||
|
|
||||||
|
### Fixed (103 changes, 12 of them are from the community)
|
||||||
|
|
||||||
|
- When user toggles task list item, keep details open until user closes the details manually. !16153
|
||||||
|
- Fix formatting welcome screen external users. !16667
|
||||||
|
- Fix signup link in admin area not being disabled. !16726 (Illya Klymov)
|
||||||
|
- Fix routing bugs in security dashboards. !16738
|
||||||
|
- Fix Jira integration favicon image with relative URL. !16802
|
||||||
|
- Add timeout mechanism for CI config validation. !16807
|
||||||
|
- Fix for count in todo badge when user has over 1,000 todos. Will now correctly display todo count after user marks some todos as done. !16844 (Jesse Hall @jessehall3)
|
||||||
|
- Naming a project "shared" will no longer automatically open the "Shared Projects" tab. !16847 (Jesse Hall @jessehall3)
|
||||||
|
- Adds the ability to delete single tags from the docker registry. Fix the issue that caused all related tags and image to be deleted at the same time. !16886
|
||||||
|
- Changed confidential quick action to only be available on non confidential issues. !16902 (Marc Schwede)
|
||||||
|
- Stop sidebar icons from jumping when expanded & collapsed. !16971
|
||||||
|
- Set name and updated_at properly in GitHub ReleaseImporter. !17020
|
||||||
|
- Remove thin white line at top of diff view code blocks. !17026
|
||||||
|
- Show correct CI indicator when build succeeded with warnings. !17034
|
||||||
|
- Create a persistent ref per pipeline for keeping pipelines run from force-push and merged results. !17043
|
||||||
|
- Move SMAU usage counters to the UsageData count field. !17074
|
||||||
|
- Allow maintainers to toggle write permission for public deploy keys. !17210
|
||||||
|
- Fix GraphQL for read-only instances. !17225
|
||||||
|
- Fix visibility level error when updating group from API. !17227 (Mathieu Parent)
|
||||||
|
- Fix stylelint errors in epics.scss. !17243
|
||||||
|
- Fix new discussion replies sometimes showing up twice. !17255
|
||||||
|
- Adjust unnapliable suggestions in expanded lines. !17286
|
||||||
|
- Show all groups user belongs to in Notification settings. !17303
|
||||||
|
- Alphabetically sorts selected sidebar labels. !17309
|
||||||
|
- Show issue weight when weight is 0. !17329 (briankabiro)
|
||||||
|
- Generate LFS token authorization for user LFS requests. !17332
|
||||||
|
- Backfill releases table updated_at column and add not null constraints to created_at and updated_at. !17400
|
||||||
|
- Log Sidekiq exceptions properly in JSON format. !17412
|
||||||
|
- Redo fix for related issues border radius. !17480
|
||||||
|
- Show the original branch name and link of merge request in pipeline emails. !17513
|
||||||
|
- Fixes issues with the security reports migration. !17519
|
||||||
|
- Users can view the blame or history of a file with newlines in its filename. !17543 (Jesse Hall @jessehall3)
|
||||||
|
- Display reCAPTCHA modal when making issue public. !17553
|
||||||
|
- Fix css selector for details in issue description. !17557
|
||||||
|
- Prevents a group path change when a project inside the group has container registry images. !17583
|
||||||
|
- Show 20 labels in dropdown instead of 5. !17596
|
||||||
|
- Nullify platform Kubernetes namespace if blank. !17657
|
||||||
|
- Fix Issue: WebIDE asks for confirmation to leave the page when committing and creating a new MR. !17671
|
||||||
|
- Catch unhandled exceptions in health checks. !17694
|
||||||
|
- Suppress error messages shown when navigating to a new page. !17706
|
||||||
|
- Specify sort order explicitly for Group and Project audit events. !17739
|
||||||
|
- Merge Request: Close JIRA issues when issues are disabled. !17743
|
||||||
|
- Disable gitlab-workhorse static error page on health endpoints. !17770
|
||||||
|
- Fix notes race condition when linking to specific note. !17777
|
||||||
|
- Fix relative positioning when moving items down and there is no space. !17781
|
||||||
|
- Fix project imports for pipelines for merge requests. !17799
|
||||||
|
- Increase the limit of includes in CI file to 100. !17807
|
||||||
|
- Geo: Fix race condition for container synchronization. !17823
|
||||||
|
- Geo: Invalidate cache after refreshing foreign tables. !17885
|
||||||
|
- Abort Merge When Pipeline Succeeds when Fast Forward merge is impossible. !17886
|
||||||
|
- Fix viewing merge reqeust from a fork that's being deleted. !17894
|
||||||
|
- Fix empty security dashboard for public projects. !17915
|
||||||
|
- Fix inline rendering of videos for uploads with uppercase file extensions. !17924
|
||||||
|
- Hide redundant labels in issue boards. !17937
|
||||||
|
- Time window filter in monitor dashboard gets reset. !17972
|
||||||
|
- Use cache_method_asymmetrically with Repository#has_visible_content?. !17975
|
||||||
|
- Allow users to compare Git revisions on a read-only instance. !18038
|
||||||
|
- Enable Google API retries for uploads. !18040
|
||||||
|
- Fix bug with new wiki not being indexed. !18051
|
||||||
|
- Stops the expand button in reports from expanding. !18064
|
||||||
|
- Make sure project insights stick on its own. !18082
|
||||||
|
- Embed metrics time window scroll no longer affects other embeds. !18109
|
||||||
|
- Fix broken notes avatar rendering in Chrome 77. !18110
|
||||||
|
- Ignore incoming emails with X-Autoreply header. !18118
|
||||||
|
- Enable grid, frame and stripes styling on AsciiDoc tables. !18165 (Guillaume Grossetie)
|
||||||
|
- Add backend support for selecting custom templates by ID. !18178
|
||||||
|
- Fix notifications for private group mentions in Notes, Issues, and Merge Requests. !18183
|
||||||
|
- Do not strip forwarded message body when creating an issue from Service Desk email. !18196
|
||||||
|
- Fix protected branch detection used by notification service. !18221
|
||||||
|
- Fix error where helper was incorrectly returning `true`. !18231
|
||||||
|
- Adjust placeholder to solve misleading regex. !18235
|
||||||
|
- Fix Flaky spec/finders/members_finder_spec.rb:85. !18257 (Jacopo Beschi @jacopo-beschi)
|
||||||
|
- Fix 500 error on clicking to LetsEncrypt Terms of Service. !18263
|
||||||
|
- Fix error tracking table layout on small screens. !18325
|
||||||
|
- GitHub import: Handle nil published_at dates. !18355
|
||||||
|
- Do not allow deactivated users to use slash commands. !18365
|
||||||
|
- Fix creating epics with dates from api. !18393
|
||||||
|
- JIRA Service: Improve username/email validation. !18397
|
||||||
|
- Stopped CRD apply retrying from allowing silent failures. !18421
|
||||||
|
- Fix erroneous "No activities found" message. !18434
|
||||||
|
- Support ES searches for project snippets. !18459
|
||||||
|
- Fix styling of set status emoji picker. !18509
|
||||||
|
- Fix showing diff when it has legacy diff notes. !18510
|
||||||
|
- JIRA Integration API URL works having a trailing slash. !18526
|
||||||
|
- Fixes embedded metrics chart tooltip spacing. !18543
|
||||||
|
- Bump GITLAB_ELASTICSEARCH_INDEXER_VERSION=v1.4.0. !18558
|
||||||
|
- Fix pod logs failure when pod contains more than 1 container. !18574
|
||||||
|
- Prevent the slash command parser from removing leading whitespace from content that is unrelated to slash commands. !18589 (Jared Deckard)
|
||||||
|
- Fix inability to set snippet visibility via API. !18612
|
||||||
|
- Fix Web IDE tree not updating modified status. !18647
|
||||||
|
- Fix button link foreground color. !18669
|
||||||
|
- Resolve missing design system notes icons. !18693
|
||||||
|
- Remove duplicate primary button in dashboard snippets. !32048 (George Tsiolis)
|
||||||
|
- Allow to view productivity analytics page without a license. !33876
|
||||||
|
- Fix container registry delete tag modal title and button. !34032
|
||||||
|
- Fixes variables overflowing in sm screens.
|
||||||
|
- Update top nav bar to fit all content in at all screen sizes.
|
||||||
|
- Fix permissions for group milestones.
|
||||||
|
- Removes Collapsible Sections from Job Log.
|
||||||
|
- Fixes job overflow in stages dropdown.
|
||||||
|
- Fix moved help URL for monitoring performance.
|
||||||
|
- Fix issue with wiki TOC links being treated as external links. (Oren Kanner)
|
||||||
|
- Show error message when setting an invalid group ID for the performance bar.
|
||||||
|
|
||||||
|
### Deprecated (1 change)
|
||||||
|
|
||||||
|
- Removing cleanup:repo, cleanup:dirs. !18087
|
||||||
|
|
||||||
|
### Changed (51 changes, 3 of them are from the community)
|
||||||
|
|
||||||
|
- Links on Releases page to commits and tags. !16128
|
||||||
|
- Add status to deployments and state to environments in API responses. !16242
|
||||||
|
- Use search scope label in empty results message. !16324
|
||||||
|
- Add step 2 of the experimental signup flow. !16583
|
||||||
|
- Add property to enable metrics dashboards to be rearranged. !16605
|
||||||
|
- Allow intra-project MR dependencies. !16799
|
||||||
|
- Use scope param instead of hide_dismissed. !16834
|
||||||
|
- Add empty state in file search. !16851
|
||||||
|
- Warn before applying issue templates. !16865
|
||||||
|
- MR Test Summary now shows errors as failures. !17039
|
||||||
|
- Add support for the association of multiple milestones to the Releases page. !17091
|
||||||
|
- Display if an issue was moved in issue list. !17102
|
||||||
|
- Improve UI for admin/projects and group/settings/projects pages. !17247
|
||||||
|
- Update registry tag delete popup message. !17257
|
||||||
|
- Show the "Set up CI/CD" prompt in empty repositories when applicable. !17274 (Ben McCormick)
|
||||||
|
- Knative version bump 0.6 -> 0.7. !17367 (Chris Baumbauer)
|
||||||
|
- Fix usability problems with the file template picker. !17522
|
||||||
|
- Make commit status created for any pipelines. !17524 (Aufar Gilbran)
|
||||||
|
- Add warnings to performance bar when page shows signs of poor performance. !17612
|
||||||
|
- Banners should only be dismissable by clicking x button. !17642
|
||||||
|
- Changes response body of liveness check to be more accurate. !17655
|
||||||
|
- Enable Request Access functionality by default for new projects and groups. !17662
|
||||||
|
- Add more attributes to issues GraphQL endpoint. !17802
|
||||||
|
- Improve admin/system_info page ui. !17829
|
||||||
|
- Adds management project for a cluster. !17866
|
||||||
|
- Upgrade gitlab-workhorse to 8.12.0. !17892
|
||||||
|
- Geo: Fix instruction from rake geo:gitlab:check. !17895
|
||||||
|
- Upgrade to Gitaly v1.66.0. !17900
|
||||||
|
- Do not start mirroring via API when paused. !17930
|
||||||
|
- Use MR links in PipelinePresenter#ref_text for branch pipelines. !17947
|
||||||
|
- Avoid knative and prometheus uninstall race condition. !18020
|
||||||
|
- Deprecate usage of state column for issues and merge requests. !18099
|
||||||
|
- Add missing page title to projects/container-registry. !18114
|
||||||
|
- Port over EE pipeline functionality to CE. !18136
|
||||||
|
- Aggregate push events when there are too many. !18239
|
||||||
|
- Cleanup background migrations for any approval rules. !18256
|
||||||
|
- Container registry tag(s) delete button pluralization. !18260
|
||||||
|
- Create clusters with VPC-Native enabled. !18284
|
||||||
|
- Update cluster link text. !18322
|
||||||
|
- Upgrade to Gitaly v1.67.0. !18326
|
||||||
|
- Improve UI of documentation under /help. !18331
|
||||||
|
- Cross-link unreplicated Geo types to issues. !18443
|
||||||
|
- Make designs read-only if the issue has been moved, or if its discussion has been locked. !18551
|
||||||
|
- Do not show new issue button on archived projects. !18590
|
||||||
|
- Increase group avatar size to 40px. !18654
|
||||||
|
- Sort vulnerabilities by severity then confidence for dashboard and pipeline views. !18675
|
||||||
|
- Add timeouts for each RPC call. !31766
|
||||||
|
- Add more specific message to clarify the role of empty images in container registry. !32919
|
||||||
|
- Embed Jaeger in Gitlab UI.
|
||||||
|
- Use text instead of icon for recent searches dropdown.
|
||||||
|
- Export liveness and readiness probes.
|
||||||
|
|
||||||
|
### Performance (25 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Limit diverging commit counts requests. !16737
|
||||||
|
- Use GetBlobs RPC for uri type. !16824
|
||||||
|
- Reduce Gitaly calls when viewing a commit. !17095
|
||||||
|
- Limit snippets search count. !17585
|
||||||
|
- Narrow snippet search scope in GitLab.com. !17625
|
||||||
|
- Handle wiki and graphql attachments in gitlab-workhorse. !17690
|
||||||
|
- Reduce lock contention of deployment creation by allocating IID outside of the pipeline transaction. !17696
|
||||||
|
- Update PumaWorkerKiller defaults. !17758
|
||||||
|
- Add trigram index on snippet content. !17806
|
||||||
|
- Fix Gitaly N+1 queries in related merge requests API. !17850
|
||||||
|
- Don't execute webhooks/services when above limit. !17874
|
||||||
|
- Only schedule updating push-mirrors once per push. !17902
|
||||||
|
- Show only personal snippets on explore page. !18092
|
||||||
|
- Priority bump authorized_projects sidekiq queue. !18125
|
||||||
|
- Avoid dumping files on disk when direct_upload is enabled. !18135
|
||||||
|
- Check if mapping is empty before caching in File Collections. !18290 (briankabiro)
|
||||||
|
- Avoid unnecessary locks on internal_ids. !18328
|
||||||
|
- Fix N+1 queries in Jira Development Panel API endpoint. !18329
|
||||||
|
- Optimize SQL requests for BlameController and CommitsController. !18342
|
||||||
|
- Remove N+1 for fetching commits signatures. !18389
|
||||||
|
- Reduce idle in transaction time when updating a merge request. !18493
|
||||||
|
- Use cascading deletes for deleting logs upon deleting a webhook. !18642
|
||||||
|
- Replace index on ci_triggers. !18652
|
||||||
|
- Hide license breakdown in /admin if user count is high. !18825
|
||||||
|
- Cache branch and tag names as Redis sets. !30476
|
||||||
|
|
||||||
|
### Added (78 changes, 12 of them are from the community)
|
||||||
|
|
||||||
|
- Adds sorting of packages at the project level. !15448
|
||||||
|
- Add projects.only option to Insights. !15930
|
||||||
|
- Add kubernetes section to group runner settings. !16338
|
||||||
|
- Enable Cloud Run on GKE cluster creation. !16566
|
||||||
|
- Add file matching rule to flexible CI rules. !16574
|
||||||
|
- Enable preview of private artifacts. !16675 (Tuomo Ala-Vannesluoma)
|
||||||
|
- Upgrade Gitaly to v1.64. !16788
|
||||||
|
- Render xml artifact files in GitLab. !16790
|
||||||
|
- Add GitHub & Gitea importers project filtering. !16823
|
||||||
|
- Add project filtering to Bitbucket Cloud import. !16828
|
||||||
|
- Provides internationalization support to chart legends. !16832
|
||||||
|
- Expose name property in imports API. !16848
|
||||||
|
- Add allowFilter and allowAnySHA1InWant for partial clones. !16850
|
||||||
|
- [ObjectStorage] Allow migrating back to local storage. !16868
|
||||||
|
- Require admins to enter admin-mode by re-authenticating before performing administrative operations. !16981 (Roger Rüttimann & Diego Louzán)
|
||||||
|
- Deactivate a user (with self-service reactivation). !17037
|
||||||
|
- Add database tables to store AWS roles and cluster providers. !17057
|
||||||
|
- Collect docker registry related metrics. !17063
|
||||||
|
- Allow releases to be targeted by URL anchor links on the Releases page. !17150
|
||||||
|
- Add project_pages_metadata DB table. !17197
|
||||||
|
- Add index on ci_builds for successful Pages deploys. !17204
|
||||||
|
- Creation of Evidence collection of new releases. !17217
|
||||||
|
- API: Add missing group parameters. !17220 (Mathieu Parent)
|
||||||
|
- Allow to exclude ancestor groups on group labels API. !17221 (Mathieu Parent)
|
||||||
|
- Added 'copy link' in epic comment dropdown. !17224
|
||||||
|
- Add columns for per project/group max pages/artifacts sizes. !17231
|
||||||
|
- Create table for grafana api token for metrics embeds. !17234
|
||||||
|
- Add proper label REST API for update, delete and promote. !17239 (Mathieu Parent)
|
||||||
|
- Allow cross-project pipeline triggering with CI_JOB_TOKEN in core. !17251
|
||||||
|
- Add user_id and created_at columns to design_management_versions table. !17316
|
||||||
|
- Add pull_mirror_branch_prefix column on projects table. !17368
|
||||||
|
- Expose web_url for epics on API. !17380
|
||||||
|
- Improve time window filtering on metrics dashboard. !17554
|
||||||
|
- Group level Container Registry browser. !17615
|
||||||
|
- Add API for manually creating and updating deployments. !17620
|
||||||
|
- Introduce diffs_batch JSON endpoint for paginated diffs. !17651
|
||||||
|
- Web IDE button should fork and open forked project when selected from read-only project. !17672
|
||||||
|
- Allow users to be searched with a @ prefix. !17742
|
||||||
|
- Add individual inherited member lookup API. !17744
|
||||||
|
- Preserve custom .gitlab-ci.yml config path when forking. !17817 (Mathieu Parent)
|
||||||
|
- Introduce CI_PROJECT_TITLE as predefined environment variable. !17849 (Nejc Habjan)
|
||||||
|
- Feature enabling embedded audio elements in markdown. !17860 (Jesse Hall @jessehall3)
|
||||||
|
- Add 'New release' to the project custom notifications. !17877
|
||||||
|
- Added timestamps (created_at and updated_at) to API pipelines response. !17911
|
||||||
|
- Added timestamp (updated_at) to API deployments response. !17913
|
||||||
|
- Add pipeline preparing status icons. !17923
|
||||||
|
- Creates Vue and Vuex app to render exposed artifacts. !17934
|
||||||
|
- Add web_exporter to expose Prometheus metrics. !17943
|
||||||
|
- Schedule background migration to populate pages metadata. !17993
|
||||||
|
- Add "Edit Release" page. !18033
|
||||||
|
- Unpin ingress image version, upgrade chart to 1.22.1. !18047
|
||||||
|
- Adds sorting of packages at the group level. !18062
|
||||||
|
- Introduce a lightweight diffs_metadata endpoint. !18104
|
||||||
|
- Limit the number of comments on an issue, MR, or commit. !18111
|
||||||
|
- Introduce new Ansi2json parser to convert job logs to JSON. !18133
|
||||||
|
- Use new Ansi2json job log converter via feature flag. !18134
|
||||||
|
- Snowplow custom events for Monitor: Health Product Categories. !18157
|
||||||
|
- Support Create/Read/Destroy operations in Feature Flag API. !18198
|
||||||
|
- Add two new predefined stages to pipelines. !18205
|
||||||
|
- Add endpoint to proxy requests to grafana's proxy endpoint. !18210
|
||||||
|
- Add ability to query todos using GraphQL. !18218
|
||||||
|
- Include in the callout message a list of jobs that caused missing dependencies failure. !18219
|
||||||
|
- Adds login input with copy box and supporting copy to empty container registry view. !18244 (nate geslin)
|
||||||
|
- Add max_artifacts_size fields under project and group settings. !18286
|
||||||
|
- Provide Merge requests and Issue links through the Release API. !18311
|
||||||
|
- Adds separate parsers for mentions of users, groups, projects in markdown content. !18318
|
||||||
|
- Add matching branch info to branch column. !18352
|
||||||
|
- Users can preview audio files in a repository. !18354 (Jesse Hall @jessehall3)
|
||||||
|
- Add edit button to release blocks on Releases page. !18411
|
||||||
|
- Add "Custom HTTP Git clone URL root" setting. !18422
|
||||||
|
- Add support for epic update through GraphQL API. !18440
|
||||||
|
- Expose subscribed attribute for epic on API. !18475
|
||||||
|
- Geo: Enable replicating uploads, LFS objects, and artifacts in Object Storage. !18482
|
||||||
|
- Show related merge requests in pipeline view. !18697
|
||||||
|
- Allow users to configure protected paths from Admin panel. !31246
|
||||||
|
- persist the refs when open the link of refs in a new tab of browser. !31998 (minghuan lei)
|
||||||
|
- Add first_parent option to list commits api. !32410 (jhenkens)
|
||||||
|
- Allow users to add and remove zoom rooms on an issue using quick action commands.
|
||||||
|
|
||||||
|
### Other (23 changes, 5 of them are from the community)
|
||||||
|
|
||||||
|
- Sync issuables state_id with null values. !16480
|
||||||
|
- Experimental separate sign up flow. !16482
|
||||||
|
- Upgrade Rouge to v3.11.0. !17011
|
||||||
|
- Better job naming for Docker.gitlab-ci.yml. !17218 (luca.orlandi@gmail.com)
|
||||||
|
- Update GitLab Runner Helm Chart to 0.9.0. !17326
|
||||||
|
- Change welcome message and make translatable. !17391
|
||||||
|
- Remove map-get($grid-breakpoints, xs) for max-width. !17420 (Takuya Noguchi)
|
||||||
|
- Document Git LFS and max file size interaction. !17609
|
||||||
|
- Refactor email notification code. !17741 (briankabiro)
|
||||||
|
- Ignore id column of ci_build_trace_sections table. !17805
|
||||||
|
- Extend graphql query endpoint for merge requests to return more attributes to support sidebar implementation. !17813
|
||||||
|
- Project list: Align star icons. !17833
|
||||||
|
- Moves the license compliance reports to the Backend. !17905
|
||||||
|
- Fixes wrong link on Protected paths admin settings. !17945
|
||||||
|
- Update Pages to v1.11.0. !18010
|
||||||
|
- Refactor checksum code in uploads. !18065 (briankabiro)
|
||||||
|
- Make instance configuration user friendly. !18363 (Takuya Noguchi)
|
||||||
|
- Update Workhorse to v8.14.0. !18391
|
||||||
|
- Attribute each Sidekiq worker to a feature category. !18462
|
||||||
|
- Update GitLab Shell to v10.2.0. !18735
|
||||||
|
- Use correct icons for issue actions.
|
||||||
|
- Increase color contrast of select option path.
|
||||||
|
- Remove Postgresql specific setup tasks and move to schema.rb.
|
||||||
|
|
||||||
|
|
||||||
## 12.3.4
|
## 12.3.4
|
||||||
|
@ -64,13 +404,6 @@ entry.
|
||||||
- Fix pipelines for merge requests in project exports. !17844
|
- Fix pipelines for merge requests in project exports. !17844
|
||||||
|
|
||||||
|
|
||||||
## 12.3.3
|
|
||||||
|
|
||||||
### Security (1 change)
|
|
||||||
|
|
||||||
- Fix private feature Elasticsearch leak.
|
|
||||||
|
|
||||||
|
|
||||||
## 12.3.2
|
## 12.3.2
|
||||||
|
|
||||||
### Security (12 changes)
|
### Security (12 changes)
|
||||||
|
@ -368,6 +701,37 @@ entry.
|
||||||
- Updates tooltip of 'detached' label/state.
|
- Updates tooltip of 'detached' label/state.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.8
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Limit search for IID to a type to avoid leaking records with the same IID that the user does not have access to.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.7
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Fix private feature Elasticsearch leak.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.6
|
||||||
|
|
||||||
|
### Security (11 changes)
|
||||||
|
|
||||||
|
- Add a policy check for system notes that may not be visible due to cross references to private items.
|
||||||
|
- Display only participants that user has permission to see on milestone page.
|
||||||
|
- Do not disclose project milestones on group milestones page when project milestones access is disabled in project settings.
|
||||||
|
- Check permissions before showing head pipeline blocking merge requests.
|
||||||
|
- Fix new project path being disclosed through unsubscribe link of issue/merge requests.
|
||||||
|
- Prevent bypassing email verification using Salesforce.
|
||||||
|
- Do not show resource label events referencing not accessible labels.
|
||||||
|
- Cancel all running CI jobs triggered by the user who is just blocked.
|
||||||
|
- Fix Gitaly SearchBlobs flag RPC injection [Gitaly v1.59.3].
|
||||||
|
- Only render fixed number of mermaid blocks.
|
||||||
|
- Prevent GitLab accounts takeover if SAML is configured.
|
||||||
|
|
||||||
|
|
||||||
## 12.2.5
|
## 12.2.5
|
||||||
|
|
||||||
### Security (1 change)
|
### Security (1 change)
|
||||||
|
@ -686,6 +1050,35 @@ entry.
|
||||||
- Update Packer.gitlab-ci.yml to use latest image. (Kelly Hair)
|
- Update Packer.gitlab-ci.yml to use latest image. (Kelly Hair)
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.14
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Limit search for IID to a type to avoid leaking records with the same IID that the user does not have access to.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.12
|
||||||
|
|
||||||
|
### Security (12 changes)
|
||||||
|
|
||||||
|
- Add a policy check for system notes that may not be visible due to cross references to private items.
|
||||||
|
- Display only participants that user has permission to see on milestone page.
|
||||||
|
- Do not disclose project milestones on group milestones page when project milestones access is disabled in project settings.
|
||||||
|
- Check permissions before showing head pipeline blocking merge requests.
|
||||||
|
- Fix new project path being disclosed through unsubscribe link of issue/merge requests.
|
||||||
|
- Prevent bypassing email verification using Salesforce.
|
||||||
|
- Do not show resource label events referencing not accessible labels.
|
||||||
|
- Cancel all running CI jobs triggered by the user who is just blocked.
|
||||||
|
- Fix Gitaly SearchBlobs flag RPC injection.
|
||||||
|
- Only render fixed number of mermaid blocks.
|
||||||
|
- Prevent GitLab accounts takeover if SAML is configured.
|
||||||
|
- Upgrade mermaid to prevent XSS.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.10
|
||||||
|
|
||||||
|
- No changes.
|
||||||
|
|
||||||
## 12.1.5
|
## 12.1.5
|
||||||
|
|
||||||
### Security (2 changes)
|
### Security (2 changes)
|
||||||
|
@ -8450,7 +8843,7 @@ entry.
|
||||||
- Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm)
|
- Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm)
|
||||||
- Fix edit button for deploy keys available from other projects. !12301 (Alexander Randa)
|
- Fix edit button for deploy keys available from other projects. !12301 (Alexander Randa)
|
||||||
- Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL. !12344
|
- Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL. !12344
|
||||||
- Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab-ee/issues/2677. !12347
|
- Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab/issues/2677. !12347
|
||||||
- Standardize timeline note margins across different viewport sizes. !12364
|
- Standardize timeline note margins across different viewport sizes. !12364
|
||||||
- Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>)
|
- Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>)
|
||||||
- Upgrade dependency to Go 1.8.3. !31943
|
- Upgrade dependency to Go 1.8.3. !31943
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_relative 'lib/gitlab_danger'
|
require_relative 'lib/gitlab_danger'
|
||||||
|
require_relative 'lib/gitlab/danger/request_helper'
|
||||||
|
|
||||||
danger.import_plugin('danger/plugins/helper.rb')
|
danger.import_plugin('danger/plugins/helper.rb')
|
||||||
danger.import_plugin('danger/plugins/roulette.rb')
|
danger.import_plugin('danger/plugins/roulette.rb')
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.65.2
|
1.67.1
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.3.0
|
1.4.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.9.0
|
1.11.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
10.0.0
|
10.2.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
8.10.1
|
8.14.1
|
||||||
|
|
16
Gemfile
16
Gemfile
|
@ -87,9 +87,9 @@ gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
|
||||||
|
|
||||||
# GraphQL API
|
# GraphQL API
|
||||||
gem 'graphql', '~> 1.9.11'
|
gem 'graphql', '~> 1.9.11'
|
||||||
# NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab-ce/issues/67293
|
# NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab/issues/31771
|
||||||
# TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released:
|
# TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released:
|
||||||
# https://gitlab.com/gitlab-org/gitlab-ce/issues/67263
|
# https://gitlab.com/gitlab-org/gitlab/issues/31747
|
||||||
gem 'graphiql-rails', '~> 1.4.10'
|
gem 'graphiql-rails', '~> 1.4.10'
|
||||||
gem 'apollo_upload_server', '~> 2.0.0.beta3'
|
gem 'apollo_upload_server', '~> 2.0.0.beta3'
|
||||||
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]
|
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]
|
||||||
|
@ -148,7 +148,7 @@ gem 'wikicloth', '0.8.1'
|
||||||
gem 'asciidoctor', '~> 2.0.10'
|
gem 'asciidoctor', '~> 2.0.10'
|
||||||
gem 'asciidoctor-include-ext', '~> 0.3.1', require: false
|
gem 'asciidoctor-include-ext', '~> 0.3.1', require: false
|
||||||
gem 'asciidoctor-plantuml', '0.0.9'
|
gem 'asciidoctor-plantuml', '0.0.9'
|
||||||
gem 'rouge', '~> 3.7'
|
gem 'rouge', '~> 3.11.0'
|
||||||
gem 'truncato', '~> 0.7.11'
|
gem 'truncato', '~> 0.7.11'
|
||||||
gem 'bootstrap_form', '~> 4.2.0'
|
gem 'bootstrap_form', '~> 4.2.0'
|
||||||
gem 'nokogiri', '~> 1.10.4'
|
gem 'nokogiri', '~> 1.10.4'
|
||||||
|
@ -311,7 +311,7 @@ gem 'gettext', '~> 3.2.2', require: false, group: :development
|
||||||
gem 'batch-loader', '~> 1.4.0'
|
gem 'batch-loader', '~> 1.4.0'
|
||||||
|
|
||||||
# Perf bar
|
# Perf bar
|
||||||
# https://gitlab.com/gitlab-org/gitlab-ee/issues/13996
|
# https://gitlab.com/gitlab-org/gitlab/issues/13996
|
||||||
gem 'gitlab-peek', '~> 0.0.1', require: 'peek'
|
gem 'gitlab-peek', '~> 0.0.1', require: 'peek'
|
||||||
|
|
||||||
# Snowplow events tracking
|
# Snowplow events tracking
|
||||||
|
@ -355,7 +355,7 @@ group :development, :test do
|
||||||
gem 'fuubar', '~> 2.2.0'
|
gem 'fuubar', '~> 2.2.0'
|
||||||
|
|
||||||
gem 'database_cleaner', '~> 1.7.0'
|
gem 'database_cleaner', '~> 1.7.0'
|
||||||
gem 'factory_bot_rails', '~> 4.8.2'
|
gem 'factory_bot_rails', '~> 5.1.0'
|
||||||
gem 'rspec-rails', '~> 3.8.0'
|
gem 'rspec-rails', '~> 3.8.0'
|
||||||
gem 'rspec-retry', '~> 0.6.1'
|
gem 'rspec-retry', '~> 0.6.1'
|
||||||
gem 'rspec_profiling', '~> 0.0.5'
|
gem 'rspec_profiling', '~> 0.0.5'
|
||||||
|
@ -405,7 +405,7 @@ group :test do
|
||||||
gem 'webmock', '~> 3.5.1'
|
gem 'webmock', '~> 3.5.1'
|
||||||
gem 'rails-controller-testing'
|
gem 'rails-controller-testing'
|
||||||
gem 'concurrent-ruby', '~> 1.1'
|
gem 'concurrent-ruby', '~> 1.1'
|
||||||
gem 'test-prof', '~> 0.2.5'
|
gem 'test-prof', '~> 0.10.0'
|
||||||
gem 'rspec_junit_formatter'
|
gem 'rspec_junit_formatter'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ group :ed25519 do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gitaly GRPC protocol definitions
|
# Gitaly GRPC protocol definitions
|
||||||
gem 'gitaly', '~> 1.58.0'
|
gem 'gitaly', '~> 1.65.0'
|
||||||
|
|
||||||
gem 'grpc', '~> 1.19.0'
|
gem 'grpc', '~> 1.19.0'
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ gem 'lograge', '~> 0.5'
|
||||||
gem 'grape_logging', '~> 1.7'
|
gem 'grape_logging', '~> 1.7'
|
||||||
|
|
||||||
# DNS Lookup
|
# DNS Lookup
|
||||||
gem 'net-dns', '~> 0.9.0'
|
gem 'gitlab-net-dns', '~> 0.9.1'
|
||||||
|
|
||||||
# Countries list
|
# Countries list
|
||||||
gem 'countries', '~> 3.0'
|
gem 'countries', '~> 3.0'
|
||||||
|
|
58
Gemfile.lock
58
Gemfile.lock
|
@ -108,7 +108,7 @@ GEM
|
||||||
binding_ninja (0.2.3)
|
binding_ninja (0.2.3)
|
||||||
binding_of_caller (0.8.0)
|
binding_of_caller (0.8.0)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
bootsnap (1.4.4)
|
bootsnap (1.4.5)
|
||||||
msgpack (~> 1.0)
|
msgpack (~> 1.0)
|
||||||
bootstrap_form (4.2.0)
|
bootstrap_form (4.2.0)
|
||||||
actionpack (>= 5.0)
|
actionpack (>= 5.0)
|
||||||
|
@ -209,10 +209,10 @@ GEM
|
||||||
descendants_tracker (0.0.4)
|
descendants_tracker (0.0.4)
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
device_detector (1.0.0)
|
device_detector (1.0.0)
|
||||||
devise (4.6.2)
|
devise (4.7.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0, < 6.0)
|
railties (>= 4.1.0)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (3.0.0)
|
devise-two-factor (3.0.0)
|
||||||
|
@ -254,7 +254,7 @@ GEM
|
||||||
mail (~> 2.7)
|
mail (~> 2.7)
|
||||||
encryptor (3.0.0)
|
encryptor (3.0.0)
|
||||||
equalizer (0.0.11)
|
equalizer (0.0.11)
|
||||||
erubi (1.8.0)
|
erubi (1.9.0)
|
||||||
escape_utils (1.2.1)
|
escape_utils (1.2.1)
|
||||||
et-orbi (1.2.1)
|
et-orbi (1.2.1)
|
||||||
tzinfo
|
tzinfo
|
||||||
|
@ -264,11 +264,11 @@ GEM
|
||||||
expression_parser (0.9.0)
|
expression_parser (0.9.0)
|
||||||
extended-markdown-filter (0.6.0)
|
extended-markdown-filter (0.6.0)
|
||||||
html-pipeline (~> 2.0)
|
html-pipeline (~> 2.0)
|
||||||
factory_bot (4.8.2)
|
factory_bot (5.1.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 4.2.0)
|
||||||
factory_bot_rails (4.8.2)
|
factory_bot_rails (5.1.0)
|
||||||
factory_bot (~> 4.8.2)
|
factory_bot (~> 5.1.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 4.2.0)
|
||||||
faraday (0.12.2)
|
faraday (0.12.2)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
faraday-http-cache (2.0.0)
|
faraday-http-cache (2.0.0)
|
||||||
|
@ -358,7 +358,7 @@ GEM
|
||||||
po_to_json (>= 1.0.0)
|
po_to_json (>= 1.0.0)
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
git (1.5.0)
|
git (1.5.0)
|
||||||
gitaly (1.58.0)
|
gitaly (1.65.0)
|
||||||
grpc (~> 1.0)
|
grpc (~> 1.0)
|
||||||
github-markup (1.7.0)
|
github-markup (1.7.0)
|
||||||
gitlab-labkit (0.5.2)
|
gitlab-labkit (0.5.2)
|
||||||
|
@ -370,6 +370,7 @@ GEM
|
||||||
redis (> 3.0.0, < 5.0.0)
|
redis (> 3.0.0, < 5.0.0)
|
||||||
gitlab-license (1.0.0)
|
gitlab-license (1.0.0)
|
||||||
gitlab-markup (1.7.0)
|
gitlab-markup (1.7.0)
|
||||||
|
gitlab-net-dns (0.9.1)
|
||||||
gitlab-peek (0.0.1)
|
gitlab-peek (0.0.1)
|
||||||
railties (>= 4.0.0)
|
railties (>= 4.0.0)
|
||||||
gitlab-sidekiq-fetcher (0.5.2)
|
gitlab-sidekiq-fetcher (0.5.2)
|
||||||
|
@ -487,7 +488,7 @@ GEM
|
||||||
mime-types (~> 3.0)
|
mime-types (~> 3.0)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.6.0)
|
i18n (1.7.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
i18n_data (0.8.0)
|
i18n_data (0.8.0)
|
||||||
icalendar (2.4.1)
|
icalendar (2.4.1)
|
||||||
|
@ -565,7 +566,7 @@ GEM
|
||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
railties (>= 4)
|
railties (>= 4)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.2.3)
|
loofah (2.3.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.7.1)
|
mail (2.7.1)
|
||||||
|
@ -586,7 +587,7 @@ GEM
|
||||||
mini_mime (1.0.1)
|
mini_mime (1.0.1)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
minitest (5.11.3)
|
minitest (5.11.3)
|
||||||
msgpack (1.3.0)
|
msgpack (1.3.1)
|
||||||
multi_json (1.13.1)
|
multi_json (1.13.1)
|
||||||
multi_xml (0.6.0)
|
multi_xml (0.6.0)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
|
@ -596,7 +597,6 @@ GEM
|
||||||
mustermann (~> 1.0.0)
|
mustermann (~> 1.0.0)
|
||||||
nakayoshi_fork (0.0.4)
|
nakayoshi_fork (0.0.4)
|
||||||
nap (1.1.0)
|
nap (1.1.0)
|
||||||
net-dns (0.9.0)
|
|
||||||
net-ldap (0.16.0)
|
net-ldap (0.16.0)
|
||||||
net-ntp (2.1.3)
|
net-ntp (2.1.3)
|
||||||
net-ssh (5.2.0)
|
net-ssh (5.2.0)
|
||||||
|
@ -770,8 +770,8 @@ GEM
|
||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.0.3)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.2.0)
|
rails-html-sanitizer (1.3.0)
|
||||||
loofah (~> 2.2, >= 2.2.2)
|
loofah (~> 2.3)
|
||||||
rails-i18n (5.1.1)
|
rails-i18n (5.1.1)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 5.0, < 6)
|
railties (>= 5.0, < 6)
|
||||||
|
@ -783,7 +783,7 @@ GEM
|
||||||
thor (>= 0.19.0, < 2.0)
|
thor (>= 0.19.0, < 2.0)
|
||||||
rainbow (3.0.0)
|
rainbow (3.0.0)
|
||||||
raindrops (0.19.0)
|
raindrops (0.19.0)
|
||||||
rake (12.3.2)
|
rake (12.3.3)
|
||||||
rb-fsevent (0.10.2)
|
rb-fsevent (0.10.2)
|
||||||
rb-inotify (0.9.10)
|
rb-inotify (0.9.10)
|
||||||
ffi (>= 0.5.0, < 2)
|
ffi (>= 0.5.0, < 2)
|
||||||
|
@ -824,9 +824,9 @@ GEM
|
||||||
declarative-option (< 0.2.0)
|
declarative-option (< 0.2.0)
|
||||||
uber (< 0.2.0)
|
uber (< 0.2.0)
|
||||||
request_store (1.3.1)
|
request_store (1.3.1)
|
||||||
responders (2.4.0)
|
responders (2.4.1)
|
||||||
actionpack (>= 4.2.0, < 5.3)
|
actionpack (>= 4.2.0, < 6.0)
|
||||||
railties (>= 4.2.0, < 5.3)
|
railties (>= 4.2.0, < 6.0)
|
||||||
rest-client (2.0.2)
|
rest-client (2.0.2)
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 4.0)
|
mime-types (>= 1.16, < 4.0)
|
||||||
|
@ -834,7 +834,7 @@ GEM
|
||||||
retriable (3.1.2)
|
retriable (3.1.2)
|
||||||
rinku (2.0.0)
|
rinku (2.0.0)
|
||||||
rotp (2.1.2)
|
rotp (2.1.2)
|
||||||
rouge (3.7.0)
|
rouge (3.11.0)
|
||||||
rqrcode (0.7.0)
|
rqrcode (0.7.0)
|
||||||
chunky_png
|
chunky_png
|
||||||
rqrcode-rails3 (0.1.7)
|
rqrcode-rails3 (0.1.7)
|
||||||
|
@ -994,7 +994,7 @@ GEM
|
||||||
temple (0.8.1)
|
temple (0.8.1)
|
||||||
terminal-table (1.8.0)
|
terminal-table (1.8.0)
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
test-prof (0.2.5)
|
test-prof (0.10.0)
|
||||||
text (1.3.1)
|
text (1.3.1)
|
||||||
thin (1.7.2)
|
thin (1.7.2)
|
||||||
daemons (~> 1.0, >= 1.0.9)
|
daemons (~> 1.0, >= 1.0.9)
|
||||||
|
@ -1058,8 +1058,8 @@ GEM
|
||||||
descendants_tracker (~> 0.0, >= 0.0.3)
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
||||||
equalizer (~> 0.0, >= 0.0.9)
|
equalizer (~> 0.0, >= 0.0.9)
|
||||||
vmstat (2.3.0)
|
vmstat (2.3.0)
|
||||||
warden (1.2.7)
|
warden (1.2.8)
|
||||||
rack (>= 1.0)
|
rack (>= 2.0.6)
|
||||||
webfinger (1.1.0)
|
webfinger (1.1.0)
|
||||||
activesupport
|
activesupport
|
||||||
httpclient (>= 2.4)
|
httpclient (>= 2.4)
|
||||||
|
@ -1144,7 +1144,7 @@ DEPENDENCIES
|
||||||
email_reply_trimmer (~> 0.1)
|
email_reply_trimmer (~> 0.1)
|
||||||
email_spec (~> 2.2.0)
|
email_spec (~> 2.2.0)
|
||||||
escape_utils (~> 1.1)
|
escape_utils (~> 1.1)
|
||||||
factory_bot_rails (~> 4.8.2)
|
factory_bot_rails (~> 5.1.0)
|
||||||
faraday (~> 0.12)
|
faraday (~> 0.12)
|
||||||
faraday_middleware-aws-signers-v4
|
faraday_middleware-aws-signers-v4
|
||||||
fast_blank
|
fast_blank
|
||||||
|
@ -1168,11 +1168,12 @@ DEPENDENCIES
|
||||||
gettext (~> 3.2.2)
|
gettext (~> 3.2.2)
|
||||||
gettext_i18n_rails (~> 1.8.0)
|
gettext_i18n_rails (~> 1.8.0)
|
||||||
gettext_i18n_rails_js (~> 1.3)
|
gettext_i18n_rails_js (~> 1.3)
|
||||||
gitaly (~> 1.58.0)
|
gitaly (~> 1.65.0)
|
||||||
github-markup (~> 1.7.0)
|
github-markup (~> 1.7.0)
|
||||||
gitlab-labkit (~> 0.5)
|
gitlab-labkit (~> 0.5)
|
||||||
gitlab-license (~> 1.0)
|
gitlab-license (~> 1.0)
|
||||||
gitlab-markup (~> 1.7.0)
|
gitlab-markup (~> 1.7.0)
|
||||||
|
gitlab-net-dns (~> 0.9.1)
|
||||||
gitlab-peek (~> 0.0.1)
|
gitlab-peek (~> 0.0.1)
|
||||||
gitlab-sidekiq-fetcher (= 0.5.2)
|
gitlab-sidekiq-fetcher (= 0.5.2)
|
||||||
gitlab-styles (~> 2.7)
|
gitlab-styles (~> 2.7)
|
||||||
|
@ -1222,7 +1223,6 @@ DEPENDENCIES
|
||||||
mini_magick
|
mini_magick
|
||||||
minitest (~> 5.11.0)
|
minitest (~> 5.11.0)
|
||||||
nakayoshi_fork (~> 0.0.4)
|
nakayoshi_fork (~> 0.0.4)
|
||||||
net-dns (~> 0.9.0)
|
|
||||||
net-ldap
|
net-ldap
|
||||||
net-ntp
|
net-ntp
|
||||||
net-ssh (~> 5.2)
|
net-ssh (~> 5.2)
|
||||||
|
@ -1276,7 +1276,7 @@ DEPENDENCIES
|
||||||
redis-rails (~> 5.0.2)
|
redis-rails (~> 5.0.2)
|
||||||
request_store (~> 1.3)
|
request_store (~> 1.3)
|
||||||
responders (~> 2.0)
|
responders (~> 2.0)
|
||||||
rouge (~> 3.7)
|
rouge (~> 3.11.0)
|
||||||
rqrcode-rails3 (~> 0.1.7)
|
rqrcode-rails3 (~> 0.1.7)
|
||||||
rspec-parameterized
|
rspec-parameterized
|
||||||
rspec-rails (~> 3.8.0)
|
rspec-rails (~> 3.8.0)
|
||||||
|
@ -1314,7 +1314,7 @@ DEPENDENCIES
|
||||||
stackprof (~> 0.2.10)
|
stackprof (~> 0.2.10)
|
||||||
state_machines-activerecord (~> 0.5.1)
|
state_machines-activerecord (~> 0.5.1)
|
||||||
sys-filesystem (~> 1.1.6)
|
sys-filesystem (~> 1.1.6)
|
||||||
test-prof (~> 0.2.5)
|
test-prof (~> 0.10.0)
|
||||||
thin (~> 1.7.0)
|
thin (~> 1.7.0)
|
||||||
timecop (~> 0.8.0)
|
timecop (~> 0.8.0)
|
||||||
toml-rb (~> 1.0.0)
|
toml-rb (~> 1.0.0)
|
||||||
|
|
151
PROCESS.md
151
PROCESS.md
|
@ -11,15 +11,6 @@
|
||||||
- [Merge request coaching](#merge-request-coaching)
|
- [Merge request coaching](#merge-request-coaching)
|
||||||
- [Assigning issues](#assigning-issues)
|
- [Assigning issues](#assigning-issues)
|
||||||
- [Be kind](#be-kind)
|
- [Be kind](#be-kind)
|
||||||
- [Feature freeze on the 7th for the release on the 22nd](#feature-freeze-on-the-7th-for-the-release-on-the-22nd)
|
|
||||||
- [Feature flags](#feature-flags)
|
|
||||||
- [Between the 1st and the 7th](#between-the-1st-and-the-7th)
|
|
||||||
- [What happens if these deadlines are missed?](#what-happens-if-these-deadlines-are-missed)
|
|
||||||
- [On the 7th](#on-the-7th)
|
|
||||||
- [Feature merge requests](#feature-merge-requests)
|
|
||||||
- [Documentation merge requests](#documentation-merge-requests)
|
|
||||||
- [After the 7th](#after-the-7th)
|
|
||||||
- [Asking for an exception](#asking-for-an-exception)
|
|
||||||
- [Bugs](#bugs)
|
- [Bugs](#bugs)
|
||||||
- [Regressions](#regressions)
|
- [Regressions](#regressions)
|
||||||
- [Managing bugs](#managing-bugs)
|
- [Managing bugs](#managing-bugs)
|
||||||
|
@ -100,135 +91,6 @@ Product Managers must have their proposal for that milestone ready by the 22nd o
|
||||||
This proposal will be shared with Engineering for discussion, feedback, and planning.
|
This proposal will be shared with Engineering for discussion, feedback, and planning.
|
||||||
The plan for the upcoming milestone must be finalized by the 1st of the month, one week before kickoff on the 8th.
|
The plan for the upcoming milestone must be finalized by the 1st of the month, one week before kickoff on the 8th.
|
||||||
|
|
||||||
## Feature freeze on the 7th for the release on the 22nd
|
|
||||||
|
|
||||||
The feature freeze on the 7th has been discontinued. [Transition period overview](https://gitlab.com/gitlab-org/release/docs/blob/21cbd409dd5f157fe252f254f3e897f01908abe2/general/deploy/auto-deploy-transition.md#transition)
|
|
||||||
describes the change to this process. During the transition period, the only guarantee that
|
|
||||||
a change will be included in the release on the 22nd is if the change has been
|
|
||||||
deployed to GitLab.com prior to this date.
|
|
||||||
|
|
||||||
### Between the 1st and the 7th
|
|
||||||
|
|
||||||
These types of merge requests for the upcoming release need special consideration:
|
|
||||||
|
|
||||||
* **Large features**: a large feature is one that is highlighted in the kick-off
|
|
||||||
and the release blogpost; typically this will have its own channel in Slack
|
|
||||||
and a dedicated team with front-end, back-end, and UX.
|
|
||||||
* **Small features**: any other feature request.
|
|
||||||
|
|
||||||
It is strongly recommended that **large features** be with a maintainer **by the
|
|
||||||
1st**. This means that:
|
|
||||||
|
|
||||||
* There is a merge request (even if it's WIP).
|
|
||||||
* The person (or people, if it needs a frontend and backend maintainer) who will
|
|
||||||
ultimately be responsible for merging this have been pinged on the MR.
|
|
||||||
|
|
||||||
It's OK if merge request isn't completely done, but this allows the maintainer
|
|
||||||
enough time to make the decision about whether this can make it in before the
|
|
||||||
freeze. If the maintainer doesn't think it will make it, they should inform the
|
|
||||||
developers working on it and the Product Manager responsible for the feature.
|
|
||||||
|
|
||||||
The maintainer can also choose to assign a reviewer to perform an initial
|
|
||||||
review, but this way the maintainer is unlikely to be surprised by receiving an
|
|
||||||
MR later in the cycle.
|
|
||||||
|
|
||||||
It is strongly recommended that **small features** be with a reviewer (not
|
|
||||||
necessarily a maintainer) **by the 3rd**.
|
|
||||||
|
|
||||||
Most merge requests from the community do not have a specific release
|
|
||||||
target. However, if one does and falls into either of the above categories, it's
|
|
||||||
the reviewer's responsibility to manage the above communication and assignment
|
|
||||||
on behalf of the community member.
|
|
||||||
|
|
||||||
Every new feature or change should be shipped with its corresponding documentation
|
|
||||||
in accordance with the
|
|
||||||
[documentation process](https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html)
|
|
||||||
and [structure](https://docs.gitlab.com/ee/development/documentation/structure.html) guides.
|
|
||||||
Note that a technical writer will review all changes to documentation. This can occur
|
|
||||||
in the same MR as the feature code, but [if there is not sufficient time or need,
|
|
||||||
it can be planned via a follow-up issue for doc review](https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html#1-product-managers-role),
|
|
||||||
and another MR, if needed. Regardless, complete docs must be merged with code by the freeze.
|
|
||||||
|
|
||||||
#### What happens if these deadlines are missed?
|
|
||||||
|
|
||||||
If a small or large feature is _not_ with a maintainer or reviewer by the
|
|
||||||
recommended date, this does _not_ mean that maintainers or reviewers will refuse
|
|
||||||
to review or merge it, or that the feature will definitely not make it in before
|
|
||||||
the feature freeze.
|
|
||||||
|
|
||||||
However, with every day that passes without review, it will become more likely
|
|
||||||
that the feature will slip, because maintainers and reviewers may not have
|
|
||||||
enough time to do a thorough review, and developers may not have enough time to
|
|
||||||
adequately address any feedback that may come back.
|
|
||||||
|
|
||||||
A maintainer or reviewer may also determine that it will not be possible to
|
|
||||||
finish the current scope of the feature in time, but that it is possible to
|
|
||||||
reduce the scope so that something can still ship this month, with the remaining
|
|
||||||
scope moving to the next release. The sooner this decision is made, in
|
|
||||||
conversation with the Product Manager and developer, the more time there is to
|
|
||||||
extract that which is now out of scope, and to finish that which remains in scope.
|
|
||||||
|
|
||||||
For these reasons, it is strongly recommended to follow the guidelines above,
|
|
||||||
to maximize the chances of your feature making it in before the feature freeze,
|
|
||||||
and to prevent any last minute surprises.
|
|
||||||
|
|
||||||
### On the 7th
|
|
||||||
|
|
||||||
Merge requests should still be complete, following the [definition of done][done].
|
|
||||||
|
|
||||||
If a merge request is not ready, but the developers and Product Manager
|
|
||||||
responsible for the feature think it is essential that it is in the release,
|
|
||||||
they can [ask for an exception](#asking-for-an-exception) in advance. This is
|
|
||||||
preferable to merging something that we are not confident in, but should still
|
|
||||||
be a rare case: most features can be allowed to slip a release.
|
|
||||||
|
|
||||||
All Community Edition merge requests from GitLab team members merged on the
|
|
||||||
freeze date (the 7th) should have a corresponding Enterprise Edition merge
|
|
||||||
request, even if there are no conflicts. This is to reduce the size of the
|
|
||||||
subsequent EE merge, as we often merge a lot to CE on the release date. For more
|
|
||||||
information, see
|
|
||||||
[Automatic CE->EE merge][automatic_ce_ee_merge] and
|
|
||||||
[Guidelines for implementing Enterprise Edition features][ee_features].
|
|
||||||
|
|
||||||
### After the 7th
|
|
||||||
|
|
||||||
Once the stable branch is frozen, the only MRs that can be cherry-picked into
|
|
||||||
the stable branch are:
|
|
||||||
|
|
||||||
* Fixes for [regressions](#regressions) where the affected version `xx.x` in `regression:xx.x` is the current release. See [Managing bugs](#managing-bugs) section.
|
|
||||||
* Fixes for security issues.
|
|
||||||
* Fixes or improvements to automated QA scenarios.
|
|
||||||
* [Documentation improvements](https://docs.gitlab.com/ee/development/documentation/workflow.html) for feature changes made in the same release, though initial docs for these features should have already been merged by the freeze, as required.
|
|
||||||
* New or updated translations (as long as they do not touch application code).
|
|
||||||
* Changes that are behind a feature flag and have the ~"feature flag" label.
|
|
||||||
|
|
||||||
During the feature freeze all merge requests that are meant to go into the
|
|
||||||
upcoming release should have the correct milestone assigned _and_ the
|
|
||||||
`Pick into X.Y` label where `X.Y` is equal to the milestone, so that release
|
|
||||||
managers can find and pick them.
|
|
||||||
Merge requests without this label will not be picked into the stable release.
|
|
||||||
|
|
||||||
For example, if the upcoming release is `10.2.0` you will need to set the
|
|
||||||
`Pick into 10.2` label.
|
|
||||||
|
|
||||||
Fixes marked like this will be shipped in the next RC (before the 22nd), or the
|
|
||||||
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:
|
|
||||||
|
|
||||||
- `Pick into 10.1`
|
|
||||||
- `Pick into 10.0`
|
|
||||||
- `Pick into 9.5`
|
|
||||||
|
|
||||||
### Asking for an exception
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
|
|
||||||
A ~bug is a defect, error, failure which causes the system to behave incorrectly or prevents it from fulfilling the product requirements.
|
A ~bug is a defect, error, failure which causes the system to behave incorrectly or prevents it from fulfilling the product requirements.
|
||||||
|
@ -256,13 +118,6 @@ Regressions should be considered high priority issues that should be solved as s
|
||||||
### Managing bugs
|
### Managing bugs
|
||||||
|
|
||||||
**Prioritization:** We give higher priority to regressions on features that worked in the last recent monthly release and the current release candidates.
|
**Prioritization:** We give higher priority to regressions on features that worked in the last recent monthly release and the current release candidates.
|
||||||
The two scenarios below can [bypass the exception request in the release process](https://gitlab.com/gitlab-org/release/docs/blob/master/general/exception-request/process.md#after-the-7th), where the affected regression version matches the current monthly release version.
|
|
||||||
* A regression which worked in the **Last monthly release**
|
|
||||||
* **Example:** In 11.0 we released a new `feature X` that is verified as working. Then in release 11.1 the feature no longer works, this is regression for 11.1. The issue should have the `regression:11.1` label.
|
|
||||||
* *Note:* When we say `the last 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 which worked in the **Current release candidates**
|
|
||||||
* **Example:** In 11.1-RC3 we shipped a new feature which has been verified as working. Then in 11.1-RC5 the feature no longer works, this is regression for 11.1. The issue should have the `regression:11.1` label.
|
|
||||||
* *Note:* Because GitLab.com runs release candidates of new releases, a regression can be reported in a release before its 'official' release date on the 22nd of the month.
|
|
||||||
|
|
||||||
When a bug is found:
|
When a bug is found:
|
||||||
1. Create an issue describing the problem in the most detailed way possible.
|
1. Create an issue describing the problem in the most detailed way possible.
|
||||||
|
@ -328,7 +183,7 @@ Thanks for the issue report. This issue has already been fixed in newer versions
|
||||||
Due to the size of this project and our limited resources we are only able to support the
|
Due to the size of this project and our limited resources we are only able to support the
|
||||||
latest stable release as outlined in our [contributing guidelines](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html).
|
latest stable release as outlined in our [contributing guidelines](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html).
|
||||||
In order to get this bug fix and enjoy many new features please
|
In order to get this bug fix and enjoy many new features please
|
||||||
[upgrade](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update).
|
[upgrade](https://gitlab.com/gitlab-org/gitlab/tree/master/doc/update).
|
||||||
If you still experience issues at that time please open a new issue following our issue
|
If you still experience issues at that time please open a new issue following our issue
|
||||||
tracker guidelines found in the [contributing guidelines](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html#issue-tracker-guidelines).
|
tracker guidelines found in the [contributing guidelines](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html#issue-tracker-guidelines).
|
||||||
```
|
```
|
||||||
|
@ -337,14 +192,14 @@ tracker guidelines found in the [contributing guidelines](https://docs.gitlab.co
|
||||||
|
|
||||||
```
|
```
|
||||||
Thanks for your interest in improving the GitLab codebase!
|
Thanks for your interest in improving the GitLab codebase!
|
||||||
Please update your merge request according to the [contributing guidelines](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/contributing/merge_request_workflow.md#merge-request-guidelines).
|
Please update your merge request according to the [contributing guidelines](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/development/contributing/merge_request_workflow.md#merge-request-guidelines).
|
||||||
```
|
```
|
||||||
|
|
||||||
### Accepting merge requests
|
### Accepting merge requests
|
||||||
|
|
||||||
```
|
```
|
||||||
Is there an issue on the
|
Is there an issue on the
|
||||||
[issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) that is
|
[issue tracker](https://gitlab.com/gitlab-org/gitlab/issues) that is
|
||||||
similar to this? Could you please link it here?
|
similar to this? Could you please link it here?
|
||||||
Please be aware that new functionality that is not marked
|
Please be aware that new functionality that is not marked
|
||||||
[`Accepting merge requests`](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html#label-for-community-contributors)
|
[`Accepting merge requests`](https://docs.gitlab.com/ee/development/contributing/issue_workflow.html#label-for-community-contributors)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
## Canonical source
|
## Canonical source
|
||||||
|
|
||||||
The canonical source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/).
|
The canonical source of GitLab where all development takes place is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab).
|
||||||
|
|
||||||
The source of GitLab Enterprise Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ee).
|
If you wish to clone a copy of GitLab without proprietary code, you can use the read-only mirror of GitLab located at https://gitlab.com/gitlab-org/gitlab-foss/. Please do not submit any issues and/or merge requests to this project.
|
||||||
|
|
||||||
## Free trial
|
## Free trial
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
12.3.9
|
12.4.6
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
app/assets/images/ci_favicons/favicon_status_preparing.png
Normal file
BIN
app/assets/images/ci_favicons/favicon_status_preparing.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -1,11 +0,0 @@
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isCustomStageForm: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showAddStageForm: () => {},
|
|
||||||
hideAddStageForm: () => {},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -36,6 +36,7 @@ const Api = {
|
||||||
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
|
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
|
||||||
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
||||||
releasesPath: '/api/:version/projects/:id/releases',
|
releasesPath: '/api/:version/projects/:id/releases',
|
||||||
|
releasePath: '/api/:version/projects/:id/releases/:tag_name',
|
||||||
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
|
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
|
||||||
adminStatisticsPath: 'api/:version/application/statistics',
|
adminStatisticsPath: 'api/:version/application/statistics',
|
||||||
|
|
||||||
|
@ -74,6 +75,11 @@ const Api = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
groupLabels(namespace) {
|
||||||
|
const url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespace);
|
||||||
|
return axios.get(url).then(({ data }) => data);
|
||||||
|
},
|
||||||
|
|
||||||
// Return namespaces list. Filtered by query
|
// Return namespaces list. Filtered by query
|
||||||
namespaces(query, callback) {
|
namespaces(query, callback) {
|
||||||
const url = Api.buildUrl(Api.namespacesPath);
|
const url = Api.buildUrl(Api.namespacesPath);
|
||||||
|
@ -386,6 +392,22 @@ const Api = {
|
||||||
return axios.get(url);
|
return axios.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
release(projectPath, tagName) {
|
||||||
|
const url = Api.buildUrl(this.releasePath)
|
||||||
|
.replace(':id', encodeURIComponent(projectPath))
|
||||||
|
.replace(':tag_name', encodeURIComponent(tagName));
|
||||||
|
|
||||||
|
return axios.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRelease(projectPath, tagName, release) {
|
||||||
|
const url = Api.buildUrl(this.releasePath)
|
||||||
|
.replace(':id', encodeURIComponent(projectPath))
|
||||||
|
.replace(':tag_name', encodeURIComponent(tagName));
|
||||||
|
|
||||||
|
return axios.put(url, release);
|
||||||
|
},
|
||||||
|
|
||||||
adminStatistics() {
|
adminStatistics() {
|
||||||
const url = Api.buildUrl(this.adminStatisticsPath);
|
const url = Api.buildUrl(this.adminStatisticsPath);
|
||||||
return axios.get(url);
|
return axios.get(url);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable no-param-reassign, prefer-template, no-void, consistent-return */
|
/* eslint-disable no-param-reassign, no-void, consistent-return */
|
||||||
|
|
||||||
import AccessorUtilities from './lib/utils/accessor';
|
import AccessorUtilities from './lib/utils/accessor';
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ export default class Autosave {
|
||||||
if (key.join != null) {
|
if (key.join != null) {
|
||||||
key = key.join('/');
|
key = key.join('/');
|
||||||
}
|
}
|
||||||
this.key = 'autosave/' + key;
|
this.key = `autosave/${key}`;
|
||||||
this.field.data('autosave', this);
|
this.field.data('autosave', this);
|
||||||
this.restore();
|
this.restore();
|
||||||
this.field.on('input', () => this.save());
|
this.field.on('input', () => this.save());
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { mapState, mapActions } from 'vuex';
|
import { mapState, mapActions } from 'vuex';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
|
||||||
import Badge from './badge.vue';
|
import Badge from './badge.vue';
|
||||||
import BadgeForm from './badge_form.vue';
|
import BadgeForm from './badge_form.vue';
|
||||||
import BadgeList from './badge_list.vue';
|
import BadgeList from './badge_list.vue';
|
||||||
|
@ -13,7 +13,7 @@ export default {
|
||||||
Badge,
|
Badge,
|
||||||
BadgeForm,
|
BadgeForm,
|
||||||
BadgeList,
|
BadgeList,
|
||||||
GlModal,
|
GlModal: DeprecatedModal2,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['badgeInModal', 'isEditing']),
|
...mapState(['badgeInModal', 'isEditing']),
|
||||||
|
|
|
@ -21,6 +21,7 @@ import Reference from './nodes/reference';
|
||||||
|
|
||||||
import TableOfContents from './nodes/table_of_contents';
|
import TableOfContents from './nodes/table_of_contents';
|
||||||
import Video from './nodes/video';
|
import Video from './nodes/video';
|
||||||
|
import Audio from './nodes/audio';
|
||||||
|
|
||||||
import BulletList from './nodes/bullet_list';
|
import BulletList from './nodes/bullet_list';
|
||||||
import OrderedList from './nodes/ordered_list';
|
import OrderedList from './nodes/ordered_list';
|
||||||
|
@ -78,6 +79,7 @@ export default [
|
||||||
|
|
||||||
new TableOfContents(),
|
new TableOfContents(),
|
||||||
new Video(),
|
new Video(),
|
||||||
|
new Audio(),
|
||||||
|
|
||||||
new BulletList(),
|
new BulletList(),
|
||||||
new OrderedList(),
|
new OrderedList(),
|
||||||
|
|
53
app/assets/javascripts/behaviors/markdown/nodes/audio.js
Normal file
53
app/assets/javascripts/behaviors/markdown/nodes/audio.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
|
import { Node } from 'tiptap';
|
||||||
|
import { defaultMarkdownSerializer } from 'prosemirror-markdown';
|
||||||
|
|
||||||
|
// Transforms generated HTML back to GFM for Banzai::Filter::AudioLinkFilter
|
||||||
|
export default class Audio extends Node {
|
||||||
|
get name() {
|
||||||
|
return 'audio';
|
||||||
|
}
|
||||||
|
|
||||||
|
get schema() {
|
||||||
|
return {
|
||||||
|
attrs: {
|
||||||
|
src: {},
|
||||||
|
alt: {
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
group: 'block',
|
||||||
|
draggable: true,
|
||||||
|
parseDOM: [
|
||||||
|
{
|
||||||
|
tag: '.audio-container',
|
||||||
|
skip: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: '.audio-container p',
|
||||||
|
priority: 51,
|
||||||
|
ignore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: 'audio[src]',
|
||||||
|
getAttrs: el => ({ src: el.getAttribute('src'), alt: el.dataset.title }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
toDOM: node => [
|
||||||
|
'audio',
|
||||||
|
{
|
||||||
|
src: node.attrs.src,
|
||||||
|
controls: true,
|
||||||
|
'data-setup': '{}',
|
||||||
|
'data-title': node.attrs.alt,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
toMarkdown(state, node) {
|
||||||
|
defaultMarkdownSerializer.nodes.image(state, node);
|
||||||
|
state.closeBlock(node);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable func-names, no-var, prefer-arrow-callback */
|
/* eslint-disable func-names, no-var */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
@ -45,26 +45,22 @@ MarkdownPreview.prototype.showPreview = function($form) {
|
||||||
this.hideReferencedUsers($form);
|
this.hideReferencedUsers($form);
|
||||||
} else {
|
} else {
|
||||||
preview.addClass('md-preview-loading').text(__('Loading...'));
|
preview.addClass('md-preview-loading').text(__('Loading...'));
|
||||||
this.fetchMarkdownPreview(
|
this.fetchMarkdownPreview(mdText, url, response => {
|
||||||
mdText,
|
var body;
|
||||||
url,
|
if (response.body.length > 0) {
|
||||||
function(response) {
|
({ body } = response);
|
||||||
var body;
|
} else {
|
||||||
if (response.body.length > 0) {
|
body = this.emptyMessage;
|
||||||
({ body } = response);
|
}
|
||||||
} else {
|
|
||||||
body = this.emptyMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
preview.removeClass('md-preview-loading').html(body);
|
preview.removeClass('md-preview-loading').html(body);
|
||||||
preview.renderGFM();
|
preview.renderGFM();
|
||||||
this.renderReferencedUsers(response.references.users, $form);
|
this.renderReferencedUsers(response.references.users, $form);
|
||||||
|
|
||||||
if (response.references.commands) {
|
if (response.references.commands) {
|
||||||
this.renderReferencedCommands(response.references.commands, $form);
|
this.renderReferencedCommands(response.references.commands, $form);
|
||||||
}
|
}
|
||||||
}.bind(this),
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,12 +128,12 @@ const markdownToolbar = $('.md-header-toolbar');
|
||||||
|
|
||||||
$.fn.setupMarkdownPreview = function() {
|
$.fn.setupMarkdownPreview = function() {
|
||||||
var $form = $(this);
|
var $form = $(this);
|
||||||
$form.find('textarea.markdown-area').on('input', function() {
|
$form.find('textarea.markdown-area').on('input', () => {
|
||||||
markdownPreview.hideReferencedUsers($form);
|
markdownPreview.hideReferencedUsers($form);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).on('markdown-preview:show', function(e, $form) {
|
$(document).on('markdown-preview:show', (e, $form) => {
|
||||||
if (!$form) {
|
if (!$form) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +158,7 @@ $(document).on('markdown-preview:show', function(e, $form) {
|
||||||
markdownPreview.showPreview($form);
|
markdownPreview.showPreview($form);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('markdown-preview:hide', function(e, $form) {
|
$(document).on('markdown-preview:hide', (e, $form) => {
|
||||||
if (!$form) {
|
if (!$form) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +187,7 @@ $(document).on('markdown-preview:hide', function(e, $form) {
|
||||||
markdownPreview.hideReferencedCommands($form);
|
markdownPreview.hideReferencedCommands($form);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('markdown-preview:toggle', function(e, keyboardEvent) {
|
$(document).on('markdown-preview:toggle', (e, keyboardEvent) => {
|
||||||
var $target;
|
var $target;
|
||||||
$target = $(keyboardEvent.target);
|
$target = $(keyboardEvent.target);
|
||||||
if ($target.is('textarea.markdown-area')) {
|
if ($target.is('textarea.markdown-area')) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ $.fn.requiresInput = function requiresInput() {
|
||||||
const values = _.map($(fieldSelector, $form), field => field.value);
|
const values = _.map($(fieldSelector, $form), field => field.value);
|
||||||
|
|
||||||
// Disable the button if any required fields are empty
|
// Disable the button if any required fields are empty
|
||||||
if (values.length && _.any(values, _.isEmpty)) {
|
if (values.length && _.some(values, _.isEmpty)) {
|
||||||
$button.disable();
|
$button.disable();
|
||||||
} else {
|
} else {
|
||||||
$button.enable();
|
$button.enable();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import sqljs from 'sql.js';
|
import sqljs from 'sql.js';
|
||||||
import { template as _template } from 'underscore';
|
import { template as _template } from 'underscore';
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import { successCodes } from '~/lib/utils/http_status';
|
||||||
|
|
||||||
const PREVIEW_TEMPLATE = _template(`
|
const PREVIEW_TEMPLATE = _template(`
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -16,30 +18,25 @@ class BalsamiqViewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFile(endpoint) {
|
loadFile(endpoint) {
|
||||||
return new Promise((resolve, reject) => {
|
return axios
|
||||||
const xhr = new XMLHttpRequest();
|
.get(endpoint, {
|
||||||
|
responseType: 'arraybuffer',
|
||||||
xhr.open('GET', endpoint, true);
|
validateStatus(status) {
|
||||||
xhr.responseType = 'arraybuffer';
|
return status !== successCodes.OK;
|
||||||
xhr.onload = loadEvent => this.fileLoaded(loadEvent, resolve, reject);
|
},
|
||||||
xhr.onerror = reject;
|
})
|
||||||
|
.then(({ data }) => {
|
||||||
xhr.send();
|
this.renderFile(data);
|
||||||
});
|
})
|
||||||
|
.catch(e => {
|
||||||
|
throw new Error(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fileLoaded(loadEvent, resolve, reject) {
|
renderFile(fileBuffer) {
|
||||||
if (loadEvent.target.status !== 200) return reject();
|
|
||||||
|
|
||||||
this.renderFile(loadEvent);
|
|
||||||
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderFile(loadEvent) {
|
|
||||||
const container = document.createElement('ul');
|
const container = document.createElement('ul');
|
||||||
|
|
||||||
this.initDatabase(loadEvent.target.response);
|
this.initDatabase(fileBuffer);
|
||||||
|
|
||||||
const previews = this.getPreviews();
|
const previews = this.getPreviews();
|
||||||
previews.forEach(preview => {
|
previews.forEach(preview => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable func-names, prefer-arrow-callback */
|
/* eslint-disable func-names */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Dropzone from 'dropzone';
|
import Dropzone from 'dropzone';
|
||||||
|
@ -43,18 +43,18 @@ export default class BlobFileDropzone {
|
||||||
previewsContainer: '.dropzone-previews',
|
previewsContainer: '.dropzone-previews',
|
||||||
headers: csrf.headers,
|
headers: csrf.headers,
|
||||||
init() {
|
init() {
|
||||||
this.on('addedfile', function() {
|
this.on('addedfile', () => {
|
||||||
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
||||||
dropzoneMessage.addClass(HIDDEN_CLASS);
|
dropzoneMessage.addClass(HIDDEN_CLASS);
|
||||||
$('.dropzone-alerts')
|
$('.dropzone-alerts')
|
||||||
.html('')
|
.html('')
|
||||||
.hide();
|
.hide();
|
||||||
});
|
});
|
||||||
this.on('removedfile', function() {
|
this.on('removedfile', () => {
|
||||||
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
||||||
dropzoneMessage.removeClass(HIDDEN_CLASS);
|
dropzoneMessage.removeClass(HIDDEN_CLASS);
|
||||||
});
|
});
|
||||||
this.on('success', function(header, response) {
|
this.on('success', (header, response) => {
|
||||||
$('#modal-upload-blob').modal('hide');
|
$('#modal-upload-blob').modal('hide');
|
||||||
visitUrl(response.filePath);
|
visitUrl(response.filePath);
|
||||||
});
|
});
|
||||||
|
@ -62,7 +62,7 @@ export default class BlobFileDropzone {
|
||||||
dropzoneMessage.addClass(HIDDEN_CLASS);
|
dropzoneMessage.addClass(HIDDEN_CLASS);
|
||||||
this.removeFile(file);
|
this.removeFile(file);
|
||||||
});
|
});
|
||||||
this.on('sending', function(file, xhr, formData) {
|
this.on('sending', (file, xhr, formData) => {
|
||||||
formData.append('branch_name', form.find('.js-branch-name').val());
|
formData.append('branch_name', form.find('.js-branch-name').val());
|
||||||
formData.append('create_merge_request', form.find('.js-create-merge-request').val());
|
formData.append('create_merge_request', form.find('.js-create-merge-request').val());
|
||||||
formData.append('commit_message', form.find('.js-commit-message').val());
|
formData.append('commit_message', form.find('.js-commit-message').val());
|
||||||
|
|
|
@ -7,6 +7,8 @@ import BlobCiYamlSelector from './template_selectors/ci_yaml_selector';
|
||||||
import DockerfileSelector from './template_selectors/dockerfile_selector';
|
import DockerfileSelector from './template_selectors/dockerfile_selector';
|
||||||
import GitignoreSelector from './template_selectors/gitignore_selector';
|
import GitignoreSelector from './template_selectors/gitignore_selector';
|
||||||
import LicenseSelector from './template_selectors/license_selector';
|
import LicenseSelector from './template_selectors/license_selector';
|
||||||
|
import toast from '~/vue_shared/plugins/global_toast';
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
|
||||||
export default class FileTemplateMediator {
|
export default class FileTemplateMediator {
|
||||||
constructor({ editor, currentAction, projectId }) {
|
constructor({ editor, currentAction, projectId }) {
|
||||||
|
@ -19,6 +21,7 @@ export default class FileTemplateMediator {
|
||||||
this.initDomElements();
|
this.initDomElements();
|
||||||
this.initDropdowns();
|
this.initDropdowns();
|
||||||
this.initPageEvents();
|
this.initPageEvents();
|
||||||
|
this.cacheFileContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
initTemplateSelectors() {
|
initTemplateSelectors() {
|
||||||
|
@ -40,6 +43,7 @@ export default class FileTemplateMediator {
|
||||||
return {
|
return {
|
||||||
name: cfg.name,
|
name: cfg.name,
|
||||||
key: cfg.key,
|
key: cfg.key,
|
||||||
|
id: cfg.key,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -58,6 +62,7 @@ export default class FileTemplateMediator {
|
||||||
this.$fileContent = $fileEditor.find('#file-content');
|
this.$fileContent = $fileEditor.find('#file-content');
|
||||||
this.$commitForm = $fileEditor.find('form');
|
this.$commitForm = $fileEditor.find('form');
|
||||||
this.$navLinks = $fileEditor.find('.nav-links');
|
this.$navLinks = $fileEditor.find('.nav-links');
|
||||||
|
this.$templateTypes = this.$templateSelectors.find('.template-type-selector');
|
||||||
}
|
}
|
||||||
|
|
||||||
initDropdowns() {
|
initDropdowns() {
|
||||||
|
@ -113,7 +118,11 @@ export default class FileTemplateMediator {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.typeSelector.setToggleText(item.name);
|
this.setFilename(item.name);
|
||||||
|
|
||||||
|
if (this.editor.getValue() !== '') {
|
||||||
|
this.setTypeSelectorToggleText(item.name);
|
||||||
|
}
|
||||||
|
|
||||||
this.cacheToggleText();
|
this.cacheToggleText();
|
||||||
}
|
}
|
||||||
|
@ -123,15 +132,24 @@ export default class FileTemplateMediator {
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTemplateFile(selector, query, data) {
|
selectTemplateFile(selector, query, data) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
selector.renderLoading();
|
selector.renderLoading();
|
||||||
// in case undo menu is already there
|
|
||||||
this.destroyUndoMenu();
|
|
||||||
this.fetchFileTemplate(selector.config.type, query, data)
|
this.fetchFileTemplate(selector.config.type, query, data)
|
||||||
.then(file => {
|
.then(file => {
|
||||||
this.showUndoMenu();
|
|
||||||
this.setEditorContent(file);
|
this.setEditorContent(file);
|
||||||
this.setFilename(selector.config.name);
|
|
||||||
selector.renderLoaded();
|
selector.renderLoaded();
|
||||||
|
this.typeSelector.setToggleText(selector.config.name);
|
||||||
|
toast(__(`${query} template applied`), {
|
||||||
|
action: {
|
||||||
|
text: __('Undo'),
|
||||||
|
onClick: (e, toastObj) => {
|
||||||
|
self.restoreFromCache();
|
||||||
|
toastObj.goAway(0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(err => new Flash(`An error occurred while fetching the template: ${err}`));
|
.catch(err => new Flash(`An error occurred while fetching the template: ${err}`));
|
||||||
}
|
}
|
||||||
|
@ -173,22 +191,6 @@ export default class FileTemplateMediator {
|
||||||
return this.templateSelectors.find(selector => selector.config.key === key);
|
return this.templateSelectors.find(selector => selector.config.key === key);
|
||||||
}
|
}
|
||||||
|
|
||||||
showUndoMenu() {
|
|
||||||
this.$undoMenu.removeClass('hidden');
|
|
||||||
|
|
||||||
this.$undoBtn.on('click', () => {
|
|
||||||
this.restoreFromCache();
|
|
||||||
this.destroyUndoMenu();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
destroyUndoMenu() {
|
|
||||||
this.cacheFileContents();
|
|
||||||
this.cacheToggleText();
|
|
||||||
this.$undoMenu.addClass('hidden');
|
|
||||||
this.$undoBtn.off('click');
|
|
||||||
}
|
|
||||||
|
|
||||||
hideTemplateSelectorMenu() {
|
hideTemplateSelectorMenu() {
|
||||||
this.$templatesMenu.hide();
|
this.$templatesMenu.hide();
|
||||||
}
|
}
|
||||||
|
@ -210,6 +212,7 @@ export default class FileTemplateMediator {
|
||||||
this.setEditorContent(this.cachedContent);
|
this.setEditorContent(this.cachedContent);
|
||||||
this.setFilename(this.cachedFilename);
|
this.setFilename(this.cachedFilename);
|
||||||
this.setTemplateSelectorToggleText();
|
this.setTemplateSelectorToggleText();
|
||||||
|
this.setTypeSelectorToggleText(__('Select a template type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
getTemplateSelectorToggleText() {
|
getTemplateSelectorToggleText() {
|
||||||
|
@ -228,6 +231,10 @@ export default class FileTemplateMediator {
|
||||||
return this.typeSelector.getToggleText();
|
return this.typeSelector.getToggleText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTypeSelectorToggleText(text) {
|
||||||
|
this.typeSelector.setToggleText(text);
|
||||||
|
}
|
||||||
|
|
||||||
getFilename() {
|
getFilename() {
|
||||||
return this.$filenameInput.val();
|
return this.$filenameInput.val();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import '~/gl_dropdown';
|
||||||
|
|
||||||
export default class TemplateSelector {
|
export default class TemplateSelector {
|
||||||
constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) {
|
constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) {
|
||||||
|
@ -26,11 +27,16 @@ export default class TemplateSelector {
|
||||||
search: {
|
search: {
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
},
|
},
|
||||||
clicked: options => this.fetchFileTemplate(options),
|
clicked: options => this.onDropdownClicked(options),
|
||||||
text: item => item.name,
|
text: item => item.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subclasses can override this method to conditionally prevent fetching file templates
|
||||||
|
onDropdownClicked(options) {
|
||||||
|
this.fetchFileTemplate(options);
|
||||||
|
}
|
||||||
|
|
||||||
initAutosizeUpdateEvent() {
|
initAutosizeUpdateEvent() {
|
||||||
this.autosizeUpdateEvent = document.createEvent('Event');
|
this.autosizeUpdateEvent = document.createEvent('Event');
|
||||||
this.autosizeUpdateEvent.initEvent('autosize:update', true, false);
|
this.autosizeUpdateEvent.initEvent('autosize:update', true, false);
|
||||||
|
@ -77,9 +83,14 @@ export default class TemplateSelector {
|
||||||
|
|
||||||
if (this.editor instanceof $) {
|
if (this.editor instanceof $) {
|
||||||
this.editor.get(0).dispatchEvent(this.autosizeUpdateEvent);
|
this.editor.get(0).dispatchEvent(this.autosizeUpdateEvent);
|
||||||
|
this.editor.trigger('input');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEditorContent() {
|
||||||
|
return this.editor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
startLoadingSpinner() {
|
startLoadingSpinner() {
|
||||||
this.$dropdownIcon.addClass('fa-spinner fa-spin').removeClass('fa-chevron-down');
|
this.$dropdownIcon.addClass('fa-spinner fa-spin').removeClass('fa-chevron-down');
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ export default class BlobCiYamlSelector extends FileTemplateSelector {
|
||||||
data: this.$dropdown.data('data'),
|
data: this.$dropdown.data('data'),
|
||||||
filterable: true,
|
filterable: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
toggleLabel: item => item.name,
|
|
||||||
search: {
|
search: {
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,7 +20,6 @@ export default class DockerfileSelector extends FileTemplateSelector {
|
||||||
data: this.$dropdown.data('data'),
|
data: this.$dropdown.data('data'),
|
||||||
filterable: true,
|
filterable: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
toggleLabel: item => item.name,
|
|
||||||
search: {
|
search: {
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,6 @@ export default class BlobGitignoreSelector extends FileTemplateSelector {
|
||||||
data: this.$dropdown.data('data'),
|
data: this.$dropdown.data('data'),
|
||||||
filterable: true,
|
filterable: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
toggleLabel: item => item.name,
|
|
||||||
search: {
|
search: {
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,6 @@ export default class BlobLicenseSelector extends FileTemplateSelector {
|
||||||
data: this.$dropdown.data('data'),
|
data: this.$dropdown.data('data'),
|
||||||
filterable: true,
|
filterable: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
toggleLabel: item => item.name,
|
|
||||||
search: {
|
search: {
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,6 @@ export default class FileTemplateTypeSelector extends FileTemplateSelector {
|
||||||
data: this.config.dropdownData,
|
data: this.config.dropdownData,
|
||||||
filterable: false,
|
filterable: false,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
toggleLabel: item => item.name,
|
|
||||||
clicked: options => this.mediator.selectTemplateTypeOptions(options),
|
clicked: options => this.mediator.selectTemplateTypeOptions(options),
|
||||||
text: item => item.name,
|
text: item => item.name,
|
||||||
});
|
});
|
||||||
|
|
|
@ -107,18 +107,18 @@ export default class BlobViewer {
|
||||||
toggleCopyButtonState() {
|
toggleCopyButtonState() {
|
||||||
if (!this.copySourceBtn) return;
|
if (!this.copySourceBtn) return;
|
||||||
if (this.simpleViewer.getAttribute('data-loaded')) {
|
if (this.simpleViewer.getAttribute('data-loaded')) {
|
||||||
this.copySourceBtn.setAttribute('title', __('Copy source to clipboard'));
|
this.copySourceBtn.setAttribute('title', __('Copy file contents'));
|
||||||
this.copySourceBtn.classList.remove('disabled');
|
this.copySourceBtn.classList.remove('disabled');
|
||||||
} else if (this.activeViewer === this.simpleViewer) {
|
} else if (this.activeViewer === this.simpleViewer) {
|
||||||
this.copySourceBtn.setAttribute(
|
this.copySourceBtn.setAttribute(
|
||||||
'title',
|
'title',
|
||||||
__('Wait for the source to load to copy it to the clipboard'),
|
__('Wait for the file to load to copy its contents'),
|
||||||
);
|
);
|
||||||
this.copySourceBtn.classList.add('disabled');
|
this.copySourceBtn.classList.add('disabled');
|
||||||
} else {
|
} else {
|
||||||
this.copySourceBtn.setAttribute(
|
this.copySourceBtn.setAttribute(
|
||||||
'title',
|
'title',
|
||||||
__('Switch to the source to copy it to the clipboard'),
|
__('Switch to the source to copy the file contents'),
|
||||||
);
|
);
|
||||||
this.copySourceBtn.classList.add('disabled');
|
this.copySourceBtn.classList.add('disabled');
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,25 +29,25 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const loadListIssues = listObj => {
|
||||||
|
const list = boardsStore.findList('title', listObj.title);
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.id = listObj.id;
|
||||||
|
list.label.id = listObj.label.id;
|
||||||
|
return list.getIssues().catch(() => {
|
||||||
|
// TODO: handle request error
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Save the labels
|
// Save the labels
|
||||||
boardsStore
|
boardsStore
|
||||||
.generateDefaultLists()
|
.generateDefaultLists()
|
||||||
.then(res => res.data)
|
.then(res => res.data)
|
||||||
.then(data => {
|
.then(data => Promise.all(data.map(loadListIssues)))
|
||||||
data.forEach(listObj => {
|
|
||||||
const list = boardsStore.findList('title', listObj.title);
|
|
||||||
|
|
||||||
if (!list) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.id = listObj.id;
|
|
||||||
list.label.id = listObj.label.id;
|
|
||||||
list.getIssues().catch(() => {
|
|
||||||
// TODO: handle request error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
boardsStore.removeList(undefined, 'label');
|
boardsStore.removeList(undefined, 'label');
|
||||||
Cookies.remove('issue_board_welcome_hidden', {
|
Cookies.remove('issue_board_welcome_hidden', {
|
||||||
|
|
|
@ -42,12 +42,19 @@ export default {
|
||||||
return {
|
return {
|
||||||
showDetail: false,
|
showDetail: false,
|
||||||
detailIssue: boardsStore.detail,
|
detailIssue: boardsStore.detail,
|
||||||
|
multiSelect: boardsStore.multiSelect,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
issueDetailVisible() {
|
issueDetailVisible() {
|
||||||
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
|
return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
|
||||||
},
|
},
|
||||||
|
multiSelectVisible() {
|
||||||
|
return this.multiSelect.list.findIndex(issue => issue.id === this.issue.id) > -1;
|
||||||
|
},
|
||||||
|
canMultiSelect() {
|
||||||
|
return gon.features && gon.features.multiSelectBoard;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
mouseDown() {
|
mouseDown() {
|
||||||
|
@ -58,14 +65,20 @@ export default {
|
||||||
},
|
},
|
||||||
showIssue(e) {
|
showIssue(e) {
|
||||||
if (e.target.classList.contains('js-no-trigger')) return;
|
if (e.target.classList.contains('js-no-trigger')) return;
|
||||||
|
|
||||||
if (this.showDetail) {
|
if (this.showDetail) {
|
||||||
this.showDetail = false;
|
this.showDetail = false;
|
||||||
|
|
||||||
|
// If CMD or CTRL is clicked
|
||||||
|
const isMultiSelect = this.canMultiSelect && (e.ctrlKey || e.metaKey);
|
||||||
|
|
||||||
if (boardsStore.detail.issue && boardsStore.detail.issue.id === this.issue.id) {
|
if (boardsStore.detail.issue && boardsStore.detail.issue.id === this.issue.id) {
|
||||||
eventHub.$emit('clearDetailIssue');
|
eventHub.$emit('clearDetailIssue', isMultiSelect);
|
||||||
|
|
||||||
|
if (isMultiSelect) {
|
||||||
|
eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
eventHub.$emit('newDetailIssue', this.issue);
|
eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
|
||||||
boardsStore.setListDetail(this.list);
|
boardsStore.setListDetail(this.list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +90,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<li
|
<li
|
||||||
:class="{
|
:class="{
|
||||||
|
'multi-select': multiSelectVisible,
|
||||||
'user-can-drag': !disabled && issue.id,
|
'user-can-drag': !disabled && issue.id,
|
||||||
'is-disabled': disabled || !issue.id,
|
'is-disabled': disabled || !issue.id,
|
||||||
'is-active': issueDetailVisible,
|
'is-active': issueDetailVisible,
|
||||||
|
|
|
@ -194,6 +194,7 @@ export default {
|
||||||
ref="name"
|
ref="name"
|
||||||
v-model="board.name"
|
v-model="board.name"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
data-qa-selector="board_name_field"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="__('Enter board name')"
|
:placeholder="__('Enter board name')"
|
||||||
@keyup.enter="submit"
|
@keyup.enter="submit"
|
||||||
|
|
|
@ -1,12 +1,22 @@
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
|
import { Sortable, MultiDrag } from 'sortablejs';
|
||||||
import Sortable from 'sortablejs';
|
|
||||||
import { GlLoadingIcon } from '@gitlab/ui';
|
import { GlLoadingIcon } from '@gitlab/ui';
|
||||||
|
import _ from 'underscore';
|
||||||
import boardNewIssue from './board_new_issue.vue';
|
import boardNewIssue from './board_new_issue.vue';
|
||||||
import boardCard from './board_card.vue';
|
import boardCard from './board_card.vue';
|
||||||
import eventHub from '../eventhub';
|
import eventHub from '../eventhub';
|
||||||
import boardsStore from '../stores/boards_store';
|
import boardsStore from '../stores/boards_store';
|
||||||
import { getBoardSortableDefaultOptions, sortableStart } from '../mixins/sortable_default_options';
|
import { sprintf, __ } from '~/locale';
|
||||||
|
import createFlash from '~/flash';
|
||||||
|
import {
|
||||||
|
getBoardSortableDefaultOptions,
|
||||||
|
sortableStart,
|
||||||
|
sortableEnd,
|
||||||
|
} from '../mixins/sortable_default_options';
|
||||||
|
|
||||||
|
if (gon.features && gon.features.multiSelectBoard) {
|
||||||
|
Sortable.mount(new MultiDrag());
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BoardList',
|
name: 'BoardList',
|
||||||
|
@ -54,6 +64,14 @@ export default {
|
||||||
showIssueForm: false,
|
showIssueForm: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
paginatedIssueText() {
|
||||||
|
return sprintf(__('Showing %{pageSize} of %{total} issues'), {
|
||||||
|
pageSize: this.list.issues.length,
|
||||||
|
total: this.list.issuesSize,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
filters: {
|
filters: {
|
||||||
handler() {
|
handler() {
|
||||||
|
@ -87,11 +105,20 @@ export default {
|
||||||
eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop);
|
eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
const multiSelectOpts = {};
|
||||||
|
if (gon.features && gon.features.multiSelectBoard) {
|
||||||
|
multiSelectOpts.multiDrag = true;
|
||||||
|
multiSelectOpts.selectedClass = 'js-multi-select';
|
||||||
|
multiSelectOpts.animation = 500;
|
||||||
|
}
|
||||||
|
|
||||||
const options = getBoardSortableDefaultOptions({
|
const options = getBoardSortableDefaultOptions({
|
||||||
scroll: true,
|
scroll: true,
|
||||||
disabled: this.disabled,
|
disabled: this.disabled,
|
||||||
filter: '.board-list-count, .is-disabled',
|
filter: '.board-list-count, .is-disabled',
|
||||||
dataIdAttr: 'data-issue-id',
|
dataIdAttr: 'data-issue-id',
|
||||||
|
removeCloneOnHide: false,
|
||||||
|
...multiSelectOpts,
|
||||||
group: {
|
group: {
|
||||||
name: 'issues',
|
name: 'issues',
|
||||||
/**
|
/**
|
||||||
|
@ -145,25 +172,66 @@ export default {
|
||||||
card.showDetail = false;
|
card.showDetail = false;
|
||||||
|
|
||||||
const { list } = card;
|
const { list } = card;
|
||||||
|
|
||||||
const issue = list.findIssue(Number(e.item.dataset.issueId));
|
const issue = list.findIssue(Number(e.item.dataset.issueId));
|
||||||
|
|
||||||
boardsStore.startMoving(list, issue);
|
boardsStore.startMoving(list, issue);
|
||||||
|
|
||||||
sortableStart();
|
sortableStart();
|
||||||
},
|
},
|
||||||
onAdd: e => {
|
onAdd: e => {
|
||||||
boardsStore.moveIssueToList(
|
const { items = [], newIndicies = [] } = e;
|
||||||
boardsStore.moving.list,
|
if (items.length) {
|
||||||
this.list,
|
// Not using e.newIndex here instead taking a min of all
|
||||||
boardsStore.moving.issue,
|
// the newIndicies. Basically we have to find that during
|
||||||
e.newIndex,
|
// a drop what is the index we're going to start putting
|
||||||
);
|
// all the dropped elements from.
|
||||||
|
const newIndex = Math.min(...newIndicies.map(obj => obj.index).filter(i => i !== -1));
|
||||||
|
const issues = items.map(item =>
|
||||||
|
boardsStore.moving.list.findIssue(Number(item.dataset.issueId)),
|
||||||
|
);
|
||||||
|
|
||||||
this.$nextTick(() => {
|
boardsStore.moveMultipleIssuesToList({
|
||||||
e.item.remove();
|
listFrom: boardsStore.moving.list,
|
||||||
});
|
listTo: this.list,
|
||||||
|
issues,
|
||||||
|
newIndex,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
boardsStore.moveIssueToList(
|
||||||
|
boardsStore.moving.list,
|
||||||
|
this.list,
|
||||||
|
boardsStore.moving.issue,
|
||||||
|
e.newIndex,
|
||||||
|
);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
e.item.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onUpdate: e => {
|
onUpdate: e => {
|
||||||
const sortedArray = this.sortable.toArray().filter(id => id !== '-1');
|
const sortedArray = this.sortable.toArray().filter(id => id !== '-1');
|
||||||
|
|
||||||
|
const { items = [], newIndicies = [], oldIndicies = [] } = e;
|
||||||
|
if (items.length) {
|
||||||
|
const newIndex = Math.min(...newIndicies.map(obj => obj.index));
|
||||||
|
const issues = items.map(item =>
|
||||||
|
boardsStore.moving.list.findIssue(Number(item.dataset.issueId)),
|
||||||
|
);
|
||||||
|
boardsStore.moveMultipleIssuesInList({
|
||||||
|
list: this.list,
|
||||||
|
issues,
|
||||||
|
oldIndicies: oldIndicies.map(obj => obj.index),
|
||||||
|
newIndex,
|
||||||
|
idArray: sortedArray,
|
||||||
|
});
|
||||||
|
e.items.forEach(el => {
|
||||||
|
Sortable.utils.deselect(el);
|
||||||
|
});
|
||||||
|
boardsStore.clearMultiSelect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boardsStore.moveIssueInList(
|
boardsStore.moveIssueInList(
|
||||||
this.list,
|
this.list,
|
||||||
boardsStore.moving.issue,
|
boardsStore.moving.issue,
|
||||||
|
@ -172,9 +240,133 @@ export default {
|
||||||
sortedArray,
|
sortedArray,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onEnd: e => {
|
||||||
|
const { items = [], clones = [], to } = e;
|
||||||
|
|
||||||
|
// This is not a multi select operation
|
||||||
|
if (!items.length && !clones.length) {
|
||||||
|
sortableEnd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let toList;
|
||||||
|
if (to) {
|
||||||
|
const containerEl = to.closest('.js-board-list');
|
||||||
|
toList = boardsStore.findList('id', Number(containerEl.dataset.board));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onEnd is called irrespective if the cards were moved in the
|
||||||
|
* same list or the other list. Don't remove items if it's same list.
|
||||||
|
*/
|
||||||
|
const isSameList = toList && toList.id === this.list.id;
|
||||||
|
|
||||||
|
if (toList && !isSameList && boardsStore.shouldRemoveIssue(this.list, toList)) {
|
||||||
|
const issues = items.map(item => this.list.findIssue(Number(item.dataset.issueId)));
|
||||||
|
|
||||||
|
if (_.compact(issues).length && !boardsStore.issuesAreContiguous(this.list, issues)) {
|
||||||
|
const indexes = [];
|
||||||
|
const ids = this.list.issues.map(i => i.id);
|
||||||
|
issues.forEach(issue => {
|
||||||
|
const index = ids.indexOf(issue.id);
|
||||||
|
if (index > -1) {
|
||||||
|
indexes.push(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Descending sort because splice would cause index discrepancy otherwise
|
||||||
|
const sortedIndexes = indexes.sort((a, b) => (a < b ? 1 : -1));
|
||||||
|
|
||||||
|
sortedIndexes.forEach(i => {
|
||||||
|
/**
|
||||||
|
* **setTimeout and splice each element one-by-one in a loop
|
||||||
|
* is intended.**
|
||||||
|
*
|
||||||
|
* The problem here is all the indexes are in the list but are
|
||||||
|
* non-contiguous. Due to that, when we splice all the indexes,
|
||||||
|
* at once, Vue -- during a re-render -- is unable to find reference
|
||||||
|
* nodes and the entire app crashes.
|
||||||
|
*
|
||||||
|
* If the indexes are contiguous, this piece of code is not
|
||||||
|
* executed. If it is, this is a possible regression. Only when
|
||||||
|
* issue indexes are far apart, this logic should ever kick in.
|
||||||
|
*/
|
||||||
|
setTimeout(() => {
|
||||||
|
this.list.issues.splice(i, 1);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toList) {
|
||||||
|
createFlash(__('Something went wrong while performing the action.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSameList) {
|
||||||
|
boardsStore.clearMultiSelect();
|
||||||
|
|
||||||
|
// Since Vue's list does not re-render the same keyed item, we'll
|
||||||
|
// remove `multi-select` class to express it's unselected
|
||||||
|
if (clones && clones.length) {
|
||||||
|
clones.forEach(el => el.classList.remove('multi-select'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Due to some bug which I am unable to figure out
|
||||||
|
// Sortable does not deselect some pending items from the
|
||||||
|
// source list.
|
||||||
|
// We'll just do it forcefully here.
|
||||||
|
Array.from(document.querySelectorAll('.js-multi-select') || []).forEach(item => {
|
||||||
|
Sortable.utils.deselect(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SortableJS leaves all the moving items "as is" on the DOM.
|
||||||
|
* Vue picks up and rehydrates the DOM, but we need to explicity
|
||||||
|
* remove the "trash" items from the DOM.
|
||||||
|
*
|
||||||
|
* This is in parity to the logic on single item move from a list/in
|
||||||
|
* a list. For reference, look at the implementation of onAdd method.
|
||||||
|
*/
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (items && items.length) {
|
||||||
|
items.forEach(item => {
|
||||||
|
item.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
sortableEnd();
|
||||||
|
},
|
||||||
onMove(e) {
|
onMove(e) {
|
||||||
return !e.related.classList.contains('board-list-count');
|
return !e.related.classList.contains('board-list-count');
|
||||||
},
|
},
|
||||||
|
onSelect(e) {
|
||||||
|
const {
|
||||||
|
item: { classList },
|
||||||
|
} = e;
|
||||||
|
|
||||||
|
if (
|
||||||
|
classList &&
|
||||||
|
classList.contains('js-multi-select') &&
|
||||||
|
!classList.contains('multi-select')
|
||||||
|
) {
|
||||||
|
Sortable.utils.deselect(e.item);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDeselect: e => {
|
||||||
|
const {
|
||||||
|
item: { dataset, classList },
|
||||||
|
} = e;
|
||||||
|
|
||||||
|
if (
|
||||||
|
classList &&
|
||||||
|
classList.contains('multi-select') &&
|
||||||
|
!classList.contains('js-multi-select')
|
||||||
|
) {
|
||||||
|
const issue = this.list.findIssue(Number(dataset.issueId));
|
||||||
|
boardsStore.toggleMultiSelect(issue);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sortable = Sortable.create(this.$refs.list, options);
|
this.sortable = Sortable.create(this.$refs.list, options);
|
||||||
|
@ -260,7 +452,7 @@ export default {
|
||||||
<li v-if="showCount" class="board-list-count text-center" data-issue-id="-1">
|
<li v-if="showCount" class="board-list-count text-center" data-issue-id="-1">
|
||||||
<gl-loading-icon v-show="list.loadingMore" label="Loading more issues" />
|
<gl-loading-icon v-show="list.loadingMore" label="Loading more issues" />
|
||||||
<span v-if="list.issues.length === list.issuesSize">{{ __('Showing all issues') }}</span>
|
<span v-if="list.issues.length === list.issuesSize">{{ __('Showing all issues') }}</span>
|
||||||
<span v-else> Showing {{ list.issues.length }} of {{ list.issuesSize }} issues </span>
|
<span v-else>{{ paginatedIssueText }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -305,13 +305,18 @@ export default {
|
||||||
<div v-if="canAdminBoard">
|
<div v-if="canAdminBoard">
|
||||||
<gl-dropdown-divider />
|
<gl-dropdown-divider />
|
||||||
|
|
||||||
<gl-dropdown-item v-if="multipleIssueBoardsAvailable" @click.prevent="showPage('new')">
|
<gl-dropdown-item
|
||||||
|
v-if="multipleIssueBoardsAvailable"
|
||||||
|
data-qa-selector="create_new_board_button"
|
||||||
|
@click.prevent="showPage('new')"
|
||||||
|
>
|
||||||
{{ s__('IssueBoards|Create new board') }}
|
{{ s__('IssueBoards|Create new board') }}
|
||||||
</gl-dropdown-item>
|
</gl-dropdown-item>
|
||||||
|
|
||||||
<gl-dropdown-item
|
<gl-dropdown-item
|
||||||
v-if="showDelete"
|
v-if="showDelete"
|
||||||
class="text-danger"
|
class="text-danger"
|
||||||
|
data-qa-selector="delete_board_button"
|
||||||
@click.prevent="showPage('delete')"
|
@click.prevent="showPage('delete')"
|
||||||
>
|
>
|
||||||
{{ s__('IssueBoards|Delete board') }}
|
{{ s__('IssueBoards|Delete board') }}
|
||||||
|
|
|
@ -99,7 +99,10 @@ export default {
|
||||||
return !groupId ? referencePath.split('#')[0] : null;
|
return !groupId ? referencePath.split('#')[0] : null;
|
||||||
},
|
},
|
||||||
orderedLabels() {
|
orderedLabels() {
|
||||||
return _.sortBy(this.issue.labels, 'title');
|
return _.chain(this.issue.labels)
|
||||||
|
.filter(this.isNonListLabel)
|
||||||
|
.sortBy('title')
|
||||||
|
.value();
|
||||||
},
|
},
|
||||||
helpLink() {
|
helpLink() {
|
||||||
return boardsStore.scopedLabels.helpLink;
|
return boardsStore.scopedLabels.helpLink;
|
||||||
|
@ -130,6 +133,9 @@ export default {
|
||||||
if (!label.id) return false;
|
if (!label.id) return false;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
isNonListLabel(label) {
|
||||||
|
return label.id && !(this.list.type === 'label' && this.list.title === label.title);
|
||||||
|
},
|
||||||
filterByLabel(label) {
|
filterByLabel(label) {
|
||||||
if (!this.updateFilters) return;
|
if (!this.updateFilters) return;
|
||||||
const labelTitle = encodeURIComponent(label.title);
|
const labelTitle = encodeURIComponent(label.title);
|
||||||
|
@ -167,7 +173,7 @@ export default {
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showLabelFooter" class="board-card-labels prepend-top-4 d-flex flex-wrap">
|
<div v-if="showLabelFooter" class="board-card-labels prepend-top-4 d-flex flex-wrap">
|
||||||
<template v-for="label in orderedLabels" v-if="showLabel(label)">
|
<template v-for="label in orderedLabels">
|
||||||
<issue-card-inner-scoped-label
|
<issue-card-inner-scoped-label
|
||||||
v-if="showScopedLabel(label)"
|
v-if="showScopedLabel(label)"
|
||||||
:key="label.id"
|
:key="label.id"
|
||||||
|
@ -212,7 +218,7 @@ export default {
|
||||||
<issue-due-date v-if="issue.dueDate" :date="issue.dueDate" />
|
<issue-due-date v-if="issue.dueDate" :date="issue.dueDate" />
|
||||||
<issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
|
<issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
|
||||||
<issue-card-weight
|
<issue-card-weight
|
||||||
v-if="issue.weight"
|
v-if="validIssueWeight"
|
||||||
:weight="issue.weight"
|
:weight="issue.weight"
|
||||||
@click="filterByWeight(issue.weight)"
|
@click="filterByWeight(issue.weight)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<span>
|
<span>
|
||||||
<span ref="issueTimeEstimate" class="board-card-info card-number">
|
<span ref="issueTimeEstimate" class="board-card-info card-number">
|
||||||
<icon name="hourglass" css-classes="board-card-info-icon align-top" /><time
|
<icon name="hourglass" class="board-card-info-icon align-top" /><time
|
||||||
class="board-card-info-text"
|
class="board-card-info-text"
|
||||||
>{{ timeEstimate }}</time
|
>{{ timeEstimate }}</time
|
||||||
>
|
>
|
||||||
|
|
11
app/assets/javascripts/boards/constants.js
Normal file
11
app/assets/javascripts/boards/constants.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export const ListType = {
|
||||||
|
assignee: 'assignee',
|
||||||
|
milestone: 'milestone',
|
||||||
|
backlog: 'backlog',
|
||||||
|
closed: 'closed',
|
||||||
|
label: 'label',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
ListType,
|
||||||
|
};
|
|
@ -22,7 +22,6 @@ import Board from 'ee_else_ce/boards/components/board';
|
||||||
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
|
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
|
||||||
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
|
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
|
||||||
import BoardAddIssuesModal from '~/boards/components/modal/index.vue';
|
import BoardAddIssuesModal from '~/boards/components/modal/index.vue';
|
||||||
import '~/vue_shared/vue_resource_interceptor';
|
|
||||||
import {
|
import {
|
||||||
NavigationType,
|
NavigationType,
|
||||||
convertObjectPropsToCamelCase,
|
convertObjectPropsToCamelCase,
|
||||||
|
@ -147,7 +146,7 @@ export default () => {
|
||||||
updateTokens() {
|
updateTokens() {
|
||||||
this.filterManager.updateTokens();
|
this.filterManager.updateTokens();
|
||||||
},
|
},
|
||||||
updateDetailIssue(newIssue) {
|
updateDetailIssue(newIssue, multiSelect = false) {
|
||||||
const { sidebarInfoEndpoint } = newIssue;
|
const { sidebarInfoEndpoint } = newIssue;
|
||||||
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
|
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
|
||||||
newIssue.setFetchingState('subscriptions', true);
|
newIssue.setFetchingState('subscriptions', true);
|
||||||
|
@ -186,9 +185,23 @@ export default () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (multiSelect) {
|
||||||
|
boardsStore.toggleMultiSelect(newIssue);
|
||||||
|
|
||||||
|
if (boardsStore.detail.issue) {
|
||||||
|
boardsStore.clearDetailIssue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boardsStore.setIssueDetail(newIssue);
|
boardsStore.setIssueDetail(newIssue);
|
||||||
},
|
},
|
||||||
clearDetailIssue() {
|
clearDetailIssue(multiSelect = false) {
|
||||||
|
if (multiSelect) {
|
||||||
|
boardsStore.clearMultiSelect();
|
||||||
|
}
|
||||||
boardsStore.clearDetailIssue();
|
boardsStore.clearDetailIssue();
|
||||||
},
|
},
|
||||||
toggleSubscription(id) {
|
toggleSubscription(id) {
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
export default {
|
export default {
|
||||||
|
computed: {
|
||||||
|
validIssueWeight() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
filterByWeight() {},
|
filterByWeight() {},
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ListLabel from './label';
|
||||||
import ListAssignee from './assignee';
|
import ListAssignee from './assignee';
|
||||||
import ListIssue from 'ee_else_ce/boards/models/issue';
|
import ListIssue from 'ee_else_ce/boards/models/issue';
|
||||||
import { urlParamsToObject } from '~/lib/utils/common_utils';
|
import { urlParamsToObject } from '~/lib/utils/common_utils';
|
||||||
|
import flash from '~/flash';
|
||||||
import boardsStore from '../stores/boards_store';
|
import boardsStore from '../stores/boards_store';
|
||||||
import ListMilestone from './milestone';
|
import ListMilestone from './milestone';
|
||||||
|
|
||||||
|
@ -176,6 +177,53 @@ class List {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addMultipleIssues(issues, listFrom, newIndex) {
|
||||||
|
let moveBeforeId = null;
|
||||||
|
let moveAfterId = null;
|
||||||
|
|
||||||
|
const listHasIssues = issues.every(issue => this.findIssue(issue.id));
|
||||||
|
|
||||||
|
if (!listHasIssues) {
|
||||||
|
if (newIndex !== undefined) {
|
||||||
|
if (this.issues[newIndex - 1]) {
|
||||||
|
moveBeforeId = this.issues[newIndex - 1].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.issues[newIndex]) {
|
||||||
|
moveAfterId = this.issues[newIndex].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.issues.splice(newIndex, 0, ...issues);
|
||||||
|
} else {
|
||||||
|
this.issues.push(...issues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.label) {
|
||||||
|
issues.forEach(issue => issue.addLabel(this.label));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.assignee) {
|
||||||
|
if (listFrom && listFrom.type === 'assignee') {
|
||||||
|
issues.forEach(issue => issue.removeAssignee(listFrom.assignee));
|
||||||
|
}
|
||||||
|
issues.forEach(issue => issue.addAssignee(this.assignee));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_EE && this.milestone) {
|
||||||
|
if (listFrom && listFrom.type === 'milestone') {
|
||||||
|
issues.forEach(issue => issue.removeMilestone(listFrom.milestone));
|
||||||
|
}
|
||||||
|
issues.forEach(issue => issue.addMilestone(this.milestone));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listFrom) {
|
||||||
|
this.issuesSize += issues.length;
|
||||||
|
|
||||||
|
this.updateMultipleIssues(issues, listFrom, moveBeforeId, moveAfterId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addIssue(issue, listFrom, newIndex) {
|
addIssue(issue, listFrom, newIndex) {
|
||||||
let moveBeforeId = null;
|
let moveBeforeId = null;
|
||||||
let moveAfterId = null;
|
let moveAfterId = null;
|
||||||
|
@ -230,6 +278,23 @@ class List {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveMultipleIssues({ issues, oldIndicies, newIndex, moveBeforeId, moveAfterId }) {
|
||||||
|
oldIndicies.reverse().forEach(index => {
|
||||||
|
this.issues.splice(index, 1);
|
||||||
|
});
|
||||||
|
this.issues.splice(newIndex, 0, ...issues);
|
||||||
|
|
||||||
|
gl.boardService
|
||||||
|
.moveMultipleIssues({
|
||||||
|
ids: issues.map(issue => issue.id),
|
||||||
|
fromListId: null,
|
||||||
|
toListId: null,
|
||||||
|
moveBeforeId,
|
||||||
|
moveAfterId,
|
||||||
|
})
|
||||||
|
.catch(() => flash(__('Something went wrong while moving issues.')));
|
||||||
|
}
|
||||||
|
|
||||||
updateIssueLabel(issue, listFrom, moveBeforeId, moveAfterId) {
|
updateIssueLabel(issue, listFrom, moveBeforeId, moveAfterId) {
|
||||||
gl.boardService
|
gl.boardService
|
||||||
.moveIssue(issue.id, listFrom.id, this.id, moveBeforeId, moveAfterId)
|
.moveIssue(issue.id, listFrom.id, this.id, moveBeforeId, moveAfterId)
|
||||||
|
@ -238,10 +303,37 @@ class List {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMultipleIssues(issues, listFrom, moveBeforeId, moveAfterId) {
|
||||||
|
gl.boardService
|
||||||
|
.moveMultipleIssues({
|
||||||
|
ids: issues.map(issue => issue.id),
|
||||||
|
fromListId: listFrom.id,
|
||||||
|
toListId: this.id,
|
||||||
|
moveBeforeId,
|
||||||
|
moveAfterId,
|
||||||
|
})
|
||||||
|
.catch(() => flash(__('Something went wrong while moving issues.')));
|
||||||
|
}
|
||||||
|
|
||||||
findIssue(id) {
|
findIssue(id) {
|
||||||
return this.issues.find(issue => issue.id === id);
|
return this.issues.find(issue => issue.id === id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeMultipleIssues(removeIssues) {
|
||||||
|
const ids = removeIssues.map(issue => issue.id);
|
||||||
|
|
||||||
|
this.issues = this.issues.filter(issue => {
|
||||||
|
const matchesRemove = ids.includes(issue.id);
|
||||||
|
|
||||||
|
if (matchesRemove) {
|
||||||
|
this.issuesSize -= 1;
|
||||||
|
issue.removeLabel(this.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !matchesRemove;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
removeIssue(removeIssue) {
|
removeIssue(removeIssue) {
|
||||||
this.issues = this.issues.filter(issue => {
|
this.issues = this.issues.filter(issue => {
|
||||||
const matchesRemove = removeIssue.id === issue.id;
|
const matchesRemove = removeIssue.id === issue.id;
|
||||||
|
|
|
@ -48,6 +48,16 @@ export default class BoardService {
|
||||||
return boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId);
|
return boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveMultipleIssues({
|
||||||
|
ids,
|
||||||
|
fromListId = null,
|
||||||
|
toListId = null,
|
||||||
|
moveBeforeId = null,
|
||||||
|
moveAfterId = null,
|
||||||
|
}) {
|
||||||
|
return boardsStore.moveMultipleIssues({ ids, fromListId, toListId, moveBeforeId, moveAfterId });
|
||||||
|
}
|
||||||
|
|
||||||
newIssue(id, issue) {
|
newIssue(id, issue) {
|
||||||
return boardsStore.newIssue(id, issue);
|
return boardsStore.newIssue(id, issue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { __ } from '~/locale';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import { mergeUrlParams } from '~/lib/utils/url_utility';
|
import { mergeUrlParams } from '~/lib/utils/url_utility';
|
||||||
import eventHub from '../eventhub';
|
import eventHub from '../eventhub';
|
||||||
|
import { ListType } from '../constants';
|
||||||
|
|
||||||
const boardsStore = {
|
const boardsStore = {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
@ -39,6 +40,7 @@ const boardsStore = {
|
||||||
issue: {},
|
issue: {},
|
||||||
list: {},
|
list: {},
|
||||||
},
|
},
|
||||||
|
multiSelect: { list: [] },
|
||||||
|
|
||||||
setEndpoints({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId, recentBoardsEndpoint }) {
|
setEndpoints({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId, recentBoardsEndpoint }) {
|
||||||
const listsEndpointGenerate = `${listsEndpoint}/generate.json`;
|
const listsEndpointGenerate = `${listsEndpoint}/generate.json`;
|
||||||
|
@ -51,7 +53,6 @@ const boardsStore = {
|
||||||
recentBoardsEndpoint: `${recentBoardsEndpoint}.json`,
|
recentBoardsEndpoint: `${recentBoardsEndpoint}.json`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
this.state.lists = [];
|
this.state.lists = [];
|
||||||
this.filter.path = getUrlParamsArray().join('&');
|
this.filter.path = getUrlParamsArray().join('&');
|
||||||
|
@ -134,6 +135,107 @@ const boardsStore = {
|
||||||
Object.assign(this.moving, { list, issue });
|
Object.assign(this.moving, { list, issue });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
moveMultipleIssuesToList({ listFrom, listTo, issues, newIndex }) {
|
||||||
|
const issueTo = issues.map(issue => listTo.findIssue(issue.id));
|
||||||
|
const issueLists = _.flatten(issues.map(issue => issue.getLists()));
|
||||||
|
const listLabels = issueLists.map(list => list.label);
|
||||||
|
|
||||||
|
const hasMoveableIssues = _.compact(issueTo).length > 0;
|
||||||
|
|
||||||
|
if (!hasMoveableIssues) {
|
||||||
|
// Check if target list assignee is already present in this issue
|
||||||
|
if (
|
||||||
|
listTo.type === ListType.assignee &&
|
||||||
|
listFrom.type === ListType.assignee &&
|
||||||
|
issues.some(issue => issue.findAssignee(listTo.assignee))
|
||||||
|
) {
|
||||||
|
const targetIssues = issues.map(issue => listTo.findIssue(issue.id));
|
||||||
|
targetIssues.forEach(targetIssue => targetIssue.removeAssignee(listFrom.assignee));
|
||||||
|
} else if (listTo.type === 'milestone') {
|
||||||
|
const currentMilestones = issues.map(issue => issue.milestone);
|
||||||
|
const currentLists = this.state.lists
|
||||||
|
.filter(list => list.type === 'milestone' && list.id !== listTo.id)
|
||||||
|
.filter(list =>
|
||||||
|
list.issues.some(listIssue => issues.some(issue => listIssue.id === issue.id)),
|
||||||
|
);
|
||||||
|
|
||||||
|
issues.forEach(issue => {
|
||||||
|
currentMilestones.forEach(milestone => {
|
||||||
|
issue.removeMilestone(milestone);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
issues.forEach(issue => {
|
||||||
|
issue.addMilestone(listTo.milestone);
|
||||||
|
});
|
||||||
|
|
||||||
|
currentLists.forEach(currentList => {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
currentList.removeIssue(issue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
listTo.addMultipleIssues(issues, listFrom, newIndex);
|
||||||
|
} else {
|
||||||
|
// Add to new lists issues if it doesn't already exist
|
||||||
|
listTo.addMultipleIssues(issues, listFrom, newIndex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listTo.updateMultipleIssues(issues, listFrom);
|
||||||
|
issues.forEach(issue => {
|
||||||
|
issue.removeLabel(listFrom.label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listTo.type === ListType.closed && listFrom.type !== ListType.backlog) {
|
||||||
|
issueLists.forEach(list => {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
list.removeIssue(issue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
issues.forEach(issue => {
|
||||||
|
issue.removeLabels(listLabels);
|
||||||
|
});
|
||||||
|
} else if (listTo.type === ListType.backlog && listFrom.type === ListType.assignee) {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
issue.removeAssignee(listFrom.assignee);
|
||||||
|
});
|
||||||
|
issueLists.forEach(list => {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
list.removeIssue(issue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (listTo.type === ListType.backlog && listFrom.type === ListType.milestone) {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
issue.removeMilestone(listFrom.milestone);
|
||||||
|
});
|
||||||
|
issueLists.forEach(list => {
|
||||||
|
issues.forEach(issue => {
|
||||||
|
list.removeIssue(issue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (
|
||||||
|
this.shouldRemoveIssue(listFrom, listTo) &&
|
||||||
|
this.issuesAreContiguous(listFrom, issues)
|
||||||
|
) {
|
||||||
|
listFrom.removeMultipleIssues(issues);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
issuesAreContiguous(list, issues) {
|
||||||
|
// When there's only 1 issue selected, we can return early.
|
||||||
|
if (issues.length === 1) return true;
|
||||||
|
|
||||||
|
// Create list of ids for issues involved.
|
||||||
|
const listIssueIds = list.issues.map(issue => issue.id);
|
||||||
|
const movedIssueIds = issues.map(issue => issue.id);
|
||||||
|
|
||||||
|
// Check if moved issue IDs is sub-array
|
||||||
|
// of source list issue IDs (i.e. contiguous selection).
|
||||||
|
return listIssueIds.join('|').includes(movedIssueIds.join('|'));
|
||||||
|
},
|
||||||
|
|
||||||
moveIssueToList(listFrom, listTo, issue, newIndex) {
|
moveIssueToList(listFrom, listTo, issue, newIndex) {
|
||||||
const issueTo = listTo.findIssue(issue.id);
|
const issueTo = listTo.findIssue(issue.id);
|
||||||
const issueLists = issue.getLists();
|
const issueLists = issue.getLists();
|
||||||
|
@ -195,6 +297,17 @@ const boardsStore = {
|
||||||
|
|
||||||
list.moveIssue(issue, oldIndex, newIndex, beforeId, afterId);
|
list.moveIssue(issue, oldIndex, newIndex, beforeId, afterId);
|
||||||
},
|
},
|
||||||
|
moveMultipleIssuesInList({ list, issues, oldIndicies, newIndex, idArray }) {
|
||||||
|
const beforeId = parseInt(idArray[newIndex - 1], 10) || null;
|
||||||
|
const afterId = parseInt(idArray[newIndex + issues.length], 10) || null;
|
||||||
|
list.moveMultipleIssues({
|
||||||
|
issues,
|
||||||
|
oldIndicies,
|
||||||
|
newIndex,
|
||||||
|
moveBeforeId: beforeId,
|
||||||
|
moveAfterId: afterId,
|
||||||
|
});
|
||||||
|
},
|
||||||
findList(key, val, type = 'label') {
|
findList(key, val, type = 'label') {
|
||||||
const filteredList = this.state.lists.filter(list => {
|
const filteredList = this.state.lists.filter(list => {
|
||||||
const byType = type
|
const byType = type
|
||||||
|
@ -260,6 +373,10 @@ const boardsStore = {
|
||||||
}`;
|
}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
generateMultiDragPath(boardId) {
|
||||||
|
return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues/bulk_move`;
|
||||||
|
},
|
||||||
|
|
||||||
all() {
|
all() {
|
||||||
return axios.get(this.state.endpoints.listsEndpoint);
|
return axios.get(this.state.endpoints.listsEndpoint);
|
||||||
},
|
},
|
||||||
|
@ -309,6 +426,16 @@ const boardsStore = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
moveMultipleIssues({ ids, fromListId, toListId, moveBeforeId, moveAfterId }) {
|
||||||
|
return axios.put(this.generateMultiDragPath(this.state.endpoints.boardId), {
|
||||||
|
from_list_id: fromListId,
|
||||||
|
to_list_id: toListId,
|
||||||
|
move_before_id: moveBeforeId,
|
||||||
|
move_after_id: moveAfterId,
|
||||||
|
ids,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
newIssue(id, issue) {
|
newIssue(id, issue) {
|
||||||
return axios.post(this.generateIssuesPath(id), {
|
return axios.post(this.generateIssuesPath(id), {
|
||||||
issue,
|
issue,
|
||||||
|
@ -379,6 +506,25 @@ const boardsStore = {
|
||||||
setCurrentBoard(board) {
|
setCurrentBoard(board) {
|
||||||
this.state.currentBoard = board;
|
this.state.currentBoard = board;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleMultiSelect(issue) {
|
||||||
|
const selectedIssueIds = this.multiSelect.list.map(issue => issue.id);
|
||||||
|
const index = selectedIssueIds.indexOf(issue.id);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
this.multiSelect.list.push(issue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.multiSelect.list = [
|
||||||
|
...this.multiSelect.list.slice(0, index),
|
||||||
|
...this.multiSelect.list.slice(index + 1),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
clearMultiSelect() {
|
||||||
|
this.multiSelect.list = [];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
BoardsStoreEE.initEESpecific(boardsStore);
|
BoardsStoreEE.initEESpecific(boardsStore);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable func-names, prefer-arrow-callback */
|
/* eslint-disable func-names */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { visitUrl } from './lib/utils/url_utility';
|
import { visitUrl } from './lib/utils/url_utility';
|
||||||
|
@ -12,11 +12,11 @@ export default class BuildArtifacts {
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
disablePropagation() {
|
disablePropagation() {
|
||||||
$('.top-block').on('click', '.download', function(e) {
|
$('.top-block').on('click', '.download', e => {
|
||||||
return e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
return $('.tree-holder').on('click', 'tr[data-link] a', function(e) {
|
return $('.tree-holder').on('click', 'tr[data-link] a', e => {
|
||||||
return e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
|
|
@ -41,6 +41,8 @@ export default class Clusters {
|
||||||
managePrometheusPath,
|
managePrometheusPath,
|
||||||
clusterEnvironmentsPath,
|
clusterEnvironmentsPath,
|
||||||
hasRbac,
|
hasRbac,
|
||||||
|
providerType,
|
||||||
|
preInstalledKnative,
|
||||||
clusterType,
|
clusterType,
|
||||||
clusterStatus,
|
clusterStatus,
|
||||||
clusterStatusReason,
|
clusterStatusReason,
|
||||||
|
@ -50,6 +52,7 @@ export default class Clusters {
|
||||||
environmentsHelpPath,
|
environmentsHelpPath,
|
||||||
clustersHelpPath,
|
clustersHelpPath,
|
||||||
deployBoardsHelpPath,
|
deployBoardsHelpPath,
|
||||||
|
cloudRunHelpPath,
|
||||||
clusterId,
|
clusterId,
|
||||||
} = document.querySelector('.js-edit-cluster-form').dataset;
|
} = document.querySelector('.js-edit-cluster-form').dataset;
|
||||||
|
|
||||||
|
@ -65,10 +68,13 @@ export default class Clusters {
|
||||||
environmentsHelpPath,
|
environmentsHelpPath,
|
||||||
clustersHelpPath,
|
clustersHelpPath,
|
||||||
deployBoardsHelpPath,
|
deployBoardsHelpPath,
|
||||||
|
cloudRunHelpPath,
|
||||||
);
|
);
|
||||||
this.store.setManagePrometheusPath(managePrometheusPath);
|
this.store.setManagePrometheusPath(managePrometheusPath);
|
||||||
this.store.updateStatus(clusterStatus);
|
this.store.updateStatus(clusterStatus);
|
||||||
this.store.updateStatusReason(clusterStatusReason);
|
this.store.updateStatusReason(clusterStatusReason);
|
||||||
|
this.store.updateProviderType(providerType);
|
||||||
|
this.store.updatePreInstalledKnative(preInstalledKnative);
|
||||||
this.store.updateRbac(hasRbac);
|
this.store.updateRbac(hasRbac);
|
||||||
this.service = new ClustersService({
|
this.service = new ClustersService({
|
||||||
endpoint: statusPath,
|
endpoint: statusPath,
|
||||||
|
@ -153,6 +159,9 @@ export default class Clusters {
|
||||||
ingressHelpPath: this.state.ingressHelpPath,
|
ingressHelpPath: this.state.ingressHelpPath,
|
||||||
managePrometheusPath: this.state.managePrometheusPath,
|
managePrometheusPath: this.state.managePrometheusPath,
|
||||||
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
|
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
|
||||||
|
cloudRunHelpPath: this.state.cloudRunHelpPath,
|
||||||
|
providerType: this.state.providerType,
|
||||||
|
preInstalledKnative: this.state.preInstalledKnative,
|
||||||
rbac: this.state.rbac,
|
rbac: this.state.rbac,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,6 +78,10 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
installedVia: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
version: {
|
version: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -311,6 +315,11 @@ export default {
|
||||||
>
|
>
|
||||||
<span v-else class="js-cluster-application-title">{{ title }}</span>
|
<span v-else class="js-cluster-application-title">{{ title }}</span>
|
||||||
</strong>
|
</strong>
|
||||||
|
<span
|
||||||
|
v-if="installedVia"
|
||||||
|
class="js-cluster-application-installed-via"
|
||||||
|
v-html="installedVia"
|
||||||
|
></span>
|
||||||
<slot name="description"></slot>
|
<slot name="description"></slot>
|
||||||
<div v-if="hasError" class="cluster-application-error text-danger prepend-top-10">
|
<div v-if="hasError" class="cluster-application-error text-danger prepend-top-10">
|
||||||
<p class="js-cluster-application-general-error-message append-bottom-0">
|
<p class="js-cluster-application-general-error-message append-bottom-0">
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { s__, sprintf } from '../../locale';
|
||||||
import applicationRow from './application_row.vue';
|
import applicationRow from './application_row.vue';
|
||||||
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
import KnativeDomainEditor from './knative_domain_editor.vue';
|
import KnativeDomainEditor from './knative_domain_editor.vue';
|
||||||
import { CLUSTER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';
|
import { CLUSTER_TYPE, PROVIDER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';
|
||||||
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
||||||
import eventHub from '~/clusters/event_hub';
|
import eventHub from '~/clusters/event_hub';
|
||||||
|
|
||||||
|
@ -54,11 +54,26 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
cloudRunHelpPath: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
managePrometheusPath: {
|
managePrometheusPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
providerType: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
preInstalledKnative: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
rbac: {
|
rbac: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -156,6 +171,25 @@ export default {
|
||||||
knative() {
|
knative() {
|
||||||
return this.applications.knative;
|
return this.applications.knative;
|
||||||
},
|
},
|
||||||
|
cloudRun() {
|
||||||
|
return this.providerType === PROVIDER_TYPE.GCP && this.preInstalledKnative;
|
||||||
|
},
|
||||||
|
installedVia() {
|
||||||
|
if (this.cloudRun) {
|
||||||
|
return sprintf(
|
||||||
|
_.escape(s__(`ClusterIntegration|installed via %{installed_via}`)),
|
||||||
|
{
|
||||||
|
installed_via: `<a href="${
|
||||||
|
this.cloudRunHelpPath
|
||||||
|
}" target="_blank" rel="noopener noreferrer">${_.escape(
|
||||||
|
s__('ClusterIntegration|Cloud Run'),
|
||||||
|
)}</a>`,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.helmInstallIllustration = helmInstallIllustration;
|
this.helmInstallIllustration = helmInstallIllustration;
|
||||||
|
@ -260,7 +294,7 @@ export default {
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
:text="ingressExternalEndpoint"
|
:text="ingressExternalEndpoint"
|
||||||
:title="s__('ClusterIntegration|Copy Ingress Endpoint to clipboard')"
|
:title="s__('ClusterIntegration|Copy Ingress Endpoint')"
|
||||||
class="input-group-text js-clipboard-btn"
|
class="input-group-text js-clipboard-btn"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
@ -438,7 +472,7 @@ export default {
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
:text="jupyterHostname"
|
:text="jupyterHostname"
|
||||||
:title="s__('ClusterIntegration|Copy Jupyter Hostname to clipboard')"
|
:title="s__('ClusterIntegration|Copy Jupyter Hostname')"
|
||||||
class="js-clipboard-btn"
|
class="js-clipboard-btn"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
@ -468,6 +502,7 @@ export default {
|
||||||
:installed="applications.knative.installed"
|
:installed="applications.knative.installed"
|
||||||
:install-failed="applications.knative.installFailed"
|
:install-failed="applications.knative.installFailed"
|
||||||
:install-application-request-params="{ hostname: applications.knative.hostname }"
|
:install-application-request-params="{ hostname: applications.knative.hostname }"
|
||||||
|
:installed-via="installedVia"
|
||||||
:uninstallable="applications.knative.uninstallable"
|
:uninstallable="applications.knative.uninstallable"
|
||||||
:uninstall-successful="applications.knative.uninstallSuccessful"
|
:uninstall-successful="applications.knative.uninstallSuccessful"
|
||||||
:uninstall-failed="applications.knative.uninstallFailed"
|
:uninstall-failed="applications.knative.uninstallFailed"
|
||||||
|
@ -499,7 +534,7 @@ export default {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<knative-domain-editor
|
<knative-domain-editor
|
||||||
v-if="knative.installed || (helmInstalled && rbac)"
|
v-if="(knative.installed || (helmInstalled && rbac)) && !preInstalledKnative"
|
||||||
:knative="knative"
|
:knative="knative"
|
||||||
:ingress-dns-help-path="ingressDnsHelpPath"
|
:ingress-dns-help-path="ingressDnsHelpPath"
|
||||||
@save="saveKnativeDomain"
|
@save="saveKnativeDomain"
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default {
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
:text="knativeExternalEndpoint"
|
:text="knativeExternalEndpoint"
|
||||||
:title="s__('ClusterIntegration|Copy Knative Endpoint to clipboard')"
|
:title="s__('ClusterIntegration|Copy Knative Endpoint')"
|
||||||
class="input-group-text js-knative-endpoint-clipboard-btn"
|
class="input-group-text js-knative-endpoint-clipboard-btn"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -5,8 +5,14 @@ import trackUninstallButtonClickMixin from 'ee_else_ce/clusters/mixins/track_uni
|
||||||
import { HELM, INGRESS, CERT_MANAGER, PROMETHEUS, RUNNER, KNATIVE, JUPYTER } from '../constants';
|
import { HELM, INGRESS, CERT_MANAGER, PROMETHEUS, RUNNER, KNATIVE, JUPYTER } from '../constants';
|
||||||
|
|
||||||
const CUSTOM_APP_WARNING_TEXT = {
|
const CUSTOM_APP_WARNING_TEXT = {
|
||||||
[HELM]: s__(
|
[HELM]: sprintf(
|
||||||
'ClusterIntegration|The associated Tiller pod will be deleted and cannot be restored.',
|
s__(
|
||||||
|
'ClusterIntegration|The associated Tiller pod, the %{gitlabManagedAppsNamespace} namespace, and all of its resources will be deleted and cannot be restored.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
gitlabManagedAppsNamespace: '<code>gitlab-managed-apps</code>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
[INGRESS]: s__(
|
[INGRESS]: s__(
|
||||||
'ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored.',
|
'ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored.',
|
||||||
|
@ -76,6 +82,7 @@ export default {
|
||||||
:modal-id="modalId"
|
:modal-id="modalId"
|
||||||
:title="title"
|
:title="title"
|
||||||
@ok="confirmUninstall()"
|
@ok="confirmUninstall()"
|
||||||
>{{ warningText }} {{ customAppWarningText }}</gl-modal
|
|
||||||
>
|
>
|
||||||
|
{{ warningText }} <span v-html="customAppWarningText"></span>
|
||||||
|
</gl-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,6 +5,11 @@ export const CLUSTER_TYPE = {
|
||||||
PROJECT: 'project_type',
|
PROJECT: 'project_type',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// These need to match the available providers in app/models/clusters/providers/
|
||||||
|
export const PROVIDER_TYPE = {
|
||||||
|
GCP: 'gcp',
|
||||||
|
};
|
||||||
|
|
||||||
// These need to match what is returned from the server
|
// These need to match what is returned from the server
|
||||||
export const APPLICATION_STATUS = {
|
export const APPLICATION_STATUS = {
|
||||||
NO_STATUS: null,
|
NO_STATUS: null,
|
||||||
|
@ -19,6 +24,7 @@ export const APPLICATION_STATUS = {
|
||||||
UNINSTALLING: 'uninstalling',
|
UNINSTALLING: 'uninstalling',
|
||||||
UNINSTALL_ERRORED: 'uninstall_errored',
|
UNINSTALL_ERRORED: 'uninstall_errored',
|
||||||
ERROR: 'errored',
|
ERROR: 'errored',
|
||||||
|
PRE_INSTALLED: 'pre_installed',
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -29,6 +35,7 @@ export const APPLICATION_INSTALLED_STATUSES = [
|
||||||
APPLICATION_STATUS.INSTALLED,
|
APPLICATION_STATUS.INSTALLED,
|
||||||
APPLICATION_STATUS.UPDATING,
|
APPLICATION_STATUS.UPDATING,
|
||||||
APPLICATION_STATUS.UNINSTALLING,
|
APPLICATION_STATUS.UNINSTALLING,
|
||||||
|
APPLICATION_STATUS.PRE_INSTALLED,
|
||||||
];
|
];
|
||||||
|
|
||||||
// These are only used client-side
|
// These are only used client-side
|
||||||
|
|
|
@ -13,6 +13,7 @@ const {
|
||||||
UPDATE_ERRORED,
|
UPDATE_ERRORED,
|
||||||
UNINSTALLING,
|
UNINSTALLING,
|
||||||
UNINSTALL_ERRORED,
|
UNINSTALL_ERRORED,
|
||||||
|
PRE_INSTALLED,
|
||||||
} = APPLICATION_STATUS;
|
} = APPLICATION_STATUS;
|
||||||
|
|
||||||
const applicationStateMachine = {
|
const applicationStateMachine = {
|
||||||
|
@ -63,6 +64,9 @@ const applicationStateMachine = {
|
||||||
uninstallFailed: true,
|
uninstallFailed: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[PRE_INSTALLED]: {
|
||||||
|
target: PRE_INSTALLED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[NOT_INSTALLABLE]: {
|
[NOT_INSTALLABLE]: {
|
||||||
|
@ -123,6 +127,27 @@ const applicationStateMachine = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[PRE_INSTALLED]: {
|
||||||
|
on: {
|
||||||
|
[UPDATE_EVENT]: {
|
||||||
|
target: UPDATING,
|
||||||
|
effects: {
|
||||||
|
updateFailed: false,
|
||||||
|
updateSuccessful: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[NOT_INSTALLABLE]: {
|
||||||
|
target: NOT_INSTALLABLE,
|
||||||
|
},
|
||||||
|
[UNINSTALL_EVENT]: {
|
||||||
|
target: UNINSTALLING,
|
||||||
|
effects: {
|
||||||
|
uninstallFailed: false,
|
||||||
|
uninstallSuccessful: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
[UPDATING]: {
|
[UPDATING]: {
|
||||||
on: {
|
on: {
|
||||||
[UPDATED]: {
|
[UPDATED]: {
|
||||||
|
|
|
@ -35,7 +35,10 @@ export default class ClusterStore {
|
||||||
environmentsHelpPath: null,
|
environmentsHelpPath: null,
|
||||||
clustersHelpPath: null,
|
clustersHelpPath: null,
|
||||||
deployBoardsHelpPath: null,
|
deployBoardsHelpPath: null,
|
||||||
|
cloudRunHelpPath: null,
|
||||||
status: null,
|
status: null,
|
||||||
|
providerType: null,
|
||||||
|
preInstalledKnative: false,
|
||||||
rbac: false,
|
rbac: false,
|
||||||
statusReason: null,
|
statusReason: null,
|
||||||
applications: {
|
applications: {
|
||||||
|
@ -95,6 +98,7 @@ export default class ClusterStore {
|
||||||
environmentsHelpPath,
|
environmentsHelpPath,
|
||||||
clustersHelpPath,
|
clustersHelpPath,
|
||||||
deployBoardsHelpPath,
|
deployBoardsHelpPath,
|
||||||
|
cloudRunHelpPath,
|
||||||
) {
|
) {
|
||||||
this.state.helpPath = helpPath;
|
this.state.helpPath = helpPath;
|
||||||
this.state.ingressHelpPath = ingressHelpPath;
|
this.state.ingressHelpPath = ingressHelpPath;
|
||||||
|
@ -102,6 +106,7 @@ export default class ClusterStore {
|
||||||
this.state.environmentsHelpPath = environmentsHelpPath;
|
this.state.environmentsHelpPath = environmentsHelpPath;
|
||||||
this.state.clustersHelpPath = clustersHelpPath;
|
this.state.clustersHelpPath = clustersHelpPath;
|
||||||
this.state.deployBoardsHelpPath = deployBoardsHelpPath;
|
this.state.deployBoardsHelpPath = deployBoardsHelpPath;
|
||||||
|
this.state.cloudRunHelpPath = cloudRunHelpPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
setManagePrometheusPath(managePrometheusPath) {
|
setManagePrometheusPath(managePrometheusPath) {
|
||||||
|
@ -112,6 +117,14 @@ export default class ClusterStore {
|
||||||
this.state.status = status;
|
this.state.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateProviderType(providerType) {
|
||||||
|
this.state.providerType = providerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePreInstalledKnative(preInstalledKnative) {
|
||||||
|
this.state.preInstalledKnative = parseBoolean(preInstalledKnative);
|
||||||
|
}
|
||||||
|
|
||||||
updateRbac(rbac) {
|
updateRbac(rbac) {
|
||||||
this.state.rbac = parseBoolean(rbac);
|
this.state.rbac = parseBoolean(rbac);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable func-names, no-var, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, one-var, no-return-assign, no-unused-expressions, no-sequences */
|
/* eslint-disable func-names, no-var, no-else-return, consistent-return, one-var, no-return-assign, no-unused-expressions, no-sequences */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
@ -13,14 +13,14 @@ export default class ImageFile {
|
||||||
$('.two-up.view .frame.deleted img', this.file),
|
$('.two-up.view .frame.deleted img', this.file),
|
||||||
(function(_this) {
|
(function(_this) {
|
||||||
return function() {
|
return function() {
|
||||||
return _this.requestImageInfo($('.two-up.view .frame.added img', _this.file), function() {
|
return _this.requestImageInfo($('.two-up.view .frame.added img', _this.file), () => {
|
||||||
_this.initViewModes();
|
_this.initViewModes();
|
||||||
|
|
||||||
// Load two-up view after images are loaded
|
// Load two-up view after images are loaded
|
||||||
// so that we can display the correct width and height information
|
// so that we can display the correct width and height information
|
||||||
const $images = $('.two-up.view img', _this.file);
|
const $images = $('.two-up.view img', _this.file);
|
||||||
|
|
||||||
$images.waitForImages(function() {
|
$images.waitForImages(() => {
|
||||||
_this.initView('two-up');
|
_this.initView('two-up');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -49,13 +49,13 @@ export default class ImageFile {
|
||||||
activateViewMode(viewMode) {
|
activateViewMode(viewMode) {
|
||||||
$('.view-modes-menu li', this.file)
|
$('.view-modes-menu li', this.file)
|
||||||
.removeClass('active')
|
.removeClass('active')
|
||||||
.filter('.' + viewMode)
|
.filter(`.${viewMode}`)
|
||||||
.addClass('active');
|
.addClass('active');
|
||||||
return $('.view:visible:not(.' + viewMode + ')', this.file).fadeOut(
|
return $(`.view:visible:not(.${viewMode})`, this.file).fadeOut(
|
||||||
200,
|
200,
|
||||||
(function(_this) {
|
(function(_this) {
|
||||||
return function() {
|
return function() {
|
||||||
$('.view.' + viewMode, _this.file).fadeIn(200);
|
$(`.view.${viewMode}`, _this.file).fadeIn(200);
|
||||||
return _this.initView(viewMode);
|
return _this.initView(viewMode);
|
||||||
};
|
};
|
||||||
})(this),
|
})(this),
|
||||||
|
@ -138,9 +138,9 @@ export default class ImageFile {
|
||||||
return $(this).width(availWidth / 2);
|
return $(this).width(availWidth / 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return _this.requestImageInfo($('img', wrap), function(width, height) {
|
return _this.requestImageInfo($('img', wrap), (width, height) => {
|
||||||
$('.image-info .meta-width', wrap).text(width + 'px');
|
$('.image-info .meta-width', wrap).text(`${width}px`);
|
||||||
$('.image-info .meta-height', wrap).text(height + 'px');
|
$('.image-info .meta-height', wrap).text(`${height}px`);
|
||||||
return $('.image-info', wrap).removeClass('hide');
|
return $('.image-info', wrap).removeClass('hide');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -175,7 +175,7 @@ export default class ImageFile {
|
||||||
|
|
||||||
wrapPadding = parseInt($swipeWrap.css('right').replace('px', ''), 10);
|
wrapPadding = parseInt($swipeWrap.css('right').replace('px', ''), 10);
|
||||||
|
|
||||||
_this.initDraggable($swipeBar, wrapPadding, function(e, left) {
|
_this.initDraggable($swipeBar, wrapPadding, (e, left) => {
|
||||||
if (left > 0 && left < $swipeFrame.width() - wrapPadding * 2) {
|
if (left > 0 && left < $swipeFrame.width() - wrapPadding * 2) {
|
||||||
$swipeWrap.width(maxWidth + 1 - left);
|
$swipeWrap.width(maxWidth + 1 - left);
|
||||||
$swipeBar.css('left', left);
|
$swipeBar.css('left', left);
|
||||||
|
@ -215,7 +215,7 @@ export default class ImageFile {
|
||||||
$frameAdded.css('opacity', 1);
|
$frameAdded.css('opacity', 1);
|
||||||
framePadding = parseInt($frameAdded.css('right').replace('px', ''), 10);
|
framePadding = parseInt($frameAdded.css('right').replace('px', ''), 10);
|
||||||
|
|
||||||
_this.initDraggable($dragger, framePadding, function(e, left) {
|
_this.initDraggable($dragger, framePadding, (e, left) => {
|
||||||
var opacity = left / dragTrackWidth;
|
var opacity = left / dragTrackWidth;
|
||||||
|
|
||||||
if (opacity >= 0 && opacity <= 1) {
|
if (opacity >= 0 && opacity <= 1) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import '../vue_shared/vue_resource_interceptor';
|
import GlFeatureFlagsPlugin from '~/vue_shared/gl_feature_flags_plugin';
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vue.use(GlFeatureFlagsPlugin);
|
||||||
|
|
|
@ -3,6 +3,8 @@ import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_searc
|
||||||
import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
|
import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
|
||||||
import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
|
import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
|
||||||
|
|
||||||
|
const findItem = (items, valueProp, value) => items.find(item => item[valueProp] === value);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
DropdownButton,
|
DropdownButton,
|
||||||
|
@ -26,7 +28,7 @@ export default {
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: [Object, String],
|
||||||
required: false,
|
required: false,
|
||||||
default: () => null,
|
default: () => null,
|
||||||
},
|
},
|
||||||
|
@ -93,8 +95,8 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
selectedItem: findItem(this.items, this.value),
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
selectedItem: null,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -127,10 +129,15 @@ export default {
|
||||||
return (this.selectedItem && this.selectedItem[this.valueProperty]) || '';
|
return (this.selectedItem && this.selectedItem[this.valueProperty]) || '';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
value(value) {
|
||||||
|
this.selectedItem = findItem(this.items, this.valueProperty, value);
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
select(item) {
|
select(item) {
|
||||||
this.selectedItem = item;
|
this.selectedItem = item;
|
||||||
this.$emit('input', item);
|
this.$emit('input', item[this.valueProperty]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,23 @@ export default {
|
||||||
ServiceCredentialsForm,
|
ServiceCredentialsForm,
|
||||||
EksClusterConfigurationForm,
|
EksClusterConfigurationForm,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
gitlabManagedClusterHelpPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
kubernetesIntegrationHelpPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<eks-cluster-configuration-form />
|
<div class="js-create-eks-cluster">
|
||||||
|
<eks-cluster-configuration-form
|
||||||
|
:gitlab-managed-cluster-help-path="gitlabManagedClusterHelpPath"
|
||||||
|
:kubernetes-integration-help-path="kubernetesIntegrationHelpPath"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,25 +1,394 @@
|
||||||
<script>
|
<script>
|
||||||
import RoleNameDropdown from './role_name_dropdown.vue';
|
import { createNamespacedHelpers, mapState, mapActions } from 'vuex';
|
||||||
import SecurityGroupDropdown from './security_group_dropdown.vue';
|
import { sprintf, s__ } from '~/locale';
|
||||||
import SubnetDropdown from './subnet_dropdown.vue';
|
import _ from 'underscore';
|
||||||
import VPCDropdown from './vpc_dropdown.vue';
|
import { GlFormInput, GlFormCheckbox } from '@gitlab/ui';
|
||||||
|
import ClusterFormDropdown from './cluster_form_dropdown.vue';
|
||||||
|
import RegionDropdown from './region_dropdown.vue';
|
||||||
|
import { KUBERNETES_VERSIONS } from '../constants';
|
||||||
|
|
||||||
|
const { mapState: mapRolesState, mapActions: mapRolesActions } = createNamespacedHelpers('roles');
|
||||||
|
const { mapState: mapRegionsState, mapActions: mapRegionsActions } = createNamespacedHelpers(
|
||||||
|
'regions',
|
||||||
|
);
|
||||||
|
const { mapState: mapKeyPairsState, mapActions: mapKeyPairsActions } = createNamespacedHelpers(
|
||||||
|
'keyPairs',
|
||||||
|
);
|
||||||
|
const { mapState: mapVpcsState, mapActions: mapVpcActions } = createNamespacedHelpers('vpcs');
|
||||||
|
const { mapState: mapSubnetsState, mapActions: mapSubnetActions } = createNamespacedHelpers(
|
||||||
|
'subnets',
|
||||||
|
);
|
||||||
|
const {
|
||||||
|
mapState: mapSecurityGroupsState,
|
||||||
|
mapActions: mapSecurityGroupsActions,
|
||||||
|
} = createNamespacedHelpers('securityGroups');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
RoleNameDropdown,
|
ClusterFormDropdown,
|
||||||
SecurityGroupDropdown,
|
RegionDropdown,
|
||||||
SubnetDropdown,
|
GlFormInput,
|
||||||
VPCDropdown,
|
GlFormCheckbox,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
gitlabManagedClusterHelpPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
kubernetesIntegrationHelpPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState([
|
||||||
|
'clusterName',
|
||||||
|
'environmentScope',
|
||||||
|
'kubernetesVersion',
|
||||||
|
'selectedRegion',
|
||||||
|
'selectedKeyPair',
|
||||||
|
'selectedVpc',
|
||||||
|
'selectedSubnet',
|
||||||
|
'selectedRole',
|
||||||
|
'selectedSecurityGroup',
|
||||||
|
'gitlabManagedCluster',
|
||||||
|
]),
|
||||||
|
...mapRolesState({
|
||||||
|
roles: 'items',
|
||||||
|
isLoadingRoles: 'isLoadingItems',
|
||||||
|
loadingRolesError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
...mapRegionsState({
|
||||||
|
regions: 'items',
|
||||||
|
isLoadingRegions: 'isLoadingItems',
|
||||||
|
loadingRegionsError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
...mapKeyPairsState({
|
||||||
|
keyPairs: 'items',
|
||||||
|
isLoadingKeyPairs: 'isLoadingItems',
|
||||||
|
loadingKeyPairsError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
...mapVpcsState({
|
||||||
|
vpcs: 'items',
|
||||||
|
isLoadingVpcs: 'isLoadingItems',
|
||||||
|
loadingVpcsError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
...mapSubnetsState({
|
||||||
|
subnets: 'items',
|
||||||
|
isLoadingSubnets: 'isLoadingItems',
|
||||||
|
loadingSubnetsError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
...mapSecurityGroupsState({
|
||||||
|
securityGroups: 'items',
|
||||||
|
isLoadingSecurityGroups: 'isLoadingItems',
|
||||||
|
loadingSecurityGroupsError: 'loadingItemsError',
|
||||||
|
}),
|
||||||
|
kubernetesVersions() {
|
||||||
|
return KUBERNETES_VERSIONS;
|
||||||
|
},
|
||||||
|
vpcDropdownDisabled() {
|
||||||
|
return !this.selectedRegion;
|
||||||
|
},
|
||||||
|
keyPairDropdownDisabled() {
|
||||||
|
return !this.selectedRegion;
|
||||||
|
},
|
||||||
|
subnetDropdownDisabled() {
|
||||||
|
return !this.selectedVpc;
|
||||||
|
},
|
||||||
|
securityGroupDropdownDisabled() {
|
||||||
|
return !this.selectedVpc;
|
||||||
|
},
|
||||||
|
kubernetesIntegrationHelpText() {
|
||||||
|
const escapedUrl = _.escape(this.kubernetesIntegrationHelpPath);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernetes cluster integration.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
link_start: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
|
||||||
|
link_end: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
roleDropdownHelpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Select the IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role name, first create one on %{startLink}Amazon Web Services%{endLink}.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://console.aws.amazon.com/iam/home?#roles" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
keyPairDropdownHelpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{startLink}Amazon Web Services%{endLink}.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#having-ec2-create-your-key-pair" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
vpcDropdownHelpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Select a VPC to use for your EKS Cluster resources. To use a new VPC, first create one on %{startLink}Amazon Web Services%{endLink}.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://console.aws.amazon.com/vpc/home?#vpc" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
subnetDropdownHelpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Choose the %{startLink}subnets%{endLink} in your VPC where your worker nodes will run.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://console.aws.amazon.com/vpc/home?#subnets" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
securityGroupDropdownHelpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Choose the %{startLink}security groups%{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://console.aws.amazon.com/vpc/home?#securityGroups" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
gitlabManagedHelpText() {
|
||||||
|
const escapedUrl = _.escape(this.gitlabManagedClusterHelpPath);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
startLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchRegions();
|
||||||
|
this.fetchRoles();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions([
|
||||||
|
'setClusterName',
|
||||||
|
'setEnvironmentScope',
|
||||||
|
'setKubernetesVersion',
|
||||||
|
'setRegion',
|
||||||
|
'setVpc',
|
||||||
|
'setSubnet',
|
||||||
|
'setRole',
|
||||||
|
'setKeyPair',
|
||||||
|
'setSecurityGroup',
|
||||||
|
'setGitlabManagedCluster',
|
||||||
|
]),
|
||||||
|
...mapRegionsActions({ fetchRegions: 'fetchItems' }),
|
||||||
|
...mapVpcActions({ fetchVpcs: 'fetchItems' }),
|
||||||
|
...mapSubnetActions({ fetchSubnets: 'fetchItems' }),
|
||||||
|
...mapRolesActions({ fetchRoles: 'fetchItems' }),
|
||||||
|
...mapKeyPairsActions({ fetchKeyPairs: 'fetchItems' }),
|
||||||
|
...mapSecurityGroupsActions({ fetchSecurityGroups: 'fetchItems' }),
|
||||||
|
setRegionAndFetchVpcsAndKeyPairs(region) {
|
||||||
|
this.setRegion({ region });
|
||||||
|
this.fetchVpcs({ region });
|
||||||
|
this.fetchKeyPairs({ region });
|
||||||
|
},
|
||||||
|
setVpcAndFetchSubnets(vpc) {
|
||||||
|
this.setVpc({ vpc });
|
||||||
|
this.fetchSubnets({ vpc });
|
||||||
|
this.fetchSecurityGroups({ vpc });
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<form name="eks-cluster-configuration-form">
|
<form name="eks-cluster-configuration-form">
|
||||||
|
<h2>
|
||||||
|
{{ s__('ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster') }}
|
||||||
|
</h2>
|
||||||
|
<p v-html="kubernetesIntegrationHelpText"></p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="label-bold" name="role" for="eks-role">
|
<label class="label-bold" for="eks-cluster-name">{{
|
||||||
{{ s__('ClusterIntegration|Role name') }}
|
s__('ClusterIntegration|Kubernetes cluster name')
|
||||||
</label>
|
}}</label>
|
||||||
<role-name-dropdown />
|
<gl-form-input
|
||||||
|
id="eks-cluster-name"
|
||||||
|
:value="clusterName"
|
||||||
|
@input="setClusterName({ clusterName: $event })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-environment-scope">{{
|
||||||
|
s__('ClusterIntegration|Environment scope')
|
||||||
|
}}</label>
|
||||||
|
<gl-form-input
|
||||||
|
id="eks-environment-scope"
|
||||||
|
:value="environmentScope"
|
||||||
|
@input="setEnvironmentScope({ environmentScope: $event })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-kubernetes-version">{{
|
||||||
|
s__('ClusterIntegration|Kubernetes version')
|
||||||
|
}}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-kubernetes-version"
|
||||||
|
field-name="eks-kubernetes-version"
|
||||||
|
:value="kubernetesVersion"
|
||||||
|
:items="kubernetesVersions"
|
||||||
|
:empty-text="s__('ClusterIntegration|Kubernetes version not found')"
|
||||||
|
@input="setKubernetesVersion({ kubernetesVersion: $event })"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="roleDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Role name') }}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-role"
|
||||||
|
field-name="eks-role"
|
||||||
|
:input="selectedRole"
|
||||||
|
:items="roles"
|
||||||
|
:loading="isLoadingRoles"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading IAM Roles')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select role name')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search IAM Roles')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No IAM Roles found')"
|
||||||
|
:has-errors="Boolean(loadingRolesError)"
|
||||||
|
:error-message="s__('ClusterIntegration|Could not load IAM roles')"
|
||||||
|
@input="setRole({ role: $event })"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="roleDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Region') }}</label>
|
||||||
|
<region-dropdown
|
||||||
|
:value="selectedRegion"
|
||||||
|
:regions="regions"
|
||||||
|
:error="loadingRegionsError"
|
||||||
|
:loading="isLoadingRegions"
|
||||||
|
@input="setRegionAndFetchVpcsAndKeyPairs($event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-key-pair">{{
|
||||||
|
s__('ClusterIntegration|Key pair name')
|
||||||
|
}}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-key-pair"
|
||||||
|
field-name="eks-key-pair"
|
||||||
|
:input="selectedKeyPair"
|
||||||
|
:items="keyPairs"
|
||||||
|
:disabled="keyPairDropdownDisabled"
|
||||||
|
:disabled-text="s__('ClusterIntegration|Select a region to choose a Key Pair')"
|
||||||
|
:loading="isLoadingKeyPairs"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading Key Pairs')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select key pair')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search Key Pairs')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No Key Pairs found')"
|
||||||
|
:has-errors="Boolean(loadingKeyPairsError)"
|
||||||
|
:error-message="s__('ClusterIntegration|Could not load Key Pairs')"
|
||||||
|
@input="setKeyPair({ keyPair: $event })"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="keyPairDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-vpc">{{ s__('ClusterIntegration|VPC') }}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-vpc"
|
||||||
|
field-name="eks-vpc"
|
||||||
|
:input="selectedVpc"
|
||||||
|
:items="vpcs"
|
||||||
|
:loading="isLoadingVpcs"
|
||||||
|
:disabled="vpcDropdownDisabled"
|
||||||
|
:disabled-text="s__('ClusterIntegration|Select a region to choose a VPC')"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading VPCs')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select a VPC')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search VPCs')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No VPCs found')"
|
||||||
|
:has-errors="Boolean(loadingVpcsError)"
|
||||||
|
:error-message="s__('ClusterIntegration|Could not load VPCs for the selected region')"
|
||||||
|
@input="setVpcAndFetchSubnets($event)"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="vpcDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Subnet') }}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-subnet"
|
||||||
|
field-name="eks-subnet"
|
||||||
|
:input="selectedSubnet"
|
||||||
|
:items="subnets"
|
||||||
|
:loading="isLoadingSubnets"
|
||||||
|
:disabled="subnetDropdownDisabled"
|
||||||
|
:disabled-text="s__('ClusterIntegration|Select a VPC to choose a subnet')"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading subnets')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select a subnet')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search subnets')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No subnet found')"
|
||||||
|
:has-errors="Boolean(loadingSubnetsError)"
|
||||||
|
:error-message="s__('ClusterIntegration|Could not load subnets for the selected VPC')"
|
||||||
|
@input="setSubnet({ subnet: $event })"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="subnetDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="label-bold" for="eks-security-group">{{
|
||||||
|
s__('ClusterIntegration|Security groups')
|
||||||
|
}}</label>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-security-group"
|
||||||
|
field-name="eks-security-group"
|
||||||
|
:input="selectedSecurityGroup"
|
||||||
|
:items="securityGroups"
|
||||||
|
:loading="isLoadingSecurityGroups"
|
||||||
|
:disabled="securityGroupDropdownDisabled"
|
||||||
|
:disabled-text="s__('ClusterIntegration|Select a VPC to choose a security group')"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading security groups')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select a security group')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search security groups')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No security group found')"
|
||||||
|
:has-errors="Boolean(loadingSecurityGroupsError)"
|
||||||
|
:error-message="
|
||||||
|
s__('ClusterIntegration|Could not load security groups for the selected VPC')
|
||||||
|
"
|
||||||
|
@input="setSecurityGroup({ securityGroup: $event })"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="securityGroupDropdownHelpText"></p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<gl-form-checkbox
|
||||||
|
:checked="gitlabManagedCluster"
|
||||||
|
@input="setGitlabManagedCluster({ gitlabManagedCluster: $event })"
|
||||||
|
>{{ s__('ClusterIntegration|GitLab-managed cluster') }}</gl-form-checkbox
|
||||||
|
>
|
||||||
|
<p class="form-text text-muted" v-html="gitlabManagedHelpText"></p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<script>
|
||||||
|
import { sprintf, s__ } from '~/locale';
|
||||||
|
|
||||||
|
import ClusterFormDropdown from './cluster_form_dropdown.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ClusterFormDropdown,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
regions: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasErrors() {
|
||||||
|
return Boolean(this.error);
|
||||||
|
},
|
||||||
|
helpText() {
|
||||||
|
return sprintf(
|
||||||
|
s__('ClusterIntegration|Learn more about %{startLink}Regions%{endLink}.'),
|
||||||
|
{
|
||||||
|
startLink:
|
||||||
|
'<a href="https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/" target="_blank" rel="noopener noreferrer">',
|
||||||
|
endLink: '</a>',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<cluster-form-dropdown
|
||||||
|
field-id="eks-region"
|
||||||
|
field-name="eks-region"
|
||||||
|
:items="regions"
|
||||||
|
:loading="loading"
|
||||||
|
:loading-text="s__('ClusterIntegration|Loading Regions')"
|
||||||
|
:placeholder="s__('ClusterIntergation|Select a region')"
|
||||||
|
:search-field-placeholder="s__('ClusterIntegration|Search regions')"
|
||||||
|
:empty-text="s__('ClusterIntegration|No region found')"
|
||||||
|
:has-errors="hasErrors"
|
||||||
|
:error-message="s__('ClusterIntegration|Could not load regions from your AWS account')"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-on="$listeners"
|
||||||
|
/>
|
||||||
|
<p class="form-text text-muted" v-html="helpText"></p>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,53 +0,0 @@
|
||||||
<script>
|
|
||||||
import { sprintf, s__ } from '~/locale';
|
|
||||||
|
|
||||||
import ClusterFormDropdown from './cluster_form_dropdown.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
ClusterFormDropdown,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
roles: {
|
|
||||||
type: Array,
|
|
||||||
required: false,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
helpText() {
|
|
||||||
return sprintf(
|
|
||||||
s__(
|
|
||||||
'ClusterIntegration|Select the IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role name, first create one on %{startLink}Amazon Web Services%{endLink}.',
|
|
||||||
),
|
|
||||||
{
|
|
||||||
startLink:
|
|
||||||
'<a href="https://console.aws.amazon.com/iam/home?#roles" target="_blank" rel="noopener noreferrer">',
|
|
||||||
endLink: '</a>',
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<cluster-form-dropdown
|
|
||||||
field-id="eks-role-name"
|
|
||||||
field-name="eks-role-name"
|
|
||||||
:items="roles"
|
|
||||||
:loading="loading"
|
|
||||||
:loading-text="s__('ClusterIntegration|Loading IAM Roles')"
|
|
||||||
:placeholder="s__('ClusterIntergation|Select role name')"
|
|
||||||
:search-field-placeholder="s__('ClusterIntegration|Search IAM Roles')"
|
|
||||||
:empty-text="s__('ClusterIntegration|No IAM Roles found')"
|
|
||||||
/>
|
|
||||||
<p class="form-text text-muted" v-html="helpText"></p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue