mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-25 12:36:27 +10:00
Merge branch 'master' into add-dates-snippets-show
Also removed fixes to btn-sm as they have appears to be already merged into master
This commit is contained in:
@@ -16,6 +16,7 @@ v 8.1.0 (unreleased)
|
||||
- Move CI charts to project graphs area
|
||||
- Fix cases where Markdown did not render links in activity feed (Stan Hu)
|
||||
- Add first and last to pagination (Zeger-Jan van de Weg)
|
||||
- Added Commit Status API
|
||||
- Show CI status on commit page
|
||||
- Show CI status on Your projects page and Starred projects page
|
||||
- Remove "Continuous Integration" page from dashboard
|
||||
@@ -46,6 +47,11 @@ v 8.1.0 (unreleased)
|
||||
- Fix bug where Emojis in Markdown would truncate remaining text (Sakata Sinji)
|
||||
- Persist filters when sorting on admin user page (Jerry Lukins)
|
||||
- Added last modified date to snippets#show (Han Loong Liauw)
|
||||
- Add spellcheck=false to certain input fields
|
||||
- Invalidate stored service password if the endpoint URL is changed
|
||||
- Project names are not fully shown if group name is too big, even on group page view
|
||||
- Apply new design for Files page
|
||||
- Add "New Page" button to Wiki Pages tab (Stan Hu)
|
||||
|
||||
v 8.0.4
|
||||
- Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
|
||||
@@ -60,6 +66,7 @@ v 8.0.3
|
||||
- Fix URL shown in Slack notifications
|
||||
- Fix bug where projects would appear to be stuck in the forked import state (Stan Hu)
|
||||
- Fix Error 500 in creating merge requests with > 1000 diffs (Stan Hu)
|
||||
- Add work_in_progress key to MR web hooks (Ben Boeckel)
|
||||
|
||||
v 8.0.2
|
||||
- Fix default avatar not rendering in network graph (Stan Hu)
|
||||
|
||||
@@ -290,7 +290,7 @@ gem 'newrelic-grape'
|
||||
|
||||
gem 'octokit', '~> 3.7.0'
|
||||
|
||||
gem "mail_room", "~> 0.5.2"
|
||||
gem "mail_room", "~> 0.6.0"
|
||||
|
||||
gem 'email_reply_parser', '~> 0.5.8'
|
||||
|
||||
|
||||
+2
-2
@@ -392,7 +392,7 @@ GEM
|
||||
systemu (~> 2.6.2)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
mail_room (0.5.2)
|
||||
mail_room (0.6.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mimemagic (0.3.0)
|
||||
@@ -854,7 +854,7 @@ DEPENDENCIES
|
||||
jquery-ui-rails (~> 4.2.1)
|
||||
kaminari (~> 0.16.3)
|
||||
letter_opener (~> 1.1.2)
|
||||
mail_room (~> 0.5.2)
|
||||
mail_room (~> 0.6.0)
|
||||
minitest (~> 5.7.0)
|
||||
mousetrap-rails (~> 1.4.6)
|
||||
mysql2 (~> 0.3.16)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# ### Example Markup
|
||||
#
|
||||
# <div id="tree-content-holder">
|
||||
# <div id="blob-content-holder">
|
||||
# <div class="file-content">
|
||||
# <div class="line-numbers">
|
||||
# <a href="#L1" id="L1" data-line-number="1">1</a>
|
||||
@@ -53,7 +53,7 @@ class @LineHighlighter
|
||||
$.scrollTo("#L#{range[0]}", offset: -150)
|
||||
|
||||
bindEvents: ->
|
||||
$('#tree-content-holder').on 'mousedown', 'a[data-line-number]', @clickHandler
|
||||
$('#blob-content-holder').on 'mousedown', 'a[data-line-number]', @clickHandler
|
||||
|
||||
# While it may seem odd to bind to the mousedown event and then throw away
|
||||
# the click event, there is a method to our madness.
|
||||
@@ -62,7 +62,7 @@ class @LineHighlighter
|
||||
# active state even when the event is cancelled, resulting in an ugly border
|
||||
# around the link and/or a persisted underline text decoration.
|
||||
|
||||
$('#tree-content-holder').on 'click', 'a[data-line-number]', (event) ->
|
||||
$('#blob-content-holder').on 'click', 'a[data-line-number]', (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
clickHandler: (event) =>
|
||||
|
||||
@@ -11,59 +11,41 @@
|
||||
*= require cal-heatmap
|
||||
*/
|
||||
|
||||
|
||||
@import "base/fonts";
|
||||
@import "base/variables";
|
||||
@import "base/mixins";
|
||||
@import "base/layout";
|
||||
|
||||
|
||||
/**
|
||||
* Customized Twitter bootstrap
|
||||
/*
|
||||
* Welcome to GitLab css!
|
||||
* If you need to add or modify UI component that is common for many pages
|
||||
* like a table or typography then make changes in the framework/ directory.
|
||||
* If you need to add unique style that should affect only one page - use pages/
|
||||
* directory.
|
||||
*/
|
||||
@import 'base/gl_variables';
|
||||
@import 'base/gl_bootstrap';
|
||||
|
||||
/**
|
||||
/*
|
||||
* GitLab UI framework
|
||||
*/
|
||||
@import "framework";
|
||||
|
||||
/*
|
||||
* NProgress load bar css
|
||||
*/
|
||||
@import 'nprogress';
|
||||
@import 'nprogress-bootstrap';
|
||||
|
||||
/**
|
||||
/*
|
||||
* Font icons
|
||||
*
|
||||
*/
|
||||
@import "font-awesome";
|
||||
|
||||
/**
|
||||
* UI themes:
|
||||
*/
|
||||
@import "themes/**/*";
|
||||
|
||||
/**
|
||||
* Generic css (forms, nav etc):
|
||||
*/
|
||||
@import "generic/**/*";
|
||||
|
||||
/**
|
||||
/*
|
||||
* Page specific styles (issues, projects etc):
|
||||
*/
|
||||
|
||||
@import "pages/**/*";
|
||||
|
||||
/**
|
||||
/*
|
||||
* Code highlight
|
||||
*/
|
||||
@import "highlight/**/*";
|
||||
|
||||
/**
|
||||
/*
|
||||
* Styles for JS behaviors.
|
||||
*/
|
||||
@import "behaviors.scss";
|
||||
|
||||
/**
|
||||
* CI specific styles:
|
||||
*/
|
||||
@import "ci/**/*";
|
||||
|
||||
@import "behaviors.scss";
|
||||
@@ -0,0 +1,33 @@
|
||||
@import "framework/fonts";
|
||||
@import "framework/variables";
|
||||
@import "framework/mixins";
|
||||
@import "framework/layout";
|
||||
@import 'framework/tw_bootstrap_variables';
|
||||
@import 'framework/tw_bootstrap';
|
||||
|
||||
@import "framework/avatar.scss";
|
||||
@import "framework/blocks.scss";
|
||||
@import "framework/buttons.scss";
|
||||
@import "framework/calendar.scss";
|
||||
@import "framework/callout.scss";
|
||||
@import "framework/common.scss";
|
||||
@import "framework/files.scss";
|
||||
@import "framework/filters.scss";
|
||||
@import "framework/flash.scss";
|
||||
@import "framework/forms.scss";
|
||||
@import "framework/gfm.scss";
|
||||
@import "framework/gitlab-theme.scss";
|
||||
@import "framework/header.scss";
|
||||
@import "framework/highlight.scss";
|
||||
@import "framework/issue_box.scss";
|
||||
@import "framework/jquery.scss";
|
||||
@import "framework/lists.scss";
|
||||
@import "framework/markdown_area.scss";
|
||||
@import "framework/mobile.scss";
|
||||
@import "framework/pagination.scss";
|
||||
@import "framework/selects.scss";
|
||||
@import "framework/sidebar.scss";
|
||||
@import "framework/tables.scss";
|
||||
@import "framework/timeline.scss";
|
||||
@import "framework/typography.scss";
|
||||
@import "framework/zen.scss";
|
||||
+6
-8
@@ -6,7 +6,7 @@
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 18px;
|
||||
padding: 11px 16px;
|
||||
padding: 11px $gl-padding;
|
||||
letter-spacing: .4px;
|
||||
|
||||
&:focus,
|
||||
@@ -22,12 +22,6 @@
|
||||
padding: 11px 24px;
|
||||
}
|
||||
|
||||
@mixin btn-sm {
|
||||
@include btn-default;
|
||||
@include border-radius(2px);
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
@mixin btn-color($light, $border-light, $normal, $border-normal, $dark, $border-dark, $color) {
|
||||
background-color: $light;
|
||||
border-color: $border-light;
|
||||
@@ -78,7 +72,11 @@
|
||||
@include btn-white;
|
||||
|
||||
&.btn-sm {
|
||||
@include btn-sm;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
&.btn-xs {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
&.btn-success,
|
||||
-4
@@ -398,7 +398,3 @@ table {
|
||||
.space-right {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.in-line {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -22,4 +22,5 @@
|
||||
|
||||
.gfm-commit, .gfm-commit_range {
|
||||
font-family: $monospace_font;
|
||||
font-size: 90%;
|
||||
}
|
||||
+5
-1
@@ -117,8 +117,12 @@ ul.content-list {
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding-top: 10px;
|
||||
padding-top: 4px;
|
||||
float: right;
|
||||
|
||||
.btn {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-141
@@ -54,147 +54,6 @@
|
||||
@include box-shadow(0 0 0 3px #f1f1f1);
|
||||
}
|
||||
|
||||
@mixin md-typography {
|
||||
color: $md-text-color;
|
||||
|
||||
a {
|
||||
color: $md-link-color;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
*:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: $monospace_font;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font-size: 11px;
|
||||
line-height: 10px;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #FCFCFC;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #CCC #CCC #BBB;
|
||||
border-image: none;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px -1px 0px #BBB inset;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 12px 0;
|
||||
padding: 0 0 10px 0;
|
||||
border-bottom: 1px solid #e7e9ed;
|
||||
color: #313236;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 12px 0;
|
||||
color: #313236;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 0.90em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 8px 21px;
|
||||
margin: 12px 0 12px;
|
||||
border-left: 3px solid #e7e9ed;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
color: #7f8fa4 !important;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
p {
|
||||
color:#5c5d5e;
|
||||
margin:6px 0 0 0;
|
||||
}
|
||||
|
||||
table {
|
||||
@extend .table;
|
||||
@extend .table-bordered;
|
||||
margin: 12px 0 12px 0;
|
||||
color: #5c5d5e;
|
||||
th {
|
||||
background: #f8fafc;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 12px 0 12px 0 !important;
|
||||
background-color: #f8fafc !important;
|
||||
font-size: 13px !important;
|
||||
color: #5b6169 !important;
|
||||
line-height: 1.6em !important;
|
||||
@include border-radius(2px);
|
||||
}
|
||||
|
||||
p > code {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
|
||||
ul {
|
||||
color: #5c5d5e;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
a[href*="/uploads/"], a[href*="storage.googleapis.com/google-code-attachments/"] {
|
||||
&:before {
|
||||
margin-right: 4px;
|
||||
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
content: "\f0c6";
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@mixin str-truncated($max_width: 82%) {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
+11
-3
@@ -23,7 +23,7 @@
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.issues-filters,
|
||||
.issues-details-filters,
|
||||
.dash-projects-filters,
|
||||
.check-all-holder {
|
||||
display: none;
|
||||
@@ -83,6 +83,7 @@
|
||||
|
||||
.center-top-menu {
|
||||
height: 45px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
li a {
|
||||
font-size: 14px;
|
||||
@@ -90,9 +91,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.projects-search-form {
|
||||
margin: 0 -5px !important;
|
||||
.activity-filter-block {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.projects-search-form {
|
||||
.btn {
|
||||
display: none;
|
||||
}
|
||||
@@ -100,6 +103,11 @@
|
||||
}
|
||||
|
||||
@media (max-width: $screen-sm-max) {
|
||||
.page-with-sidebar .content-wrapper {
|
||||
padding: 0;
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.issues-filters {
|
||||
.milestone-filter, .labels-filter {
|
||||
display: none;
|
||||
+17
-1
@@ -1,5 +1,21 @@
|
||||
table {
|
||||
&.table {
|
||||
.dropdown-menu a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.success,
|
||||
.warning,
|
||||
.danger,
|
||||
.info {
|
||||
color: #fff;
|
||||
|
||||
a:not(.btn) {
|
||||
text-decoration: underline;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
td, th {
|
||||
padding: 8px 10px;
|
||||
@@ -12,7 +28,7 @@ table {
|
||||
border-bottom: 1px solid $border-color !important;
|
||||
}
|
||||
td {
|
||||
border-color: #F1F1F1 !important;
|
||||
border-color: $table-border-color !important;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
}
|
||||
-22
@@ -32,8 +32,6 @@
|
||||
@import "bootstrap/pager";
|
||||
@import "bootstrap/labels";
|
||||
@import "bootstrap/badges";
|
||||
@import "bootstrap/jumbotron";
|
||||
@import "bootstrap/thumbnails";
|
||||
@import "bootstrap/alerts";
|
||||
@import "bootstrap/progress-bars";
|
||||
@import "bootstrap/list-group";
|
||||
@@ -251,23 +249,3 @@
|
||||
.text-info:hover {
|
||||
color: $brand-info;
|
||||
}
|
||||
|
||||
// Tables =====================================================================
|
||||
|
||||
table.table {
|
||||
.dropdown-menu a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.success,
|
||||
.warning,
|
||||
.danger,
|
||||
.info {
|
||||
color: #fff;
|
||||
|
||||
a:not(.btn) {
|
||||
text-decoration: underline;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -156,3 +156,5 @@ $nav-link-padding: 13px $gl-padding;
|
||||
$pre-bg: #f8fafc !default;
|
||||
$pre-color: $gl-gray !default;
|
||||
$pre-border-color: #e7e9ed;
|
||||
|
||||
$table-bg-accent: $background-color;
|
||||
@@ -0,0 +1,271 @@
|
||||
@mixin md-typography {
|
||||
color: $md-text-color;
|
||||
|
||||
a {
|
||||
color: $md-link-color;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
*:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: $monospace_font;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font-size: 11px;
|
||||
line-height: 10px;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #FCFCFC;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #CCC #CCC #BBB;
|
||||
border-image: none;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px -1px 0px #BBB inset;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 12px 0;
|
||||
padding: 0 0 10px 0;
|
||||
border-bottom: 1px solid #e7e9ed;
|
||||
color: #313236;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 12px 0;
|
||||
color: #313236;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 24px 0 12px 0;
|
||||
font-size: 0.90em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 8px 21px;
|
||||
margin: 12px 0 12px;
|
||||
border-left: 3px solid #e7e9ed;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
color: #7f8fa4 !important;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
p {
|
||||
color:#5c5d5e;
|
||||
margin:6px 0 0 0;
|
||||
}
|
||||
|
||||
table {
|
||||
@extend .table;
|
||||
@extend .table-bordered;
|
||||
margin: 12px 0 12px 0;
|
||||
color: #5c5d5e;
|
||||
th {
|
||||
background: #f8fafc;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 12px 0 12px 0 !important;
|
||||
background-color: #f8fafc !important;
|
||||
font-size: 13px !important;
|
||||
color: #5b6169 !important;
|
||||
line-height: 1.6em !important;
|
||||
@include border-radius(2px);
|
||||
}
|
||||
|
||||
p > code {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
|
||||
ul {
|
||||
color: #5c5d5e;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
a[href*="/uploads/"], a[href*="storage.googleapis.com/google-code-attachments/"] {
|
||||
&:before {
|
||||
margin-right: 4px;
|
||||
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
content: "\f0c6";
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Headers
|
||||
*
|
||||
*/
|
||||
body {
|
||||
text-rendering:optimizeLegibility;
|
||||
-webkit-text-shadow: rgba(255,255,255,0.01) 0 0 1px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin-top: 0px;
|
||||
line-height: 1.3;
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page-title-empty {
|
||||
margin-top: 0px;
|
||||
line-height: 1.3;
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
margin: 12px 7px 12px 7px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: $gl-header-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/** CODE **/
|
||||
pre {
|
||||
font-family: $monospace_font;
|
||||
|
||||
&.dark {
|
||||
background: #333;
|
||||
color: $background-color;
|
||||
}
|
||||
|
||||
&.plain-readme {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.monospace {
|
||||
font-family: $monospace_font;
|
||||
}
|
||||
|
||||
code {
|
||||
&.key-fingerprint {
|
||||
background: $body-bg;
|
||||
color: $text-color;
|
||||
}
|
||||
}
|
||||
|
||||
a > code {
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wiki typography
|
||||
*
|
||||
*/
|
||||
.wiki {
|
||||
@include md-typography;
|
||||
|
||||
word-wrap: break-word;
|
||||
padding: 7px;
|
||||
|
||||
/* Link to current header. */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
position: relative;
|
||||
|
||||
a.anchor {
|
||||
// Setting `display: none` would prevent the anchor being scrolled to, so
|
||||
// instead we set the height to 0 and it gets updated on hover.
|
||||
height: 0;
|
||||
}
|
||||
|
||||
&:hover > a.anchor {
|
||||
$size: 16px;
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
top: 50%;
|
||||
margin-top: -$size/2;
|
||||
margin-right: 0px;
|
||||
padding-right: 20px;
|
||||
display: inline-block;
|
||||
width: $size;
|
||||
height: $size;
|
||||
background-image: image-url("icon-link.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
ul,ol {
|
||||
padding: 0;
|
||||
margin: 6px 0 6px 18px !important;
|
||||
}
|
||||
ol {
|
||||
color: #5c5d5e;
|
||||
}
|
||||
}
|
||||
|
||||
.md-area {
|
||||
@include md-typography;
|
||||
}
|
||||
|
||||
.md {
|
||||
@include md-typography;
|
||||
}
|
||||
|
||||
/**
|
||||
* Textareas intended for GFM
|
||||
*
|
||||
*/
|
||||
textarea.js-gfm-input {
|
||||
font-family: $monospace_font;
|
||||
}
|
||||
|
||||
.md-preview {
|
||||
}
|
||||
|
||||
.strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
+1
@@ -16,6 +16,7 @@ $avatar_radius: 50%;
|
||||
$code_font_size: 13px;
|
||||
$code_line_height: 1.5;
|
||||
$border-color: #dce0e6;
|
||||
$table-border-color: #eef0f2;
|
||||
$background-color: #F7F8FA;
|
||||
$header-height: 58px;
|
||||
$fixed-layout-width: 1200px;
|
||||
@@ -1,130 +0,0 @@
|
||||
/**
|
||||
* Headers
|
||||
*
|
||||
*/
|
||||
body {
|
||||
text-rendering:optimizeLegibility;
|
||||
-webkit-text-shadow: rgba(255,255,255,0.01) 0 0 1px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin-top: 0px;
|
||||
line-height: 1.3;
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page-title-empty {
|
||||
margin-top: 0px;
|
||||
line-height: 1.3;
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
margin: 12px 7px 12px 7px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: $gl-header-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/** CODE **/
|
||||
pre {
|
||||
font-family: $monospace_font;
|
||||
|
||||
&.dark {
|
||||
background: #333;
|
||||
color: $background-color;
|
||||
}
|
||||
|
||||
&.plain-readme {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.monospace {
|
||||
font-family: $monospace_font;
|
||||
}
|
||||
|
||||
code {
|
||||
&.key-fingerprint {
|
||||
background: $body-bg;
|
||||
color: $text-color;
|
||||
}
|
||||
}
|
||||
|
||||
a > code {
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wiki typography
|
||||
*
|
||||
*/
|
||||
.wiki {
|
||||
@include md-typography;
|
||||
|
||||
word-wrap: break-word;
|
||||
padding: 7px;
|
||||
|
||||
/* Link to current header. */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
position: relative;
|
||||
|
||||
a.anchor {
|
||||
// Setting `display: none` would prevent the anchor being scrolled to, so
|
||||
// instead we set the height to 0 and it gets updated on hover.
|
||||
height: 0;
|
||||
}
|
||||
|
||||
&:hover > a.anchor {
|
||||
$size: 16px;
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
top: 50%;
|
||||
margin-top: -$size/2;
|
||||
margin-right: 0px;
|
||||
padding-right: 20px;
|
||||
display: inline-block;
|
||||
width: $size;
|
||||
height: $size;
|
||||
background-image: image-url("icon-link.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
ul,ol {
|
||||
padding: 0;
|
||||
margin: 6px 0 6px 18px !important;
|
||||
}
|
||||
ol {
|
||||
color: #5c5d5e;
|
||||
}
|
||||
}
|
||||
|
||||
.md-area {
|
||||
@include md-typography;
|
||||
}
|
||||
|
||||
.md {
|
||||
@include md-typography;
|
||||
}
|
||||
|
||||
/**
|
||||
* Textareas intended for GFM
|
||||
*
|
||||
*/
|
||||
textarea.js-gfm-input {
|
||||
font-family: $monospace_font;
|
||||
}
|
||||
|
||||
.md-preview {
|
||||
}
|
||||
|
||||
.strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
@@ -65,7 +65,6 @@
|
||||
|
||||
.note-image-attach {
|
||||
@extend .col-md-4;
|
||||
@extend .thumbnail;
|
||||
margin-left: 45px;
|
||||
float: none;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0 $gl-padding;
|
||||
color: #5c5d5e;
|
||||
}
|
||||
}
|
||||
@@ -510,8 +511,3 @@ pre.light-well {
|
||||
margin-top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.inline-form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.tree-holder {
|
||||
.tree-content-holder {
|
||||
float: left;
|
||||
width: 100%;
|
||||
.tree-table-holder {
|
||||
margin-left: -$gl-padding;
|
||||
margin-right: -$gl-padding;
|
||||
}
|
||||
|
||||
.tree_progress {
|
||||
@@ -13,10 +13,15 @@
|
||||
}
|
||||
|
||||
.tree-table {
|
||||
@extend .table;
|
||||
@include border-radius(0);
|
||||
margin-bottom: 0;
|
||||
|
||||
tr {
|
||||
> td, > th {
|
||||
padding: 10px $gl-padding;
|
||||
line-height: 32px;
|
||||
border-color: $table-border-color !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
td {
|
||||
background: $hover;
|
||||
@@ -27,9 +32,9 @@
|
||||
}
|
||||
&.selected {
|
||||
td {
|
||||
background: $background-color;
|
||||
border-top: 1px solid #EEE;
|
||||
border-bottom: 1px solid #EEE;
|
||||
background: $gray-dark;
|
||||
border-top: 1px solid $border-gray-dark;
|
||||
border-bottom: 1px solid $border-gray-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,19 +90,6 @@
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.readme-holder {
|
||||
margin: 0 auto;
|
||||
|
||||
.readme-file-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
color: #777;
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.blob-commit-info {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
|
||||
@@ -88,7 +88,7 @@ class GroupsController < Groups::ApplicationController
|
||||
def destroy
|
||||
DestroyGroupService.new(@group, current_user).execute
|
||||
|
||||
redirect_to root_path, alert: "Group '#{@group.name} was deleted."
|
||||
redirect_to root_path, alert: "Group '#{@group.name}' was successfully deleted."
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
@@ -135,6 +135,8 @@ class Ability
|
||||
|
||||
def project_report_rules
|
||||
project_guest_rules + [
|
||||
:create_commit_status,
|
||||
:read_commit_statuses,
|
||||
:download_code,
|
||||
:fork_project,
|
||||
:create_project_snippet,
|
||||
|
||||
+25
-72
@@ -24,32 +24,19 @@
|
||||
#
|
||||
|
||||
module Ci
|
||||
class Build < ActiveRecord::Base
|
||||
extend Ci::Model
|
||||
|
||||
class Build < CommitStatus
|
||||
LAZY_ATTRIBUTES = ['trace']
|
||||
|
||||
belongs_to :commit, class_name: 'Ci::Commit'
|
||||
belongs_to :runner, class_name: 'Ci::Runner'
|
||||
belongs_to :trigger_request, class_name: 'Ci::TriggerRequest'
|
||||
belongs_to :user
|
||||
|
||||
serialize :options
|
||||
|
||||
validates :commit, presence: true
|
||||
validates :status, presence: true
|
||||
validates :coverage, numericality: true, allow_blank: true
|
||||
validates_presence_of :ref
|
||||
|
||||
scope :running, ->() { where(status: "running") }
|
||||
scope :pending, ->() { where(status: "pending") }
|
||||
scope :success, ->() { where(status: "success") }
|
||||
scope :failed, ->() { where(status: "failed") }
|
||||
scope :unstarted, ->() { where(runner_id: nil) }
|
||||
scope :running_or_pending, ->() { where(status:[:running, :pending]) }
|
||||
scope :latest, ->() { where(id: unscope(:select).select('max(id)').group(:name, :ref)).order(stage_idx: :asc) }
|
||||
scope :ignore_failures, ->() { where(allow_failure: false) }
|
||||
scope :for_ref, ->(ref) { where(ref: ref) }
|
||||
scope :similar, ->(build) { where(ref: build.ref, tag: build.tag, trigger_request_id: build.trigger_request_id) }
|
||||
|
||||
acts_as_taggable
|
||||
@@ -74,13 +61,14 @@ module Ci
|
||||
|
||||
def create_from(build)
|
||||
new_build = build.dup
|
||||
new_build.status = :pending
|
||||
new_build.status = 'pending'
|
||||
new_build.runner_id = nil
|
||||
new_build.trigger_request_id = nil
|
||||
new_build.save
|
||||
end
|
||||
|
||||
def retry(build)
|
||||
new_build = Ci::Build.new(status: :pending)
|
||||
new_build = Ci::Build.new(status: 'pending')
|
||||
new_build.ref = build.ref
|
||||
new_build.tag = build.tag
|
||||
new_build.options = build.options
|
||||
@@ -98,28 +86,7 @@ module Ci
|
||||
end
|
||||
|
||||
state_machine :status, initial: :pending do
|
||||
event :run do
|
||||
transition pending: :running
|
||||
end
|
||||
|
||||
event :drop do
|
||||
transition running: :failed
|
||||
end
|
||||
|
||||
event :success do
|
||||
transition running: :success
|
||||
end
|
||||
|
||||
event :cancel do
|
||||
transition [:pending, :running] => :canceled
|
||||
end
|
||||
|
||||
after_transition pending: :running do |build, transition|
|
||||
build.update_attributes started_at: Time.now
|
||||
end
|
||||
|
||||
after_transition any => [:success, :failed, :canceled] do |build, transition|
|
||||
build.update_attributes finished_at: Time.now
|
||||
project = build.project
|
||||
|
||||
if project.web_hooks?
|
||||
@@ -136,19 +103,10 @@ module Ci
|
||||
build.update_coverage
|
||||
end
|
||||
end
|
||||
|
||||
state :pending, value: 'pending'
|
||||
state :running, value: 'running'
|
||||
state :failed, value: 'failed'
|
||||
state :success, value: 'success'
|
||||
state :canceled, value: 'canceled'
|
||||
end
|
||||
|
||||
delegate :sha, :short_sha, :project, :gl_project,
|
||||
to: :commit, prefix: false
|
||||
|
||||
def before_sha
|
||||
Gitlab::Git::BLANK_SHA
|
||||
def ignored?
|
||||
failed? && allow_failure?
|
||||
end
|
||||
|
||||
def trace_html
|
||||
@@ -156,22 +114,6 @@ module Ci
|
||||
html || ''
|
||||
end
|
||||
|
||||
def started?
|
||||
!pending? && !canceled? && started_at
|
||||
end
|
||||
|
||||
def active?
|
||||
running? || pending?
|
||||
end
|
||||
|
||||
def complete?
|
||||
canceled? || success? || failed?
|
||||
end
|
||||
|
||||
def ignored?
|
||||
failed? && allow_failure?
|
||||
end
|
||||
|
||||
def timeout
|
||||
project.timeout
|
||||
end
|
||||
@@ -180,14 +122,6 @@ module Ci
|
||||
yaml_variables + project_variables + trigger_variables
|
||||
end
|
||||
|
||||
def duration
|
||||
if started_at && finished_at
|
||||
finished_at - started_at
|
||||
elsif started_at
|
||||
Time.now - started_at
|
||||
end
|
||||
end
|
||||
|
||||
def project
|
||||
commit.project
|
||||
end
|
||||
@@ -278,6 +212,25 @@ module Ci
|
||||
"#{dir_to_trace}/#{id}.log"
|
||||
end
|
||||
|
||||
def target_url
|
||||
Gitlab::Application.routes.url_helpers.
|
||||
namespace_project_build_url(gl_project.namespace, gl_project, self)
|
||||
end
|
||||
|
||||
def cancel_url
|
||||
if active?
|
||||
Gitlab::Application.routes.url_helpers.
|
||||
cancel_namespace_project_build_path(gl_project.namespace, gl_project, self, return_to: request.original_url)
|
||||
end
|
||||
end
|
||||
|
||||
def retry_url
|
||||
if commands.present?
|
||||
Gitlab::Application.routes.url_helpers.
|
||||
cancel_namespace_project_build_path(gl_project.namespace, gl_project, self, return_to: request.original_url)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def yaml_variables
|
||||
|
||||
+43
-51
@@ -20,7 +20,8 @@ module Ci
|
||||
extend Ci::Model
|
||||
|
||||
belongs_to :gl_project, class_name: '::Project', foreign_key: :gl_project_id
|
||||
has_many :builds, dependent: :destroy, class_name: 'Ci::Build'
|
||||
has_many :statuses, dependent: :destroy, class_name: 'CommitStatus'
|
||||
has_many :builds, class_name: 'Ci::Build'
|
||||
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
|
||||
|
||||
validates_presence_of :sha
|
||||
@@ -47,7 +48,7 @@ module Ci
|
||||
end
|
||||
|
||||
def retry
|
||||
builds_without_retry.each do |build|
|
||||
latest_builds.each do |build|
|
||||
Ci::Build.retry(build)
|
||||
end
|
||||
end
|
||||
@@ -81,12 +82,11 @@ module Ci
|
||||
end
|
||||
|
||||
def stage
|
||||
running_or_pending = builds_without_retry.running_or_pending
|
||||
running_or_pending.limit(1).pluck(:stage).first
|
||||
running_or_pending = statuses.latest.running_or_pending.ordered
|
||||
running_or_pending.first.try(:stage)
|
||||
end
|
||||
|
||||
def create_builds(ref, tag, user, trigger_request = nil)
|
||||
return if skip_ci? && trigger_request.blank?
|
||||
return unless config_processor
|
||||
config_processor.stages.any? do |stage|
|
||||
CreateBuildsService.new.execute(self, stage, ref, tag, user, trigger_request).present?
|
||||
@@ -94,7 +94,6 @@ module Ci
|
||||
end
|
||||
|
||||
def create_next_builds(ref, tag, user, trigger_request)
|
||||
return if skip_ci? && trigger_request.blank?
|
||||
return unless config_processor
|
||||
|
||||
stages = builds.where(ref: ref, tag: tag, trigger_request: trigger_request).group_by(&:stage)
|
||||
@@ -107,61 +106,60 @@ module Ci
|
||||
end
|
||||
|
||||
def refs
|
||||
builds.group(:ref).pluck(:ref)
|
||||
statuses.order(:ref).pluck(:ref).uniq
|
||||
end
|
||||
|
||||
def last_ref
|
||||
builds.latest.first.try(:ref)
|
||||
def latest_statuses
|
||||
@latest_statuses ||= statuses.latest.to_a
|
||||
end
|
||||
|
||||
def builds_without_retry
|
||||
builds.latest
|
||||
def latest_builds
|
||||
@latest_builds ||= builds.latest.to_a
|
||||
end
|
||||
|
||||
def builds_without_retry_for_ref(ref)
|
||||
builds.for_ref(ref).latest
|
||||
def latest_builds_for_ref(ref)
|
||||
latest_builds.select { |build| build.ref == ref }
|
||||
end
|
||||
|
||||
def retried_builds
|
||||
@retried_builds ||= (builds.order(id: :desc) - builds_without_retry)
|
||||
def retried
|
||||
@retried ||= (statuses.order(id: :desc) - statuses.latest)
|
||||
end
|
||||
|
||||
def status
|
||||
if skip_ci?
|
||||
return 'skipped'
|
||||
elsif yaml_errors.present?
|
||||
if yaml_errors.present?
|
||||
return 'failed'
|
||||
elsif builds.none?
|
||||
return 'skipped'
|
||||
elsif success?
|
||||
'success'
|
||||
elsif pending?
|
||||
'pending'
|
||||
elsif running?
|
||||
'running'
|
||||
elsif canceled?
|
||||
'canceled'
|
||||
else
|
||||
'failed'
|
||||
end
|
||||
|
||||
@status ||= begin
|
||||
latest = latest_statuses
|
||||
latest.reject! { |status| status.try(&:allow_failure?) }
|
||||
|
||||
if latest.none?
|
||||
'skipped'
|
||||
elsif latest.all?(&:success?)
|
||||
'success'
|
||||
elsif latest.all?(&:pending?)
|
||||
'pending'
|
||||
elsif latest.any?(&:running?) || latest.any?(&:pending?)
|
||||
'running'
|
||||
elsif latest.all?(&:canceled?)
|
||||
'canceled'
|
||||
else
|
||||
'failed'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pending?
|
||||
builds_without_retry.all? do |build|
|
||||
build.pending?
|
||||
end
|
||||
status == 'pending'
|
||||
end
|
||||
|
||||
def running?
|
||||
builds_without_retry.any? do |build|
|
||||
build.running? || build.pending?
|
||||
end
|
||||
status == 'running'
|
||||
end
|
||||
|
||||
def success?
|
||||
builds_without_retry.all? do |build|
|
||||
build.success? || build.ignored?
|
||||
end
|
||||
status == 'success'
|
||||
end
|
||||
|
||||
def failed?
|
||||
@@ -169,26 +167,21 @@ module Ci
|
||||
end
|
||||
|
||||
def canceled?
|
||||
builds_without_retry.all? do |build|
|
||||
build.canceled?
|
||||
end
|
||||
status == 'canceled'
|
||||
end
|
||||
|
||||
def duration
|
||||
@duration ||= builds_without_retry.select(&:duration).sum(&:duration).to_i
|
||||
end
|
||||
|
||||
def duration_for_ref(ref)
|
||||
builds_without_retry_for_ref(ref).select(&:duration).sum(&:duration).to_i
|
||||
duration_array = latest_statuses.map(&:duration).compact
|
||||
duration_array.reduce(:+).to_i
|
||||
end
|
||||
|
||||
def finished_at
|
||||
@finished_at ||= builds.order('finished_at DESC').first.try(:finished_at)
|
||||
@finished_at ||= statuses.order('finished_at DESC').first.try(:finished_at)
|
||||
end
|
||||
|
||||
def coverage
|
||||
if project.coverage_enabled?
|
||||
coverage_array = builds_without_retry.map(&:coverage).compact
|
||||
coverage_array = latest_builds.map(&:coverage).compact
|
||||
if coverage_array.size >= 1
|
||||
'%.2f' % (coverage_array.reduce(:+) / coverage_array.size)
|
||||
end
|
||||
@@ -196,7 +189,7 @@ module Ci
|
||||
end
|
||||
|
||||
def matrix_for_ref?(ref)
|
||||
builds_without_retry_for_ref(ref).pluck(:id).size > 1
|
||||
latest_builds_for_ref(ref).size > 1
|
||||
end
|
||||
|
||||
def config_processor
|
||||
@@ -217,7 +210,6 @@ module Ci
|
||||
end
|
||||
|
||||
def skip_ci?
|
||||
return false if builds.any?
|
||||
git_commit_message =~ /(\[ci skip\])/ if git_commit_message
|
||||
end
|
||||
|
||||
|
||||
@@ -184,4 +184,12 @@ class Commit
|
||||
def parents
|
||||
@parents ||= Commit.decorate(super, project)
|
||||
end
|
||||
|
||||
def ci_commit
|
||||
project.ci_commit(sha)
|
||||
end
|
||||
|
||||
def status
|
||||
ci_commit.try(:status) || :not_found
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
class CommitStatus < ActiveRecord::Base
|
||||
self.table_name = 'ci_builds'
|
||||
|
||||
belongs_to :commit, class_name: 'Ci::Commit'
|
||||
belongs_to :user
|
||||
|
||||
validates :commit, presence: true
|
||||
validates :status, inclusion: { in: %w(pending running failed success canceled) }
|
||||
|
||||
validates_presence_of :name
|
||||
|
||||
alias_attribute :author, :user
|
||||
|
||||
scope :running, -> { where(status: 'running') }
|
||||
scope :pending, -> { where(status: 'pending') }
|
||||
scope :success, -> { where(status: 'success') }
|
||||
scope :failed, -> { where(status: 'failed') }
|
||||
scope :running_or_pending, -> { where(status:[:running, :pending]) }
|
||||
scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
|
||||
scope :ordered, -> { order(:ref, :stage_idx, :name) }
|
||||
scope :for_ref, ->(ref) { where(ref: ref) }
|
||||
scope :running_or_pending, -> { where(status: [:running, :pending]) }
|
||||
|
||||
state_machine :status, initial: :pending do
|
||||
event :run do
|
||||
transition pending: :running
|
||||
end
|
||||
|
||||
event :drop do
|
||||
transition running: :failed
|
||||
end
|
||||
|
||||
event :success do
|
||||
transition [:pending, :running] => :success
|
||||
end
|
||||
|
||||
event :cancel do
|
||||
transition [:pending, :running] => :canceled
|
||||
end
|
||||
|
||||
after_transition pending: :running do |build, transition|
|
||||
build.update_attributes started_at: Time.now
|
||||
end
|
||||
|
||||
after_transition any => [:success, :failed, :canceled] do |build, transition|
|
||||
build.update_attributes finished_at: Time.now
|
||||
end
|
||||
|
||||
state :pending, value: 'pending'
|
||||
state :running, value: 'running'
|
||||
state :failed, value: 'failed'
|
||||
state :success, value: 'success'
|
||||
state :canceled, value: 'canceled'
|
||||
end
|
||||
|
||||
delegate :sha, :short_sha, :gl_project,
|
||||
to: :commit, prefix: false
|
||||
|
||||
# TODO: this should be removed with all references
|
||||
def before_sha
|
||||
Gitlab::Git::BLANK_SHA
|
||||
end
|
||||
|
||||
def started?
|
||||
!pending? && !canceled? && started_at
|
||||
end
|
||||
|
||||
def active?
|
||||
running? || pending?
|
||||
end
|
||||
|
||||
def complete?
|
||||
canceled? || success? || failed?
|
||||
end
|
||||
|
||||
def duration
|
||||
if started_at && finished_at
|
||||
finished_at - started_at
|
||||
elsif started_at
|
||||
Time.now - started_at
|
||||
end
|
||||
end
|
||||
|
||||
def cancel_url
|
||||
nil
|
||||
end
|
||||
|
||||
def retry_url
|
||||
nil
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
class GenericCommitStatus < CommitStatus
|
||||
before_validation :set_default_values
|
||||
|
||||
# GitHub compatible API
|
||||
alias_attribute :context, :name
|
||||
|
||||
def set_default_values
|
||||
self.context ||= 'default'
|
||||
self.stage ||= 'external'
|
||||
end
|
||||
|
||||
def tags
|
||||
[:external]
|
||||
end
|
||||
end
|
||||
@@ -227,7 +227,7 @@ class MergeRequest < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def work_in_progress?
|
||||
title =~ /\A\[?WIP\]?:? /i
|
||||
!!(title =~ /\A\[?WIP\]?:? /i)
|
||||
end
|
||||
|
||||
def mergeable?
|
||||
@@ -275,7 +275,8 @@ class MergeRequest < ActiveRecord::Base
|
||||
attrs = {
|
||||
source: source_project.hook_attrs,
|
||||
target: target_project.hook_attrs,
|
||||
last_commit: nil
|
||||
last_commit: nil,
|
||||
work_in_progress: work_in_progress?
|
||||
}
|
||||
|
||||
unless last_commit.nil?
|
||||
|
||||
@@ -40,12 +40,19 @@ class BambooService < CiService
|
||||
attr_accessor :response
|
||||
|
||||
after_save :compose_service_hook, if: :activated?
|
||||
before_update :reset_password
|
||||
|
||||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
hook.save
|
||||
end
|
||||
|
||||
def reset_password
|
||||
if prop_updated?(:bamboo_url)
|
||||
self.password = nil
|
||||
end
|
||||
end
|
||||
|
||||
def title
|
||||
'Atlassian Bamboo CI'
|
||||
end
|
||||
|
||||
@@ -49,7 +49,7 @@ module Ci
|
||||
|
||||
commit = build.commit
|
||||
return unless commit
|
||||
return unless commit.builds_without_retry.include? build
|
||||
return unless commit.latest_builds.include? build
|
||||
|
||||
case commit.status.to_sym
|
||||
when :failed
|
||||
|
||||
@@ -48,7 +48,7 @@ module Ci
|
||||
# it doesn't make sense to send emails for retried builds
|
||||
commit = build.commit
|
||||
return unless commit
|
||||
return unless commit.builds_without_retry.include?(build)
|
||||
return unless commit.latest_builds.include?(build)
|
||||
|
||||
case build.status.to_sym
|
||||
when :failed
|
||||
|
||||
@@ -23,7 +23,7 @@ module Ci
|
||||
def attachments
|
||||
fields = []
|
||||
|
||||
commit.builds_without_retry.each do |build|
|
||||
commit.latest_builds.each do |build|
|
||||
next if build.allow_failure?
|
||||
next unless build.failed?
|
||||
fields << {
|
||||
|
||||
@@ -48,7 +48,7 @@ module Ci
|
||||
|
||||
commit = build.commit
|
||||
return unless commit
|
||||
return unless commit.builds_without_retry.include?(build)
|
||||
return unless commit.latest_builds.include?(build)
|
||||
|
||||
case commit.status.to_sym
|
||||
when :failed
|
||||
|
||||
@@ -37,12 +37,19 @@ class TeamcityService < CiService
|
||||
attr_accessor :response
|
||||
|
||||
after_save :compose_service_hook, if: :activated?
|
||||
before_update :reset_password
|
||||
|
||||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
hook.save
|
||||
end
|
||||
|
||||
def reset_password
|
||||
if prop_updated?(:teamcity_url)
|
||||
self.password = nil
|
||||
end
|
||||
end
|
||||
|
||||
def title
|
||||
'JetBrains TeamCity CI'
|
||||
end
|
||||
|
||||
@@ -117,6 +117,15 @@ class Service < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
# ActiveRecord does not provide a mechanism to track changes in serialized keys.
|
||||
# This is why we need to perform extra query to do it mannually.
|
||||
def prop_updated?(prop_name)
|
||||
relation_name = self.type.underscore
|
||||
previous_value = project.send(relation_name).send(prop_name)
|
||||
return false if previous_value.nil?
|
||||
previous_value != send(prop_name)
|
||||
end
|
||||
|
||||
def async_execute(data)
|
||||
return unless supported_events.include?(data[:object_kind])
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ module Ci
|
||||
|
||||
tag = origin_ref.start_with?('refs/tags/')
|
||||
commit = project.gl_project.ensure_ci_commit(sha)
|
||||
commit.update_committed!
|
||||
commit.create_builds(ref, tag, user)
|
||||
unless commit.skip_ci?
|
||||
commit.update_committed!
|
||||
commit.create_builds(ref, tag, user)
|
||||
end
|
||||
|
||||
commit
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
%hr
|
||||
= form_tag admin_users_path, method: :get, class: 'form-inline' do
|
||||
.form-group
|
||||
= search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'form-control'
|
||||
= search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'form-control', spellcheck: false
|
||||
= hidden_field_tag "filter", params[:filter]
|
||||
= button_tag class: 'btn btn-primary' do
|
||||
%i.fa.fa-search
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
.pull-left
|
||||
= form_tag ci_admin_runners_path, id: 'runners-search', class: 'form-inline', method: :get do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], class: 'form-control', placeholder: 'Runner description or token'
|
||||
= search_field_tag :search, params[:search], class: 'form-control', placeholder: 'Runner description or token', spellcheck: false
|
||||
= submit_tag 'Search', class: 'btn'
|
||||
|
||||
.pull-right.light
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
%td
|
||||
= form_tag ci_admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], class: 'form-control'
|
||||
= search_field_tag :search, params[:search], class: 'form-control', spellcheck: false
|
||||
= submit_tag 'Search', class: 'btn'
|
||||
|
||||
%td
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
.gray-content-block
|
||||
- if current_user
|
||||
%ul.nav.nav-pills.event_filter.pull-right
|
||||
%li.pull-right
|
||||
= link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
.pull-right
|
||||
= link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
= render 'shared/event_filter'
|
||||
|
||||
.content_list
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.projects-list-holder
|
||||
.projects-search-form
|
||||
.input-group
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false
|
||||
- if current_user.can_create_project?
|
||||
%span.input-group-btn
|
||||
= link_to new_project_path, class: 'btn btn-green' do
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
= form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f|
|
||||
= hidden_field_tag :sort, @sort
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input", id: "groups_search"
|
||||
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input", id: "groups_search", spellcheck: false
|
||||
.form-group
|
||||
= button_tag 'Search', class: "btn btn-default"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.pull-left
|
||||
= form_tag explore_projects_filter_path, method: :get, class: 'form-inline form-tiny' do |f|
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input", id: "projects_search"
|
||||
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input", id: "projects_search", spellcheck: false
|
||||
.form-group
|
||||
= button_tag 'Search', class: "btn btn-success"
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.panel.panel-default.projects-list-holder
|
||||
.panel-heading.clearfix
|
||||
.input-group
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false
|
||||
- if can? current_user, :create_projects, @group
|
||||
%span.input-group-btn
|
||||
= link_to new_project_path(namespace_id: @group.id), class: 'btn btn-green' do
|
||||
New project
|
||||
|
||||
= render 'shared/projects/list', projects: @projects, projects_limit: 20, stars: false
|
||||
= render 'shared/projects/list', projects: @projects, projects_limit: 20, stars: false, skip_namespace: true
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.clearfix.js-toggle-container
|
||||
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' }
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input', spellcheck: false }
|
||||
= button_tag 'Search', class: 'btn'
|
||||
|
||||
- if current_user && current_user.can?(:admin_group_member, @group)
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
.hidden-xs
|
||||
- if current_user
|
||||
= render "events/event_last_push", event: @last_push
|
||||
|
||||
%ul.nav.nav-pills.event_filter.pull-right
|
||||
%li
|
||||
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
.pull-right
|
||||
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'btn rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
|
||||
= render 'shared/event_filter'
|
||||
%hr
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
= brand_header_logo
|
||||
.gitlab-text-container
|
||||
%h3 GitLab
|
||||
|
||||
|
||||
- if defined?(sidebar) && sidebar
|
||||
= render "layouts/nav/#{sidebar}"
|
||||
- elsif current_user
|
||||
@@ -23,6 +23,7 @@
|
||||
= current_user.username
|
||||
.content-wrapper
|
||||
= render "layouts/flash"
|
||||
= yield :flash_message
|
||||
%div{ class: container_class }
|
||||
.content
|
||||
.clearfix
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.search
|
||||
= form_tag search_path, method: :get, class: 'navbar-form pull-left' do |f|
|
||||
= search_field_tag "search", nil, placeholder: search_placeholder, class: "search-input form-control"
|
||||
= search_field_tag "search", nil, placeholder: search_placeholder, class: "search-input form-control", spellcheck: false
|
||||
= hidden_field_tag :group_id, @group.try(:id)
|
||||
- if @project && @project.persisted?
|
||||
= hidden_field_tag :project_id, @project.id
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
= render 'projects/last_push'
|
||||
.gray-content-block.activity-filter-block
|
||||
- if current_user
|
||||
%ul.nav.nav-pills.event_filter.pull-right
|
||||
%li
|
||||
= link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Feed", class: 'rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
.pull-right
|
||||
= link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Feed", class: 'btn rss-btn' do
|
||||
%i.fa.fa-rss
|
||||
|
||||
= render 'shared/event_filter'
|
||||
.content_list{:"data-href" => activity_project_path(@project)}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- blob_commit = @repository.last_commit_for_path(@commit.id, blob.path)
|
||||
= render blob_commit, project: @project
|
||||
|
||||
%div#tree-content-holder.tree-content-holder
|
||||
%div#blob-content-holder.blob-content-holder
|
||||
%article.file-holder
|
||||
.file-title
|
||||
= blob_icon blob.mode, blob.name
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
- gl_project = build.project.gl_project
|
||||
%tr.build
|
||||
%td.status
|
||||
= ci_status_with_icon(build.status)
|
||||
|
||||
%td.build-link
|
||||
= link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
|
||||
%strong Build ##{build.id}
|
||||
|
||||
- if defined?(ref)
|
||||
%td
|
||||
= build.ref
|
||||
|
||||
%td
|
||||
= build.stage
|
||||
|
||||
%td
|
||||
= build.name
|
||||
.pull-right
|
||||
- if build.tags.any?
|
||||
- build.tag_list.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
- if build.trigger_request
|
||||
%span.label.label-info triggered
|
||||
- if build.allow_failure
|
||||
%span.label.label-danger allowed to fail
|
||||
|
||||
%td.duration
|
||||
- if build.duration
|
||||
#{duration_in_words(build.finished_at, build.started_at)}
|
||||
|
||||
%td.timestamp
|
||||
- if build.finished_at
|
||||
%span #{time_ago_in_words build.finished_at} ago
|
||||
|
||||
- if build.project.coverage_enabled?
|
||||
%td.coverage
|
||||
- if build.coverage
|
||||
#{build.coverage}%
|
||||
|
||||
%td
|
||||
- if defined?(controls) && current_user && can?(current_user, :manage_builds, gl_project)
|
||||
.pull-right
|
||||
- if build.active?
|
||||
= link_to cancel_namespace_project_build_path(gl_project.namespace, gl_project, build, return_to: request.original_url), title: 'Cancel build' do
|
||||
%i.fa.fa-remove.cred
|
||||
- elsif build.commands.present?
|
||||
= link_to retry_namespace_project_build_path(gl_project.namespace, gl_project, build, return_to: request.original_url), method: :post, title: 'Retry build' do
|
||||
%i.fa.fa-repeat
|
||||
@@ -9,7 +9,7 @@
|
||||
#up-build-trace
|
||||
- if @commit.matrix_for_ref?(@build.ref)
|
||||
%ul.center-top-menu.build-top-menu
|
||||
- @commit.builds_without_retry_for_ref(@build.ref).each do |build|
|
||||
- @commit.latest_builds_for_ref(@build.ref).each do |build|
|
||||
%li{class: ('active' if build == @build) }
|
||||
= link_to namespace_project_build_path(@project.namespace, @project, build) do
|
||||
= ci_icon_for_status(build.status)
|
||||
@@ -20,7 +20,7 @@
|
||||
= build.id
|
||||
|
||||
|
||||
- unless @commit.builds_without_retry_for_ref(@build.ref).include?(@build)
|
||||
- unless @commit.latest_builds_for_ref(@build.ref).include?(@build)
|
||||
%li.active
|
||||
%a
|
||||
Build ##{@build.id}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- return unless @membership
|
||||
|
||||
= form_tag profile_notifications_path, method: :put, remote: true, class: 'inline-form', id: 'notification-form' do
|
||||
= form_tag profile_notifications_path, method: :put, remote: true, class: 'inline', id: 'notification-form' do
|
||||
= hidden_field_tag :notification_type, 'project'
|
||||
= hidden_field_tag :notification_id, @membership.id
|
||||
= hidden_field_tag :notification_level
|
||||
|
||||
@@ -20,30 +20,31 @@
|
||||
.bs-callout.bs-callout-warning
|
||||
\.gitlab-ci.yml not found in this commit
|
||||
|
||||
- @ci_commit.refs.each do |ref|
|
||||
.gray-content-block.second-block
|
||||
Latest builds
|
||||
- if @ci_commit.duration > 0
|
||||
%small.pull-right
|
||||
%i.fa.fa-time
|
||||
#{time_interval_in_words @ci_commit.duration}
|
||||
|
||||
%table.table.builds
|
||||
%thead
|
||||
%tr
|
||||
%th Status
|
||||
%th Build ID
|
||||
%th Ref
|
||||
%th Stage
|
||||
%th Name
|
||||
%th Duration
|
||||
%th Finished at
|
||||
- if @ci_project && @ci_project.coverage_enabled?
|
||||
%th Coverage
|
||||
%th
|
||||
- @ci_commit.refs.each do |ref|
|
||||
= render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered, coverage: @ci_project.try(:coverage_enabled?), controls: true
|
||||
|
||||
- if @ci_commit.retried.any?
|
||||
.gray-content-block.second-block
|
||||
Builds for #{ref}
|
||||
- if @ci_commit.duration_for_ref(ref) > 0
|
||||
%small.pull-right
|
||||
%i.fa.fa-time
|
||||
#{time_interval_in_words @ci_commit.duration_for_ref(ref)}
|
||||
|
||||
%table.table.builds
|
||||
%thead
|
||||
%tr
|
||||
%th Status
|
||||
%th Build ID
|
||||
%th Stage
|
||||
%th Name
|
||||
%th Duration
|
||||
%th Finished at
|
||||
- if @ci_project && @ci_project.coverage_enabled?
|
||||
%th Coverage
|
||||
%th
|
||||
= render partial: "projects/builds/build", collection: @ci_commit.builds_without_retry.for_ref(ref), controls: true
|
||||
|
||||
- if @ci_commit.retried_builds.any?
|
||||
%h3
|
||||
Retried builds
|
||||
|
||||
%table.table.builds
|
||||
@@ -59,4 +60,4 @@
|
||||
- if @ci_project && @ci_project.coverage_enabled?
|
||||
%th Coverage
|
||||
%th
|
||||
= render partial: "projects/builds/build", collection: @ci_commit.retried_builds, ref: true
|
||||
= render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, coverage: @ci_project.try(:coverage_enabled?)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
%tr.commit_status
|
||||
%td.status
|
||||
= ci_status_with_icon(commit_status.status)
|
||||
|
||||
%td.commit_status-link
|
||||
- if commit_status.target_url
|
||||
= link_to commit_status.target_url do
|
||||
%strong Build ##{commit_status.id}
|
||||
- else
|
||||
%strong Build ##{commit_status.id}
|
||||
|
||||
%td
|
||||
= commit_status.ref
|
||||
|
||||
%td
|
||||
= commit_status.stage
|
||||
|
||||
%td
|
||||
= commit_status.name
|
||||
.pull-right
|
||||
- if commit_status.tags.any?
|
||||
- commit_status.tags.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
- if commit_status.try(:trigger_request)
|
||||
%span.label.label-info triggered
|
||||
- if commit_status.try(:allow_failure)
|
||||
%span.label.label-danger allowed to fail
|
||||
|
||||
%td.duration
|
||||
- if commit_status.duration
|
||||
#{duration_in_words(commit_status.finished_at, commit_status.started_at)}
|
||||
|
||||
%td.timestamp
|
||||
- if commit_status.finished_at
|
||||
%span #{time_ago_in_words commit_status.finished_at} ago
|
||||
|
||||
- if defined?(coverage) && coverage
|
||||
%td.coverage
|
||||
- if commit_status.try(:coverage)
|
||||
#{commit_status.coverage}%
|
||||
|
||||
%td
|
||||
- if defined?(controls) && controls && current_user && can?(current_user, :manage_builds, gl_project)
|
||||
.pull-right
|
||||
- if commit_status.cancel_url
|
||||
= link_to commit_status.cancel_url, title: 'Cancel' do
|
||||
%i.fa.fa-remove.cred
|
||||
- elsif commit_status.retry_url
|
||||
= link_to commit_status.retry_url, method: :post, title: 'Retry' do
|
||||
%i.fa.fa-repeat
|
||||
@@ -111,10 +111,10 @@
|
||||
|
||||
- if current_user.can_create_group?
|
||||
.pull-right
|
||||
.light.in-line
|
||||
.light.inline
|
||||
.space-right
|
||||
Need a group for several dependent projects?
|
||||
= link_to new_group_path, class: "btn btn-xs" do
|
||||
= link_to new_group_path, class: "btn" do
|
||||
Create a group
|
||||
|
||||
.save-project-loader.hide
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.clearfix.js-toggle-container
|
||||
= form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' }
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input', spellcheck: false }
|
||||
= button_tag 'Search', class: 'btn'
|
||||
|
||||
- if can?(current_user, :admin_project_member, @project)
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
- split_button = split_button || false
|
||||
- if split_button == true
|
||||
%span.btn-group{class: btn_class}
|
||||
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn col-xs-10', rel: 'nofollow' do
|
||||
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn btn-success col-xs-10', rel: 'nofollow' do
|
||||
%i.fa.fa-download
|
||||
%span Download zip
|
||||
%a.col-xs-2.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' }
|
||||
%a.col-xs-2.btn.btn-success.dropdown-toggle{ 'data-toggle' => 'dropdown' }
|
||||
%span.caret
|
||||
%span.sr-only
|
||||
Select Archive Format
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
- if current_user
|
||||
= auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "#{@project.name} activity")
|
||||
|
||||
- if current_user && can?(current_user, :download_code, @project)
|
||||
= render 'shared/no_ssh'
|
||||
= render 'shared/no_password'
|
||||
= content_for :flash_message do
|
||||
- if current_user && can?(current_user, :download_code, @project)
|
||||
= render 'shared/no_ssh'
|
||||
= render 'shared/no_password'
|
||||
|
||||
- if prefer_readme?
|
||||
= render 'projects/last_push'
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
%article.readme-holder#README
|
||||
= link_to '#README' do
|
||||
%h4.readme-file-title
|
||||
%i.fa.fa-file
|
||||
= readme.name
|
||||
.wiki
|
||||
%article.file-holder.readme-holder#README
|
||||
.file-title
|
||||
= link_to '#README' do
|
||||
%strong
|
||||
%i.fa.fa-file
|
||||
= readme.name
|
||||
.file-content.wiki
|
||||
= render_readme(readme)
|
||||
|
||||
@@ -1,59 +1,61 @@
|
||||
%ul.breadcrumb.repo-breadcrumb
|
||||
%li
|
||||
= link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
|
||||
= @project.path
|
||||
- tree_breadcrumbs(tree, 6) do |title, path|
|
||||
.gray-content-block
|
||||
%ul.breadcrumb.repo-breadcrumb
|
||||
%li
|
||||
- if path
|
||||
= link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, path)
|
||||
- else
|
||||
= link_to title, '#'
|
||||
- if allowed_tree_edit?
|
||||
%li
|
||||
%span.dropdown
|
||||
%a.dropdown-toggle.btn.btn-xs.add-to-tree{href: '#', "data-toggle" => "dropdown"}
|
||||
= icon('plus')
|
||||
%ul.dropdown-menu
|
||||
%li
|
||||
= link_to namespace_project_new_blob_path(@project.namespace, @project, @id), title: 'Create file', id: 'new-file-link' do
|
||||
= icon('pencil fw')
|
||||
Create file
|
||||
%li
|
||||
= link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal'} do
|
||||
= icon('file fw')
|
||||
Upload file
|
||||
%li.divider
|
||||
%li
|
||||
= link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal'} do
|
||||
= icon('folder fw')
|
||||
New directory
|
||||
= link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
|
||||
= @project.path
|
||||
- tree_breadcrumbs(tree, 6) do |title, path|
|
||||
%li
|
||||
- if path
|
||||
= link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, path)
|
||||
- else
|
||||
= link_to title, '#'
|
||||
- if allowed_tree_edit?
|
||||
%li
|
||||
%span.dropdown
|
||||
%a.dropdown-toggle.btn.add-to-tree{href: '#', "data-toggle" => "dropdown"}
|
||||
= icon('plus')
|
||||
%ul.dropdown-menu
|
||||
%li
|
||||
= link_to namespace_project_new_blob_path(@project.namespace, @project, @id), title: 'Create file', id: 'new-file-link' do
|
||||
= icon('pencil fw')
|
||||
Create file
|
||||
%li
|
||||
= link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal'} do
|
||||
= icon('file fw')
|
||||
Upload file
|
||||
%li.divider
|
||||
%li
|
||||
= link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal'} do
|
||||
= icon('folder fw')
|
||||
New directory
|
||||
|
||||
%div#tree-content-holder.tree-content-holder.prepend-top-20
|
||||
%table#tree-slider{class: "table_#{@hex_path} tree-table" }
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Last Update
|
||||
%th.hidden-xs
|
||||
.pull-left Last Commit
|
||||
.last-commit.hidden-sm.pull-left
|
||||
|
||||
%i.fa.fa-angle-right
|
||||
|
||||
%small.light
|
||||
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit)
|
||||
–
|
||||
= truncate(@commit.title, length: 50)
|
||||
= link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'pull-right'
|
||||
%div#tree-content-holder.tree-content-holder
|
||||
.tree-table-holder
|
||||
%table.table#tree-slider{class: "table_#{@hex_path} tree-table table-striped" }
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Last Update
|
||||
%th.hidden-xs
|
||||
.pull-left Last Commit
|
||||
.last-commit.hidden-sm.pull-left
|
||||
|
||||
%i.fa.fa-angle-right
|
||||
|
||||
%small.light
|
||||
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit)
|
||||
–
|
||||
= truncate(@commit.title, length: 50)
|
||||
= link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'pull-right'
|
||||
|
||||
- if @path.present?
|
||||
%tr.tree-item
|
||||
%td.tree-item-file-name
|
||||
= link_to "..", namespace_project_tree_path(@project.namespace, @project, up_dir_path), class: 'prepend-left-10'
|
||||
%td
|
||||
%td.hidden-xs
|
||||
- if @path.present?
|
||||
%tr.tree-item
|
||||
%td.tree-item-file-name
|
||||
= link_to "..", namespace_project_tree_path(@project.namespace, @project, up_dir_path), class: 'prepend-left-10'
|
||||
%td
|
||||
%td.hidden-xs
|
||||
|
||||
= render_tree(tree)
|
||||
= render_tree(tree)
|
||||
|
||||
- if tree.readme
|
||||
= render "projects/tree/readme", readme: tree.readme
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
= render 'nav'
|
||||
.gray-content-block
|
||||
= render 'main_links'
|
||||
%h3.page-title
|
||||
All Pages
|
||||
%ul.content-list
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
.search-holder.clearfix
|
||||
.input-group
|
||||
= search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true
|
||||
= search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true, spellcheck: false
|
||||
%span.input-group-btn
|
||||
= button_tag 'Search', class: "btn btn-primary"
|
||||
- unless params[:snippets].eql? 'true'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
= form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do
|
||||
.append-right-10.hidden-xs.hidden-sm
|
||||
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input' }
|
||||
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input', spellcheck: false }
|
||||
= hidden_field_tag :state, params['state']
|
||||
= hidden_field_tag :scope, params['scope']
|
||||
= hidden_field_tag :assignee_id, params['assignee_id']
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
- avatar = true unless local_assigns[:avatar] == false
|
||||
- stars = true unless local_assigns[:stars] == false
|
||||
- ci = false unless local_assigns[:ci] == true
|
||||
- skip_namespace = false unless local_assigns[:skip_namespace] == true
|
||||
|
||||
%ul.projects-list
|
||||
- projects.each_with_index do |project, i|
|
||||
- css_class = (i >= projects_limit) ? 'hide' : nil
|
||||
= render "shared/projects/project", project: project,
|
||||
= render "shared/projects/project", project: project, skip_namespace: skip_namespace,
|
||||
avatar: avatar, stars: stars, css_class: css_class, ci: ci
|
||||
|
||||
- if projects.size > projects_limit
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
- avatar = true unless local_assigns[:avatar] == false
|
||||
- stars = true unless local_assigns[:stars] == false
|
||||
- ci = false unless local_assigns[:ci] == true
|
||||
- skip_namespace = false unless local_assigns[:skip_namespace] == true
|
||||
- css_class = '' unless local_assigns[:css_class]
|
||||
- css_class += " no-description" unless project.description.present?
|
||||
%li.project-row{ class: css_class }
|
||||
@@ -11,7 +12,7 @@
|
||||
= project_icon(project, alt: '', class: 'avatar project-avatar s46')
|
||||
%span.project-full-name
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
- if project.namespace && !skip_namespace
|
||||
= project.namespace.human_name
|
||||
\/
|
||||
%span.project-name.filter-title
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
# :email: "gitlab-incoming@gmail.com"
|
||||
# # Email account password
|
||||
# :password: "password"
|
||||
|
||||
# # The name of the mailbox where incoming mail will end up. Usually "inbox".
|
||||
# :name: "inbox"
|
||||
|
||||
# # Always "sidekiq".
|
||||
# :delivery_method: sidekiq
|
||||
# # Always true.
|
||||
@@ -25,5 +27,13 @@
|
||||
# :namespace: resque:gitlab
|
||||
# # Always "incoming_email".
|
||||
# :queue: incoming_email
|
||||
# # Always "EmailReceiverWorker"
|
||||
# # Always "EmailReceiverWorker".
|
||||
# :worker: EmailReceiverWorker
|
||||
|
||||
# # Always "redis".
|
||||
# :arbitration_method: redis
|
||||
# :arbitration_options:
|
||||
# # The URL to the Redis server. Should match the URL in config/resque.yml.
|
||||
# :redis_url: redis://localhost:6379
|
||||
# # Always "mail_room:gitlab".
|
||||
# :namespace: mail_room:gitlab
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class AddTypeAndDescriptionToBuilds < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :ci_builds, :type, :string
|
||||
add_column :ci_builds, :target_url, :string
|
||||
add_column :ci_builds, :description, :string
|
||||
add_index :ci_builds, [:commit_id, :type, :ref]
|
||||
add_index :ci_builds, [:commit_id, :type, :name, :ref]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class MigrateNameToDescriptionForBuilds < ActiveRecord::Migration
|
||||
def change
|
||||
execute("UPDATE ci_builds SET type='Ci::Build' WHERE type IS NULL")
|
||||
end
|
||||
end
|
||||
+6
-1
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20151007120511) do
|
||||
ActiveRecord::Schema.define(version: 20151008130321) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -103,9 +103,14 @@ ActiveRecord::Schema.define(version: 20151007120511) do
|
||||
t.boolean "tag"
|
||||
t.string "ref"
|
||||
t.integer "user_id"
|
||||
t.string "type"
|
||||
t.string "target_url"
|
||||
t.string "description"
|
||||
end
|
||||
|
||||
add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree
|
||||
add_index "ci_builds", ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref", using: :btree
|
||||
add_index "ci_builds", ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref", using: :btree
|
||||
add_index "ci_builds", ["commit_id"], name: "index_ci_builds_on_commit_id", using: :btree
|
||||
add_index "ci_builds", ["project_id", "commit_id"], name: "index_ci_builds_on_project_id_and_commit_id", using: :btree
|
||||
add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree
|
||||
|
||||
+83
-1
@@ -62,7 +62,8 @@ Parameters:
|
||||
"authored_date": "2012-09-20T09:06:12+03:00",
|
||||
"parent_ids": [
|
||||
"ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"
|
||||
]
|
||||
],
|
||||
"status": "running"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -156,3 +157,84 @@ Parameters:
|
||||
"line_type": "new"
|
||||
}
|
||||
```
|
||||
|
||||
## Get the status of a commit
|
||||
|
||||
Get the statuses of a commit in a project.
|
||||
|
||||
```
|
||||
GET /projects/:id/repository/commits/:sha/statuses
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
- `id` (required) - The ID of a project
|
||||
- `sha` (required) - The commit SHA
|
||||
- `ref` (optional) - Filter by ref name, it can be branch or tag
|
||||
- `stage` (optional) - Filter by stage
|
||||
- `name` (optional) - Filer by status name, eg. jenkins
|
||||
- `all` (optional) - The flag to return all statuses, not only latest ones
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 13,
|
||||
"sha": "b0b3a907f41409829b307a28b82fdbd552ee5a27",
|
||||
"ref": "test",
|
||||
"status": "success",
|
||||
"name": "ci/jenkins",
|
||||
"target_url": "http://jenkins/project/url",
|
||||
"description": "Jenkins success",
|
||||
"created_at": "2015-10-12T09:47:16.250Z",
|
||||
"started_at": "2015-10-12T09:47:16.250Z"",
|
||||
"finished_at": "2015-10-12T09:47:16.262Z",
|
||||
"author": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"email": "admin@local.host",
|
||||
"name": "Administrator",
|
||||
"blocked": false,
|
||||
"created_at": "2012-04-29T08:46:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Post the status to commit
|
||||
|
||||
Adds or updates a status of a commit.
|
||||
|
||||
```
|
||||
POST /projects/:id/statuses/:sha
|
||||
```
|
||||
|
||||
- `id` (required) - The ID of a project
|
||||
- `sha` (required) - The commit SHA
|
||||
- `state` (required) - The state of the status. Can be: pending, running, success, failed, canceled
|
||||
- `ref` (optional) - The ref (branch or tag) to which the status refers
|
||||
- `name` or `context` (optional) - The label to differentiate this status from the status of other systems. Default: "default"
|
||||
- `target_url` (optional) - The target URL to associate with this status
|
||||
- `description` (optional) - The short description of the status
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 13,
|
||||
"sha": "b0b3a907f41409829b307a28b82fdbd552ee5a27",
|
||||
"ref": "test",
|
||||
"status": "success",
|
||||
"name": "ci/jenkins",
|
||||
"target_url": "http://jenkins/project/url",
|
||||
"description": "Jenkins success",
|
||||
"created_at": "2015-10-12T09:47:16.250Z",
|
||||
"started_at": "2015-10-12T09:47:16.250Z"",
|
||||
"finished_at": "2015-10-12T09:47:16.262Z",
|
||||
"author": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"email": "admin@local.host",
|
||||
"name": "Administrator",
|
||||
"blocked": false,
|
||||
"created_at": "2012-04-29T08:46:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -188,6 +188,7 @@ Parameters:
|
||||
- `title` (required) - Title of MR
|
||||
- `description` (optional) - Description of MR
|
||||
- `target_project_id` (optional) - The target project (numeric id)
|
||||
- `labels` (optional) - Labels for MR as a comma-separated list
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -239,6 +240,7 @@ Parameters:
|
||||
- `title` - Title of MR
|
||||
- `description` - Description of MR
|
||||
- `state_event` - New state (close|reopen|merge)
|
||||
- `labels` (optional) - Labels for MR as a comma-separated list
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user