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
|
||||
# - ./ee/app/models/license.rb
|
||||
# - ./lib/gitlab.rb
|
||||
# - ./lib/gitlab/utils.rb
|
||||
# - ./qa/
|
||||
# - ./INSTALLATION_TYPE
|
||||
# - ./VERSION
|
||||
|
@ -49,7 +50,6 @@
|
|||
/lib/flowdock/
|
||||
/lib/generators/
|
||||
/lib/gitaly/
|
||||
/lib/gitlab/
|
||||
/lib/api/
|
||||
/lib/token/
|
||||
/lib/mattermost/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
extends:
|
||||
- '@gitlab'
|
||||
- plugin:promise/recommended
|
||||
globals:
|
||||
__webpack_public_path__: true
|
||||
gl: false
|
||||
|
@ -10,6 +11,7 @@ plugins:
|
|||
- import
|
||||
- "@gitlab/i18n"
|
||||
- "@gitlab/vue-i18n"
|
||||
- no-jquery
|
||||
settings:
|
||||
import/resolver:
|
||||
webpack:
|
||||
|
@ -36,6 +38,13 @@ rules:
|
|||
vue/no-use-v-if-with-v-for: off
|
||||
vue/no-v-html: 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:
|
||||
files:
|
||||
- '**/spec/**/*'
|
||||
|
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1,3 +1,2 @@
|
|||
VERSION merge=ours
|
||||
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 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!
|
||||
|
||||
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/
|
||||
**/tmp/rubocop_cache/**
|
||||
.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:
|
||||
- prepare
|
||||
|
@ -8,17 +8,17 @@ stages:
|
|||
- review
|
||||
- qa
|
||||
- post-test
|
||||
- notification
|
||||
- pages
|
||||
|
||||
variables:
|
||||
RAILS_ENV: "test"
|
||||
NODE_ENV: "test"
|
||||
SIMPLECOV: "true"
|
||||
GIT_DEPTH: "20"
|
||||
GIT_DEPTH: "50"
|
||||
GIT_SUBMODULE_STRATEGY: "none"
|
||||
GET_SOURCES_ATTEMPTS: "3"
|
||||
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
|
||||
EE_KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master-ee.json
|
||||
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/report-master.json
|
||||
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
|
||||
BUILD_ASSETS_IMAGE: "false"
|
||||
ES_JAVA_OPTS: "-Xms256m -Xmx256m"
|
||||
|
@ -28,11 +28,12 @@ after_script:
|
|||
- date
|
||||
|
||||
include:
|
||||
- local: .gitlab/ci/global.gitlab-ci.yml
|
||||
- local: .gitlab/ci/cng.gitlab-ci.yml
|
||||
- local: .gitlab/ci/docs.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/notifications.gitlab-ci.yml
|
||||
- local: .gitlab/ci/pages.gitlab-ci.yml
|
||||
- local: .gitlab/ci/qa.gitlab-ci.yml
|
||||
- local: .gitlab/ci/reports.gitlab-ci.yml
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
/doc/ @axil @marcia @eread @mikelewis
|
||||
|
||||
# Frontend maintainers should see everything in `app/assets/`
|
||||
app/assets/ @ClemMakesApps @fatihacet @filipa @mikegreiling @timzallmann @kushalpandya @pslaughter
|
||||
*.scss @annabeldunstone @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 @wortschi @ntepluhina
|
||||
|
||||
# Database maintainers should review changes in `db/`
|
||||
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/ci/templates/ @nolith @zj
|
||||
/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/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:
|
||||
GIT_STRATEGY: none
|
||||
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
|
||||
# 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
|
||||
before_script:
|
||||
# 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:
|
||||
extends: .review-docs
|
||||
environment:
|
||||
name: review-docs/$CI_COMMIT_REF_SLUG
|
||||
name: review-docs/$DOCS_GITLAB_REPO_SUFFIX-$CI_MERGE_REQUEST_IID
|
||||
action: stop
|
||||
script:
|
||||
- ./trigger-build-docs cleanup
|
||||
|
@ -67,3 +67,19 @@ docs lint:
|
|||
- bundle exec nanoc check internal_links
|
||||
# Check the internal anchor links
|
||||
- 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
|
||||
- .assets-compile-cache
|
||||
- .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
|
||||
dependencies: ["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
|
||||
only:
|
||||
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"
|
||||
tags:
|
||||
- gitlab-org
|
||||
- docker
|
||||
|
||||
gitlab:assets:compile:
|
||||
gitlab:assets:compile pull-push-cache:
|
||||
extends: .gitlab:assets:compile-metadata
|
||||
only:
|
||||
refs:
|
||||
|
@ -63,9 +63,6 @@ gitlab:assets:compile:
|
|||
|
||||
gitlab:assets:compile pull-cache:
|
||||
extends: .gitlab:assets:compile-metadata
|
||||
except:
|
||||
refs:
|
||||
- master
|
||||
cache:
|
||||
policy: pull
|
||||
|
||||
|
@ -77,7 +74,7 @@ gitlab:assets:compile pull-cache:
|
|||
- .default-before_script
|
||||
- .assets-compile-cache
|
||||
- .only-code-qa-changes
|
||||
- .use-pg
|
||||
- .use-pg9
|
||||
stage: prepare
|
||||
script:
|
||||
- node --version
|
||||
|
@ -89,14 +86,14 @@ gitlab:assets:compile pull-cache:
|
|||
# we override the max_old_space_size to prevent OOM errors
|
||||
NODE_OPTIONS: --max_old_space_size=3584
|
||||
cache:
|
||||
key: "assets-compile:test:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:v6"
|
||||
key: "assets-compile:v7"
|
||||
artifacts:
|
||||
expire_in: 7d
|
||||
paths:
|
||||
- node_modules
|
||||
- public/assets
|
||||
|
||||
compile-assets:
|
||||
compile-assets pull-push-cache:
|
||||
extends: .compile-assets-metadata
|
||||
only:
|
||||
refs:
|
||||
|
@ -104,14 +101,26 @@ compile-assets:
|
|||
cache:
|
||||
policy: pull-push
|
||||
|
||||
compile-assets pull-cache:
|
||||
extends: .compile-assets-metadata
|
||||
except:
|
||||
compile-assets pull-push-cache foss:
|
||||
extends: [".compile-assets-metadata", ".only-ee-as-if-foss"]
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
cache:
|
||||
policy: pull-push
|
||||
key: "assets-compile:v7:foss"
|
||||
|
||||
compile-assets pull-cache:
|
||||
extends: .compile-assets-metadata
|
||||
cache:
|
||||
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:
|
||||
extends:
|
||||
- .default-tags
|
||||
|
@ -120,10 +129,12 @@ compile-assets pull-cache:
|
|||
- .default-only
|
||||
- .default-before_script
|
||||
- .only-code-changes
|
||||
- .use-pg
|
||||
dependencies: ["compile-assets", "compile-assets pull-cache", "setup-test-env"]
|
||||
- .use-pg9
|
||||
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
|
||||
variables:
|
||||
# we override the max_old_space_size to prevent OOM errors
|
||||
|
@ -134,6 +145,9 @@ karma:
|
|||
- scripts/gitaly-test-spawn
|
||||
- date
|
||||
- bundle exec rake karma
|
||||
|
||||
karma:
|
||||
extends: .karma-base
|
||||
coverage: '/^Statements *: (\d+\.\d+%)/'
|
||||
artifacts:
|
||||
name: coverage-javascript
|
||||
|
@ -146,7 +160,12 @@ karma:
|
|||
reports:
|
||||
junit: junit_karma.xml
|
||||
|
||||
jest:
|
||||
karma-foss:
|
||||
extends:
|
||||
- .karma-base
|
||||
- .only-ee-as-if-foss
|
||||
|
||||
.jest-base:
|
||||
extends: .only-code-frontend-job-base
|
||||
script:
|
||||
- scripts/gitaly-test-spawn
|
||||
|
@ -154,6 +173,14 @@ jest:
|
|||
- bundle exec rake frontend:fixtures
|
||||
- date
|
||||
- yarn jest --ci --coverage
|
||||
cache:
|
||||
key: jest
|
||||
paths:
|
||||
- tmp/jest/jest/
|
||||
policy: pull-push
|
||||
|
||||
jest:
|
||||
extends: .jest-base
|
||||
artifacts:
|
||||
name: coverage-frontend
|
||||
expire_in: 31d
|
||||
|
@ -164,34 +191,13 @@ jest:
|
|||
- tmp/tests/frontend/
|
||||
reports:
|
||||
junit: junit_jest.xml
|
||||
cache:
|
||||
key: jest
|
||||
paths:
|
||||
- tmp/jest/jest/
|
||||
policy: pull-push
|
||||
|
||||
.qa-job-base:
|
||||
jest-foss:
|
||||
extends:
|
||||
- .default-tags
|
||||
- .default-retry
|
||||
- .default-cache
|
||||
- .default-only
|
||||
- .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
|
||||
- .jest-base
|
||||
- .only-ee-as-if-foss
|
||||
cache:
|
||||
policy: pull
|
||||
|
||||
.qa-frontend-node:
|
||||
extends:
|
||||
|
@ -200,6 +206,7 @@ qa:selectors:
|
|||
- .default-cache
|
||||
- .default-only
|
||||
- .only-code-changes
|
||||
stage: test
|
||||
dependencies: []
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
|
@ -232,7 +239,9 @@ webpack-dev-server:
|
|||
- .default-cache
|
||||
- .default-only
|
||||
- .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:
|
||||
WEBPACK_MEMORY_TEST: "true"
|
||||
script:
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
.default-before_script:
|
||||
before_script:
|
||||
- date
|
||||
- export GOPATH=$CI_PROJECT_DIR/.go
|
||||
- mkdir -p $GOPATH
|
||||
- source scripts/utils.sh
|
||||
- source scripts/prepare_build.sh
|
||||
- date
|
||||
|
@ -22,6 +24,7 @@
|
|||
cache:
|
||||
key: "debian-stretch-ruby-2.6.3-node-12.x"
|
||||
paths:
|
||||
- .go/pkg/mod
|
||||
- vendor/ruby
|
||||
- .yarn-cache/
|
||||
- vendor/gitaly-ruby
|
||||
|
@ -33,6 +36,7 @@
|
|||
- master
|
||||
- /^[\d-]+-stable(-ee)?$/
|
||||
- /^\d+-\d+-auto-deploy-\d+$/
|
||||
- /^security\//
|
||||
- merge_requests
|
||||
- tags
|
||||
|
||||
|
@ -51,7 +55,7 @@
|
|||
- "{babel.config,jest.config}.js"
|
||||
- "config.ru"
|
||||
- "{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
|
||||
|
||||
.only-qa-changes:
|
||||
|
@ -67,6 +71,12 @@
|
|||
- "doc/**/*"
|
||||
- ".markdownlint.json"
|
||||
|
||||
.only-graphql-changes:
|
||||
only:
|
||||
changes:
|
||||
- "{,ee/}app/graphql/**/*"
|
||||
- "{,ee/}lib/gitlab/graphql/**/*"
|
||||
|
||||
.only-code-qa-changes:
|
||||
only:
|
||||
changes:
|
||||
|
@ -82,7 +92,7 @@
|
|||
- "{babel.config,jest.config}.js"
|
||||
- "config.ru"
|
||||
- "{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
|
||||
- ".dockerignore"
|
||||
- "qa/**/*"
|
||||
|
@ -96,30 +106,57 @@
|
|||
refs:
|
||||
- master
|
||||
- /^\d+-\d+-auto-deploy-\d+$/
|
||||
- /^[\d-]+-stable(-ee)?$/
|
||||
|
||||
.only-review-schedules:
|
||||
only:
|
||||
refs:
|
||||
- schedules
|
||||
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
|
||||
|
||||
.use-pg:
|
||||
.only-canonical-schedules:
|
||||
only:
|
||||
refs:
|
||||
- schedules@gitlab-org/gitlab
|
||||
- schedules@gitlab-org/gitlab-foss
|
||||
|
||||
.use-pg9:
|
||||
services:
|
||||
- name: postgres:9.6.14
|
||||
- name: postgres:9.6
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:alpine
|
||||
|
||||
.use-pg-10:
|
||||
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"
|
||||
.use-pg10:
|
||||
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
|
||||
|
||||
.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:
|
||||
variables:
|
||||
- $CI_PROJECT_NAME == "gitlab"
|
||||
- $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:
|
||||
extends:
|
||||
- .only-code-memory-job-base
|
||||
- .use-pg-10
|
||||
- .use-pg10
|
||||
variables:
|
||||
NODE_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:
|
||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
||||
stage: pages
|
||||
dependencies: ["coverage", "karma", "gitlab:assets:compile"]
|
||||
dependencies: ["coverage", "karma", "gitlab:assets:compile pull-cache"]
|
||||
script:
|
||||
- mv public/ .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:
|
||||
extends: .default-only
|
||||
image: ruby:2.6-alpine
|
||||
stage: qa
|
||||
dependencies: []
|
||||
variables:
|
||||
GIT_DEPTH: "1"
|
||||
retry: 0
|
||||
script:
|
||||
- source scripts/utils.sh
|
||||
|
@ -12,7 +42,7 @@
|
|||
- ./scripts/trigger-build omnibus
|
||||
only:
|
||||
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:
|
||||
extends:
|
||||
|
@ -21,20 +51,10 @@ package-and-qa-manual:
|
|||
except:
|
||||
refs:
|
||||
- master
|
||||
- /^\d+-\d+-auto-deploy-\d+$/
|
||||
when: manual
|
||||
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:
|
||||
extends:
|
||||
- .package-and-qa-base
|
||||
|
@ -42,5 +62,13 @@ package-and-qa:
|
|||
except:
|
||||
refs:
|
||||
- master
|
||||
- /^\d+-\d+-auto-deploy-\d+$/
|
||||
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
|
||||
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
|
||||
- .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:
|
||||
extends: .only-code-rails-job-base
|
||||
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:
|
||||
- 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}_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
|
||||
- source scripts/rspec_helpers.sh
|
||||
- rspec_paralellized_job "--tag ~quarantine --tag ~geo"
|
||||
artifacts:
|
||||
expire_in: 31d
|
||||
when: always
|
||||
|
@ -71,79 +71,172 @@
|
|||
reports:
|
||||
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:
|
||||
- .rspec-base
|
||||
- .use-pg
|
||||
- .use-pg9
|
||||
|
||||
.rspec-base-pg-10:
|
||||
.rspec-base-pg9-foss:
|
||||
extends:
|
||||
- .rspec-base-foss
|
||||
- .use-pg9
|
||||
|
||||
.rspec-base-pg10:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg-10
|
||||
- .use-pg10
|
||||
- .only-master
|
||||
|
||||
setup-test-env:
|
||||
extends:
|
||||
- .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
|
||||
rspec unit pg9:
|
||||
extends: .rspec-base-pg9
|
||||
parallel: 20
|
||||
|
||||
rspec integration pg:
|
||||
extends: .rspec-base-pg
|
||||
parallel: 6
|
||||
|
||||
rspec system pg:
|
||||
extends: .rspec-base-pg
|
||||
parallel: 24
|
||||
|
||||
rspec unit pg-10:
|
||||
extends:
|
||||
- .rspec-base-pg-10
|
||||
- .only-master
|
||||
rspec unit pg9-foss:
|
||||
extends: .rspec-base-pg9-foss
|
||||
parallel: 20
|
||||
|
||||
rspec integration pg-10:
|
||||
extends:
|
||||
- .rspec-base-pg-10
|
||||
- .only-master
|
||||
rspec integration pg9:
|
||||
extends: .rspec-base-pg9
|
||||
parallel: 6
|
||||
|
||||
rspec system pg-10:
|
||||
extends:
|
||||
- .rspec-base-pg-10
|
||||
- .only-master
|
||||
rspec integration pg9-foss:
|
||||
extends: .rspec-base-pg9-foss
|
||||
parallel: 6
|
||||
|
||||
rspec system pg9:
|
||||
extends: .rspec-base-pg9
|
||||
parallel: 24
|
||||
|
||||
rspec-fast-spec-helper:
|
||||
extends: .rspec-base-pg
|
||||
script:
|
||||
- bundle exec rspec spec/fast_spec_helper.rb
|
||||
rspec system pg9-foss:
|
||||
extends: .rspec-base-pg9-foss
|
||||
parallel: 24
|
||||
|
||||
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:
|
||||
- .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
|
||||
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:
|
||||
- export NO_KNAPSACK=1 CACHE_CLASSES=true
|
||||
- scripts/gitaly-test-spawn
|
||||
- bin/rspec --color --format documentation --tag quarantine -- spec/
|
||||
- source scripts/rspec_helpers.sh
|
||||
- scripts/prepare_postgres_fdw.sh
|
||||
- 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
|
||||
|
||||
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:
|
||||
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:
|
||||
SETUP_DB: "false"
|
||||
script:
|
||||
|
@ -166,16 +259,16 @@ downtime_check:
|
|||
variables:
|
||||
- $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/
|
||||
stage: test
|
||||
dependencies: ["setup-test-env"]
|
||||
needs: ["setup-test-env"]
|
||||
dependencies: ["setup-test-env"]
|
||||
|
||||
.db-job-base:
|
||||
extends:
|
||||
- .only-code-rails-job-base
|
||||
- .use-pg
|
||||
- .use-pg9
|
||||
stage: test
|
||||
dependencies: ["setup-test-env"]
|
||||
needs: ["setup-test-env"]
|
||||
dependencies: ["setup-test-env"]
|
||||
|
||||
# DB migration, rollback, and seed jobs
|
||||
db:migrate:reset:
|
||||
|
@ -256,108 +349,6 @@ coverage:
|
|||
- coverage/assets/
|
||||
- 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:
|
||||
extends:
|
||||
- db:rollback
|
||||
|
@ -365,5 +356,3 @@ db:rollback geo:
|
|||
script:
|
||||
- bundle exec rake geo:db:migrate VERSION=20170627195211
|
||||
- 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
|
||||
# override an included `only.refs`.
|
||||
# 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:
|
||||
extends:
|
||||
- .default-retry
|
||||
|
@ -196,6 +198,7 @@ dast:
|
|||
- .only-code-qa-changes
|
||||
- .only-review
|
||||
stage: qa
|
||||
needs: ["review-deploy"]
|
||||
dependencies: ["review-deploy"]
|
||||
before_script:
|
||||
- export DAST_WEBSITE="$(cat review_app_url.txt)"
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
.review-base:
|
||||
extends:
|
||||
- .default-tags
|
||||
- .default-retry
|
||||
- .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
|
||||
.except-deploys:
|
||||
except:
|
||||
refs:
|
||||
- /^\d+-\d+-auto-deploy-\d+$/
|
||||
|
||||
.review-docker:
|
||||
extends:
|
||||
- .default-tags
|
||||
- .default-retry
|
||||
- .default-only
|
||||
- .except-deploys
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine
|
||||
services:
|
||||
- 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}
|
||||
- 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:
|
||||
extends:
|
||||
- .default-only
|
||||
- .only-code-qa-changes
|
||||
- .except-deploys
|
||||
image: ruby:2.6-alpine
|
||||
stage: review-prepare
|
||||
before_script:
|
||||
|
@ -65,16 +80,23 @@ schedule:review-build-cng:
|
|||
extends:
|
||||
- .review-build-cng-base
|
||||
- .only-review-schedules
|
||||
needs: ["gitlab:assets:compile"]
|
||||
needs: ["gitlab:assets:compile pull-cache"]
|
||||
|
||||
.review-deploy-base:
|
||||
extends: .review-base
|
||||
allow_failure: true
|
||||
extends:
|
||||
- .default-tags
|
||||
- .default-retry
|
||||
- .default-only
|
||||
- .only-code-qa-changes
|
||||
- .except-deploys
|
||||
stage: review
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
|
||||
dependencies: []
|
||||
allow_failure: true
|
||||
variables:
|
||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||
GITLAB_HELM_CHART_REF: "master"
|
||||
GITLAB_HELM_CHART_REF: "v2.3.7"
|
||||
GITLAB_EDITION: "ce"
|
||||
environment:
|
||||
name: review/${CI_COMMIT_REF_NAME}
|
||||
|
@ -90,13 +112,21 @@ schedule:review-build-cng:
|
|||
- install_api_client_dependencies_with_apk
|
||||
- source scripts/review_apps/review-apps.sh
|
||||
script:
|
||||
- date
|
||||
- check_kube_domain
|
||||
- date
|
||||
- ensure_namespace
|
||||
- date
|
||||
- install_tiller
|
||||
- date
|
||||
- install_external_dns
|
||||
- date
|
||||
- download_chart
|
||||
- date
|
||||
- deploy || (display_deployment_debug && exit 1)
|
||||
- date
|
||||
- add_license
|
||||
- date
|
||||
artifacts:
|
||||
paths: [review_app_url.txt]
|
||||
expire_in: 2 days
|
||||
|
@ -105,6 +135,7 @@ schedule:review-build-cng:
|
|||
review-deploy:
|
||||
extends:
|
||||
- .review-deploy-base
|
||||
- .only-review
|
||||
needs: ["review-build-cng"]
|
||||
|
||||
schedule:review-deploy:
|
||||
|
@ -116,6 +147,7 @@ schedule:review-deploy:
|
|||
review-stop:
|
||||
extends:
|
||||
- .review-deploy-base
|
||||
- .only-review
|
||||
when: manual
|
||||
environment:
|
||||
action: stop
|
||||
|
@ -148,6 +180,7 @@ review-cleanup-failed-deployment:
|
|||
- .only-review
|
||||
- .only-code-qa-changes
|
||||
stage: qa
|
||||
allow_failure: true
|
||||
variables:
|
||||
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
|
||||
QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
|
||||
|
@ -158,6 +191,7 @@ review-cleanup-failed-deployment:
|
|||
GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
||||
GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
|
||||
EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
|
||||
needs: ["review-deploy"]
|
||||
dependencies: ["review-deploy"]
|
||||
artifacts:
|
||||
paths:
|
||||
|
@ -176,26 +210,76 @@ review-cleanup-failed-deployment:
|
|||
|
||||
review-qa-smoke:
|
||||
extends: .review-qa-base
|
||||
allow_failure: true
|
||||
script:
|
||||
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
|
||||
|
||||
review-qa-all:
|
||||
extends: .review-qa-base
|
||||
allow_failure: true
|
||||
when: manual
|
||||
parallel: 5
|
||||
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
|
||||
- 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:
|
||||
extends:
|
||||
- .default-tags
|
||||
- .default-only
|
||||
- .only-code-qa-changes
|
||||
- .only-review
|
||||
- .except-deploys
|
||||
image: ruby:2.6-alpine
|
||||
stage: post-test
|
||||
dependencies: ["review-qa-all"]
|
||||
|
@ -220,46 +304,6 @@ parallel-spec-reports:
|
|||
- '[[ -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
|
||||
|
||||
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:
|
||||
extends:
|
||||
- .default-tags
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
.tests-metadata-state:
|
||||
extends:
|
||||
- .default-only
|
||||
- .only-code-changes
|
||||
variables:
|
||||
TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache"
|
||||
before_script:
|
||||
- source scripts/utils.sh
|
||||
cache:
|
||||
key: tests_metadata
|
||||
paths:
|
||||
- knapsack/
|
||||
- rspec_flaky/
|
||||
artifacts:
|
||||
expire_in: 31d
|
||||
paths:
|
||||
|
@ -13,55 +19,29 @@
|
|||
- rspec_profiling/
|
||||
|
||||
retrieve-tests-metadata:
|
||||
extends:
|
||||
- .tests-metadata-state
|
||||
- .only-code-changes
|
||||
extends: .tests-metadata-state
|
||||
stage: prepare
|
||||
cache:
|
||||
key: tests_metadata
|
||||
policy: pull
|
||||
script:
|
||||
- mkdir -p knapsack/${CI_PROJECT_NAME}/
|
||||
- wget -O $KNAPSACK_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_RSPEC_SUITE_REPORT_PATH || rm $KNAPSACK_RSPEC_SUITE_REPORT_PATH
|
||||
- '[[ -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}'
|
||||
- source scripts/rspec_helpers.sh
|
||||
- retrieve_tests_metadata
|
||||
|
||||
update-tests-metadata:
|
||||
extends:
|
||||
- .tests-metadata-state
|
||||
- .only-code-changes
|
||||
extends: .tests-metadata-state
|
||||
stage: post-test
|
||||
cache:
|
||||
key: tests_metadata
|
||||
paths:
|
||||
- knapsack/
|
||||
- rspec_flaky/
|
||||
policy: push
|
||||
script:
|
||||
- retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document
|
||||
- echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}
|
||||
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec_*_pg_node_*.json
|
||||
- '[[ -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
|
||||
- source scripts/rspec_helpers.sh
|
||||
- update_tests_metadata
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
- schedules
|
||||
variables:
|
||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org"
|
||||
- $CI_SERVER_HOST == "dev.gitlab.org"
|
||||
# Only update the Knapsack metadata on GitLab.com/gitlab-org/gitlab
|
||||
- $CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab"
|
||||
|
||||
flaky-examples-check:
|
||||
extends:
|
||||
|
|
|
@ -25,7 +25,7 @@ Then leave running while monitoring and performing some testing through web, api
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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
|
||||
|
||||
|
@ -41,7 +41,7 @@ Then leave running while monitoring for at least **15 minutes** while performing
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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
|
||||
|
||||
|
@ -57,7 +57,7 @@ Then leave running while monitoring for at least **15 minutes** while performing
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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
|
||||
|
||||
|
@ -69,7 +69,7 @@ Then leave running while monitoring for at least **30 minutes** while performing
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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
|
||||
|
||||
|
@ -81,7 +81,7 @@ Then leave running while monitoring for at least **12 hours** while performing s
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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
|
||||
|
||||
|
@ -93,7 +93,7 @@ Then leave running while monitoring for at least **1 week**.
|
|||
|
||||
- [ ] [Monitor Using Grafana](https://dashboards.gitlab.net)
|
||||
- [ ] [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?
|
||||
|
||||
|
|
|
@ -2,17 +2,10 @@
|
|||
Please read this!
|
||||
|
||||
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-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
|
||||
- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=regression
|
||||
- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=bug
|
||||
|
||||
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 ~"Style decision"
|
||||
/label ~Documentation
|
||||
/label ~documentation
|
||||
|
||||
/cc @gitlab-org/maintainers/rails-backend
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
## References
|
||||
|
||||
Merged MR that introduced documentation requiring review:
|
||||
Merged MR that introduced documentation requiring review:
|
||||
|
||||
Related issue(s):
|
||||
Related issue(s):
|
||||
|
||||
## Further Details
|
||||
|
||||
<!-- Any additional context, questions, or notes for the technical writer. -->
|
||||
|
||||
|
||||
/label ~Documentation ~docs-review
|
||||
/label ~documentation ~"Technical Writing"
|
||||
|
|
|
@ -2,23 +2,13 @@
|
|||
|
||||
* Use this issue template for suggesting new docs or updates to existing docs.
|
||||
Note: Doc work as part of feature development is covered in the Feature Request template.
|
||||
|
||||
|
||||
* For issues related to features of the docs.gitlab.com site, see
|
||||
https://gitlab.com/gitlab-org/gitlab-docs/issues/
|
||||
https://gitlab.com/gitlab-org/gitlab-docs/issues/
|
||||
|
||||
* For information about documentation content and process, see
|
||||
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
|
||||
|
||||
<!-- Include the following detail as necessary:
|
||||
|
@ -50,4 +40,4 @@
|
|||
|
||||
<!-- 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.
|
||||
|
||||
- `gitlab-org/gitlab-ce`/`gitlab-org/gitlab-ee` projects
|
||||
- `gitlab-org/gitlab` project
|
||||
- `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
|
||||
- [ ] Ensure that documentation has been updated
|
||||
- [ ] 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
|
||||
- [ ] Enable on GitLab.com by running chatops command in `#production`
|
||||
- [ ] Cross post chatops slack command to `#support_gitlab-com` and in your team channel
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
## Confidence
|
||||
|
||||
<!-- How do we know this is a problem? Please provide and link to any supporting information (e.g. data, customer verbatims) and use this basis to provide a numerical assessment on our confidence level in this problem's severity:
|
||||
<!-- How do we know this is a problem? Please provide and link to any supporting information (e.g. data, customer verbatims) and use this basis to provide a numerical assessment on our confidence level in this problem's severity:
|
||||
|
||||
100% = High confidence
|
||||
80% = Medium confidence
|
||||
|
@ -34,8 +34,8 @@
|
|||
|
||||
## Effort
|
||||
|
||||
<!-- How much effort do we think it will be to solve this problem? Please include all counterparts (Product, UX, Engineering, etc) in your assessment and quantify the number of person-months needed to dedicate to the effort.
|
||||
<!-- How much effort do we think it will be to solve this problem? Please include all counterparts (Product, UX, Engineering, etc) in your assessment and quantify the number of person-months needed to dedicate to the effort.
|
||||
|
||||
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:
|
||||
|
||||
### CE
|
||||
|
||||
* {https://gitlab.com/gitlab-org/gitlab-ce/issues link}
|
||||
|
||||
### EE
|
||||
|
||||
* {https://gitlab.com/gitlab-org/gitlab-ee/issues link}
|
||||
* {https://gitlab.com/gitlab-org/gitlab/issues link}
|
||||
|
||||
## Security Issues in dev.gitlab.org:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<!-- 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 -->
|
||||
|
||||
|
@ -63,7 +63,7 @@ intersection of Components and Attributes.
|
|||
Some features might be simple enough that they only involve one Component, while
|
||||
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
|
||||
* Intuitive
|
||||
* It's easy to select the desired file template
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
<!-- Mention the issue(s) this MR closes or is related to -->
|
||||
|
||||
Closes
|
||||
Closes
|
||||
|
||||
## Moving docs to a new location?
|
||||
|
||||
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
|
||||
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).
|
||||
- [ ] 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 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 rollback procedure. Include either a rollback procedure or description how to rollback changes
|
||||
|
||||
When adding or modifying queries to improve performance:
|
||||
|
||||
|
@ -37,7 +38,7 @@ When adding foreign keys to existing 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 indexes for fields that are used in statements such as `WHERE`, `ORDER BY`, `GROUP BY`, and `JOIN`s
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!-- Follow the documentation workflow https://docs.gitlab.com/ee/development/documentation/workflow.html -->
|
||||
<!-- Additional information is located at https://docs.gitlab.com/ee/development/documentation/ -->
|
||||
<!-- Additional information is located at https://docs.gitlab.com/ee/development/documentation/ -->
|
||||
|
||||
<!-- Mention "documentation" or "docs" in the MR title -->
|
||||
<!-- For changing documentation location use the "Change documentation location" template -->
|
||||
|
@ -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).
|
||||
- [ ] 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.
|
||||
- [ ] Apply the ~Documentation label.
|
||||
- [ ] Apply the ~documentation label.
|
||||
|
||||
## Review checklist
|
||||
|
||||
|
@ -26,7 +26,7 @@ All reviewers can help ensure accuracy, clarity, completeness, and adherence to
|
|||
**1. Primary Reviewer**
|
||||
|
||||
* [ ] Review by a code reviewer or other selected colleague to confirm accuracy, clarity, and completeness. This can be skipped for minor fixes without substantive content changes.
|
||||
|
||||
|
||||
**2. Technical Writer**
|
||||
|
||||
* [ ] Optional: Technical writer review. If not requested for this MR, must be scheduled post-merge. To request for this MR, assign the writer listed for the applicable [DevOps stage](https://about.gitlab.com/handbook/product/categories/#devops-stages).
|
||||
|
@ -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. [ ] 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/_new_project_fields.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/browse.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/_commit_message_container.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/_group_form.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/**/*'
|
||||
- 'db/**/*'
|
||||
- 'ee/db/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
- 'ee/lib/tasks/**/*'
|
||||
- 'lib/tasks/**/*'
|
||||
- 'qa/**/*'
|
||||
|
@ -179,6 +178,11 @@ Gitlab/ModuleWithInstanceVariables:
|
|||
- spec/support/**/*.rb
|
||||
- features/steps/**/*.rb
|
||||
|
||||
Gitlab/ConstGetInheritFalse:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'qa/bin/*'
|
||||
|
||||
Gitlab/HTTParty:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
|
@ -218,6 +222,12 @@ ActiveRecordAssociationReload:
|
|||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
|
||||
Naming/PredicateName:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
|
||||
RSpec/FactoriesInMigrationSpecs:
|
||||
Enabled: true
|
||||
Include:
|
||||
|
|
|
@ -273,11 +273,6 @@ RSpec/ContextWording:
|
|||
RSpec/EmptyLineAfterFinalLet:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 232
|
||||
# Cop supports --auto-correct.
|
||||
RSpec/EmptyLineAfterSubject:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 719
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
|
@ -442,19 +437,6 @@ Rails/LinkToBlank:
|
|||
- 'ee/app/helpers/ee/user_callouts_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
|
||||
# Cop supports --auto-correct.
|
||||
# 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.
|
||||
|
||||
## 12.3.8
|
||||
## 12.4.5
|
||||
|
||||
- No changes.
|
||||
|
||||
## 12.3.7
|
||||
## 12.4.4
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## 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.
|
||||
- Redact search results based on Ability.allowed?.
|
||||
- Do not show private cross references in epic notes.
|
||||
- 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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
## 12.3.3
|
||||
|
||||
### Security (1 change)
|
||||
|
||||
- Restrict access for security reports in MR widget.
|
||||
|
||||
|
||||
## 12.3.2
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
- 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)
|
||||
|
||||
- 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.
|
||||
- Disable retries for remote mirror update worker. !848
|
||||
- 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
|
||||
entry.
|
||||
|
||||
## 12.3.9
|
||||
## 12.4.6
|
||||
|
||||
- No changes.
|
||||
|
||||
## 12.3.8
|
||||
## 12.4.5
|
||||
|
||||
- No changes.
|
||||
|
||||
## 12.3.7
|
||||
## 12.4.4
|
||||
|
||||
### Security (12 changes)
|
||||
|
||||
|
@ -28,13 +28,43 @@ entry.
|
|||
- 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.
|
||||
- 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.
|
||||
- Analyze incoming GraphQL queries and check for recursion.
|
||||
- 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.
|
||||
|
@ -44,16 +74,326 @@ entry.
|
|||
- Mask sentry auth token in Error Tracking dashboard.
|
||||
- Fixes a Open Redirect issue in `InternalRedirect`.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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
|
||||
|
@ -64,13 +404,6 @@ entry.
|
|||
- Fix pipelines for merge requests in project exports. !17844
|
||||
|
||||
|
||||
## 12.3.3
|
||||
|
||||
### Security (1 change)
|
||||
|
||||
- Fix private feature Elasticsearch leak.
|
||||
|
||||
|
||||
## 12.3.2
|
||||
|
||||
### Security (12 changes)
|
||||
|
@ -368,6 +701,37 @@ entry.
|
|||
- 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
|
||||
|
||||
### Security (1 change)
|
||||
|
@ -686,6 +1050,35 @@ entry.
|
|||
- 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
|
||||
|
||||
### Security (2 changes)
|
||||
|
@ -8450,7 +8843,7 @@ entry.
|
|||
- 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 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
|
||||
- Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>)
|
||||
- Upgrade dependency to Go 1.8.3. !31943
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'lib/gitlab_danger'
|
||||
require_relative 'lib/gitlab/danger/request_helper'
|
||||
|
||||
danger.import_plugin('danger/plugins/helper.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
|
||||
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:
|
||||
# https://gitlab.com/gitlab-org/gitlab-ce/issues/67263
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/31747
|
||||
gem 'graphiql-rails', '~> 1.4.10'
|
||||
gem 'apollo_upload_server', '~> 2.0.0.beta3'
|
||||
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-include-ext', '~> 0.3.1', require: false
|
||||
gem 'asciidoctor-plantuml', '0.0.9'
|
||||
gem 'rouge', '~> 3.7'
|
||||
gem 'rouge', '~> 3.11.0'
|
||||
gem 'truncato', '~> 0.7.11'
|
||||
gem 'bootstrap_form', '~> 4.2.0'
|
||||
gem 'nokogiri', '~> 1.10.4'
|
||||
|
@ -311,7 +311,7 @@ gem 'gettext', '~> 3.2.2', require: false, group: :development
|
|||
gem 'batch-loader', '~> 1.4.0'
|
||||
|
||||
# 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'
|
||||
|
||||
# Snowplow events tracking
|
||||
|
@ -355,7 +355,7 @@ group :development, :test do
|
|||
gem 'fuubar', '~> 2.2.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-retry', '~> 0.6.1'
|
||||
gem 'rspec_profiling', '~> 0.0.5'
|
||||
|
@ -405,7 +405,7 @@ group :test do
|
|||
gem 'webmock', '~> 3.5.1'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'concurrent-ruby', '~> 1.1'
|
||||
gem 'test-prof', '~> 0.2.5'
|
||||
gem 'test-prof', '~> 0.10.0'
|
||||
gem 'rspec_junit_formatter'
|
||||
end
|
||||
|
||||
|
@ -446,7 +446,7 @@ group :ed25519 do
|
|||
end
|
||||
|
||||
# Gitaly GRPC protocol definitions
|
||||
gem 'gitaly', '~> 1.58.0'
|
||||
gem 'gitaly', '~> 1.65.0'
|
||||
|
||||
gem 'grpc', '~> 1.19.0'
|
||||
|
||||
|
@ -465,7 +465,7 @@ gem 'lograge', '~> 0.5'
|
|||
gem 'grape_logging', '~> 1.7'
|
||||
|
||||
# DNS Lookup
|
||||
gem 'net-dns', '~> 0.9.0'
|
||||
gem 'gitlab-net-dns', '~> 0.9.1'
|
||||
|
||||
# Countries list
|
||||
gem 'countries', '~> 3.0'
|
||||
|
|
58
Gemfile.lock
58
Gemfile.lock
|
@ -108,7 +108,7 @@ GEM
|
|||
binding_ninja (0.2.3)
|
||||
binding_of_caller (0.8.0)
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootsnap (1.4.4)
|
||||
bootsnap (1.4.5)
|
||||
msgpack (~> 1.0)
|
||||
bootstrap_form (4.2.0)
|
||||
actionpack (>= 5.0)
|
||||
|
@ -209,10 +209,10 @@ GEM
|
|||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
device_detector (1.0.0)
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (3.0.0)
|
||||
|
@ -254,7 +254,7 @@ GEM
|
|||
mail (~> 2.7)
|
||||
encryptor (3.0.0)
|
||||
equalizer (0.0.11)
|
||||
erubi (1.8.0)
|
||||
erubi (1.9.0)
|
||||
escape_utils (1.2.1)
|
||||
et-orbi (1.2.1)
|
||||
tzinfo
|
||||
|
@ -264,11 +264,11 @@ GEM
|
|||
expression_parser (0.9.0)
|
||||
extended-markdown-filter (0.6.0)
|
||||
html-pipeline (~> 2.0)
|
||||
factory_bot (4.8.2)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_bot_rails (4.8.2)
|
||||
factory_bot (~> 4.8.2)
|
||||
railties (>= 3.0.0)
|
||||
factory_bot (5.1.0)
|
||||
activesupport (>= 4.2.0)
|
||||
factory_bot_rails (5.1.0)
|
||||
factory_bot (~> 5.1.0)
|
||||
railties (>= 4.2.0)
|
||||
faraday (0.12.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-http-cache (2.0.0)
|
||||
|
@ -358,7 +358,7 @@ GEM
|
|||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
git (1.5.0)
|
||||
gitaly (1.58.0)
|
||||
gitaly (1.65.0)
|
||||
grpc (~> 1.0)
|
||||
github-markup (1.7.0)
|
||||
gitlab-labkit (0.5.2)
|
||||
|
@ -370,6 +370,7 @@ GEM
|
|||
redis (> 3.0.0, < 5.0.0)
|
||||
gitlab-license (1.0.0)
|
||||
gitlab-markup (1.7.0)
|
||||
gitlab-net-dns (0.9.1)
|
||||
gitlab-peek (0.0.1)
|
||||
railties (>= 4.0.0)
|
||||
gitlab-sidekiq-fetcher (0.5.2)
|
||||
|
@ -487,7 +488,7 @@ GEM
|
|||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.6.0)
|
||||
i18n (1.7.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n_data (0.8.0)
|
||||
icalendar (2.4.1)
|
||||
|
@ -565,7 +566,7 @@ GEM
|
|||
activesupport (>= 4)
|
||||
railties (>= 4)
|
||||
request_store (~> 1.0)
|
||||
loofah (2.2.3)
|
||||
loofah (2.3.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
|
@ -586,7 +587,7 @@ GEM
|
|||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
msgpack (1.3.0)
|
||||
msgpack (1.3.1)
|
||||
multi_json (1.13.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
|
@ -596,7 +597,6 @@ GEM
|
|||
mustermann (~> 1.0.0)
|
||||
nakayoshi_fork (0.0.4)
|
||||
nap (1.1.0)
|
||||
net-dns (0.9.0)
|
||||
net-ldap (0.16.0)
|
||||
net-ntp (2.1.3)
|
||||
net-ssh (5.2.0)
|
||||
|
@ -770,8 +770,8 @@ GEM
|
|||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.2.0)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
loofah (~> 2.3)
|
||||
rails-i18n (5.1.1)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 5.0, < 6)
|
||||
|
@ -783,7 +783,7 @@ GEM
|
|||
thor (>= 0.19.0, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
raindrops (0.19.0)
|
||||
rake (12.3.2)
|
||||
rake (12.3.3)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
|
@ -824,9 +824,9 @@ GEM
|
|||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
request_store (1.3.1)
|
||||
responders (2.4.0)
|
||||
actionpack (>= 4.2.0, < 5.3)
|
||||
railties (>= 4.2.0, < 5.3)
|
||||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
railties (>= 4.2.0, < 6.0)
|
||||
rest-client (2.0.2)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
|
@ -834,7 +834,7 @@ GEM
|
|||
retriable (3.1.2)
|
||||
rinku (2.0.0)
|
||||
rotp (2.1.2)
|
||||
rouge (3.7.0)
|
||||
rouge (3.11.0)
|
||||
rqrcode (0.7.0)
|
||||
chunky_png
|
||||
rqrcode-rails3 (0.1.7)
|
||||
|
@ -994,7 +994,7 @@ GEM
|
|||
temple (0.8.1)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
test-prof (0.2.5)
|
||||
test-prof (0.10.0)
|
||||
text (1.3.1)
|
||||
thin (1.7.2)
|
||||
daemons (~> 1.0, >= 1.0.9)
|
||||
|
@ -1058,8 +1058,8 @@ GEM
|
|||
descendants_tracker (~> 0.0, >= 0.0.3)
|
||||
equalizer (~> 0.0, >= 0.0.9)
|
||||
vmstat (2.3.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
warden (1.2.8)
|
||||
rack (>= 2.0.6)
|
||||
webfinger (1.1.0)
|
||||
activesupport
|
||||
httpclient (>= 2.4)
|
||||
|
@ -1144,7 +1144,7 @@ DEPENDENCIES
|
|||
email_reply_trimmer (~> 0.1)
|
||||
email_spec (~> 2.2.0)
|
||||
escape_utils (~> 1.1)
|
||||
factory_bot_rails (~> 4.8.2)
|
||||
factory_bot_rails (~> 5.1.0)
|
||||
faraday (~> 0.12)
|
||||
faraday_middleware-aws-signers-v4
|
||||
fast_blank
|
||||
|
@ -1168,11 +1168,12 @@ DEPENDENCIES
|
|||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly (~> 1.58.0)
|
||||
gitaly (~> 1.65.0)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-labkit (~> 0.5)
|
||||
gitlab-license (~> 1.0)
|
||||
gitlab-markup (~> 1.7.0)
|
||||
gitlab-net-dns (~> 0.9.1)
|
||||
gitlab-peek (~> 0.0.1)
|
||||
gitlab-sidekiq-fetcher (= 0.5.2)
|
||||
gitlab-styles (~> 2.7)
|
||||
|
@ -1222,7 +1223,6 @@ DEPENDENCIES
|
|||
mini_magick
|
||||
minitest (~> 5.11.0)
|
||||
nakayoshi_fork (~> 0.0.4)
|
||||
net-dns (~> 0.9.0)
|
||||
net-ldap
|
||||
net-ntp
|
||||
net-ssh (~> 5.2)
|
||||
|
@ -1276,7 +1276,7 @@ DEPENDENCIES
|
|||
redis-rails (~> 5.0.2)
|
||||
request_store (~> 1.3)
|
||||
responders (~> 2.0)
|
||||
rouge (~> 3.7)
|
||||
rouge (~> 3.11.0)
|
||||
rqrcode-rails3 (~> 0.1.7)
|
||||
rspec-parameterized
|
||||
rspec-rails (~> 3.8.0)
|
||||
|
@ -1314,7 +1314,7 @@ DEPENDENCIES
|
|||
stackprof (~> 0.2.10)
|
||||
state_machines-activerecord (~> 0.5.1)
|
||||
sys-filesystem (~> 1.1.6)
|
||||
test-prof (~> 0.2.5)
|
||||
test-prof (~> 0.10.0)
|
||||
thin (~> 1.7.0)
|
||||
timecop (~> 0.8.0)
|
||||
toml-rb (~> 1.0.0)
|
||||
|
|
151
PROCESS.md
151
PROCESS.md
|
@ -11,15 +11,6 @@
|
|||
- [Merge request coaching](#merge-request-coaching)
|
||||
- [Assigning issues](#assigning-issues)
|
||||
- [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)
|
||||
- [Regressions](#regressions)
|
||||
- [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.
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
**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:
|
||||
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
|
||||
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
|
||||
[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
|
||||
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!
|
||||
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
|
||||
|
||||
```
|
||||
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?
|
||||
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)
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
## 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
|
||||
|
||||
|
|
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',
|
||||
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
||||
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',
|
||||
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
|
||||
namespaces(query, callback) {
|
||||
const url = Api.buildUrl(Api.namespacesPath);
|
||||
|
@ -386,6 +392,22 @@ const Api = {
|
|||
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() {
|
||||
const url = Api.buildUrl(this.adminStatisticsPath);
|
||||
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';
|
||||
|
||||
|
@ -10,7 +10,7 @@ export default class Autosave {
|
|||
if (key.join != null) {
|
||||
key = key.join('/');
|
||||
}
|
||||
this.key = 'autosave/' + key;
|
||||
this.key = `autosave/${key}`;
|
||||
this.field.data('autosave', this);
|
||||
this.restore();
|
||||
this.field.on('input', () => this.save());
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { mapState, mapActions } from 'vuex';
|
||||
import createFlash from '~/flash';
|
||||
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 BadgeForm from './badge_form.vue';
|
||||
import BadgeList from './badge_list.vue';
|
||||
|
@ -13,7 +13,7 @@ export default {
|
|||
Badge,
|
||||
BadgeForm,
|
||||
BadgeList,
|
||||
GlModal,
|
||||
GlModal: DeprecatedModal2,
|
||||
},
|
||||
computed: {
|
||||
...mapState(['badgeInModal', 'isEditing']),
|
||||
|
|
|
@ -21,6 +21,7 @@ import Reference from './nodes/reference';
|
|||
|
||||
import TableOfContents from './nodes/table_of_contents';
|
||||
import Video from './nodes/video';
|
||||
import Audio from './nodes/audio';
|
||||
|
||||
import BulletList from './nodes/bullet_list';
|
||||
import OrderedList from './nodes/ordered_list';
|
||||
|
@ -78,6 +79,7 @@ export default [
|
|||
|
||||
new TableOfContents(),
|
||||
new Video(),
|
||||
new Audio(),
|
||||
|
||||
new BulletList(),
|
||||
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 axios from '~/lib/utils/axios_utils';
|
||||
|
@ -45,26 +45,22 @@ MarkdownPreview.prototype.showPreview = function($form) {
|
|||
this.hideReferencedUsers($form);
|
||||
} else {
|
||||
preview.addClass('md-preview-loading').text(__('Loading...'));
|
||||
this.fetchMarkdownPreview(
|
||||
mdText,
|
||||
url,
|
||||
function(response) {
|
||||
var body;
|
||||
if (response.body.length > 0) {
|
||||
({ body } = response);
|
||||
} else {
|
||||
body = this.emptyMessage;
|
||||
}
|
||||
this.fetchMarkdownPreview(mdText, url, response => {
|
||||
var body;
|
||||
if (response.body.length > 0) {
|
||||
({ body } = response);
|
||||
} else {
|
||||
body = this.emptyMessage;
|
||||
}
|
||||
|
||||
preview.removeClass('md-preview-loading').html(body);
|
||||
preview.renderGFM();
|
||||
this.renderReferencedUsers(response.references.users, $form);
|
||||
preview.removeClass('md-preview-loading').html(body);
|
||||
preview.renderGFM();
|
||||
this.renderReferencedUsers(response.references.users, $form);
|
||||
|
||||
if (response.references.commands) {
|
||||
this.renderReferencedCommands(response.references.commands, $form);
|
||||
}
|
||||
}.bind(this),
|
||||
);
|
||||
if (response.references.commands) {
|
||||
this.renderReferencedCommands(response.references.commands, $form);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -132,12 +128,12 @@ const markdownToolbar = $('.md-header-toolbar');
|
|||
|
||||
$.fn.setupMarkdownPreview = function() {
|
||||
var $form = $(this);
|
||||
$form.find('textarea.markdown-area').on('input', function() {
|
||||
$form.find('textarea.markdown-area').on('input', () => {
|
||||
markdownPreview.hideReferencedUsers($form);
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on('markdown-preview:show', function(e, $form) {
|
||||
$(document).on('markdown-preview:show', (e, $form) => {
|
||||
if (!$form) {
|
||||
return;
|
||||
}
|
||||
|
@ -162,7 +158,7 @@ $(document).on('markdown-preview:show', function(e, $form) {
|
|||
markdownPreview.showPreview($form);
|
||||
});
|
||||
|
||||
$(document).on('markdown-preview:hide', function(e, $form) {
|
||||
$(document).on('markdown-preview:hide', (e, $form) => {
|
||||
if (!$form) {
|
||||
return;
|
||||
}
|
||||
|
@ -191,7 +187,7 @@ $(document).on('markdown-preview:hide', function(e, $form) {
|
|||
markdownPreview.hideReferencedCommands($form);
|
||||
});
|
||||
|
||||
$(document).on('markdown-preview:toggle', function(e, keyboardEvent) {
|
||||
$(document).on('markdown-preview:toggle', (e, keyboardEvent) => {
|
||||
var $target;
|
||||
$target = $(keyboardEvent.target);
|
||||
if ($target.is('textarea.markdown-area')) {
|
||||
|
|
|
@ -26,7 +26,7 @@ $.fn.requiresInput = function requiresInput() {
|
|||
const values = _.map($(fieldSelector, $form), field => field.value);
|
||||
|
||||
// Disable the button if any required fields are empty
|
||||
if (values.length && _.any(values, _.isEmpty)) {
|
||||
if (values.length && _.some(values, _.isEmpty)) {
|
||||
$button.disable();
|
||||
} else {
|
||||
$button.enable();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import sqljs from 'sql.js';
|
||||
import { template as _template } from 'underscore';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { successCodes } from '~/lib/utils/http_status';
|
||||
|
||||
const PREVIEW_TEMPLATE = _template(`
|
||||
<div class="card">
|
||||
|
@ -16,30 +18,25 @@ class BalsamiqViewer {
|
|||
}
|
||||
|
||||
loadFile(endpoint) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('GET', endpoint, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = loadEvent => this.fileLoaded(loadEvent, resolve, reject);
|
||||
xhr.onerror = reject;
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
return axios
|
||||
.get(endpoint, {
|
||||
responseType: 'arraybuffer',
|
||||
validateStatus(status) {
|
||||
return status !== successCodes.OK;
|
||||
},
|
||||
})
|
||||
.then(({ data }) => {
|
||||
this.renderFile(data);
|
||||
})
|
||||
.catch(e => {
|
||||
throw new Error(e);
|
||||
});
|
||||
}
|
||||
|
||||
fileLoaded(loadEvent, resolve, reject) {
|
||||
if (loadEvent.target.status !== 200) return reject();
|
||||
|
||||
this.renderFile(loadEvent);
|
||||
|
||||
return resolve();
|
||||
}
|
||||
|
||||
renderFile(loadEvent) {
|
||||
renderFile(fileBuffer) {
|
||||
const container = document.createElement('ul');
|
||||
|
||||
this.initDatabase(loadEvent.target.response);
|
||||
this.initDatabase(fileBuffer);
|
||||
|
||||
const previews = this.getPreviews();
|
||||
previews.forEach(preview => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable func-names, prefer-arrow-callback */
|
||||
/* eslint-disable func-names */
|
||||
|
||||
import $ from 'jquery';
|
||||
import Dropzone from 'dropzone';
|
||||
|
@ -43,18 +43,18 @@ export default class BlobFileDropzone {
|
|||
previewsContainer: '.dropzone-previews',
|
||||
headers: csrf.headers,
|
||||
init() {
|
||||
this.on('addedfile', function() {
|
||||
this.on('addedfile', () => {
|
||||
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
||||
dropzoneMessage.addClass(HIDDEN_CLASS);
|
||||
$('.dropzone-alerts')
|
||||
.html('')
|
||||
.hide();
|
||||
});
|
||||
this.on('removedfile', function() {
|
||||
this.on('removedfile', () => {
|
||||
toggleLoading(submitButton, submitButtonLoadingIcon, false);
|
||||
dropzoneMessage.removeClass(HIDDEN_CLASS);
|
||||
});
|
||||
this.on('success', function(header, response) {
|
||||
this.on('success', (header, response) => {
|
||||
$('#modal-upload-blob').modal('hide');
|
||||
visitUrl(response.filePath);
|
||||
});
|
||||
|
@ -62,7 +62,7 @@ export default class BlobFileDropzone {
|
|||
dropzoneMessage.addClass(HIDDEN_CLASS);
|
||||
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('create_merge_request', form.find('.js-create-merge-request').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 GitignoreSelector from './template_selectors/gitignore_selector';
|
||||
import LicenseSelector from './template_selectors/license_selector';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default class FileTemplateMediator {
|
||||
constructor({ editor, currentAction, projectId }) {
|
||||
|
@ -19,6 +21,7 @@ export default class FileTemplateMediator {
|
|||
this.initDomElements();
|
||||
this.initDropdowns();
|
||||
this.initPageEvents();
|
||||
this.cacheFileContents();
|
||||
}
|
||||
|
||||
initTemplateSelectors() {
|
||||
|
@ -40,6 +43,7 @@ export default class FileTemplateMediator {
|
|||
return {
|
||||
name: cfg.name,
|
||||
key: cfg.key,
|
||||
id: cfg.key,
|
||||
};
|
||||
}),
|
||||
});
|
||||
|
@ -58,6 +62,7 @@ export default class FileTemplateMediator {
|
|||
this.$fileContent = $fileEditor.find('#file-content');
|
||||
this.$commitForm = $fileEditor.find('form');
|
||||
this.$navLinks = $fileEditor.find('.nav-links');
|
||||
this.$templateTypes = this.$templateSelectors.find('.template-type-selector');
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -123,15 +132,24 @@ export default class FileTemplateMediator {
|
|||
}
|
||||
|
||||
selectTemplateFile(selector, query, data) {
|
||||
const self = this;
|
||||
|
||||
selector.renderLoading();
|
||||
// in case undo menu is already there
|
||||
this.destroyUndoMenu();
|
||||
|
||||
this.fetchFileTemplate(selector.config.type, query, data)
|
||||
.then(file => {
|
||||
this.showUndoMenu();
|
||||
this.setEditorContent(file);
|
||||
this.setFilename(selector.config.name);
|
||||
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}`));
|
||||
}
|
||||
|
@ -173,22 +191,6 @@ export default class FileTemplateMediator {
|
|||
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() {
|
||||
this.$templatesMenu.hide();
|
||||
}
|
||||
|
@ -210,6 +212,7 @@ export default class FileTemplateMediator {
|
|||
this.setEditorContent(this.cachedContent);
|
||||
this.setFilename(this.cachedFilename);
|
||||
this.setTemplateSelectorToggleText();
|
||||
this.setTypeSelectorToggleText(__('Select a template type'));
|
||||
}
|
||||
|
||||
getTemplateSelectorToggleText() {
|
||||
|
@ -228,6 +231,10 @@ export default class FileTemplateMediator {
|
|||
return this.typeSelector.getToggleText();
|
||||
}
|
||||
|
||||
setTypeSelectorToggleText(text) {
|
||||
this.typeSelector.setToggleText(text);
|
||||
}
|
||||
|
||||
getFilename() {
|
||||
return this.$filenameInput.val();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable class-methods-use-this */
|
||||
|
||||
import $ from 'jquery';
|
||||
import '~/gl_dropdown';
|
||||
|
||||
export default class TemplateSelector {
|
||||
constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) {
|
||||
|
@ -26,11 +27,16 @@ export default class TemplateSelector {
|
|||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
clicked: options => this.fetchFileTemplate(options),
|
||||
clicked: options => this.onDropdownClicked(options),
|
||||
text: item => item.name,
|
||||
});
|
||||
}
|
||||
|
||||
// Subclasses can override this method to conditionally prevent fetching file templates
|
||||
onDropdownClicked(options) {
|
||||
this.fetchFileTemplate(options);
|
||||
}
|
||||
|
||||
initAutosizeUpdateEvent() {
|
||||
this.autosizeUpdateEvent = document.createEvent('Event');
|
||||
this.autosizeUpdateEvent.initEvent('autosize:update', true, false);
|
||||
|
@ -77,9 +83,14 @@ export default class TemplateSelector {
|
|||
|
||||
if (this.editor instanceof $) {
|
||||
this.editor.get(0).dispatchEvent(this.autosizeUpdateEvent);
|
||||
this.editor.trigger('input');
|
||||
}
|
||||
}
|
||||
|
||||
getEditorContent() {
|
||||
return this.editor.getValue();
|
||||
}
|
||||
|
||||
startLoadingSpinner() {
|
||||
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'),
|
||||
filterable: true,
|
||||
selectable: true,
|
||||
toggleLabel: item => item.name,
|
||||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
|
|
|
@ -20,7 +20,6 @@ export default class DockerfileSelector extends FileTemplateSelector {
|
|||
data: this.$dropdown.data('data'),
|
||||
filterable: true,
|
||||
selectable: true,
|
||||
toggleLabel: item => item.name,
|
||||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
|
|
|
@ -18,7 +18,6 @@ export default class BlobGitignoreSelector extends FileTemplateSelector {
|
|||
data: this.$dropdown.data('data'),
|
||||
filterable: true,
|
||||
selectable: true,
|
||||
toggleLabel: item => item.name,
|
||||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
|
|
|
@ -18,7 +18,6 @@ export default class BlobLicenseSelector extends FileTemplateSelector {
|
|||
data: this.$dropdown.data('data'),
|
||||
filterable: true,
|
||||
selectable: true,
|
||||
toggleLabel: item => item.name,
|
||||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
|
|
|
@ -16,7 +16,6 @@ export default class FileTemplateTypeSelector extends FileTemplateSelector {
|
|||
data: this.config.dropdownData,
|
||||
filterable: false,
|
||||
selectable: true,
|
||||
toggleLabel: item => item.name,
|
||||
clicked: options => this.mediator.selectTemplateTypeOptions(options),
|
||||
text: item => item.name,
|
||||
});
|
||||
|
|
|
@ -107,18 +107,18 @@ export default class BlobViewer {
|
|||
toggleCopyButtonState() {
|
||||
if (!this.copySourceBtn) return;
|
||||
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');
|
||||
} else if (this.activeViewer === this.simpleViewer) {
|
||||
this.copySourceBtn.setAttribute(
|
||||
'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');
|
||||
} else {
|
||||
this.copySourceBtn.setAttribute(
|
||||
'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');
|
||||
}
|
||||
|
|
|
@ -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
|
||||
boardsStore
|
||||
.generateDefaultLists()
|
||||
.then(res => res.data)
|
||||
.then(data => {
|
||||
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
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(data => Promise.all(data.map(loadListIssues)))
|
||||
.catch(() => {
|
||||
boardsStore.removeList(undefined, 'label');
|
||||
Cookies.remove('issue_board_welcome_hidden', {
|
||||
|
|
|
@ -42,12 +42,19 @@ export default {
|
|||
return {
|
||||
showDetail: false,
|
||||
detailIssue: boardsStore.detail,
|
||||
multiSelect: boardsStore.multiSelect,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
issueDetailVisible() {
|
||||
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: {
|
||||
mouseDown() {
|
||||
|
@ -58,14 +65,20 @@ export default {
|
|||
},
|
||||
showIssue(e) {
|
||||
if (e.target.classList.contains('js-no-trigger')) return;
|
||||
|
||||
if (this.showDetail) {
|
||||
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) {
|
||||
eventHub.$emit('clearDetailIssue');
|
||||
eventHub.$emit('clearDetailIssue', isMultiSelect);
|
||||
|
||||
if (isMultiSelect) {
|
||||
eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
|
||||
}
|
||||
} else {
|
||||
eventHub.$emit('newDetailIssue', this.issue);
|
||||
eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
|
||||
boardsStore.setListDetail(this.list);
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +90,7 @@ export default {
|
|||
<template>
|
||||
<li
|
||||
:class="{
|
||||
'multi-select': multiSelectVisible,
|
||||
'user-can-drag': !disabled && issue.id,
|
||||
'is-disabled': disabled || !issue.id,
|
||||
'is-active': issueDetailVisible,
|
||||
|
|
|
@ -194,6 +194,7 @@ export default {
|
|||
ref="name"
|
||||
v-model="board.name"
|
||||
class="form-control"
|
||||
data-qa-selector="board_name_field"
|
||||
type="text"
|
||||
:placeholder="__('Enter board name')"
|
||||
@keyup.enter="submit"
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
<script>
|
||||
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
|
||||
import Sortable from 'sortablejs';
|
||||
import { Sortable, MultiDrag } from 'sortablejs';
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import _ from 'underscore';
|
||||
import boardNewIssue from './board_new_issue.vue';
|
||||
import boardCard from './board_card.vue';
|
||||
import eventHub from '../eventhub';
|
||||
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 {
|
||||
name: 'BoardList',
|
||||
|
@ -54,6 +64,14 @@ export default {
|
|||
showIssueForm: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
paginatedIssueText() {
|
||||
return sprintf(__('Showing %{pageSize} of %{total} issues'), {
|
||||
pageSize: this.list.issues.length,
|
||||
total: this.list.issuesSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
filters: {
|
||||
handler() {
|
||||
|
@ -87,11 +105,20 @@ export default {
|
|||
eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop);
|
||||
},
|
||||
mounted() {
|
||||
const multiSelectOpts = {};
|
||||
if (gon.features && gon.features.multiSelectBoard) {
|
||||
multiSelectOpts.multiDrag = true;
|
||||
multiSelectOpts.selectedClass = 'js-multi-select';
|
||||
multiSelectOpts.animation = 500;
|
||||
}
|
||||
|
||||
const options = getBoardSortableDefaultOptions({
|
||||
scroll: true,
|
||||
disabled: this.disabled,
|
||||
filter: '.board-list-count, .is-disabled',
|
||||
dataIdAttr: 'data-issue-id',
|
||||
removeCloneOnHide: false,
|
||||
...multiSelectOpts,
|
||||
group: {
|
||||
name: 'issues',
|
||||
/**
|
||||
|
@ -145,25 +172,66 @@ export default {
|
|||
card.showDetail = false;
|
||||
|
||||
const { list } = card;
|
||||
|
||||
const issue = list.findIssue(Number(e.item.dataset.issueId));
|
||||
|
||||
boardsStore.startMoving(list, issue);
|
||||
|
||||
sortableStart();
|
||||
},
|
||||
onAdd: e => {
|
||||
boardsStore.moveIssueToList(
|
||||
boardsStore.moving.list,
|
||||
this.list,
|
||||
boardsStore.moving.issue,
|
||||
e.newIndex,
|
||||
);
|
||||
const { items = [], newIndicies = [] } = e;
|
||||
if (items.length) {
|
||||
// Not using e.newIndex here instead taking a min of all
|
||||
// the newIndicies. Basically we have to find that during
|
||||
// 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(() => {
|
||||
e.item.remove();
|
||||
});
|
||||
boardsStore.moveMultipleIssuesToList({
|
||||
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 => {
|
||||
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(
|
||||
this.list,
|
||||
boardsStore.moving.issue,
|
||||
|
@ -172,9 +240,133 @@ export default {
|
|||
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) {
|
||||
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);
|
||||
|
@ -260,7 +452,7 @@ export default {
|
|||
<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" />
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -305,13 +305,18 @@ export default {
|
|||
<div v-if="canAdminBoard">
|
||||
<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') }}
|
||||
</gl-dropdown-item>
|
||||
|
||||
<gl-dropdown-item
|
||||
v-if="showDelete"
|
||||
class="text-danger"
|
||||
data-qa-selector="delete_board_button"
|
||||
@click.prevent="showPage('delete')"
|
||||
>
|
||||
{{ s__('IssueBoards|Delete board') }}
|
||||
|
|
|
@ -99,7 +99,10 @@ export default {
|
|||
return !groupId ? referencePath.split('#')[0] : null;
|
||||
},
|
||||
orderedLabels() {
|
||||
return _.sortBy(this.issue.labels, 'title');
|
||||
return _.chain(this.issue.labels)
|
||||
.filter(this.isNonListLabel)
|
||||
.sortBy('title')
|
||||
.value();
|
||||
},
|
||||
helpLink() {
|
||||
return boardsStore.scopedLabels.helpLink;
|
||||
|
@ -130,6 +133,9 @@ export default {
|
|||
if (!label.id) return false;
|
||||
return true;
|
||||
},
|
||||
isNonListLabel(label) {
|
||||
return label.id && !(this.list.type === 'label' && this.list.title === label.title);
|
||||
},
|
||||
filterByLabel(label) {
|
||||
if (!this.updateFilters) return;
|
||||
const labelTitle = encodeURIComponent(label.title);
|
||||
|
@ -167,7 +173,7 @@ export default {
|
|||
</h4>
|
||||
</div>
|
||||
<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
|
||||
v-if="showScopedLabel(label)"
|
||||
:key="label.id"
|
||||
|
@ -212,7 +218,7 @@ export default {
|
|||
<issue-due-date v-if="issue.dueDate" :date="issue.dueDate" />
|
||||
<issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
|
||||
<issue-card-weight
|
||||
v-if="issue.weight"
|
||||
v-if="validIssueWeight"
|
||||
:weight="issue.weight"
|
||||
@click="filterByWeight(issue.weight)"
|
||||
/>
|
||||
|
|
|
@ -34,7 +34,7 @@ export default {
|
|||
<template>
|
||||
<span>
|
||||
<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"
|
||||
>{{ 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 initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
|
||||
import BoardAddIssuesModal from '~/boards/components/modal/index.vue';
|
||||
import '~/vue_shared/vue_resource_interceptor';
|
||||
import {
|
||||
NavigationType,
|
||||
convertObjectPropsToCamelCase,
|
||||
|
@ -147,7 +146,7 @@ export default () => {
|
|||
updateTokens() {
|
||||
this.filterManager.updateTokens();
|
||||
},
|
||||
updateDetailIssue(newIssue) {
|
||||
updateDetailIssue(newIssue, multiSelect = false) {
|
||||
const { sidebarInfoEndpoint } = newIssue;
|
||||
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
|
||||
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);
|
||||
},
|
||||
clearDetailIssue() {
|
||||
clearDetailIssue(multiSelect = false) {
|
||||
if (multiSelect) {
|
||||
boardsStore.clearMultiSelect();
|
||||
}
|
||||
boardsStore.clearDetailIssue();
|
||||
},
|
||||
toggleSubscription(id) {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
export default {
|
||||
computed: {
|
||||
validIssueWeight() {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
filterByWeight() {},
|
||||
},
|
||||
|
|
|
@ -5,6 +5,7 @@ import ListLabel from './label';
|
|||
import ListAssignee from './assignee';
|
||||
import ListIssue from 'ee_else_ce/boards/models/issue';
|
||||
import { urlParamsToObject } from '~/lib/utils/common_utils';
|
||||
import flash from '~/flash';
|
||||
import boardsStore from '../stores/boards_store';
|
||||
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) {
|
||||
let moveBeforeId = 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) {
|
||||
gl.boardService
|
||||
.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) {
|
||||
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) {
|
||||
this.issues = this.issues.filter(issue => {
|
||||
const matchesRemove = removeIssue.id === issue.id;
|
||||
|
|
|
@ -48,6 +48,16 @@ export default class BoardService {
|
|||
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) {
|
||||
return boardsStore.newIssue(id, issue);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { __ } from '~/locale';
|
|||
import axios from '~/lib/utils/axios_utils';
|
||||
import { mergeUrlParams } from '~/lib/utils/url_utility';
|
||||
import eventHub from '../eventhub';
|
||||
import { ListType } from '../constants';
|
||||
|
||||
const boardsStore = {
|
||||
disabled: false,
|
||||
|
@ -39,6 +40,7 @@ const boardsStore = {
|
|||
issue: {},
|
||||
list: {},
|
||||
},
|
||||
multiSelect: { list: [] },
|
||||
|
||||
setEndpoints({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId, recentBoardsEndpoint }) {
|
||||
const listsEndpointGenerate = `${listsEndpoint}/generate.json`;
|
||||
|
@ -51,7 +53,6 @@ const boardsStore = {
|
|||
recentBoardsEndpoint: `${recentBoardsEndpoint}.json`,
|
||||
};
|
||||
},
|
||||
|
||||
create() {
|
||||
this.state.lists = [];
|
||||
this.filter.path = getUrlParamsArray().join('&');
|
||||
|
@ -134,6 +135,107 @@ const boardsStore = {
|
|||
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) {
|
||||
const issueTo = listTo.findIssue(issue.id);
|
||||
const issueLists = issue.getLists();
|
||||
|
@ -195,6 +297,17 @@ const boardsStore = {
|
|||
|
||||
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') {
|
||||
const filteredList = this.state.lists.filter(list => {
|
||||
const byType = type
|
||||
|
@ -260,6 +373,10 @@ const boardsStore = {
|
|||
}`;
|
||||
},
|
||||
|
||||
generateMultiDragPath(boardId) {
|
||||
return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues/bulk_move`;
|
||||
},
|
||||
|
||||
all() {
|
||||
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) {
|
||||
return axios.post(this.generateIssuesPath(id), {
|
||||
issue,
|
||||
|
@ -379,6 +506,25 @@ const boardsStore = {
|
|||
setCurrentBoard(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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable func-names, prefer-arrow-callback */
|
||||
/* eslint-disable func-names */
|
||||
|
||||
import $ from 'jquery';
|
||||
import { visitUrl } from './lib/utils/url_utility';
|
||||
|
@ -12,11 +12,11 @@ export default class BuildArtifacts {
|
|||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
disablePropagation() {
|
||||
$('.top-block').on('click', '.download', function(e) {
|
||||
return e.stopPropagation();
|
||||
$('.top-block').on('click', '.download', e => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
return $('.tree-holder').on('click', 'tr[data-link] a', function(e) {
|
||||
return e.stopImmediatePropagation();
|
||||
return $('.tree-holder').on('click', 'tr[data-link] a', e => {
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
|
|
|
@ -41,6 +41,8 @@ export default class Clusters {
|
|||
managePrometheusPath,
|
||||
clusterEnvironmentsPath,
|
||||
hasRbac,
|
||||
providerType,
|
||||
preInstalledKnative,
|
||||
clusterType,
|
||||
clusterStatus,
|
||||
clusterStatusReason,
|
||||
|
@ -50,6 +52,7 @@ export default class Clusters {
|
|||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
cloudRunHelpPath,
|
||||
clusterId,
|
||||
} = document.querySelector('.js-edit-cluster-form').dataset;
|
||||
|
||||
|
@ -65,10 +68,13 @@ export default class Clusters {
|
|||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
cloudRunHelpPath,
|
||||
);
|
||||
this.store.setManagePrometheusPath(managePrometheusPath);
|
||||
this.store.updateStatus(clusterStatus);
|
||||
this.store.updateStatusReason(clusterStatusReason);
|
||||
this.store.updateProviderType(providerType);
|
||||
this.store.updatePreInstalledKnative(preInstalledKnative);
|
||||
this.store.updateRbac(hasRbac);
|
||||
this.service = new ClustersService({
|
||||
endpoint: statusPath,
|
||||
|
@ -153,6 +159,9 @@ export default class Clusters {
|
|||
ingressHelpPath: this.state.ingressHelpPath,
|
||||
managePrometheusPath: this.state.managePrometheusPath,
|
||||
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
|
||||
cloudRunHelpPath: this.state.cloudRunHelpPath,
|
||||
providerType: this.state.providerType,
|
||||
preInstalledKnative: this.state.preInstalledKnative,
|
||||
rbac: this.state.rbac,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -78,6 +78,10 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
installedVia: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
version: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -311,6 +315,11 @@ export default {
|
|||
>
|
||||
<span v-else class="js-cluster-application-title">{{ title }}</span>
|
||||
</strong>
|
||||
<span
|
||||
v-if="installedVia"
|
||||
class="js-cluster-application-installed-via"
|
||||
v-html="installedVia"
|
||||
></span>
|
||||
<slot name="description"></slot>
|
||||
<div v-if="hasError" class="cluster-application-error text-danger prepend-top-10">
|
||||
<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 clipboardButton from '../../vue_shared/components/clipboard_button.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 eventHub from '~/clusters/event_hub';
|
||||
|
||||
|
@ -54,11 +54,26 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
cloudRunHelpPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
managePrometheusPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
providerType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
preInstalledKnative: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
rbac: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
|
@ -156,6 +171,25 @@ export default {
|
|||
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() {
|
||||
this.helmInstallIllustration = helmInstallIllustration;
|
||||
|
@ -260,7 +294,7 @@ export default {
|
|||
<span class="input-group-append">
|
||||
<clipboard-button
|
||||
:text="ingressExternalEndpoint"
|
||||
:title="s__('ClusterIntegration|Copy Ingress Endpoint to clipboard')"
|
||||
:title="s__('ClusterIntegration|Copy Ingress Endpoint')"
|
||||
class="input-group-text js-clipboard-btn"
|
||||
/>
|
||||
</span>
|
||||
|
@ -438,7 +472,7 @@ export default {
|
|||
<span class="input-group-btn">
|
||||
<clipboard-button
|
||||
:text="jupyterHostname"
|
||||
:title="s__('ClusterIntegration|Copy Jupyter Hostname to clipboard')"
|
||||
:title="s__('ClusterIntegration|Copy Jupyter Hostname')"
|
||||
class="js-clipboard-btn"
|
||||
/>
|
||||
</span>
|
||||
|
@ -468,6 +502,7 @@ export default {
|
|||
:installed="applications.knative.installed"
|
||||
:install-failed="applications.knative.installFailed"
|
||||
:install-application-request-params="{ hostname: applications.knative.hostname }"
|
||||
:installed-via="installedVia"
|
||||
:uninstallable="applications.knative.uninstallable"
|
||||
:uninstall-successful="applications.knative.uninstallSuccessful"
|
||||
:uninstall-failed="applications.knative.uninstallFailed"
|
||||
|
@ -499,7 +534,7 @@ export default {
|
|||
</p>
|
||||
|
||||
<knative-domain-editor
|
||||
v-if="knative.installed || (helmInstalled && rbac)"
|
||||
v-if="(knative.installed || (helmInstalled && rbac)) && !preInstalledKnative"
|
||||
:knative="knative"
|
||||
:ingress-dns-help-path="ingressDnsHelpPath"
|
||||
@save="saveKnativeDomain"
|
||||
|
|
|
@ -103,7 +103,7 @@ export default {
|
|||
<span class="input-group-append">
|
||||
<clipboard-button
|
||||
: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"
|
||||
/>
|
||||
</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';
|
||||
|
||||
const CUSTOM_APP_WARNING_TEXT = {
|
||||
[HELM]: s__(
|
||||
'ClusterIntegration|The associated Tiller pod will be deleted and cannot be restored.',
|
||||
[HELM]: sprintf(
|
||||
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__(
|
||||
'ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored.',
|
||||
|
@ -76,6 +82,7 @@ export default {
|
|||
:modal-id="modalId"
|
||||
:title="title"
|
||||
@ok="confirmUninstall()"
|
||||
>{{ warningText }} {{ customAppWarningText }}</gl-modal
|
||||
>
|
||||
{{ warningText }} <span v-html="customAppWarningText"></span>
|
||||
</gl-modal>
|
||||
</template>
|
||||
|
|
|
@ -5,6 +5,11 @@ export const CLUSTER_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
|
||||
export const APPLICATION_STATUS = {
|
||||
NO_STATUS: null,
|
||||
|
@ -19,6 +24,7 @@ export const APPLICATION_STATUS = {
|
|||
UNINSTALLING: 'uninstalling',
|
||||
UNINSTALL_ERRORED: 'uninstall_errored',
|
||||
ERROR: 'errored',
|
||||
PRE_INSTALLED: 'pre_installed',
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -29,6 +35,7 @@ export const APPLICATION_INSTALLED_STATUSES = [
|
|||
APPLICATION_STATUS.INSTALLED,
|
||||
APPLICATION_STATUS.UPDATING,
|
||||
APPLICATION_STATUS.UNINSTALLING,
|
||||
APPLICATION_STATUS.PRE_INSTALLED,
|
||||
];
|
||||
|
||||
// These are only used client-side
|
||||
|
|
|
@ -13,6 +13,7 @@ const {
|
|||
UPDATE_ERRORED,
|
||||
UNINSTALLING,
|
||||
UNINSTALL_ERRORED,
|
||||
PRE_INSTALLED,
|
||||
} = APPLICATION_STATUS;
|
||||
|
||||
const applicationStateMachine = {
|
||||
|
@ -63,6 +64,9 @@ const applicationStateMachine = {
|
|||
uninstallFailed: true,
|
||||
},
|
||||
},
|
||||
[PRE_INSTALLED]: {
|
||||
target: PRE_INSTALLED,
|
||||
},
|
||||
},
|
||||
},
|
||||
[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]: {
|
||||
on: {
|
||||
[UPDATED]: {
|
||||
|
|
|
@ -35,7 +35,10 @@ export default class ClusterStore {
|
|||
environmentsHelpPath: null,
|
||||
clustersHelpPath: null,
|
||||
deployBoardsHelpPath: null,
|
||||
cloudRunHelpPath: null,
|
||||
status: null,
|
||||
providerType: null,
|
||||
preInstalledKnative: false,
|
||||
rbac: false,
|
||||
statusReason: null,
|
||||
applications: {
|
||||
|
@ -95,6 +98,7 @@ export default class ClusterStore {
|
|||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
cloudRunHelpPath,
|
||||
) {
|
||||
this.state.helpPath = helpPath;
|
||||
this.state.ingressHelpPath = ingressHelpPath;
|
||||
|
@ -102,6 +106,7 @@ export default class ClusterStore {
|
|||
this.state.environmentsHelpPath = environmentsHelpPath;
|
||||
this.state.clustersHelpPath = clustersHelpPath;
|
||||
this.state.deployBoardsHelpPath = deployBoardsHelpPath;
|
||||
this.state.cloudRunHelpPath = cloudRunHelpPath;
|
||||
}
|
||||
|
||||
setManagePrometheusPath(managePrometheusPath) {
|
||||
|
@ -112,6 +117,14 @@ export default class ClusterStore {
|
|||
this.state.status = status;
|
||||
}
|
||||
|
||||
updateProviderType(providerType) {
|
||||
this.state.providerType = providerType;
|
||||
}
|
||||
|
||||
updatePreInstalledKnative(preInstalledKnative) {
|
||||
this.state.preInstalledKnative = parseBoolean(preInstalledKnative);
|
||||
}
|
||||
|
||||
updateRbac(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';
|
||||
|
||||
|
@ -13,14 +13,14 @@ export default class ImageFile {
|
|||
$('.two-up.view .frame.deleted img', this.file),
|
||||
(function(_this) {
|
||||
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();
|
||||
|
||||
// Load two-up view after images are loaded
|
||||
// so that we can display the correct width and height information
|
||||
const $images = $('.two-up.view img', _this.file);
|
||||
|
||||
$images.waitForImages(function() {
|
||||
$images.waitForImages(() => {
|
||||
_this.initView('two-up');
|
||||
});
|
||||
});
|
||||
|
@ -49,13 +49,13 @@ export default class ImageFile {
|
|||
activateViewMode(viewMode) {
|
||||
$('.view-modes-menu li', this.file)
|
||||
.removeClass('active')
|
||||
.filter('.' + viewMode)
|
||||
.filter(`.${viewMode}`)
|
||||
.addClass('active');
|
||||
return $('.view:visible:not(.' + viewMode + ')', this.file).fadeOut(
|
||||
return $(`.view:visible:not(.${viewMode})`, this.file).fadeOut(
|
||||
200,
|
||||
(function(_this) {
|
||||
return function() {
|
||||
$('.view.' + viewMode, _this.file).fadeIn(200);
|
||||
$(`.view.${viewMode}`, _this.file).fadeIn(200);
|
||||
return _this.initView(viewMode);
|
||||
};
|
||||
})(this),
|
||||
|
@ -138,9 +138,9 @@ export default class ImageFile {
|
|||
return $(this).width(availWidth / 2);
|
||||
}
|
||||
});
|
||||
return _this.requestImageInfo($('img', wrap), function(width, height) {
|
||||
$('.image-info .meta-width', wrap).text(width + 'px');
|
||||
$('.image-info .meta-height', wrap).text(height + 'px');
|
||||
return _this.requestImageInfo($('img', wrap), (width, height) => {
|
||||
$('.image-info .meta-width', wrap).text(`${width}px`);
|
||||
$('.image-info .meta-height', wrap).text(`${height}px`);
|
||||
return $('.image-info', wrap).removeClass('hide');
|
||||
});
|
||||
};
|
||||
|
@ -175,7 +175,7 @@ export default class ImageFile {
|
|||
|
||||
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) {
|
||||
$swipeWrap.width(maxWidth + 1 - left);
|
||||
$swipeBar.css('left', left);
|
||||
|
@ -215,7 +215,7 @@ export default class ImageFile {
|
|||
$frameAdded.css('opacity', 1);
|
||||
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;
|
||||
|
||||
if (opacity >= 0 && opacity <= 1) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
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') {
|
||||
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 DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
|
||||
|
||||
const findItem = (items, valueProp, value) => items.find(item => item[valueProp] === value);
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DropdownButton,
|
||||
|
@ -26,7 +28,7 @@ export default {
|
|||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
type: [Object, String],
|
||||
required: false,
|
||||
default: () => null,
|
||||
},
|
||||
|
@ -93,8 +95,8 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
selectedItem: findItem(this.items, this.value),
|
||||
searchQuery: '',
|
||||
selectedItem: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -127,10 +129,15 @@ export default {
|
|||
return (this.selectedItem && this.selectedItem[this.valueProperty]) || '';
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(value) {
|
||||
this.selectedItem = findItem(this.items, this.valueProperty, value);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
select(item) {
|
||||
this.selectedItem = item;
|
||||
this.$emit('input', item);
|
||||
this.$emit('input', item[this.valueProperty]);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,8 +7,23 @@ export default {
|
|||
ServiceCredentialsForm,
|
||||
EksClusterConfigurationForm,
|
||||
},
|
||||
props: {
|
||||
gitlabManagedClusterHelpPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
kubernetesIntegrationHelpPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<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>
|
||||
|
|
|
@ -1,25 +1,394 @@
|
|||
<script>
|
||||
import RoleNameDropdown from './role_name_dropdown.vue';
|
||||
import SecurityGroupDropdown from './security_group_dropdown.vue';
|
||||
import SubnetDropdown from './subnet_dropdown.vue';
|
||||
import VPCDropdown from './vpc_dropdown.vue';
|
||||
import { createNamespacedHelpers, mapState, mapActions } from 'vuex';
|
||||
import { sprintf, s__ } from '~/locale';
|
||||
import _ from 'underscore';
|
||||
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 {
|
||||
components: {
|
||||
RoleNameDropdown,
|
||||
SecurityGroupDropdown,
|
||||
SubnetDropdown,
|
||||
VPCDropdown,
|
||||
ClusterFormDropdown,
|
||||
RegionDropdown,
|
||||
GlFormInput,
|
||||
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>
|
||||
<template>
|
||||
<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">
|
||||
<label class="label-bold" name="role" for="eks-role">
|
||||
{{ s__('ClusterIntegration|Role name') }}
|
||||
</label>
|
||||
<role-name-dropdown />
|
||||
<label class="label-bold" for="eks-cluster-name">{{
|
||||
s__('ClusterIntegration|Kubernetes cluster name')
|
||||
}}</label>
|
||||
<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>
|
||||
</form>
|
||||
</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