Commit fecb1a2f authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'master' into issue-discussions-refactor

* master: (21 commits)
  Fix issues with pdf-js dependencies
  fix missing changelog entries for security release on 2017-01-23
  Update top bar issues icon
  Fix order of CI lint ace editor loading
  Fix spec
  Fix spec
  Fix spec
  Add changelog
  fix
  Add a spec for concurrent process
  Add changelog
  essential
  add CHANGELOG.md for !13208
  adjust user contribution calendar time formatting
  fix rubocop violations 👮
  fix mysql syntax for date INTERVAL arithmatic
  add tests for proper timezone date grouping within ContributionsCalendar
  adjust timezone for date grouping in contributions calendar
  use timezone-aware Date.current instead of Date.today in ContributionsCalendar class
  display system timezone underneath activity calendar
  ...
parents 7065bb3e 03b816f3
......@@ -1708,8 +1708,6 @@ entry.
## 8.16.7 (2017-02-27)
- No changes.
- No changes.
- Fix MR changes tab size count when there are over 100 files in the diff.
## 8.16.6 (2017-02-17)
......@@ -1923,6 +1921,14 @@ entry.
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
- Patch XSS vulnerability in RDOC support.
## 8.15.5 (2017-01-20)
- Ensure export files are removed after a namespace is deleted.
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
- Prevent users from creating notes on resources they can't access.
- Prevent users from deleting system deploy keys via the project deploy key API.
- Upgrade omniauth gem to 1.3.2.
## 8.15.4 (2017-01-09)
- Make successful pipeline emails off for watchers. !8176
......@@ -2205,6 +2211,14 @@ entry.
- Speed up group milestone index by passing group_id to IssuesFinder. !8363
- Ensure issuable state changes only fire webhooks once.
## 8.14.7 (2017-01-21)
- Ensure export files are removed after a namespace is deleted.
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
- Prevent users from creating notes on resources they can't access.
- Prevent users from deleting system deploy keys via the project deploy key API.
- Upgrade omniauth gem to 1.3.2.
## 8.14.6 (2017-01-10)
- Update the gitlab-markup gem to the version 1.5.1. !8509
......@@ -2487,6 +2501,14 @@ entry.
- Fix "Without projects" filter. !6611 (Ben Bodenmiller)
- Fix 404 when visit /projects page
## 8.13.12 (2017-01-21)
- Ensure export files are removed after a namespace is deleted.
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
- Prevent users from creating notes on resources they can't access.
- Prevent users from deleting system deploy keys via the project deploy key API.
- Upgrade omniauth gem to 1.3.2.
## 8.13.11 (2017-01-10)
- Update the gitlab-markup gem to the version 1.5.1. !8509
......
......@@ -9,8 +9,8 @@
</template>
<script>
import pdfjsLib from 'pdfjs-dist';
import workerSrc from 'vendor/pdf.worker';
import pdfjsLib from 'vendor/pdf';
import workerSrc from 'vendor/pdf.worker.min';
import page from './page/index.vue';
......
......@@ -7,6 +7,14 @@ const LOADING_HTML = `
</div>
`;
function getSystemDate(systemUtcOffsetSeconds) {
const date = new Date();
const localUtcOffsetMinutes = 0 - date.getTimezoneOffset();
const systemUtcOffsetMinutes = systemUtcOffsetSeconds / 60;
date.setMinutes((date.getMinutes() - localUtcOffsetMinutes) + systemUtcOffsetMinutes);
return date;
}
function formatTooltipText({ date, count }) {
const dateObject = new Date(date);
const dateDayName = gl.utils.getDayName(dateObject);
......@@ -22,7 +30,7 @@ function formatTooltipText({ date, count }) {
const initColorKey = () => d3.scale.linear().range(['#acd5f2', '#254e77']).domain([0, 3]);
export default class ActivityCalendar {
constructor(container, timestamps, calendarActivitiesPath) {
constructor(container, timestamps, calendarActivitiesPath, utcOffset = 0) {
this.calendarActivitiesPath = calendarActivitiesPath;
this.clickDay = this.clickDay.bind(this);
this.currentSelectedDate = '';
......@@ -37,7 +45,7 @@ export default class ActivityCalendar {
this.timestampsTmp = [];
let group = 0;
const today = new Date();
const today = getSystemDate(utcOffset);
today.setHours(0, 0, 0, 0, 0);
const oneYearAgo = new Date(today);
......
......@@ -150,15 +150,21 @@ export default class UserTabs {
const $calendarWrap = this.$parentEl.find('.user-calendar');
const calendarPath = $calendarWrap.data('calendarPath');
const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath');
const utcOffset = $calendarWrap.data('utcOffset');
let utcFormatted = 'UTC';
if (utcOffset !== 0) {
utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`;
}
$.ajax({
dataType: 'json',
url: calendarPath,
success: (activityData) => {
$calendarWrap.html(CALENDAR_TEMPLATE);
$calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`);
// eslint-disable-next-line no-new
new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath);
new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath, utcOffset);
},
});
......
......@@ -45,6 +45,7 @@
margin-top: -23px;
float: right;
font-size: 12px;
direction: ltr;
}
.pika-single.gitlab-theme {
......
......@@ -325,9 +325,9 @@ header {
li {
.badge {
position: inherit;
top: -3px;
top: -8px;
font-weight: normal;
margin-left: -12px;
margin-left: -11px;
font-size: 11px;
color: $white-light;
padding: 1px 5px 2px;
......
......@@ -328,9 +328,17 @@
margin-bottom: 10px;
color: $issuable-sidebar-color;
svg {
fill: $issuable-sidebar-color;
}
&:hover,
&:hover .todo-undone {
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
span {
......
......@@ -12,7 +12,6 @@ module MergeRequests
merge_request.source_project = source_project
merge_request.source_branch = params[:source_branch]
merge_request.merge_params['force_remove_source_branch'] = params.delete(:force_remove_source_branch)
merge_request.head_pipeline = head_pipeline_for(merge_request)
create(merge_request)
end
......@@ -22,10 +21,16 @@ module MergeRequests
notification_service.new_merge_request(issuable, current_user)
todo_service.new_merge_request(issuable, current_user)
issuable.cache_merge_request_closes_issues!(current_user)
update_merge_requests_head_pipeline(issuable)
end
private
def update_merge_requests_head_pipeline(merge_request)
pipeline = head_pipeline_for(merge_request)
merge_request.update(head_pipeline_id: pipeline.id) if pipeline
end
def head_pipeline_for(merge_request)
return unless merge_request.source_project
......
- page_title "CI Lint"
- page_description "Validate your GitLab CI configuration file"
- content_for :page_specific_javascripts do
- content_for :library_javascripts do
= page_specific_javascript_tag('lib/ace.js')
%h2 Check your .gitlab-ci.yml
......
......@@ -38,6 +38,9 @@
= Gon::Base.render_data
- if content_for?(:library_javascripts)
= yield :library_javascripts
= webpack_bundle_tag "webpack_runtime"
= webpack_bundle_tag "common"
= webpack_bundle_tag "locale"
......
......@@ -44,7 +44,7 @@
= icon('tachometer fw')
%li
= link_to assigned_issues_dashboard_path, title: 'Issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('hashtag fw')
= custom_icon('issues')
- issues_count = assigned_issuables_count(:issues)
%span.badge.issues-count{ class: ('hidden' if issues_count.zero?) }
= number_with_delimiter(issues_count)
......
......@@ -38,7 +38,7 @@
= icon('tachometer fw')
%li
= link_to assigned_issues_dashboard_path, title: 'Issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('hashtag fw')
= custom_icon('issues')
- issues_count = assigned_issuables_count(:issues)
%span.badge.issues-count{ class: ('hidden' if issues_count.zero?) }
= number_with_delimiter(issues_count)
......
......@@ -15,7 +15,7 @@
- else
= s_("PipelineSchedules|None")
%td.next-run-cell
- if pipeline_schedule.active?
- if pipeline_schedule.active? && pipeline_schedule.next_run_at
= time_ago_with_tooltip(pipeline_schedule.real_next_run)
- else
= s_("PipelineSchedules|Inactive")
......
......@@ -67,7 +67,7 @@
.block.issues
.sidebar-collapsed-icon
%strong
= icon('hashtag', 'aria-hidden': 'true')
= custom_icon('issues')
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
Issues
......
%h4.prepend-top-20
Contributions for
%strong= @calendar_date.to_s(:short)
%strong= @calendar_date.to_s(:medium)
- if @events.any?
%ul.bordered-list
......@@ -8,7 +8,7 @@
%li
%span.light
%i.fa.fa-clock-o
= event.created_at.to_s(:time)
= event.created_at.strftime('%-I:%M%P')
- if event.push?
#{event.action_name} #{event.ref_type}
%strong
......@@ -30,4 +30,4 @@
= event.project_name
- else
%p
No contributions found for #{@calendar_date.to_s(:short)}
No contributions found for #{@calendar_date.to_s(:medium)}
......@@ -104,7 +104,7 @@
.tab-content
#activity.tab-pane
.row-content-block.calender-block.white.second-block.hidden-xs
.user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path } }
.user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
%h4.center.light
%i.fa.fa-spinner.fa-spin
.user-calendar-activities
......
---
title: Fix timezone inconsistencies in user contribution graph
merge_request: 13208
author:
---
title: Fix an order of operations for CI connection error message in merge request
widget
merge_request: 13252
author:
---
title: Fix pipeline_schedules pages when active schedule has an abnormal state
merge_request: 13286
author:
......@@ -111,9 +111,12 @@ var config = {
options: { limit: 2048 },
},
{
test: /\.(worker\.js|pdf|bmpr)$/,
test: /\.(worker(\.min)?\.js|pdf|bmpr)$/,
exclude: /node_modules/,
loader: 'file-loader',
options: {
name: '[name].[hash].[ext]',
}
},
{
test: /locale\/\w+\/(.*)\.js$/,
......
......@@ -48,7 +48,7 @@ module Gitlab
end
def starting_month
Date.today.month
Date.current.month
end
private
......@@ -66,12 +66,18 @@ module Gitlab
.select(:id)
conditions = t[:created_at].gteq(date_from.beginning_of_day)
.and(t[:created_at].lteq(Date.today.end_of_day))
.and(t[:created_at].lteq(Date.current.end_of_day))
.and(t[:author_id].eq(contributor.id))
date_interval = if Gitlab::Database.postgresql?
"INTERVAL '#{Time.zone.now.utc_offset} seconds'"
else
"INTERVAL #{Time.zone.now.utc_offset} SECOND"
end
Event.reorder(nil)
.select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount')
.group(t[:project_id], t[:target_type], t[:action], 'date(created_at)')
.select(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval}) AS date", 'count(id) as total_amount')
.group(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval})")
.where(conditions)
.having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql)))
end
......
require 'spec_helper'
feature 'Pipelines for Merge Requests', js: true do
given(:user) { create(:user) }
given(:merge_request) { create(:merge_request) }
given(:project) { merge_request.target_project }
describe 'pipeline tab' do
given(:user) { create(:user) }
given(:merge_request) { create(:merge_request) }
given(:project) { merge_request.target_project }
before do
project.team << [user, :master]
sign_in user
end
context 'with pipelines' do
let!(:pipeline) do
create(:ci_empty_pipeline,
project: merge_request.source_project,
ref: merge_request.source_branch,
sha: merge_request.diff_head_sha)
before do
project.team << [user, :master]
sign_in user
end
before do
visit project_merge_request_path(project, merge_request)
context 'with pipelines' do
let!(:pipeline) do
create(:ci_empty_pipeline,
project: merge_request.source_project,
ref: merge_request.source_branch,
sha: merge_request.diff_head_sha)
end
before do
visit project_merge_request_path(project, merge_request)
end
scenario 'user visits merge request pipelines tab' do
page.within('.merge-request-tabs') do
click_link('Pipelines')
end
wait_for_requests
expect(page).to have_selector('.stage-cell')
end
end
scenario 'user visits merge request pipelines tab' do
page.within('.merge-request-tabs') do
click_link('Pipelines')
context 'without pipelines' do
before do
visit project_merge_request_path(project, merge_request)
end
wait_for_requests
expect(page).to have_selector('.stage-cell')
scenario 'user visits merge request page' do
page.within('.merge-request-tabs') do
expect(page).to have_no_link('Pipelines')
end
end
end
end
context 'without pipelines' do
before do
visit project_merge_request_path(project, merge_request)
describe 'race condition' do
given(:project) { create(:project, :repository) }
given(:user) { create(:user) }
given(:build_push_data) { { ref: 'feature', checkout_sha: TestEnv::BRANCH_SHA['feature'] } }
given(:merge_request_params) do
{ "source_branch" => "feature", "source_project_id" => project.id,
"target_branch" => "master", "target_project_id" => project.id, "title" => "A" }
end
background do
project.add_master(user)
sign_in user
end
scenario 'user visits merge request page' do
page.within('.merge-request-tabs') do
expect(page).to have_no_link('Pipelines')
context 'when pipeline and merge request were created simultaneously' do
background do
stub_ci_pipeline_to_return_yaml_file
threads = []
threads << Thread.new do
@merge_request = MergeRequests::CreateService.new(project, user, merge_request_params).execute
end
threads << Thread.new do
@pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push)
end
threads.each { |thr| thr.join }
end
scenario 'user sees pipeline in merge request widget' do
visit project_merge_request_path(project, @merge_request)
expect(page.find(".ci-widget")).to have_content(TestEnv::BRANCH_SHA['feature'])
expect(page.find(".ci-widget")).to have_content("##{@pipeline.id}")
end
end
end
......
......@@ -219,6 +219,25 @@ feature 'Pipeline Schedules', :js do
end
end
end
context 'when active is true and next_run_at is NULL' do
background do
create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
pipeline_schedule.update_attribute(:cron, nil) # Consequently next_run_at will be nil
end
end
scenario 'user edit and recover the problematic pipeline schedule' do
visit_pipelines_schedules
find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
fill_in 'schedule_cron', with: '* 1 2 3 4'
click_button 'Save pipeline schedule'
page.within('.pipeline-schedule-table-row:nth-child(1)') do
expect(page).to have_css(".next-run-cell time")
end
end
end
end
context 'logged in as non-member' do
......
/* eslint-disable import/no-unresolved */
import Vue from 'vue';
import { PDFJS } from 'pdfjs-dist';
import workerSrc from 'vendor/pdf.worker';
import { PDFJS } from 'vendor/pdf';
import workerSrc from 'vendor/pdf.worker.min';
import PDFLab from '~/pdf/index.vue';
import pdf from '../fixtures/blob/pdf/test.pdf';
......
/* eslint-disable import/no-unresolved */
import Vue from 'vue';
import pdfjsLib from 'pdfjs-dist';
import workerSrc from 'vendor/pdf.worker';
import pdfjsLib from 'vendor/pdf';
import workerSrc from 'vendor/pdf.worker.min';
import PageComponent from '~/pdf/page/index.vue';
import testPDF from '../fixtures/blob/pdf/test.pdf';
......
......@@ -22,12 +22,14 @@ describe Gitlab::ContributionsCalendar do
end
end
let(:today) { Time.now.to_date }
let(:today) { Time.now.utc.to_date }
let(:yesterday) { today - 1.day }
let(:tomorrow) { today + 1.day }
let(:last_week) { today - 7.days }
let(:last_year) { today - 1.year }
before do
travel_to today
travel_to Time.now.utc.end_of_day
end
after do
......@@ -38,7 +40,7 @@ describe Gitlab::ContributionsCalendar do
described_class.new(contributor, current_user)
end
def create_event(project, day)
def create_event(project, day, hour = 0)
@targets ||= {}
@targets[project] ||= create(:issue, project: project, author: contributor)
......@@ -47,7 +49,7 @@ describe Gitlab::ContributionsCalendar do
action: Event::CREATED,
target: @targets[project],
author: contributor,
created_at: day
created_at: DateTime.new(day.year, day.month, day.day, hour)
)
end
......@@ -68,6 +70,34 @@ describe Gitlab::ContributionsCalendar do
expect(calendar(user).activity_dates[today]).to eq(0)
expect(calendar(contributor).activity_dates[today]).to eq(2)
end
context "when events fall under different dates depending on the time zone" do
before do
create_event(public_project, today, 1)
create_event(public_project, today, 4)
create_event(public_project, today, 10)
create_event(public_project, today, 16)
create_event(public_project, today, 23)
end
it "renders correct event counts within the UTC timezone" do
Time.use_zone('UTC') do
expect(calendar.activity_dates).to eq(today => 5)
end
end
it "renders correct event counts within the Sydney timezone" do
Time.use_zone('Sydney') do
expect(calendar.activity_dates).to eq(today => 3, tomorrow => 2)
end
end
it "renders correct event counts within the US Central timezone" do
Time.use_zone('Central Time (US & Canada)') do
expect(calendar.activity_dates).to eq(yesterday => 2, today => 3)
end
end
end
end
describe '#events_by_date' do
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
......@@ -3771,10 +3771,6 @@ nested-error-stacks@^1.0.0:
dependencies:
inherits "~2.0.1"
node-ensure@^0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7"
node-libs-browser@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-1.1.1.tgz#2a38243abedd7dffcd07a97c9aca5668975a6fea"
......@@ -4185,13 +4181,6 @@ pbkdf2@^3.0.3:
dependencies:
create-hmac "^1.1.2"
pdfjs-dist@^1.8.252:
version "1.8.252"
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-1.8.252.tgz#2477245695341f7fe096824dacf327bc324c0f52"
dependencies:
node-ensure "^0.0.0"
worker-loader "^0.8.0"
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
......@@ -5932,12 +5921,6 @@ wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
worker-loader@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-0.8.0.tgz#13582960dcd7d700dc829d3fd252a7561696167e"
dependencies:
loader-utils "^1.0.2"
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment