summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/issue_templates/Security developer workflow.md8
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock5
-rw-r--r--Gemfile.rails5.lock5
-rw-r--r--app/assets/javascripts/commons/polyfills.js1
-rw-r--r--app/assets/javascripts/diffs/components/app.vue12
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue16
-rw-r--r--app/assets/javascripts/diffs/constants.js3
-rw-r--r--app/assets/javascripts/diffs/store/actions.js21
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js43
-rw-r--r--app/assets/javascripts/jobs/components/artifacts_block.vue98
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss2
-rw-r--r--app/assets/stylesheets/framework/buttons.scss4
-rw-r--r--app/assets/stylesheets/framework/common.scss2
-rw-r--r--app/assets/stylesheets/framework/files.scss6
-rw-r--r--app/assets/stylesheets/framework/flash.scss4
-rw-r--r--app/assets/stylesheets/framework/forms.scss2
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss2
-rw-r--r--app/assets/stylesheets/framework/typography.scss10
-rw-r--r--app/assets/stylesheets/framework/variables.scss15
-rw-r--r--app/assets/stylesheets/framework/zen.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss2
-rw-r--r--app/assets/stylesheets/pages/boards.scss2
-rw-r--r--app/assets/stylesheets/pages/builds.scss2
-rw-r--r--app/assets/stylesheets/pages/commits.scss4
-rw-r--r--app/assets/stylesheets/pages/cycle_analytics.scss2
-rw-r--r--app/assets/stylesheets/pages/diff.scss4
-rw-r--r--app/assets/stylesheets/pages/environments.scss4
-rw-r--r--app/assets/stylesheets/pages/graph.scss4
-rw-r--r--app/assets/stylesheets/pages/issuable.scss10
-rw-r--r--app/assets/stylesheets/pages/issues.scss4
-rw-r--r--app/assets/stylesheets/pages/labels.scss6
-rw-r--r--app/assets/stylesheets/pages/milestone.scss2
-rw-r--r--app/assets/stylesheets/pages/note_form.scss8
-rw-r--r--app/assets/stylesheets/pages/notes.scss28
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss2
-rw-r--r--app/assets/stylesheets/pages/projects.scss4
-rw-r--r--app/assets/stylesheets/pages/search.scss2
-rw-r--r--app/helpers/icons_helper.rb2
-rw-r--r--app/models/ci/job_artifact.rb2
-rw-r--r--app/views/search/results/_blob.html.haml2
-rw-r--r--app/views/shared/runners/_form.html.haml30
-rwxr-xr-xbin/secpick4
-rw-r--r--changelogs/unreleased/49905-fix-checkboxes-runners.yml5
-rw-r--r--changelogs/unreleased/50101-aritfacts-block.yml5
-rw-r--r--changelogs/unreleased/50180-fa-icon-google-audit.yml5
-rw-r--r--changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml5
-rw-r--r--changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml5
-rw-r--r--changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml5
-rw-r--r--changelogs/unreleased/mk-bump-rainbow-gem.yml5
-rw-r--r--changelogs/unreleased/tz-mr-incremental-rendering.yml4
-rw-r--r--doc/api/jobs.md28
-rw-r--r--doc/api/system_hooks.md5
-rw-r--r--lib/api/entities.rb6
-rw-r--r--lib/api/jobs.rb4
-rw-r--r--locale/gitlab.pot48
-rw-r--r--spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb2
-rw-r--r--spec/helpers/icons_helper_spec.rb20
-rw-r--r--spec/javascripts/diffs/components/diff_file_spec.js10
-rw-r--r--spec/javascripts/diffs/mock_data/diff_file.js1
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js18
-rw-r--r--spec/javascripts/jobs/artifacts_block_spec.js120
-rw-r--r--spec/requests/api/jobs_spec.rb74
-rw-r--r--vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml6
65 files changed, 643 insertions, 132 deletions
diff --git a/.gitlab/issue_templates/Security developer workflow.md b/.gitlab/issue_templates/Security developer workflow.md
index c1f702e9385..64b54b171f7 100644
--- a/.gitlab/issue_templates/Security developer workflow.md
+++ b/.gitlab/issue_templates/Security developer workflow.md
@@ -12,7 +12,7 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Link to the original issue adding it to the [links section](#links)
- [ ] Run `scripts/security-harness` in the CE, EE, and/or Omnibus to prevent pushing to any remote besides `dev.gitlab.org`
- [ ] Create an MR targetting `org` `master`, prefixing your branch with `security-`
-- [ ] Label your MR with the ~security label, prefix the title with `WIP: [master]`
+- [ ] Label your MR with the ~security label, prefix the title with `WIP: [master]`
- [ ] Add a link to the MR to the [links section](#links)
- [ ] Add a link to an EE MR if required
- [ ] Make sure the MR remains in-progress and gets approved after the review cycle, **but never merged**.
@@ -22,13 +22,13 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Once the MR is ready to be merged, create MRs targetting the last 3 releases
- [ ] At this point, it might be easy to squash the commits from the MR into one
- - You can use the script `bin/secpick` instead of the following steps, to help you cherry-picking. See the [seckpick documentation]
+ - You can use the script `bin/secpick` instead of the following steps, to help you cherry-picking. See the [secpick documentation]
- [ ] Create the branch `security-X-Y` from `X-Y-stable` if it doesn't exist (and make sure it's up to date with stable)
- [ ] Create each MR targetting the security branch `security-X-Y`
- [ ] Add the ~security label and prefix with the version `WIP: [X.Y]` the title of the MR
- [ ] Make sure all MRs have a link in the [links section](#links) and are assigned to a Release Manager.
-[seckpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
+[secpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
#### Documentation and final details
@@ -68,4 +68,4 @@ Set the title to: `[Security] Description of the original issue`
[security process for developers]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md
[RM list]: https://about.gitlab.com/release-managers/
-/label ~security
+/label ~security
diff --git a/Gemfile b/Gemfile
index d9066081f74..5666e6cebc5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -180,7 +180,7 @@ gem 'rufus-scheduler', '~> 3.4'
gem 'httparty', '~> 0.13.3'
# Colored output to console
-gem 'rainbow', '~> 2.2'
+gem 'rainbow', '~> 3.0'
# Progress bar
gem 'ruby-progressbar'
diff --git a/Gemfile.lock b/Gemfile.lock
index 62c3b28f386..b33dd75c278 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -691,8 +691,7 @@ GEM
activesupport (= 4.2.10)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
- rainbow (2.2.2)
- rake
+ rainbow (3.0.0)
raindrops (0.18.0)
rake (12.3.1)
rb-fsevent (0.10.2)
@@ -1134,7 +1133,7 @@ DEPENDENCIES
rails (= 4.2.10)
rails-deprecated_sanitizer (~> 1.0.3)
rails-i18n (~> 4.0.9)
- rainbow (~> 2.2)
+ rainbow (~> 3.0)
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock
index 39305927c0f..af70e2c1939 100644
--- a/Gemfile.rails5.lock
+++ b/Gemfile.rails5.lock
@@ -701,8 +701,7 @@ GEM
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
- rainbow (2.2.2)
- rake
+ rainbow (3.0.0)
raindrops (0.18.0)
rake (12.3.1)
rb-fsevent (0.10.2)
@@ -1147,7 +1146,7 @@ DEPENDENCIES
rails-controller-testing
rails-deprecated_sanitizer (~> 1.0.3)
rails-i18n (~> 5.1)
- rainbow (~> 2.2)
+ rainbow (~> 3.0)
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
diff --git a/app/assets/javascripts/commons/polyfills.js b/app/assets/javascripts/commons/polyfills.js
index 589eeee9695..742cf490ad2 100644
--- a/app/assets/javascripts/commons/polyfills.js
+++ b/app/assets/javascripts/commons/polyfills.js
@@ -8,6 +8,7 @@ import 'core-js/fn/object/assign';
import 'core-js/fn/promise';
import 'core-js/fn/string/code-point-at';
import 'core-js/fn/string/from-code-point';
+import 'core-js/fn/string/includes';
import 'core-js/fn/symbol';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 7cc4e6a2c3a..b5b05df4d34 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -114,11 +114,15 @@ export default {
this.adjustView();
},
methods: {
- ...mapActions('diffs', ['setBaseConfig', 'fetchDiffFiles']),
+ ...mapActions('diffs', ['setBaseConfig', 'fetchDiffFiles', 'startRenderDiffsQueue']),
fetchData() {
- this.fetchDiffFiles().catch(() => {
- createFlash(__('Something went wrong on our end. Please try again!'));
- });
+ this.fetchDiffFiles()
+ .then(() => {
+ requestIdleCallback(this.startRenderDiffsQueue, { timeout: 1000 });
+ })
+ .catch(() => {
+ createFlash(__('Something went wrong on our end. Please try again!'));
+ });
if (!this.isNotesFetched) {
eventHub.$emit('fetchNotesData');
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 7e7058d8d08..59e9ba08b8b 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -46,16 +46,25 @@ export default {
showExpandMessage() {
return this.isCollapsed && !this.isLoadingCollapsedDiff && !this.file.tooLarge;
},
+ showLoadingIcon() {
+ return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed);
+ },
},
methods: {
...mapActions('diffs', ['loadCollapsedDiff']),
handleToggle() {
const { collapsed, highlightedDiffLines, parallelDiffLines } = this.file;
- if (collapsed && !highlightedDiffLines && !parallelDiffLines.length) {
+ if (
+ collapsed &&
+ !highlightedDiffLines &&
+ parallelDiffLines !== undefined &&
+ !parallelDiffLines.length
+ ) {
this.handleLoadCollapsedDiff();
} else {
this.file.collapsed = !this.file.collapsed;
+ this.file.renderIt = true;
}
},
handleLoadCollapsedDiff() {
@@ -65,6 +74,7 @@ export default {
.then(() => {
this.isLoadingCollapsedDiff = false;
this.file.collapsed = false;
+ this.file.renderIt = true;
})
.catch(() => {
this.isLoadingCollapsedDiff = false;
@@ -121,12 +131,12 @@ export default {
</div>
<diff-content
- v-if="!isCollapsed"
+ v-if="!isCollapsed && file.renderIt"
:class="{ hidden: isCollapsed || file.tooLarge }"
:diff-file="file"
/>
<loading-icon
- v-if="isLoadingCollapsedDiff"
+ v-else-if="showLoadingIcon"
class="diff-content loading"
/>
<div
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index 2fa8367f528..f68afa44837 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -25,3 +25,6 @@ export const CONTEXT_LINE_CLASS_NAME = 'diff-expanded';
export const UNFOLD_COUNT = 20;
export const COUNT_OF_AVATARS_IN_GUTTER = 3;
export const LENGTH_OF_AVATAR_TOOLTIP = 17;
+
+export const LINES_TO_BE_RENDERED_DIRECTLY = 100;
+export const MAX_LINES_TO_BE_RENDERED = 2000;
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 27001142257..4ab6ceb249a 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -29,6 +29,27 @@ export const fetchDiffFiles = ({ state, commit }) => {
.then(handleLocationHash);
};
+export const startRenderDiffsQueue = ({ state, commit }) => {
+ const checkItem = () => {
+ const nextFile = state.diffFiles.find(
+ file => !file.renderIt && (!file.collapsed || !file.text),
+ );
+ if (nextFile) {
+ requestAnimationFrame(() => {
+ commit(types.RENDER_FILE, nextFile);
+ });
+ requestIdleCallback(
+ () => {
+ checkItem();
+ },
+ { timeout: 1000 },
+ );
+ }
+ };
+
+ checkItem();
+};
+
export const setInlineDiffViewType = ({ commit }) => {
commit(types.SET_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE);
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 2c8e1a1466f..c999d637d50 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -8,3 +8,4 @@ export const REMOVE_COMMENT_FORM_LINE = 'REMOVE_COMMENT_FORM_LINE';
export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES';
export const ADD_COLLAPSED_DIFFS = 'ADD_COLLAPSED_DIFFS';
export const EXPAND_ALL_FILES = 'EXPAND_ALL_FILES';
+export const RENDER_FILE = 'RENDER_FILE';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index a98b2be89a3..0522e32c410 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -2,6 +2,7 @@ import Vue from 'vue';
import _ from 'underscore';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { findDiffFile, addLineReferences, removeMatchLine, addContextLines } from './utils';
+import { LINES_TO_BE_RENDERED_DIRECTLY, MAX_LINES_TO_BE_RENDERED } from '../constants';
import * as types from './mutation_types';
export default {
@@ -15,8 +16,48 @@ export default {
},
[types.SET_DIFF_DATA](state, data) {
+ const diffData = convertObjectPropsToCamelCase(data, { deep: true });
+ let showingLines = 0;
+ const filesLength = diffData.diffFiles.length;
+ let i;
+ for (i = 0; i < filesLength; i += 1) {
+ const file = diffData.diffFiles[i];
+ if (file.parallelDiffLines) {
+ const linesLength = file.parallelDiffLines.length;
+ let u = 0;
+ for (u = 0; u < linesLength; u += 1) {
+ const line = file.parallelDiffLines[u];
+ if (line.left) delete line.left.text;
+ if (line.right) delete line.right.text;
+ }
+ }
+
+ if (file.highlightedDiffLines) {
+ const linesLength = file.highlightedDiffLines.length;
+ let u;
+ for (u = 0; u < linesLength; u += 1) {
+ const line = file.highlightedDiffLines[u];
+ delete line.text;
+ }
+ }
+
+ if (file.highlightedDiffLines) {
+ showingLines += file.parallelDiffLines.length;
+ }
+ Object.assign(file, {
+ renderIt: showingLines < LINES_TO_BE_RENDERED_DIRECTLY,
+ collapsed: file.text && showingLines > MAX_LINES_TO_BE_RENDERED,
+ });
+ }
+
Object.assign(state, {
- ...convertObjectPropsToCamelCase(data, { deep: true }),
+ ...diffData,
+ });
+ },
+
+ [types.RENDER_FILE](state, file) {
+ Object.assign(file, {
+ renderIt: true,
});
},
diff --git a/app/assets/javascripts/jobs/components/artifacts_block.vue b/app/assets/javascripts/jobs/components/artifacts_block.vue
new file mode 100644
index 00000000000..525c5eec91a
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/artifacts_block.vue
@@ -0,0 +1,98 @@
+<script>
+ import TimeagoTooltiop from '~/vue_shared/components/time_ago_tooltip.vue';
+
+ export default {
+ components: {
+ TimeagoTooltiop,
+ },
+ props: {
+ // @build.artifacts_expired?
+ haveArtifactsExpired: {
+ type: Boolean,
+ required: true,
+ },
+ // @build.has_expiring_artifacts?
+ willArtifactsExpire: {
+ type: Boolean,
+ required: true,
+ },
+ expireAt: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ keepArtifactsPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ downloadArtifactsPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ browseArtifactsPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ };
+</script>
+<template>
+ <div class="block">
+ <div class="title">
+ {{ s__('Job|Job artifacts') }}
+ </div>
+
+ <p
+ v-if="haveArtifactsExpired"
+ class="js-artifacts-removed build-detail-row"
+ >
+ {{ s__('Job|The artifacts were removed') }}
+ </p>
+ <p
+ v-else-if="willArtifactsExpire"
+ class="js-artifacts-will-be-removed build-detail-row"
+ >
+ {{ s__('Job|The artifacts will be removed') }}
+ </p>
+
+ <timeago-tooltiop
+ v-if="expireAt"
+ :time="expireAt"
+ />
+
+ <div
+ class="btn-group d-flex"
+ role="group"
+ >
+ <a
+ v-if="keepArtifactsPath"
+ :href="keepArtifactsPath"
+ class="js-keep-artifacts btn btn-sm btn-default"
+ data-method="post"
+ >
+ {{ s__('Job|Keep') }}
+ </a>
+
+ <a
+ v-if="downloadArtifactsPath"
+ :href="downloadArtifactsPath"
+ class="js-download-artifacts btn btn-sm btn-default"
+ download
+ rel="nofollow"
+ >
+ {{ s__('Job|Download') }}
+ </a>
+
+ <a
+ v-if="browseArtifactsPath"
+ :href="browseArtifactsPath"
+ class="js-browse-artifacts btn btn-sm btn-default"
+ >
+ {{ s__('Job|Browse') }}
+ </a>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index 056d4b7207a..e8e707cf90c 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -85,7 +85,7 @@ strong {
}
a {
- color: $gl-link-color;
+ color: $blue-600;
}
hr {
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index ea4798fcefd..0dc7aa4ef68 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -434,7 +434,7 @@
&:hover,
&:active,
&:focus {
- color: $gl-link-color;
+ color: $blue-600;
text-decoration: none;
}
}
@@ -445,7 +445,7 @@
&:hover,
&:active,
&:focus {
- color: $gl-link-color;
+ color: $blue-600;
text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index af17210f341..268e68dbb15 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -114,7 +114,7 @@ hr {
.item-title { font-weight: $gl-font-weight-bold; }
.author-link {
- color: $gl-link-color;
+ color: $blue-600;
}
.back-link {
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 00eac1688f2..54882633fea 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -286,19 +286,19 @@ span.idiff {
.new-file {
a {
- color: $gl-text-green;
+ color: $green-600;
}
}
.renamed-file {
a {
- color: $gl-text-orange;
+ color: $orange-600;
}
}
.deleted-file {
a {
- color: $gl-text-red;
+ color: $red-500;
}
}
diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss
index e4bcb92876d..7a4c3914fb0 100644
--- a/app/assets/stylesheets/framework/flash.scss
+++ b/app/assets/stylesheets/framework/flash.scss
@@ -16,10 +16,10 @@
color: $gl-text-color;
a {
- color: $gl-link-color;
+ color: $blue-600;
&:hover {
- color: $gl-link-hover-color;
+ color: $blue-800;
text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss
index 437fcff5c62..a70eece8f68 100644
--- a/app/assets/stylesheets/framework/forms.scss
+++ b/app/assets/stylesheets/framework/forms.scss
@@ -170,7 +170,7 @@ label {
}
.form-control::-webkit-input-placeholder {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
}
.input-group {
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 7290a174668..d8391b59a8c 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -179,7 +179,7 @@
&:hover,
&:focus {
svg {
- fill: $gl-link-color;
+ fill: $blue-600;
}
}
}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 473ca408c04..eccc814b747 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -180,7 +180,7 @@
}
a > code {
- color: $gl-link-color;
+ color: $blue-600;
}
dd {
@@ -423,25 +423,25 @@ h4 {
input,
textarea {
&::-webkit-input-placeholder {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
}
// support firefox 19+ vendor prefix
&::-moz-placeholder {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
opacity: 1; // FF defaults to 0.54
}
// scss-lint:disable PseudoElement
// support Edge vendor prefix
&::-ms-input-placeholder {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
}
// scss-lint:disable PseudoElement
// support IE vendor prefix
&:-ms-input-placeholder {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
}
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index d2ea314f176..866cb88ba5b 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -195,19 +195,10 @@ $gl-text-color-quaternary: #d6d6d6;
$gl-text-color-inverted: rgba(255, 255, 255, 1);
$gl-text-color-secondary-inverted: rgba(255, 255, 255, 0.85);
$gl-text-color-disabled: #919191;
-$gl-text-green: $green-600;
-$gl-text-green-hover: $green-700;
-$gl-text-red: $red-500;
-$gl-text-orange: $orange-600;
-$gl-link-color: $blue-600;
-$gl-link-hover-color: $blue-800;
$gl-grayish-blue: #7f8fa4;
-$gl-gray: $gl-text-color;
$gl-gray-dark: #313236;
$gl-gray-light: #5c5c5c;
$gl-header-color: #4c4e54;
-$gl-header-nav-hover-color: #434343;
-$placeholder-text-color: $gl-text-color-tertiary;
/*
* Lists
@@ -226,7 +217,7 @@ $list-warning-row-color: $orange-700;
/*
* Markdown
*/
-$md-link-color: $gl-link-color;
+$md-link-color: $blue-600;
$md-area-border: #ddd;
/*
@@ -583,8 +574,8 @@ $commit-message-text-area-bg: rgba(0, 0, 0, 0);
$common-gray: $gl-text-color;
$common-gray-light: #bbb;
$common-gray-dark: #444;
-$common-red: $gl-text-red;
-$common-green: $gl-text-green;
+$common-red: $red-500;
+$common-green: $green-600;
/*
* Editor
diff --git a/app/assets/stylesheets/framework/zen.scss b/app/assets/stylesheets/framework/zen.scss
index dbd3144b9b4..f2d296fb875 100644
--- a/app/assets/stylesheets/framework/zen.scss
+++ b/app/assets/stylesheets/framework/zen.scss
@@ -44,7 +44,7 @@
color: $gl-text-color-secondary;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index 2b8163b8c68..af91497d0ea 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -1158,7 +1158,7 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding;
}
a {
- color: $gl-link-color;
+ color: $blue-600;
}
}
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index a68b47b1d02..91f470ca709 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -225,7 +225,7 @@
outline: 0;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
}
}
diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss
index e8158cd7f6b..1696d18584d 100644
--- a/app/assets/stylesheets/pages/builds.scss
+++ b/app/assets/stylesheets/pages/builds.scss
@@ -221,7 +221,7 @@
color: $gl-text-color;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index bce83bf0dd0..10764e0f3df 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -279,7 +279,7 @@
}
&.autodevops-link {
- color: $gl-link-color;
+ color: $blue-600;
}
}
@@ -321,7 +321,7 @@
}
.commit-sha {
- color: $gl-link-color;
+ color: $blue-600;
}
.commit-row-message {
diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss
index e2c0a7a6225..bba9f38d3dd 100644
--- a/app/assets/stylesheets/pages/cycle_analytics.scss
+++ b/app/assets/stylesheets/pages/cycle_analytics.scss
@@ -360,7 +360,7 @@
}
.commit-sha {
- color: $gl-link-color;
+ color: $blue-600;
line-height: 1.3;
vertical-align: top;
font-weight: $gl-font-weight-normal;
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 591e21243ed..47778110bae 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -511,13 +511,13 @@
padding: 0;
background-color: transparent;
border: 0;
- color: $gl-link-color;
+ color: $blue-600;
font-weight: $gl-font-weight-bold;
&:hover,
&:focus {
outline: none;
- color: $gl-link-hover-color;
+ color: $blue-800;
}
.caret-icon {
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 8a074017344..179c0964567 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -479,10 +479,10 @@
.deploy-info-text-link {
font-family: $monospace-font;
- fill: $gl-link-color;
+ fill: $blue-600;
&:hover {
- fill: $gl-link-hover-color;
+ fill: $blue-800;
}
}
diff --git a/app/assets/stylesheets/pages/graph.scss b/app/assets/stylesheets/pages/graph.scss
index 49d8a5d959b..22fce893fd7 100644
--- a/app/assets/stylesheets/pages/graph.scss
+++ b/app/assets/stylesheets/pages/graph.scss
@@ -24,11 +24,11 @@
}
.graph-additions {
- color: $gl-text-green;
+ color: $green-600;
}
.graph-deletions {
- color: $gl-text-red;
+ color: $red-500;
}
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 8e78d9f65eb..d16a63d009a 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -141,7 +141,7 @@
color: inherit;
&:hover {
- color: $gl-link-hover-color;
+ color: $blue-800;
.avatar {
border-color: rgba($avatar-border, .2);
@@ -241,7 +241,7 @@
&:hover {
text-decoration: underline;
- color: $gl-link-hover-color;
+ color: $blue-800;
}
}
}
@@ -329,7 +329,7 @@
}
.btn-secondary-hover-link:hover {
- color: $gl-link-color;
+ color: $blue-600;
}
.sidebar-collapsed-icon {
@@ -448,8 +448,8 @@
}
.todo-undone {
- color: $gl-link-color;
- fill: $gl-link-color;
+ color: $blue-600;
+ fill: $blue-600;
}
.author {
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 212e5979273..0f95fb911e1 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -157,7 +157,7 @@ ul.related-merge-requests > li {
.issuable-email-modal-btn {
padding: 0;
- color: $gl-link-color;
+ color: $blue-600;
background-color: transparent;
border: 0;
outline: 0;
@@ -190,7 +190,7 @@ ul.related-merge-requests > li {
.create-mr-dropdown-wrap {
.ref::selection {
- color: $placeholder-text-color;
+ color: $gl-text-color-tertiary;
}
.dropdown {
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index b25dc4f419a..d32943fceec 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -114,7 +114,7 @@
}
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
&.remove-row {
color: $gl-danger;
@@ -343,10 +343,10 @@
&.remove-row {
&:hover {
- color: $gl-text-red;
+ color: $red-500;
svg {
- fill: $gl-text-red;
+ fill: $red-500;
}
}
}
diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss
index 46437ce5841..1e92582d6d9 100644
--- a/app/assets/stylesheets/pages/milestone.scss
+++ b/app/assets/stylesheets/pages/milestone.scss
@@ -30,7 +30,7 @@
.milestone-progress {
a {
- color: $gl-link-color;
+ color: $blue-600;
}
}
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 8acd64ca1a1..4f861d43f55 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -306,7 +306,7 @@
&:hover,
&:focus {
- color: $gl-link-color;
+ color: $blue-600;
outline: 0;
}
@@ -424,7 +424,7 @@
.uploading-error-icon,
.uploading-error-message {
- color: $gl-text-red;
+ color: $red-500;
}
.uploading-error-message {
@@ -443,7 +443,7 @@
.attach-new-file,
.button-attach-file,
.retry-uploading-link {
- color: $gl-link-color;
+ color: $blue-600;
padding: 0;
background: none;
border: 0;
@@ -452,5 +452,5 @@
}
.markdown-selector {
- color: $gl-link-color;
+ color: $blue-600;
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index c369d89d63c..8d28daac750 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -210,7 +210,7 @@ ul.notes {
}
a {
- color: $gl-link-color;
+ color: $blue-600;
}
p {
@@ -253,14 +253,14 @@ ul.notes {
overflow: hidden;
.system-note-commit-list-toggler {
- color: $gl-link-color;
+ color: $blue-600;
padding: 10px 0 0;
cursor: pointer;
position: relative;
z-index: 2;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
text-decoration: underline;
}
}
@@ -390,7 +390,7 @@ ul.notes {
color: inherit;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
}
&:focus,
@@ -451,7 +451,7 @@ ul.notes {
.discussion-headline-light {
a {
- color: $gl-link-color;
+ color: $blue-600;
}
}
@@ -560,12 +560,12 @@ ul.notes {
&:hover,
&.is-active {
.danger-highlight {
- color: $gl-text-red;
+ color: $red-500;
}
.link-highlight {
- color: $gl-link-color;
- fill: $gl-link-color;
+ color: $blue-600;
+ fill: $blue-600;
}
.award-control-icon-neutral {
@@ -597,13 +597,13 @@ ul.notes {
transition: color 0.1s linear;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
}
&:focus {
text-decoration: underline;
outline: none;
- color: $gl-link-color;
+ color: $blue-600;
}
.fa {
@@ -673,7 +673,7 @@ ul.notes {
}
a {
- color: $gl-link-color;
+ color: $blue-600;
}
}
@@ -759,16 +759,16 @@ ul.notes {
&:not(.is-disabled) {
&:hover,
&:focus {
- color: $gl-text-green;
+ color: $green-600;
}
}
&.is-active {
- color: $gl-text-green;
+ color: $green-600;
&:hover,
&:focus {
- color: $gl-text-green-hover;
+ color: $green-700;
}
}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index b68c89c25d8..ad057ed3c83 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -175,7 +175,7 @@
}
.commit-sha {
- color: $gl-link-color;
+ color: $blue-600;
}
.badge {
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 6d9f415e869..fffb440027c 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -388,7 +388,7 @@
line-height: $gl-btn-line-height;
&:hover {
- color: $gl-link-color;
+ color: $blue-600;
}
}
}
@@ -961,7 +961,7 @@ pre.light-well {
margin-left: 5px;
&.is-done {
- color: $gl-text-green;
+ color: $green-600;
}
}
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index c9405004c38..5b3a468cd1c 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -259,6 +259,6 @@ input[type='checkbox']:hover {
&:hover,
&:focus {
- color: $gl-link-color;
+ color: $blue-600;
}
}
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index 41084ec686f..a8a10c98d69 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -62,6 +62,8 @@ module IconsHelper
names = "key"
when "two-factor"
names = "key"
+ when "google_oauth2"
+ names = "google"
end
options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index d7c5f29be96..17b7ee4f07e 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -33,7 +33,7 @@ module Ci
where(file_type: types)
end
- delegate :exists?, :open, to: :file
+ delegate :filename, :exists?, :open, to: :file
enum file_type: {
archive: 1,
diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml
index fdcd126e7a3..a8d4d4af93a 100644
--- a/app/views/search/results/_blob.html.haml
+++ b/app/views/search/results/_blob.html.haml
@@ -1,4 +1,6 @@
- project = find_project_for_result_blob(blob)
+- return unless project
+
- file_name, blob = parse_search_result(blob)
- blob_link = project_blob_path(project, tree_join(blob.ref, file_name))
diff --git a/app/views/shared/runners/_form.html.haml b/app/views/shared/runners/_form.html.haml
index 0337680d79b..fa93307be31 100644
--- a/app/views/shared/runners/_form.html.haml
+++ b/app/views/shared/runners/_form.html.haml
@@ -1,56 +1,56 @@
= form_for runner, url: runner_form_url do |f|
= form_errors(runner)
.form-group.row
- = label :active, "Active", class: 'col-form-label col-sm-2'
+ = label :active, _("Active"), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :active, { class: 'form-check-input' }
- %span.light Paused Runners don't accept new jobs
+ %label.light{ for: :runner_active }= _("Paused Runners don't accept new jobs")
.form-group.row
- = label :protected, "Protected", class: 'col-form-label col-sm-2'
+ = label :protected, _("Protected"), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :access_level, { class: 'form-check-input' }, 'ref_protected', 'not_protected'
- %span.light This runner will only run on pipelines triggered on protected branches
+ %label.light{ for: :runner_access_level }= _('This runner will only run on pipelines triggered on protected branches')
.form-group.row
- = label :run_untagged, 'Run untagged jobs', class: 'col-form-label col-sm-2'
+ = label :run_untagged, _('Run untagged jobs'), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :run_untagged, { class: 'form-check-input' }
- %span.light Indicates whether this runner can pick jobs without tags
+ %label.light{ for: :runner_run_untagged }= _('Indicates whether this runner can pick jobs without tags')
- unless runner.group_type?
.form-group.row
= label :locked, _('Lock to current projects'), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :locked, { class: 'form-check-input' }
- %span.light= _('When a runner is locked, it cannot be assigned to other projects')
+ %label.light{ for: :runner_locked }= _('When a runner is locked, it cannot be assigned to other projects')
.form-group.row
= label_tag :token, class: 'col-form-label col-sm-2' do
- Token
+ = _('Token')
.col-sm-10
= f.text_field :token, class: 'form-control', readonly: true
.form-group.row
= label_tag :ip_address, class: 'col-form-label col-sm-2' do
- IP Address
+ = _('IP Address')
.col-sm-10
= f.text_field :ip_address, class: 'form-control', readonly: true
.form-group.row
= label_tag :description, class: 'col-form-label col-sm-2' do
- Description
+ = _('Description')
.col-sm-10
= f.text_field :description, class: 'form-control'
.form-group.row
= label_tag :maximum_timeout_human_readable, class: 'col-form-label col-sm-2' do
- Maximum job timeout
+ = _('Maximum job timeout')
.col-sm-10
= f.text_field :maximum_timeout_human_readable, class: 'form-control'
- .form-text.text-muted This timeout will take precedence when lower than Project-defined timeout
+ .form-text.text-muted= _('This timeout will take precedence when lower than Project-defined timeout')
.form-group.row
= label_tag :tag_list, class: 'col-form-label col-sm-2' do
- Tags
+ = _('Tags')
.col-sm-10
= f.text_field :tag_list, value: runner.tag_list.sort.join(', '), class: 'form-control'
- .form-text.text-muted You can setup jobs to only use Runners with specific tags. Separate tags with commas.
+ .form-text.text-muted= _('You can setup jobs to only use Runners with specific tags. Separate tags with commas.')
.form-actions
- = f.submit 'Save changes', class: 'btn btn-save'
+ = f.submit _('Save changes'), class: 'btn btn-success'
diff --git a/bin/secpick b/bin/secpick
index 5029fe57cfe..5e30c8e72c5 100755
--- a/bin/secpick
+++ b/bin/secpick
@@ -35,7 +35,9 @@ parser.parse!
abort("Missing options. Use #{$0} --help to see the list of options available".red) if options.values.include?(nil)
abort("Wrong version format #{options[:version].bold}".red) unless options[:version] =~ /\A\d*\-\d*\Z/
-branch = [BRANCH_PREFIX, options[:branch], options[:version]].join('-').freeze
+branch = "#{options[:branch]}-#{options[:version]}"
+branch.prepend("#{BRANCH_PREFIX}-") unless branch.start_with?("#{BRANCH_PREFIX}-")
+branch = branch.freeze
stable_branch = "#{BRANCH_PREFIX}-#{options[:version]}".freeze
command = "git fetch #{REMOTE} #{stable_branch} && git checkout #{stable_branch} && git pull #{REMOTE} #{stable_branch} && git checkout -B #{branch} && git cherry-pick #{options[:sha]} && git push #{REMOTE} #{branch}"
diff --git a/changelogs/unreleased/49905-fix-checkboxes-runners.yml b/changelogs/unreleased/49905-fix-checkboxes-runners.yml
new file mode 100644
index 00000000000..af40e5348b8
--- /dev/null
+++ b/changelogs/unreleased/49905-fix-checkboxes-runners.yml
@@ -0,0 +1,5 @@
+---
+title: Fix checkboxes on runner admin settings - The labels are now clickable
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/50101-aritfacts-block.yml b/changelogs/unreleased/50101-aritfacts-block.yml
new file mode 100644
index 00000000000..435e9d9d486
--- /dev/null
+++ b/changelogs/unreleased/50101-aritfacts-block.yml
@@ -0,0 +1,5 @@
+---
+title: Creates Vue component for artifacts block on job page
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/50180-fa-icon-google-audit.yml b/changelogs/unreleased/50180-fa-icon-google-audit.yml
new file mode 100644
index 00000000000..fb1771a7570
--- /dev/null
+++ b/changelogs/unreleased/50180-fa-icon-google-audit.yml
@@ -0,0 +1,5 @@
+---
+title: Show google icon in audit log
+merge_request: 21207
+author: Jan Beckmann
+type: fixed
diff --git a/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml b/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml
new file mode 100644
index 00000000000..eb20e34c466
--- /dev/null
+++ b/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken JavaScript in IE11
+merge_request: 21214
+author:
+type: fixed
diff --git a/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml b/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml
new file mode 100644
index 00000000000..a1625193189
--- /dev/null
+++ b/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml
@@ -0,0 +1,5 @@
+---
+title: 'Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28'
+merge_request: 21191
+author: sgerrand
+type: fixed
diff --git a/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml b/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml
new file mode 100644
index 00000000000..1453d39934b
--- /dev/null
+++ b/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml
@@ -0,0 +1,5 @@
+---
+title: Expose all artifacts sizes in jobs api
+merge_request: 20821
+author: Peter Marko
+type: added
diff --git a/changelogs/unreleased/mk-bump-rainbow-gem.yml b/changelogs/unreleased/mk-bump-rainbow-gem.yml
new file mode 100644
index 00000000000..31c003fb4d9
--- /dev/null
+++ b/changelogs/unreleased/mk-bump-rainbow-gem.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bin/secpick error and security branch prefixing
+merge_request: 21210
+author:
+type: fixed
diff --git a/changelogs/unreleased/tz-mr-incremental-rendering.yml b/changelogs/unreleased/tz-mr-incremental-rendering.yml
new file mode 100644
index 00000000000..a35fa200363
--- /dev/null
+++ b/changelogs/unreleased/tz-mr-incremental-rendering.yml
@@ -0,0 +1,4 @@
+title: Incremental rendering with Vue on merge request page
+merge_request: 21063
+author:
+type: performance
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index 9a950097675..4bf65a8fafd 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -33,7 +33,6 @@ Example of response
},
"coverage": null,
"created_at": "2015-12-24T15:51:21.727Z",
- "artifacts_file": null,
"finished_at": "2015-12-24T17:54:24.921Z",
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
"id": 6,
@@ -45,6 +44,7 @@ Example of response
"status": "pending"
},
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": "2015-12-24T17:54:24.729Z",
@@ -82,6 +82,12 @@ Example of response
"filename": "artifacts.zip",
"size": 1000
},
+ "artifacts": [
+ {"file_type": "archive", "size": 1000, "filename": "artifacts.zip", "file_format": "zip"},
+ {"file_type": "metadata", "size": 186, "filename": "metadata.gz", "file_format": "gzip"},
+ {"file_type": "trace", "size": 1500, "filename": "job.log", "file_format": "raw"},
+ {"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
+ ],
"finished_at": "2015-12-24T17:54:27.895Z",
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
"id": 7,
@@ -93,6 +99,7 @@ Example of response
"status": "pending"
},
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": "2015-12-24T17:54:27.722Z",
@@ -151,7 +158,6 @@ Example of response
},
"coverage": null,
"created_at": "2015-12-24T15:51:21.727Z",
- "artifacts_file": null,
"finished_at": "2015-12-24T17:54:24.921Z",
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
"id": 6,
@@ -163,6 +169,7 @@ Example of response
"status": "pending"
},
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": "2015-12-24T17:54:24.729Z",
@@ -200,6 +207,12 @@ Example of response
"filename": "artifacts.zip",
"size": 1000
},
+ "artifacts": [
+ {"file_type": "archive", "size": 1000, "filename": "artifacts.zip", "file_format": "zip"},
+ {"file_type": "metadata", "size": 186, "filename": "metadata.gz", "file_format": "gzip"},
+ {"file_type": "trace", "size": 1500, "filename": "job.log", "file_format": "raw"},
+ {"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
+ ],
"finished_at": "2015-12-24T17:54:27.895Z",
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
"id": 7,
@@ -211,6 +224,7 @@ Example of response
"status": "pending"
},
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": "2015-12-24T17:54:27.722Z",
@@ -267,7 +281,6 @@ Example of response
},
"coverage": null,
"created_at": "2015-12-24T15:51:21.880Z",
- "artifacts_file": null,
"finished_at": "2015-12-24T17:54:31.198Z",
"artifacts_expire_at": "2016-01-23T17:54:31.198Z",
"id": 8,
@@ -279,6 +292,7 @@ Example of response
"status": "pending"
},
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": "2015-12-24T17:54:30.733Z",
@@ -458,11 +472,11 @@ Example of response
},
"coverage": null,
"created_at": "2016-01-11T10:13:33.506Z",
- "artifacts_file": null,
"finished_at": "2016-01-11T10:14:09.526Z",
"id": 42,
"name": "rubocop",
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": null,
@@ -505,11 +519,11 @@ Example of response
},
"coverage": null,
"created_at": "2016-01-11T10:13:33.506Z",
- "artifacts_file": null,
"finished_at": null,
"id": 42,
"name": "rubocop",
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": null,
@@ -559,6 +573,7 @@ Example of response
"id": 42,
"name": "rubocop",
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"created_at": "2016-01-11T10:13:33.506Z",
@@ -610,6 +625,7 @@ Example response:
"id": 42,
"name": "rubocop",
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"created_at": "2016-01-11T10:13:33.506Z",
@@ -654,11 +670,11 @@ Example of response
},
"coverage": null,
"created_at": "2016-01-11T10:13:33.506Z",
- "artifacts_file": null,
"finished_at": null,
"id": 42,
"name": "rubocop",
"ref": "master",
+ "artifacts": [],
"runner": null,
"stage": "test",
"started_at": null,
diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md
index dd424470b67..7b8db6cfa8f 100644
--- a/doc/api/system_hooks.md
+++ b/doc/api/system_hooks.md
@@ -34,6 +34,7 @@ Example response:
"push_events":true,
"tag_push_events":false,
"merge_requests_events": true,
+ "repository_update_events": true,
"enable_ssl_verification":true
}
]
@@ -56,6 +57,7 @@ POST /hooks
| `push_events` | boolean | no | When true, the hook will fire on push events |
| `tag_push_events` | boolean | no | When true, the hook will fire on new tags being pushed |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
+| `repository_update_events` | boolean | no | Trigger hook on repository update events |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook |
Example request:
@@ -75,6 +77,7 @@ Example response:
"push_events":true,
"tag_push_events":false,
"merge_requests_events": true,
+ "repository_update_events": true,
"enable_ssl_verification":true
}
]
@@ -127,4 +130,4 @@ Example request:
```bash
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/hooks/2
-```
+``` \ No newline at end of file
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 453ebb9c669..458ee320099 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -1080,6 +1080,10 @@ module API
expose :filename, :size
end
+ class JobArtifact < Grape::Entity
+ expose :file_type, :size, :filename, :file_format
+ end
+
class JobBasic < Grape::Entity
expose :id, :status, :stage, :name, :ref, :tag, :coverage
expose :created_at, :started_at, :finished_at
@@ -1094,7 +1098,9 @@ module API
end
class Job < JobBasic
+ # artifacts_file is included in job_artifacts, but kept for backward compatibility (remove in api/v5)
expose :artifacts_file, using: JobArtifactFile, if: -> (job, opts) { job.artifacts? }
+ expose :job_artifacts, as: :artifacts, using: JobArtifact
expose :runner, with: Runner
expose :artifacts_expire_at
end
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index 10c6e565f09..fc8c52085ab 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -38,7 +38,7 @@ module API
builds = user_project.builds.order('id DESC')
builds = filter_builds(builds, params[:scope])
- builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project)
+ builds = builds.preload(:user, :job_artifacts_archive, :job_artifacts, :runner, pipeline: :project)
present paginate(builds), with: Entities::Job
end
@@ -54,7 +54,7 @@ module API
pipeline = user_project.pipelines.find(params[:pipeline_id])
builds = pipeline.builds
builds = filter_builds(builds, params[:scope])
- builds = builds.preload(:job_artifacts_archive, project: [:namespace])
+ builds = builds.preload(:job_artifacts_archive, :job_artifacts, project: [:namespace])
present paginate(builds), with: Entities::Job
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8f3914c5f69..e5e818f57b9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2971,6 +2971,9 @@ msgstr ""
msgid "IDE|Review"
msgstr ""
+msgid "IP Address"
+msgstr ""
+
msgid "Identifier"
msgstr ""
@@ -3061,6 +3064,9 @@ msgstr ""
msgid "Incompatible Project"
msgstr ""
+msgid "Indicates whether this runner can pick jobs without tags"
+msgstr ""
+
msgid "Inline"
msgstr ""
@@ -3133,12 +3139,30 @@ msgstr ""
msgid "Jobs"
msgstr ""
+msgid "Job|Browse"
+msgstr ""
+
+msgid "Job|Download"
+msgstr ""
+
+msgid "Job|Job artifacts"
+msgstr ""
+
msgid "Job|Job has been erased"
msgstr ""
msgid "Job|Job has been erased by"
msgstr ""
+msgid "Job|Keep"
+msgstr ""
+
+msgid "Job|The artifacts were removed"
+msgstr ""
+
+msgid "Job|The artifacts will be removed"
+msgstr ""
+
msgid "Jul"
msgstr ""
@@ -3390,6 +3414,9 @@ msgstr ""
msgid "Maximum git storage failures"
msgstr ""
+msgid "Maximum job timeout"
+msgstr ""
+
msgid "May"
msgstr ""
@@ -3932,6 +3959,9 @@ msgstr ""
msgid "Pause"
msgstr ""
+msgid "Paused Runners don't accept new jobs"
+msgstr ""
+
msgid "Pending"
msgstr ""
@@ -4424,6 +4454,9 @@ msgstr ""
msgid "Promote to group label"
msgstr ""
+msgid "Protected"
+msgstr ""
+
msgid "Protip:"
msgstr ""
@@ -4639,6 +4672,9 @@ msgstr ""
msgid "Revoke"
msgstr ""
+msgid "Run untagged jobs"
+msgstr ""
+
msgid "Runner token"
msgstr ""
@@ -5480,9 +5516,15 @@ msgstr ""
msgid "This repository"
msgstr ""
+msgid "This runner will only run on pipelines triggered on protected branches"
+msgstr ""
+
msgid "This source diff could not be displayed because it is too large."
msgstr ""
+msgid "This timeout will take precedence when lower than Project-defined timeout"
+msgstr ""
+
msgid "This user has no identities"
msgstr ""
@@ -5724,6 +5766,9 @@ msgstr ""
msgid "ToggleButton|Toggle Status: ON"
msgstr ""
+msgid "Token"
+msgstr ""
+
msgid "Too many changes to show."
msgstr ""
@@ -6150,6 +6195,9 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
+msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgstr ""
+
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
diff --git a/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb b/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
index c1608be402a..fd4175d5227 100644
--- a/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
+++ b/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
@@ -28,7 +28,7 @@ describe 'Merge request > User sees MR with deleted source branch', :js do
click_on 'Changes'
wait_for_requests
- expect(page).to have_selector('.diffs.tab-pane .nothing-here-block')
+ expect(page).to have_selector('.diffs.tab-pane .file-holder')
expect(page).to have_content('Source branch does not exist.')
end
end
diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb
index 82f588d1a08..4b40d523287 100644
--- a/spec/helpers/icons_helper_spec.rb
+++ b/spec/helpers/icons_helper_spec.rb
@@ -80,6 +80,26 @@ describe IconsHelper do
end
end
+ describe 'audit icon' do
+ it 'returns right icon name for standard auth' do
+ icon_name = 'standard'
+ expect(audit_icon(icon_name).to_s)
+ .to eq '<i class="fa fa-key"></i>'
+ end
+
+ it 'returns right icon name for two-factor auth' do
+ icon_name = 'two-factor'
+ expect(audit_icon(icon_name).to_s)
+ .to eq '<i class="fa fa-key"></i>'
+ end
+
+ it 'returns right icon name for google_oauth2 auth' do
+ icon_name = 'google_oauth2'
+ expect(audit_icon(icon_name).to_s)
+ .to eq '<i class="fa fa-google"></i>'
+ end
+ end
+
describe 'file_type_icon_class' do
it 'returns folder class' do
expect(file_type_icon_class('folder', 0, 'folder_name')).to eq 'folder'
diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js
index 7a4616ec8eb..44a38f7ca82 100644
--- a/spec/javascripts/diffs/components/diff_file_spec.js
+++ b/spec/javascripts/diffs/components/diff_file_spec.js
@@ -22,11 +22,18 @@ describe('DiffFile', () => {
expect(el.id).toEqual(fileHash);
expect(el.classList.contains('diff-file')).toEqual(true);
+
expect(el.querySelectorAll('.diff-content.hidden').length).toEqual(0);
expect(el.querySelector('.js-file-title')).toBeDefined();
expect(el.querySelector('.file-title-name').innerText.indexOf(filePath) > -1).toEqual(true);
expect(el.querySelector('.js-syntax-highlight')).toBeDefined();
- expect(el.querySelectorAll('.line_content').length > 5).toEqual(true);
+
+ expect(vm.file.renderIt).toEqual(false);
+ vm.file.renderIt = true;
+
+ vm.$nextTick(() => {
+ expect(el.querySelectorAll('.line_content').length > 5).toEqual(true);
+ });
});
describe('collapsed', () => {
@@ -34,6 +41,7 @@ describe('DiffFile', () => {
expect(vm.$el.querySelectorAll('.diff-content').length).toEqual(1);
expect(vm.file.collapsed).toEqual(false);
vm.file.collapsed = true;
+ vm.file.renderIt = true;
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.diff-content').length).toEqual(0);
diff --git a/spec/javascripts/diffs/mock_data/diff_file.js b/spec/javascripts/diffs/mock_data/diff_file.js
index d3bf9525924..cce36ecc91f 100644
--- a/spec/javascripts/diffs/mock_data/diff_file.js
+++ b/spec/javascripts/diffs/mock_data/diff_file.js
@@ -39,6 +39,7 @@ export default {
viewPath: '/gitlab-org/gitlab-test/blob/spooky-stuff/CHANGELOG',
replacedViewPath: null,
collapsed: false,
+ renderIt: false,
tooLarge: false,
contextLinesPath:
'/gitlab-org/gitlab-test/blob/c48ee0d1bf3b30453f5b32250ce03134beaa6d13/CHANGELOG/diff',
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 1af49f4985c..8f89984c6e5 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -1,6 +1,7 @@
import mutations from '~/diffs/store/mutations';
import * as types from '~/diffs/store/mutation_types';
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
+import diffFileMockData from '../mock_data/diff_file';
describe('DiffsStoreMutations', () => {
describe('SET_BASE_CONFIG', () => {
@@ -24,6 +25,23 @@ describe('DiffsStoreMutations', () => {
});
});
+ describe('SET_DIFF_DATA', () => {
+ it('should set diff data type properly', () => {
+ const state = {};
+ const diffMock = {
+ diff_files: [diffFileMockData],
+ };
+
+ mutations[types.SET_DIFF_DATA](state, diffMock);
+
+ const firstLine = state.diffFiles[0].parallelDiffLines[0];
+
+ expect(firstLine.right.text).toBeUndefined();
+ expect(state.diffFiles[0].renderIt).toEqual(true);
+ expect(state.diffFiles[0].collapsed).toEqual(false);
+ });
+ });
+
describe('SET_DIFF_VIEW_TYPE', () => {
it('should set diff view type properly', () => {
const state = {};
diff --git a/spec/javascripts/jobs/artifacts_block_spec.js b/spec/javascripts/jobs/artifacts_block_spec.js
new file mode 100644
index 00000000000..c544c6f3e89
--- /dev/null
+++ b/spec/javascripts/jobs/artifacts_block_spec.js
@@ -0,0 +1,120 @@
+import Vue from 'vue';
+import { getTimeago } from '~/lib/utils/datetime_utility';
+import component from '~/jobs/components/artifacts_block.vue';
+import mountComponent from '../helpers/vue_mount_component_helper';
+
+describe('Artifacts block', () => {
+ const Component = Vue.extend(component);
+ let vm;
+
+ const expireAt = '2018-08-14T09:38:49.157Z';
+ const timeago = getTimeago();
+ const formatedDate = timeago.format(expireAt);
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with expired artifacts', () => {
+ it('renders expired artifact date and info', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ });
+
+ expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull();
+ expect(vm.$el.textContent).toContain(formatedDate);
+ });
+ });
+
+ describe('with artifacts that will expire', () => {
+ it('renders will expire artifact date and info', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: false,
+ willArtifactsExpire: true,
+ expireAt,
+ });
+
+ expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull();
+ expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull();
+ expect(vm.$el.textContent).toContain(formatedDate);
+ });
+ });
+
+ describe('when the user can keep the artifacts', () => {
+ it('renders the keep button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ keepArtifactsPath: '/keep',
+ });
+
+ expect(vm.$el.querySelector('.js-keep-artifacts')).not.toBeNull();
+ });
+ });
+
+ describe('when the user can not keep the artifacts', () => {
+ it('does not render the keep button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ });
+
+ expect(vm.$el.querySelector('.js-keep-artifacts')).toBeNull();
+ });
+ });
+
+ describe('when the user can download the artifacts', () => {
+ it('renders the download button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ downloadArtifactsPath: '/download',
+ });
+
+ expect(vm.$el.querySelector('.js-download-artifacts')).not.toBeNull();
+ });
+ });
+
+ describe('when the user can not download the artifacts', () => {
+ it('does not render the keep button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ });
+
+ expect(vm.$el.querySelector('.js-download-artifacts')).toBeNull();
+ });
+ });
+
+ describe('when the user can browse the artifacts', () => {
+ it('does not render the browse button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ browseArtifactsPath: '/browse',
+ });
+
+ expect(vm.$el.querySelector('.js-browse-artifacts')).not.toBeNull();
+ });
+ });
+
+ describe('when the user can not browse the artifacts', () => {
+ it('does not render the browse button', () => {
+ vm = mountComponent(Component, {
+ haveArtifactsExpired: true,
+ willArtifactsExpire: false,
+ expireAt,
+ });
+
+ expect(vm.$el.querySelector('.js-browse-artifacts')).toBeNull();
+ });
+ });
+});
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 5814d834572..6adbbb40489 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -3,6 +3,32 @@ require 'spec_helper'
describe API::Jobs do
include HttpIOHelpers
+ shared_examples 'a job with artifacts and trace' do |result_is_array: true|
+ context 'with artifacts and trace' do
+ let!(:second_job) { create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline) }
+
+ it 'returns artifacts and trace data', :skip_before_request do
+ get api(api_endpoint, api_user)
+ json_job = result_is_array ? json_response.select { |job| job['id'] == second_job.id }.first : json_response
+
+ expect(json_job['artifacts_file']).not_to be_nil
+ expect(json_job['artifacts_file']).not_to be_empty
+ expect(json_job['artifacts_file']['filename']).to eq(second_job.artifacts_file.filename)
+ expect(json_job['artifacts_file']['size']).to eq(second_job.artifacts_file.size)
+ expect(json_job['artifacts']).not_to be_nil
+ expect(json_job['artifacts']).to be_an Array
+ expect(json_job['artifacts'].size).to eq(second_job.job_artifacts.length)
+ json_job['artifacts'].each do |artifact|
+ expect(artifact).not_to be_nil
+ file_type = Ci::JobArtifact.file_types[artifact['file_type']]
+ expect(artifact['size']).to eq(second_job.job_artifacts.where(file_type: file_type).first.size)
+ expect(artifact['filename']).to eq(second_job.job_artifacts.where(file_type: file_type).first.filename)
+ expect(artifact['file_format']).to eq(second_job.job_artifacts.where(file_type: file_type).first.file_format)
+ end
+ end
+ end
+ end
+
set(:project) do
create(:project, :repository, public_builds: false)
end
@@ -49,6 +75,20 @@ describe API::Jobs do
expect(Time.parse(json_response.first['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at)
end
+ context 'without artifacts and trace' do
+ it 'returns no artifacts nor trace data' do
+ json_job = json_response.first
+
+ expect(json_job['artifacts_file']).to be_nil
+ expect(json_job['artifacts']).to be_an Array
+ expect(json_job['artifacts']).to be_empty
+ end
+ end
+
+ it_behaves_like 'a job with artifacts and trace' do
+ let(:api_endpoint) { "/projects/#{project.id}/jobs" }
+ end
+
it 'returns pipeline data' do
json_job = json_response.first
@@ -60,7 +100,7 @@ describe API::Jobs do
end
it 'avoids N+1 queries', :skip_before_request do
- first_build = create(:ci_build, :artifacts, pipeline: pipeline)
+ first_build = create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline)
first_build.runner = create(:ci_runner)
first_build.user = create(:user)
first_build.save
@@ -68,7 +108,7 @@ describe API::Jobs do
control_count = ActiveRecord::QueryRecorder.new { go }.count
second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch)
- second_build = create(:ci_build, :artifacts, pipeline: second_pipeline)
+ second_build = create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: second_pipeline)
second_build.runner = create(:ci_runner)
second_build.user = create(:user)
second_build.save
@@ -117,9 +157,11 @@ describe API::Jobs do
describe 'GET /projects/:id/pipelines/:pipeline_id/jobs' do
let(:query) { Hash.new }
- before do
- job
- get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
+ before do |example|
+ unless example.metadata[:skip_before_request]
+ job
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
+ end
end
context 'authorized user' do
@@ -133,6 +175,13 @@ describe API::Jobs do
expect(json_response).not_to be_empty
expect(json_response.first['commit']['id']).to eq project.commit.id
expect(Time.parse(json_response.first['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at)
+ expect(json_response.first['artifacts_file']).to be_nil
+ expect(json_response.first['artifacts']).to be_an Array
+ expect(json_response.first['artifacts']).to be_empty
+ end
+
+ it_behaves_like 'a job with artifacts and trace' do
+ let(:api_endpoint) { "/projects/#{project.id}/pipelines/#{pipeline.id}/jobs" }
end
it 'returns pipeline data' do
@@ -183,7 +232,7 @@ describe API::Jobs do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
end.count
- 3.times { create(:ci_build, :artifacts, pipeline: pipeline) }
+ 3.times { create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline) }
expect do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
@@ -201,8 +250,10 @@ describe API::Jobs do
end
describe 'GET /projects/:id/jobs/:job_id' do
- before do
- get api("/projects/#{project.id}/jobs/#{job.id}", api_user)
+ before do |example|
+ unless example.metadata[:skip_before_request]
+ get api("/projects/#{project.id}/jobs/#{job.id}", api_user)
+ end
end
context 'authorized user' do
@@ -219,10 +270,17 @@ describe API::Jobs do
expect(Time.parse(json_response['started_at'])).to be_like_time(job.started_at)
expect(Time.parse(json_response['finished_at'])).to be_like_time(job.finished_at)
expect(Time.parse(json_response['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at)
+ expect(json_response['artifacts_file']).to be_nil
+ expect(json_response['artifacts']).to be_an Array
+ expect(json_response['artifacts']).to be_empty
expect(json_response['duration']).to eq(job.duration)
expect(json_response['web_url']).to be_present
end
+ it_behaves_like 'a job with artifacts and trace', result_is_array: false do
+ let(:api_endpoint) { "/projects/#{project.id}/jobs/#{second_job.id}" }
+ end
+
it 'returns pipeline data' do
json_job = json_response
diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
index 39876805ffa..ffcf5648075 100644
--- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
@@ -642,9 +642,9 @@ rollout 100%:
function install_dependencies() {
apk add -U openssl curl tar gzip bash ca-certificates git
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
- wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk
- apk add glibc-2.23-r3.apk
- rm glibc-2.23-r3.apk
+ wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
+ apk add glibc-2.28-r0.apk
+ rm glibc-2.28-r0.apk
curl "https://kubernetes-helm.storage.googleapis.com/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx
mv linux-amd64/helm /usr/bin/