Skip to content
Snippets Groups Projects
Commit 83874edb authored by Grzegorz Bizon's avatar Grzegorz Bizon
Browse files

Merge branch 'master' into 'update-kubeclient'

 Conflicts:
   Gemfile.lock
parents 53e2987b ea5221ae
No related branches found
No related tags found
No related merge requests found
Showing
with 309 additions and 227 deletions
import NotificationsForm from '../../../../notifications_form';
import notificationsDropdown from '../../../../notifications_dropdown';
document.addEventListener('DOMContentLoaded', () => {
new NotificationsForm(); // eslint-disable-line no-new
notificationsDropdown();
});
import Vue from 'vue';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import BlobViewer from '~/blob/viewer/index';
import initBlob from '~/pages/projects/init_blob';
 
document.addEventListener('DOMContentLoaded', () => {
new BlobViewer(); // eslint-disable-line no-new
initBlob();
const CommitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
const statusLink = document.querySelector('.commit-actions .ci-status-link');
if (statusLink) {
statusLink.remove();
// eslint-disable-next-line no-new
new Vue({
el: CommitPipelineStatusEl,
components: {
commitPipelineStatus,
},
render(createElement) {
return createElement('commit-pipeline-status', {
props: {
endpoint: CommitPipelineStatusEl.dataset.endpoint,
},
});
},
});
}
});
Loading
Loading
@@ -14,8 +14,6 @@ export default class PerformanceBar {
 
init(opts) {
const $container = $(opts.container);
this.$sqlProfileLink = $container.find('.js-toggle-modal-peek-sql');
this.$sqlProfileModal = $container.find('#modal-peek-pg-queries');
this.$lineProfileLink = $container.find('.js-toggle-modal-peek-line-profile');
this.$lineProfileModal = $('#modal-peek-line-profile');
this.initEventListeners();
Loading
Loading
@@ -23,7 +21,6 @@ export default class PerformanceBar {
}
 
initEventListeners() {
this.$sqlProfileLink.on('click', () => this.handleSQLProfileLink());
this.$lineProfileLink.on('click', e => this.handleLineProfileLink(e));
$(document).on('click', '.js-lineprof-file', PerformanceBar.toggleLineProfileFile);
}
Loading
Loading
@@ -36,10 +33,6 @@ export default class PerformanceBar {
}
}
 
handleSQLProfileLink() {
PerformanceBar.toggleModal(this.$sqlProfileModal);
}
handleLineProfileLink(e) {
const lineProfilerParameter = getParameterValues('lineprofiler');
const lineProfilerParameterRegex = new RegExp(`lineprofiler=${lineProfilerParameter[0]}`);
Loading
Loading
<script>
import timeagoMixin from '../../vue_shared/mixins/timeago';
import tooltip from '../../vue_shared/directives/tooltip';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
import { visitUrl } from '../../lib/utils/url_utility';
import createFlash from '../../flash';
import MemoryUsage from './memory_usage.vue';
import StatusIcon from './mr_widget_status_icon.vue';
import MRWidgetService from '../services/mr_widget_service';
export default {
name: 'Deployment',
components: {
LoadingButton,
MemoryUsage,
StatusIcon,
},
directives: {
tooltip,
},
mixins: [
timeagoMixin,
],
props: {
deployment: {
type: Object,
required: true,
},
},
data() {
return {
isStopping: false,
};
},
computed: {
deployTimeago() {
return this.timeFormated(this.deployment.deployed_at);
},
hasExternalUrls() {
return !!(this.deployment.external_url && this.deployment.external_url_formatted);
},
hasDeploymentTime() {
return !!(this.deployment.deployed_at && this.deployment.deployed_at_formatted);
},
hasDeploymentMeta() {
return !!(this.deployment.url && this.deployment.name);
},
hasMetrics() {
return !!(this.deployment.metrics_url);
},
},
methods: {
stopEnvironment() {
const msg = 'Are you sure you want to stop this environment?';
const isConfirmed = confirm(msg); // eslint-disable-line
if (isConfirmed) {
this.isStopping = true;
MRWidgetService.stopEnvironment(this.deployment.stop_url)
.then(res => res.data)
.then((data) => {
if (data.redirect_url) {
visitUrl(data.redirect_url);
}
this.isStopping = false;
})
.catch(() => {
createFlash('Something went wrong while stopping this environment. Please try again.');
this.isStopping = false;
});
}
},
},
};
</script>
<template>
<div class="mr-widget-heading deploy-heading">
<div class="ci-widget media">
<div class="ci-status-icon ci-status-icon-success">
<span class="js-icon-link icon-link">
<status-icon status="success" />
</span>
</div>
<div class="media-body">
<div class="deploy-body">
<template v-if="hasDeploymentMeta">
<span>
Deployed to
</span>
<a
:href="deployment.url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-meta"
>
{{ deployment.name }}
</a>
</template>
<template v-if="hasExternalUrls">
<span>
on
</span>
<a
:href="deployment.external_url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-url"
>
<i
class="fa fa-external-link"
aria-hidden="true"
>
</i>
{{ deployment.external_url_formatted }}
</a>
</template>
<span
v-if="hasDeploymentTime"
v-tooltip
:title="deployment.deployed_at_formatted"
class="js-deploy-time"
>
{{ deployTimeago }}
</span>
<loading-button
v-if="deployment.stop_url"
container-class="btn btn-default btn-xs prepend-left-default"
label="Stop environment"
:loading="isStopping"
@click="stopEnvironment"
/>
</div>
<memory-usage
v-if="hasMetrics"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
</div>
</div>
</template>
import { getTimeago } from '~/lib/utils/datetime_utility';
import { visitUrl } from '../../lib/utils/url_utility';
import Flash from '../../flash';
import MemoryUsage from './memory_usage.vue';
import StatusIcon from './mr_widget_status_icon.vue';
import MRWidgetService from '../services/mr_widget_service';
export default {
name: 'MRWidgetDeployment',
props: {
mr: { type: Object, required: true },
service: { type: Object, required: true },
},
components: {
MemoryUsage,
StatusIcon,
},
methods: {
formatDate(date) {
return getTimeago().format(date);
},
hasExternalUrls(deployment = {}) {
return deployment.external_url && deployment.external_url_formatted;
},
hasDeploymentTime(deployment = {}) {
return deployment.deployed_at && deployment.deployed_at_formatted;
},
hasDeploymentMeta(deployment = {}) {
return deployment.url && deployment.name;
},
stopEnvironment(deployment) {
const msg = 'Are you sure you want to stop this environment?';
const isConfirmed = confirm(msg); // eslint-disable-line
if (isConfirmed) {
MRWidgetService.stopEnvironment(deployment.stop_url)
.then(res => res.data)
.then((data) => {
if (data.redirect_url) {
visitUrl(data.redirect_url);
}
})
.catch(() => {
new Flash('Something went wrong while stopping this environment. Please try again.'); // eslint-disable-line
});
}
},
},
template: `
<div class="mr-widget-heading deploy-heading">
<div v-for="deployment in mr.deployments">
<div class="ci-widget media">
<div class="ci-status-icon ci-status-icon-success">
<span class="js-icon-link icon-link">
<status-icon status="success" />
</span>
</div>
<div class="media-body space-children">
<span>
<span
v-if="hasDeploymentMeta(deployment)">
Deployed to
</span>
<a
v-if="hasDeploymentMeta(deployment)"
:href="deployment.url"
target="_blank"
rel="noopener noreferrer nofollow"
class="js-deploy-meta inline">
{{deployment.name}}
</a>
<span
v-if="hasExternalUrls(deployment)">
on
</span>
<a
v-if="hasExternalUrls(deployment)"
:href="deployment.external_url"
target="_blank"
rel="noopener noreferrer nofollow"
class="js-deploy-url inline">
<i
class="fa fa-external-link"
aria-hidden="true" />
{{deployment.external_url_formatted}}
</a>
<span
v-if="hasDeploymentTime(deployment)"
:data-title="deployment.deployed_at_formatted"
class="js-deploy-time"
data-toggle="tooltip"
data-placement="top">
{{formatDate(deployment.deployed_at)}}
</span>
</span>
<button
type="button"
v-if="deployment.stop_url"
@click="stopEnvironment(deployment)"
class="btn btn-default btn-xs">
Stop environment
</button>
<memory-usage
v-if="deployment.metrics_url"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
</div>
</div>
</div>
`,
};
Loading
Loading
@@ -14,7 +14,7 @@ export { default as SmartInterval } from '~/smart_interval';
export { default as WidgetHeader } from './components/mr_widget_header.vue';
export { default as WidgetMergeHelp } from './components/mr_widget_merge_help.vue';
export { default as WidgetPipeline } from './components/mr_widget_pipeline.vue';
export { default as WidgetDeployment } from './components/mr_widget_deployment';
export { default as Deployment } from './components/deployment.vue';
export { default as WidgetMaintainerEdit } from './components/mr_widget_maintainer_edit.vue';
export { default as WidgetRelatedLinks } from './components/mr_widget_related_links.vue';
export { default as MergedState } from './components/states/mr_widget_merged.vue';
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ import {
WidgetHeader,
WidgetMergeHelp,
WidgetPipeline,
WidgetDeployment,
Deployment,
WidgetMaintainerEdit,
WidgetRelatedLinks,
MergedState,
Loading
Loading
@@ -67,9 +67,6 @@ export default {
shouldRenderRelatedLinks() {
return !!this.mr.relatedLinks && !this.mr.isNothingToMergeState;
},
shouldRenderDeployments() {
return this.mr.deployments.length;
},
shouldRenderSourceBranchRemovalStatus() {
return !this.mr.canRemoveSourceBranch && this.mr.shouldRemoveSourceBranch &&
(!this.mr.isNothingToMergeState && !this.mr.isMergedState);
Loading
Loading
@@ -216,7 +213,7 @@ export default {
'mr-widget-header': WidgetHeader,
'mr-widget-merge-help': WidgetMergeHelp,
'mr-widget-pipeline': WidgetPipeline,
'mr-widget-deployment': WidgetDeployment,
Deployment,
'mr-widget-maintainer-edit': WidgetMaintainerEdit,
'mr-widget-related-links': WidgetRelatedLinks,
'mr-widget-merged': MergedState,
Loading
Loading
@@ -250,10 +247,11 @@ export default {
:ci-status="mr.ciStatus"
:has-ci="mr.hasCI"
/>
<mr-widget-deployment
v-if="shouldRenderDeployments"
:mr="mr"
:service="service" />
<deployment
v-for="deployment in mr.deployments"
:key="deployment.id"
:deployment="deployment"
/>
<div class="mr-widget-section">
<component
:is="componentName"
Loading
Loading
Loading
Loading
@@ -17,8 +17,6 @@
*/
@mixin markdown-table {
width: auto;
display: block;
overflow-x: auto;
}
 
/*
Loading
Loading
Loading
Loading
@@ -194,8 +194,6 @@
 
.commit-actions {
@media (min-width: $screen-sm-min) {
font-size: 0;
.fa-spinner {
font-size: 12px;
}
Loading
Loading
@@ -204,7 +202,7 @@
.ci-status-link {
display: inline-block;
position: relative;
top: 1px;
top: 2px;
}
 
.btn-clipboard,
Loading
Loading
@@ -226,7 +224,7 @@
 
.ci-status-icon {
position: relative;
top: 1px;
top: 2px;
}
}
 
Loading
Loading
Loading
Loading
@@ -718,6 +718,8 @@
}
 
.mr-memory-usage {
width: 100%;
p.usage-info-loading .usage-info-load-spinner {
margin-right: 10px;
font-size: 16px;
Loading
Loading
@@ -727,3 +729,36 @@
.fork-sprite {
margin-right: -5px;
}
.deploy-heading {
.media-body {
min-width: 0;
}
}
.deploy-body {
display: flex;
flex-wrap: wrap;
@media (min-width: $screen-xs) {
flex-wrap: nowrap;
white-space: nowrap;
}
> *:not(:last-child) {
margin-right: .3em;
}
}
.deploy-link {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 100px;
max-width: 150px;
@media (min-width: $screen-xs) {
min-width: 0;
max-width: 100%;
}
}
Loading
Loading
@@ -16,7 +16,7 @@ ul.notes {
 
.note-created-ago,
.note-updated-at {
white-space: nowrap;
white-space: normal;
}
 
.discussion-body {
Loading
Loading
Loading
Loading
@@ -180,6 +180,11 @@ ul.wiki-pages-list.content-list {
}
}
 
.wiki-holder {
overflow-x: auto;
overflow-y: hidden;
}
.wiki {
table {
@include markdown-table;
Loading
Loading
Loading
Loading
@@ -19,6 +19,12 @@ class Projects::DiscussionsController < Projects::ApplicationController
render_discussion
end
 
def show
render json: {
discussion_html: view_to_html_string('discussions/_diff_with_notes', discussion: discussion, expanded: true)
}
end
private
 
def render_discussion
Loading
Loading
Loading
Loading
@@ -16,8 +16,7 @@ class Admin::ProjectsFinder
items = by_archived(items)
items = by_personal(items)
items = by_name(items)
items = sort(items)
items.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page])
sort(items).page(params[:page])
end
 
private
Loading
Loading
Loading
Loading
@@ -2,9 +2,4 @@ module JavascriptHelper
def page_specific_javascript_tag(js)
javascript_include_tag asset_path(js)
end
# deprecated; use webpack_bundle_tag directly instead
def page_specific_javascript_bundle_tag(bundle)
webpack_bundle_tag(bundle)
end
end
Loading
Loading
@@ -347,15 +347,15 @@ class ApplicationSetting < ActiveRecord::Base
end
 
def home_page_url_column_exists?
ActiveRecord::Base.connection.column_exists?(:application_settings, :home_page_url)
::Gitlab::Database.cached_column_exists?(:application_settings, :home_page_url)
end
 
def help_page_support_url_column_exists?
ActiveRecord::Base.connection.column_exists?(:application_settings, :help_page_support_url)
::Gitlab::Database.cached_column_exists?(:application_settings, :help_page_support_url)
end
 
def sidekiq_throttling_column_exists?
ActiveRecord::Base.connection.column_exists?(:application_settings, :sidekiq_throttling_enabled)
::Gitlab::Database.cached_column_exists?(:application_settings, :sidekiq_throttling_enabled)
end
 
def domain_whitelist_raw
Loading
Loading
Loading
Loading
@@ -252,23 +252,23 @@ module Ci
# All variables, including those dependent on environment, which could
# contain unexpanded variables.
def variables(environment: persisted_environment)
variables = predefined_variables
variables += project.predefined_variables
variables += pipeline.predefined_variables
variables += runner.predefined_variables if runner
variables += project.container_registry_variables
variables += project.deployment_variables if has_environment?
variables += project.auto_devops_variables
variables += yaml_variables
variables += user_variables
variables += project.group.secret_variables_for(ref, project).map(&:to_runner_variable) if project.group
variables += secret_variables(environment: environment)
variables += trigger_request.user_variables if trigger_request
variables += pipeline.variables.map(&:to_runner_variable)
variables += pipeline.pipeline_schedule.job_variables if pipeline.pipeline_schedule
variables += persisted_environment_variables if environment
variables
collection = Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.concat(predefined_variables)
variables.concat(project.predefined_variables)
variables.concat(pipeline.predefined_variables)
variables.concat(runner.predefined_variables) if runner
variables.concat(project.deployment_variables(environment: environment)) if has_environment?
variables.concat(yaml_variables)
variables.concat(user_variables)
variables.concat(project.group.secret_variables_for(ref, project)) if project.group
variables.concat(secret_variables(environment: environment))
variables.concat(trigger_request.user_variables) if trigger_request
variables.concat(pipeline.variables)
variables.concat(pipeline.pipeline_schedule.job_variables) if pipeline.pipeline_schedule
variables.concat(persisted_environment_variables) if environment
end
collection.to_runner_variables
end
 
def features
Loading
Loading
@@ -430,14 +430,14 @@ module Ci
end
 
def user_variables
return [] if user.blank?
Gitlab::Ci::Variables::Collection.new.tap do |variables|
return variables if user.blank?
 
[
{ key: 'GITLAB_USER_ID', value: user.id.to_s, public: true },
{ key: 'GITLAB_USER_EMAIL', value: user.email, public: true },
{ key: 'GITLAB_USER_LOGIN', value: user.username, public: true },
{ key: 'GITLAB_USER_NAME', value: user.name, public: true }
]
variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s)
variables.append(key: 'GITLAB_USER_EMAIL', value: user.email)
variables.append(key: 'GITLAB_USER_LOGIN', value: user.username)
variables.append(key: 'GITLAB_USER_NAME', value: user.name)
end
end
 
def secret_variables(environment: persisted_environment)
Loading
Loading
@@ -540,60 +540,57 @@ module Ci
CI_REGISTRY_USER = 'gitlab-ci-token'.freeze
 
def predefined_variables
variables = [
{ key: 'CI', value: 'true', public: true },
{ key: 'GITLAB_CI', value: 'true', public: true },
{ key: 'GITLAB_FEATURES', value: project.namespace.features.join(','), public: true },
{ key: 'CI_SERVER_NAME', value: 'GitLab', public: true },
{ key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true },
{ key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true },
{ key: 'CI_JOB_ID', value: id.to_s, public: true },
{ key: 'CI_JOB_NAME', value: name, public: true },
{ key: 'CI_JOB_STAGE', value: stage, public: true },
{ key: 'CI_JOB_TOKEN', value: token, public: false },
{ key: 'CI_COMMIT_SHA', value: sha, public: true },
{ key: 'CI_COMMIT_REF_NAME', value: ref, public: true },
{ key: 'CI_COMMIT_REF_SLUG', value: ref_slug, public: true },
{ key: 'CI_REGISTRY_USER', value: CI_REGISTRY_USER, public: true },
{ key: 'CI_REGISTRY_PASSWORD', value: token, public: false },
{ key: 'CI_REPOSITORY_URL', value: repo_url, public: false }
]
variables << { key: "CI_COMMIT_TAG", value: ref, public: true } if tag?
variables << { key: "CI_PIPELINE_TRIGGERED", value: 'true', public: true } if trigger_request
variables << { key: "CI_JOB_MANUAL", value: 'true', public: true } if action?
variables.concat(legacy_variables)
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'CI', value: 'true')
variables.append(key: 'GITLAB_CI', value: 'true')
variables.append(key: 'GITLAB_FEATURES', value: project.namespace.features.join(','))
variables.append(key: 'CI_SERVER_NAME', value: 'GitLab')
variables.append(key: 'CI_SERVER_VERSION', value: Gitlab::VERSION)
variables.append(key: 'CI_SERVER_REVISION', value: Gitlab::REVISION)
variables.append(key: 'CI_JOB_ID', value: id.to_s)
variables.append(key: 'CI_JOB_NAME', value: name)
variables.append(key: 'CI_JOB_STAGE', value: stage)
variables.append(key: 'CI_JOB_TOKEN', value: token, public: false)
variables.append(key: 'CI_COMMIT_SHA', value: sha)
variables.append(key: 'CI_COMMIT_REF_NAME', value: ref)
variables.append(key: 'CI_COMMIT_REF_SLUG', value: ref_slug)
variables.append(key: 'CI_REGISTRY_USER', value: CI_REGISTRY_USER)
variables.append(key: 'CI_REGISTRY_PASSWORD', value: token, public: false)
variables.append(key: 'CI_REPOSITORY_URL', value: repo_url, public: false)
variables.append(key: "CI_COMMIT_TAG", value: ref) if tag?
variables.append(key: "CI_PIPELINE_TRIGGERED", value: 'true') if trigger_request
variables.append(key: "CI_JOB_MANUAL", value: 'true') if action?
variables.concat(legacy_variables)
end
end
 
def persisted_environment_variables
return [] unless persisted_environment
Gitlab::Ci::Variables::Collection.new.tap do |variables|
return variables unless persisted_environment
 
variables = persisted_environment.predefined_variables
variables.concat(persisted_environment.predefined_variables)
 
# Here we're passing unexpanded environment_url for runner to expand,
# and we need to make sure that CI_ENVIRONMENT_NAME and
# CI_ENVIRONMENT_SLUG so on are available for the URL be expanded.
variables << { key: 'CI_ENVIRONMENT_URL', value: environment_url, public: true } if environment_url
variables
# Here we're passing unexpanded environment_url for runner to expand,
# and we need to make sure that CI_ENVIRONMENT_NAME and
# CI_ENVIRONMENT_SLUG so on are available for the URL be expanded.
variables.append(key: 'CI_ENVIRONMENT_URL', value: environment_url) if environment_url
end
end
 
def legacy_variables
variables = [
{ key: 'CI_BUILD_ID', value: id.to_s, public: true },
{ key: 'CI_BUILD_TOKEN', value: token, public: false },
{ key: 'CI_BUILD_REF', value: sha, public: true },
{ key: 'CI_BUILD_BEFORE_SHA', value: before_sha, public: true },
{ key: 'CI_BUILD_REF_NAME', value: ref, public: true },
{ key: 'CI_BUILD_REF_SLUG', value: ref_slug, public: true },
{ key: 'CI_BUILD_NAME', value: name, public: true },
{ key: 'CI_BUILD_STAGE', value: stage, public: true }
]
variables << { key: "CI_BUILD_TAG", value: ref, public: true } if tag?
variables << { key: "CI_BUILD_TRIGGERED", value: 'true', public: true } if trigger_request
variables << { key: "CI_BUILD_MANUAL", value: 'true', public: true } if action?
variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'CI_BUILD_ID', value: id.to_s)
variables.append(key: 'CI_BUILD_TOKEN', value: token, public: false)
variables.append(key: 'CI_BUILD_REF', value: sha)
variables.append(key: 'CI_BUILD_BEFORE_SHA', value: before_sha)
variables.append(key: 'CI_BUILD_REF_NAME', value: ref)
variables.append(key: 'CI_BUILD_REF_SLUG', value: ref_slug)
variables.append(key: 'CI_BUILD_NAME', value: name)
variables.append(key: 'CI_BUILD_STAGE', value: stage)
variables.append(key: "CI_BUILD_TAG", value: ref) if tag?
variables.append(key: "CI_BUILD_TRIGGERED", value: 'true') if trigger_request
variables.append(key: "CI_BUILD_MANUAL", value: 'true') if action?
end
end
 
def environment_url
Loading
Loading
Loading
Loading
@@ -473,11 +473,10 @@ module Ci
end
 
def predefined_variables
[
{ key: 'CI_PIPELINE_ID', value: id.to_s, public: true },
{ key: 'CI_CONFIG_PATH', value: ci_yaml_file_path, public: true },
{ key: 'CI_PIPELINE_SOURCE', value: source.to_s, public: true }
]
Gitlab::Ci::Variables::Collection.new
.append(key: 'CI_PIPELINE_ID', value: id.to_s)
.append(key: 'CI_CONFIG_PATH', value: ci_yaml_file_path)
.append(key: 'CI_PIPELINE_SOURCE', value: source.to_s)
end
 
def queued_duration
Loading
Loading
Loading
Loading
@@ -132,11 +132,10 @@ module Ci
end
 
def predefined_variables
[
{ key: 'CI_RUNNER_ID', value: id.to_s, public: true },
{ key: 'CI_RUNNER_DESCRIPTION', value: description, public: true },
{ key: 'CI_RUNNER_TAGS', value: tag_list.to_s, public: true }
]
Gitlab::Ci::Variables::Collection.new
.append(key: 'CI_RUNNER_ID', value: id.to_s)
.append(key: 'CI_RUNNER_DESCRIPTION', value: description)
.append(key: 'CI_RUNNER_TAGS', value: tag_list.to_s)
end
 
def tick_runner_queue
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment