Commit cc502768 authored by John Jarvis's avatar John Jarvis

Merge commit '207d3100' into 11-9-stable-prepare-rc4

parents 3190b498 207d3100

Too many changes to show.

To preserve performance only 407 of 407+ files are displayed.

......@@ -444,6 +444,17 @@ setup-test-env:
- master
- /(^docs[\/-].*|.*-docs$)/
.review-schedules-only: &review-schedules-only
only:
refs:
- schedules@gitlab-org/gitlab-ce
- schedules@gitlab-org/gitlab-ee
kubernetes: active
except:
refs:
- tags
- /(^docs[\/-].*|.*-docs$)/
.review-base: &review-base
<<: *dedicated-no-docs-no-db-pull-cache-job
<<: *review-only
......@@ -672,6 +683,35 @@ gitlab:assets:compile:
- docker
- gitlab-org
gitlab:ui:visual:
<<: *except-docs
tags:
- gitlab-org
before_script: []
dependencies:
- compile-assets
script:
# Remove node modules from GitLab that may conflict with gitlab-ui
- rm -r node_modules
- git clone https://gitlab.com/gitlab-org/gitlab-ui.git
- cp public/assets/application-*.css gitlab-ui/styles/application.css
- cd gitlab-ui
- yarn install
- CSS_URL=./application.css yarn test
only:
changes:
- app/assets/stylesheets/*.scss
- app/assets/stylesheets/**/*.scss
- app/assets/stylesheets/**/**/*.scss
except:
refs:
- master
variables:
- $CI_COMMIT_MESSAGE =~ /\[skip visual\]/i
artifacts:
paths:
- tests/__image_snapshots__/
karma:
<<: *dedicated-no-docs-pull-cache-job
<<: *use-pg
......@@ -959,8 +999,7 @@ no_ee_check:
- //@gitlab-org/gitlab-ce
# GitLab Review apps
review-build-cng:
<<: *review-only
.review-build-cng-base: &review-build-cng-base
image: ruby:2.5-alpine
stage: test
before_script: []
......@@ -976,7 +1015,15 @@ review-build-cng:
- wait_for_job_to_be_done "gitlab:assets:compile"
- BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
review-deploy:
review-build-cng:
<<: *review-only
<<: *review-build-cng-base
schedule:review-build-cng:
<<: *review-schedules-only
<<: *review-build-cng-base
.review-deploy-base: &review-deploy-base
<<: *review-base
retry: 2
allow_failure: true
......@@ -998,6 +1045,8 @@ review-deploy:
- source ./scripts/review_apps/review-apps.sh
script:
- wait_for_job_to_be_done "review-build-cng"
after_script:
- source ./scripts/review_apps/review-apps.sh
- check_kube_domain
- download_gitlab_chart
- ensure_namespace
......@@ -1006,6 +1055,15 @@ review-deploy:
- time deploy
- add_license
review-deploy:
<<: *review-deploy-base
schedule:review-deploy:
<<: *review-deploy-base
<<: *review-schedules-only
script:
- wait_for_job_to_be_done "schedule:review-build-cng"
.review-qa-base: &review-qa-base
<<: *review-docker
allow_failure: true
......@@ -1032,22 +1090,26 @@ review-deploy:
- apk update && apk add curl jq
- source ./scripts/review_apps/review-apps.sh
- gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}}
- wait_for_job_to_be_done "review-deploy"
review-qa-smoke:
<<: *review-qa-base
script:
- wait_for_job_to_be_done "review-deploy"
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
review-qa-all:
<<: *review-qa-base
script:
- wait_for_job_to_be_done "review-deploy"
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
when: manual
review-performance:
.review-performance-base: &review-performance-base
<<: *review-qa-base
script:
- wait_for_job_to_be_done "review-deploy"
after_script:
- mkdir gitlab-exporter
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
- mkdir sitespeed-results
......@@ -1059,6 +1121,9 @@ review-performance:
reports:
performance: performance.json
review-performance:
<<: *review-performance-base
review-stop:
<<: *review-base
<<: *single-script-job
......@@ -1078,21 +1143,20 @@ review-stop:
schedule:review-cleanup:
<<: *review-base
<<: *review-schedules-only
stage: build
allow_failure: true
variables:
GIT_DEPTH: "1"
environment:
name: review/auto-cleanup
only:
refs:
- schedules@gitlab-org/gitlab-ce
- schedules@gitlab-org/gitlab-ee
kubernetes: active
except:
- tags
- /(^docs[\/-].*|.*-docs$)/
before_script:
- gem install gitlab --no-document
script:
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
schedule:review-performance:
<<: *review-performance-base
<<: *review-schedules-only
script:
- wait_for_job_to_be_done "schedule:review-deploy"
......@@ -181,3 +181,6 @@ Cop/InjectEnterpriseEditionModule:
Exclude:
- 'spec/**/*'
- 'ee/spec/**/*'
Style/ReturnNil:
Enabled: true
1.23.0
\ No newline at end of file
1.26.0
......@@ -267,7 +267,6 @@ gem 'gemojione', '~> 3.3'
gem 'gon', '~> 6.2'
gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'request_store', '~> 1.3'
gem 'select2-rails', '~> 3.5.9'
gem 'virtus', '~> 1.0.1'
gem 'base32', '~> 0.3.0'
......@@ -421,7 +420,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 1.12.0', require: 'gitaly'
gem 'gitaly-proto', '~> 1.13.0', require: 'gitaly'
gem 'grpc', '~> 1.15.0'
......
......@@ -279,7 +279,7 @@ GEM
gettext_i18n_rails (>= 0.7.1)
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gitaly-proto (1.12.0)
gitaly-proto (1.13.0)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab-default_value_for (3.1.1)
......@@ -310,7 +310,7 @@ GEM
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
google-protobuf (3.6.1)
googleapis-common-protos-types (1.0.2)
googleapis-common-protos-types (1.0.3)
google-protobuf (~> 3.0)
googleauth (0.6.6)
faraday (~> 0.12)
......@@ -811,8 +811,6 @@ GEM
seed-fu (2.3.7)
activerecord (>= 3.1)
activesupport (>= 3.1)
select2-rails (3.5.9.3)
thor (~> 0.14)
selenium-webdriver (3.12.0)
childprocess (~> 0.5)
rubyzip (~> 1.2)
......@@ -1018,7 +1016,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly-proto (~> 1.12.0)
gitaly-proto (~> 1.13.0)
github-markup (~> 1.7.0)
gitlab-default_value_for (~> 3.1.1)
gitlab-markup (~> 1.6.5)
......
......@@ -615,10 +615,18 @@ export class AwardsHandler {
let awardsHandlerPromise = null;
export default function loadAwardsHandler(reload = false) {
if (!awardsHandlerPromise || reload) {
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(Emoji => {
const awardsHandler = new AwardsHandler(Emoji);
awardsHandler.bindEvents();
return awardsHandler;
awardsHandlerPromise = new Promise((resolve, reject) => {
import(/* webpackChunkName: 'emoji' */ './emoji')
.then(Emoji => {
Emoji.initEmojiMap()
.then(() => {
const awardsHandler = new AwardsHandler(Emoji);
awardsHandler.bindEvents();
resolve(awardsHandler);
})
.catch(() => reject);
})
.catch(() => reject);
});
}
return awardsHandlerPromise;
......
import 'document-register-element';
import isEmojiUnicodeSupported from '../emoji/support';
import { initEmojiMap, getEmojiInfo, emojiFallbackImageSrc, emojiImageTag } from '../emoji';
class GlEmoji extends HTMLElement {
constructor() {
super();
const emojiUnicode = this.textContent.trim();
const { name, unicodeVersion, fallbackSrc, fallbackSpriteClass } = this.dataset;
const isEmojiUnicode =
this.childNodes &&
Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3);
const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
if (emojiUnicode && isEmojiUnicode && !isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)) {
// CSS sprite fallback takes precedence over image fallback
if (hasCssSpriteFalback) {
if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) {
const emojiSpriteLinkTag = document.createElement('link');
emojiSpriteLinkTag.setAttribute('rel', 'stylesheet');
emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path);
document.head.appendChild(emojiSpriteLinkTag);
gon.emoji_sprites_css_added = true;
}
// IE 11 doesn't like adding multiple at once :(
this.classList.add('emoji-icon');
this.classList.add(fallbackSpriteClass);
} else {
import(/* webpackChunkName: 'emoji' */ '../emoji')
.then(({ emojiImageTag, emojiFallbackImageSrc }) => {
if (hasImageFallback) {
this.innerHTML = emojiImageTag(name, fallbackSrc);
let emojiUnicode = this.textContent.trim();
const { fallbackSpriteClass, fallbackSrc, forceFallback } = this.dataset;
let { name, unicodeVersion } = this.dataset;
initEmojiMap()
.then(() => {
if (!unicodeVersion) {
const emojiInfo = getEmojiInfo(name);
if (emojiInfo) {
if (name !== emojiInfo.name) {
({ name } = emojiInfo);
this.dataset.name = emojiInfo.name;
}
unicodeVersion = emojiInfo.u;
this.dataset.uni = unicodeVersion;
if (forceFallback === 'true' && !fallbackSpriteClass) {
this.innerHTML = emojiImageTag(name, emojiFallbackImageSrc(name));
} else {
const src = emojiFallbackImageSrc(name);
this.innerHTML = emojiImageTag(name, src);
emojiUnicode = emojiInfo.e;
this.innerHTML = emojiInfo.e;
}
})
.catch(() => {
// do nothing
});
}
}
this.title = emojiInfo.d;
}
}
const isEmojiUnicode =
this.childNodes &&
Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3);
const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
if (
emojiUnicode &&
isEmojiUnicode &&
!isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)
) {
// CSS sprite fallback takes precedence over image fallback
if (hasCssSpriteFalback) {
if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) {
const emojiSpriteLinkTag = document.createElement('link');
emojiSpriteLinkTag.setAttribute('rel', 'stylesheet');
emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path);
document.head.appendChild(emojiSpriteLinkTag);
gon.emoji_sprites_css_added = true;
}
// IE 11 doesn't like adding multiple at once :(
this.classList.add('emoji-icon');
this.classList.add(fallbackSpriteClass);
} else if (hasImageFallback) {
this.innerHTML = emojiImageTag(name, fallbackSrc);
} else {
const src = emojiFallbackImageSrc(name);
this.innerHTML = emojiImageTag(name, src);
}
}
})
.catch(error => {
// Only reject is already handled in initEmojiMap
throw error;
});
}
}
......
......@@ -13,7 +13,7 @@ export default () => {
if (editBlobForm.length) {
const urlRoot = editBlobForm.data('relativeUrlRoot');
const assetsPath = editBlobForm.data('assetsPrefix');
const filePath = editBlobForm.data('blobFilename');
const filePath = `${editBlobForm.data('blobFilename')}`;
const currentAction = $('.js-file-title').data('currentAction');
const projectId = editBlobForm.data('project-id');
const isMarkdown = editBlobForm.data('is-markdown');
......
......@@ -53,7 +53,7 @@ export default {
} else if (timeDifference === -1) {
return __('Yesterday');
} else if (timeDifference > 0 && timeDifference < 7) {
return dateFormat(issueDueDate, 'dddd', true);
return dateFormat(issueDueDate, 'dddd');
}
return standardDateFormat;
......
......@@ -58,6 +58,7 @@ export default () => {
state: boardsStore.state,
loading: true,
boardsEndpoint: $boardApp.dataset.boardsEndpoint,
recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
listsEndpoint: $boardApp.dataset.listsEndpoint,
boardId: $boardApp.dataset.boardId,
disabled: parseBoolean($boardApp.dataset.disabled),
......@@ -75,6 +76,7 @@ export default () => {
created() {
gl.boardService = new BoardService({
boardsEndpoint: this.boardsEndpoint,
recentBoardsEndpoint: this.recentBoardsEndpoint,
listsEndpoint: this.listsEndpoint,
bulkUpdatePath: this.bulkUpdatePath,
boardId: this.boardId,
......
......@@ -2,12 +2,13 @@ import axios from '../../lib/utils/axios_utils';
import { mergeUrlParams } from '../../lib/utils/url_utility';
export default class BoardService {
constructor({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId }) {
constructor({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId, recentBoardsEndpoint }) {
this.boardsEndpoint = boardsEndpoint;
this.boardId = boardId;
this.listsEndpoint = listsEndpoint;
this.listsEndpointGenerate = `${listsEndpoint}/generate.json`;
this.bulkUpdatePath = bulkUpdatePath;
this.recentBoardsEndpoint = `${recentBoardsEndpoint}.json`;
}
generateBoardsPath(id) {
......
......@@ -36,6 +36,7 @@ export default class Clusters {
installRunnerPath,
installJupyterPath,
installKnativePath,
updateKnativePath,
installPrometheusPath,
managePrometheusPath,
hasRbac,
......@@ -62,6 +63,7 @@ export default class Clusters {
installPrometheusEndpoint: installPrometheusPath,
installJupyterEndpoint: installJupyterPath,
installKnativeEndpoint: installKnativePath,
updateKnativeEndpoint: updateKnativePath,
});
this.installApplication = this.installApplication.bind(this);
......@@ -119,8 +121,7 @@ export default class Clusters {
static initDismissableCallout() {
const callout = document.querySelector('.js-cluster-security-warning');
if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
PersistentUserCallout.factory(callout);
}
addListeners() {
......@@ -129,6 +130,8 @@ export default class Clusters {
eventHub.$on('upgradeApplication', data => this.upgradeApplication(data));
eventHub.$on('upgradeFailed', appId => this.upgradeFailed(appId));
eventHub.$on('dismissUpgradeSuccess', appId => this.dismissUpgradeSuccess(appId));
eventHub.$on('saveKnativeDomain', data => this.saveKnativeDomain(data));
eventHub.$on('setKnativeHostname', data => this.setKnativeHostname(data));
}
removeListeners() {
......@@ -137,6 +140,8 @@ export default class Clusters {
eventHub.$off('upgradeApplication', this.upgradeApplication);
eventHub.$off('upgradeFailed', this.upgradeFailed);
eventHub.$off('dismissUpgradeSuccess', this.dismissUpgradeSuccess);
eventHub.$off('saveKnativeDomain');
eventHub.$off('setKnativeHostname');
}
initPolling() {
......@@ -272,6 +277,18 @@ export default class Clusters {
this.store.updateAppProperty(appId, 'requestStatus', null);
}
saveKnativeDomain(data) {
const appId = data.id;
this.store.updateAppProperty(appId, 'status', APPLICATION_STATUS.UPDATING);
this.service.updateApplication(appId, data.params);
}
setKnativeHostname(data) {
const appId = data.id;
this.store.updateAppProperty(appId, 'isEditingHostName', true);
this.store.updateAppProperty(appId, 'hostname', data.hostname);
}
destroy() {
this.destroyed = true;
......
......@@ -191,14 +191,7 @@ export default {
return this.status === APPLICATION_STATUS.UPDATE_ERRORED;
},
upgradeFailureDescription() {
return sprintf(
s__(
'ClusterIntegration|Something went wrong when upgrading %{title}. Please check the logs and try again.',
),
{
title: this.title,
},
);
return s__('ClusterIntegration|Update failed. Please check the logs and try again.');
},
upgradeSuccessDescription() {
return sprintf(s__('ClusterIntegration|%{title} upgraded successfully.'), {
......@@ -210,9 +203,9 @@ export default {
if (this.upgradeAvailable && !this.upgradeFailed && !this.isUpgrading) {
label = s__('ClusterIntegration|Upgrade');
} else if (this.isUpgrading) {
label = s__('ClusterIntegration|Upgrading');
label = s__('ClusterIntegration|Updating');
} else if (this.upgradeFailed) {
label = s__('ClusterIntegration|Retry upgrade');
label = s__('ClusterIntegration|Retry update');
}
return label;
......@@ -224,6 +217,14 @@ export default {
(this.upgradeRequested && !this.upgradeSuccessful)
);
},
shouldShowUpgradeDetails() {
// This method only returns true when;
// Upgrade was successful OR Upgrade failed
// AND new upgrade is unavailable AND version information is present.
return (
(this.upgradeSuccessful || this.upgradeFailed) && !this.upgradeAvailable && this.version
);
},
},
watch: {
status() {
......@@ -303,7 +304,7 @@ export default {
</div>
<div
v-if="(upgradeSuccessful || upgradeFailed) && !upgradeAvailable"
v-if="shouldShowUpgradeDetails"
class="form-text text-muted label p-0 js-cluster-application-upgrade-details"
>
{{ versionLabel }}
......
......@@ -15,11 +15,14 @@ import { s__, sprintf } from '../../locale';
import applicationRow from './application_row.vue';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import { CLUSTER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';