Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_canceled.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_created.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_failed.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_manual.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_not_found.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_pending.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_running.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_skipped.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_success.icobin0 -> 5430 bytes
-rwxr-xr-xapp/assets/images/ci_favicons/icon_status_warning.icobin0 -> 5430 bytes
-rw-r--r--app/assets/javascripts/build.js1
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js31
-rw-r--r--app/assets/javascripts/merge_request_widget.js7
-rw-r--r--app/assets/javascripts/pipelines.js4
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/_show.html.haml1
-rw-r--r--changelogs/unreleased/12818-ci-status-as-favicon.yml4
-rw-r--r--spec/javascripts/build_spec.js2
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js51
-rw-r--r--spec/javascripts/merge_request_widget_spec.js7
21 files changed, 109 insertions, 3 deletions
diff --git a/app/assets/images/ci_favicons/icon_status_canceled.ico b/app/assets/images/ci_favicons/icon_status_canceled.ico
new file mode 100755
index 00000000000..5a19458f2a2
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_canceled.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_created.ico b/app/assets/images/ci_favicons/icon_status_created.ico
new file mode 100755
index 00000000000..4dca9640cb3
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_created.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_failed.ico b/app/assets/images/ci_favicons/icon_status_failed.ico
new file mode 100755
index 00000000000..c961ff9a69b
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_failed.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_manual.ico b/app/assets/images/ci_favicons/icon_status_manual.ico
new file mode 100755
index 00000000000..5fbbc99ea7c
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_manual.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_not_found.ico b/app/assets/images/ci_favicons/icon_status_not_found.ico
new file mode 100755
index 00000000000..21afa9c72e6
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_not_found.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_pending.ico b/app/assets/images/ci_favicons/icon_status_pending.ico
new file mode 100755
index 00000000000..8be32dab85a
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_pending.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_running.ico b/app/assets/images/ci_favicons/icon_status_running.ico
new file mode 100755
index 00000000000..f328ff1a5ed
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_running.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_skipped.ico b/app/assets/images/ci_favicons/icon_status_skipped.ico
new file mode 100755
index 00000000000..b4394e1b4af
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_skipped.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_success.ico b/app/assets/images/ci_favicons/icon_status_success.ico
new file mode 100755
index 00000000000..4f436c95242
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_success.ico
Binary files differ
diff --git a/app/assets/images/ci_favicons/icon_status_warning.ico b/app/assets/images/ci_favicons/icon_status_warning.ico
new file mode 100755
index 00000000000..805cc20cdec
--- /dev/null
+++ b/app/assets/images/ci_favicons/icon_status_warning.ico
Binary files differ
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 6efd26ccc37..fe54ecffdfe 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -88,6 +88,7 @@ window.Build = (function() {
dataType: 'json',
success: function(buildData) {
$('.js-build-output').html(buildData.trace_html);
+ gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
if (window.location.hash === DOWN_BUILD_TRACE) {
$("html,body").scrollTop(this.$buildTrace.height());
}
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 80490052389..9c7acc903d1 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -226,9 +226,11 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'projects:pipelines:builds':
case 'projects:pipelines:show':
const { controllerAction } = document.querySelector('.js-pipeline-container').dataset;
+ const pipelineStatusUrl = `${document.querySelector('.js-pipeline-tab-link a').getAttribute('href')}/status.json`;
new gl.Pipelines({
initTabs: true,
+ pipelineStatusUrl,
tabsOptions: {
action: controllerAction,
defaultAction: 'pipelines',
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 46b80c04e20..e1e6ca25446 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -2,6 +2,8 @@
(function() {
(function(w) {
var base;
+ const faviconEl = document.getElementById('favicon');
+ const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
w.gl || (w.gl = {});
(base = w.gl).utils || (base.utils = {});
w.gl.utils.isInGroupsPage = function() {
@@ -361,5 +363,34 @@
fn(next, stop);
});
};
+
+ w.gl.utils.setFavicon = (iconName) => {
+ if (faviconEl && iconName) {
+ faviconEl.setAttribute('href', `/assets/${iconName}.ico`);
+ }
+ };
+
+ w.gl.utils.resetFavicon = () => {
+ if (faviconEl) {
+ faviconEl.setAttribute('href', originalFavicon);
+ }
+ };
+
+ w.gl.utils.setCiStatusFavicon = (pageUrl) => {
+ $.ajax({
+ url: pageUrl,
+ dataType: 'json',
+ success: function(data) {
+ if (data && data.icon) {
+ gl.utils.setFavicon(`ci_favicons/${data.icon}`);
+ } else {
+ gl.utils.resetFavicon();
+ }
+ },
+ error: function() {
+ gl.utils.resetFavicon();
+ }
+ });
+ };
})(window);
}).call(window);
diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js
index 0e2af3df071..b0254b17dd2 100644
--- a/app/assets/javascripts/merge_request_widget.js
+++ b/app/assets/javascripts/merge_request_widget.js
@@ -38,11 +38,13 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior
//
- // check_enable - Boolean, whether to check automerge status
- // merge_check_url - String, URL to use to check automerge status
+ // check_enable - Boolean, whether to check automerge status
+ // merge_check_url - String, URL to use to check automerge status
// ci_status_url - String, URL to use to check CI status
+ // pipeline_status_url - String, URL to use to get CI status for Favicon
//
this.opts = opts;
+ this.opts.pipeline_status_url = `${this.opts.pipeline_status_url}.json`;
this.$widgetBody = $('.mr-widget-body');
$('#modal_merge_info').modal({
show: false
@@ -159,6 +161,7 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
_this.status = data.status;
_this.hasCi = data.has_ci;
_this.updateMergeButton(_this.status, _this.hasCi);
+ gl.utils.setCiStatusFavicon(_this.opts.pipeline_status_url);
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (data.status !== _this.opts.ci_status ||
data.sha !== _this.opts.ci_sha ||
diff --git a/app/assets/javascripts/pipelines.js b/app/assets/javascripts/pipelines.js
index 9203abefbbc..4252b615887 100644
--- a/app/assets/javascripts/pipelines.js
+++ b/app/assets/javascripts/pipelines.js
@@ -9,6 +9,10 @@ require('./lib/utils/bootstrap_linked_tabs');
new global.LinkedTabs(options.tabsOptions);
}
+ if (options.pipelineStatusUrl) {
+ gl.utils.setCiStatusFavicon(options.pipelineStatusUrl);
+ }
+
this.addMarginToBuildColumns();
}
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index f6d8bb08a64..a611481a0a4 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -23,7 +23,7 @@
%title= page_title(site_name)
%meta{ name: "description", content: page_description }
- = favicon_link_tag favicon
+ = favicon_link_tag favicon, id: 'favicon'
= stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print"
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index 0b0fb7854c2..c716b69b35b 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -12,6 +12,7 @@
merge_check_url: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
ci_status_url: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+ pipeline_status_url: "#{pipeline_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
ci_environments_status_url: "#{ci_environments_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
gitlab_icon: "#{asset_path 'gitlab_logo.png'}",
ci_status: "#{@merge_request.head_pipeline ? @merge_request.head_pipeline.status : ''}",
diff --git a/changelogs/unreleased/12818-ci-status-as-favicon.yml b/changelogs/unreleased/12818-ci-status-as-favicon.yml
new file mode 100644
index 00000000000..70194178d90
--- /dev/null
+++ b/changelogs/unreleased/12818-ci-status-as-favicon.yml
@@ -0,0 +1,4 @@
+---
+title: Show CI status as Favicon on Pipelines, Job and MR pages
+merge_request: 10144
+author:
diff --git a/spec/javascripts/build_spec.js b/spec/javascripts/build_spec.js
index 549c7af8ea8..beee6cb2969 100644
--- a/spec/javascripts/build_spec.js
+++ b/spec/javascripts/build_spec.js
@@ -75,6 +75,7 @@ describe('Build', () => {
expect(url).toBe(`${BUILD_URL}.json`);
expect(dataType).toBe('json');
expect(success).toEqual(jasmine.any(Function));
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
success.call(context, { trace_html: '<span>Example</span>', status: 'running' });
@@ -83,6 +84,7 @@ describe('Build', () => {
it('removes the spinner', () => {
const [{ success, context }] = $.ajax.calls.argsFor(0);
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
success.call(context, { trace_html: '<span>Example</span>', status: 'success' });
expect($('.js-build-refresh').length).toBe(0);
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index 5a93d479c1f..03f3c206f44 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -310,5 +310,56 @@ require('~/lib/utils/common_utils');
});
}, 10000);
});
+
+ describe('gl.utils.setFavicon', () => {
+ it('should set page favicon to provided favicon', () => {
+ const faviconName = 'custom_favicon';
+ const fakeLink = {
+ setAttribute() {},
+ };
+
+ spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
+ spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
+ expect(attr).toEqual('href');
+ expect(val.indexOf('/assets/custom_favicon.ico') > -1).toBe(true);
+ });
+ gl.utils.setFavicon(faviconName);
+ });
+ });
+
+ describe('gl.utils.resetFavicon', () => {
+ it('should reset page favicon to tanuki', () => {
+ const fakeLink = {
+ setAttribute() {},
+ };
+
+ spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
+ spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
+ expect(attr).toEqual('href');
+ expect(val).toMatch(/favicon/);
+ });
+ gl.utils.resetFavicon();
+ });
+ });
+
+ describe('gl.utils.setCiStatusFavicon', () => {
+ it('should set page favicon to CI status favicon based on provided status', () => {
+ const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/builds/1/status.json`;
+ const FAVICON_PATH = 'ci_favicons/';
+ const FAVICON = 'icon_status_success';
+ const spySetFavicon = spyOn(gl.utils, 'setFavicon').and.stub();
+ const spyResetFavicon = spyOn(gl.utils, 'resetFavicon').and.stub();
+ spyOn($, 'ajax').and.callFake(function (options) {
+ options.success({ icon: FAVICON });
+ expect(spySetFavicon).toHaveBeenCalledWith(FAVICON_PATH + FAVICON);
+ options.success();
+ expect(spyResetFavicon).toHaveBeenCalled();
+ options.error();
+ expect(spyResetFavicon).toHaveBeenCalled();
+ });
+
+ gl.utils.setCiStatusFavicon(BUILD_URL);
+ });
+ });
});
})();
diff --git a/spec/javascripts/merge_request_widget_spec.js b/spec/javascripts/merge_request_widget_spec.js
index d5193b41c33..88dae8c3e06 100644
--- a/spec/javascripts/merge_request_widget_spec.js
+++ b/spec/javascripts/merge_request_widget_spec.js
@@ -142,18 +142,21 @@ require('~/lib/utils/datetime_utility');
it('should call showCIStatus even if a notification should not be displayed', function() {
var spy;
spy = spyOn(this["class"], 'showCIStatus').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(false);
return expect(spy).toHaveBeenCalledWith(this.ciStatusData.status);
});
it('should call showCIStatus when a notification should be displayed', function() {
var spy;
spy = spyOn(this["class"], 'showCIStatus').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(true);
return expect(spy).toHaveBeenCalledWith(this.ciStatusData.status);
});
it('should call showCICoverage when the coverage rate is set', function() {
var spy;
spy = spyOn(this["class"], 'showCICoverage').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(false);
return expect(spy).toHaveBeenCalledWith(this.ciStatusData.coverage);
});
@@ -161,12 +164,14 @@ require('~/lib/utils/datetime_utility');
var spy;
this.ciStatusData.coverage = null;
spy = spyOn(this["class"], 'showCICoverage').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(false);
return expect(spy).not.toHaveBeenCalled();
});
it('should not display a notification on the first check after the widget has been created', function() {
var spy;
spy = spyOn(window, 'notify');
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"] = new window.gl.MergeRequestWidget(this.opts);
this["class"].getCIStatus(true);
return expect(spy).not.toHaveBeenCalled();
@@ -174,6 +179,7 @@ require('~/lib/utils/datetime_utility');
it('should update the pipeline URL when the pipeline changes', function() {
var spy;
spy = spyOn(this["class"], 'updatePipelineUrls').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(false);
this.ciStatusData.pipeline += 1;
this["class"].getCIStatus(false);
@@ -182,6 +188,7 @@ require('~/lib/utils/datetime_utility');
it('should update the commit URL when the sha changes', function() {
var spy;
spy = spyOn(this["class"], 'updateCommitUrls').and.stub();
+ spyOn(gl.utils, 'setCiStatusFavicon').and.callFake(() => {});
this["class"].getCIStatus(false);
this.ciStatusData.sha = "9b50b99a";
this["class"].getCIStatus(false);