Skip to content
Snippets Groups Projects
Commit 31025753 authored by Andriy Dyadyura's avatar Andriy Dyadyura
Browse files

update

parents e29ce9ac b6ae2def
No related branches found
No related tags found
No related merge requests found
Showing
with 493 additions and 78 deletions
Loading
Loading
@@ -10,8 +10,7 @@
%i.fa.fa-sign-out
 
= image_tag group_icon(group), class: "avatar s46 hidden-xs"
= link_to group, class: 'group-name' do
%strong= group.name
= link_to group.name, group, class: 'group-name'
 
- if group_member
as
Loading
Loading
.issues-filters
.issues-state-filters
%ul.center-top-menu
%ul.nav-links
- if defined?(type) && type == :merge_requests
- page_context_word = 'merge requests'
- else
Loading
Loading
- page_title t('sherlock.title'), t('sherlock.transaction'), t('sherlock.query')
- header_title t('sherlock.title'), sherlock_transactions_path
 
%ul.center-top-menu
%ul.nav-links
%li.active
%a(href="#tab-general" data-toggle="tab")
= t('sherlock.general')
Loading
Loading
- page_title t('sherlock.title'), t('sherlock.transaction')
- header_title t('sherlock.title'), sherlock_transactions_path
 
%ul.center-top-menu
%ul.nav-links
%li.active
%a(href="#tab-general" data-toggle="tab")
= t('sherlock.general')
Loading
Loading
- page_title @user.name
- page_description @user.bio
- header_title @user.name, user_path(@user)
- @no_container = true
- @blank_container = true
 
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
Loading
Loading
@@ -8,6 +10,25 @@
= render 'shared/show_aside'
 
.cover-block
.cover-controls
- if @user == current_user
= link_to profile_path, class: 'btn btn-gray' do
= icon('pencil')
- elsif current_user
%span.report-abuse
- if @user.abuse_report
%button.btn.btn-danger{ title: 'Already reported for abuse',
data: { toggle: 'tooltip', placement: 'left', container: 'body' }}
= icon('exclamation-circle')
- else
= link_to new_abuse_report_path(user_id: @user.id), class: 'btn btn-gray',
title: 'Report abuse', data: {toggle: 'tooltip', placement: 'left', container: 'body'} do
= icon('exclamation-circle')
- if current_user
 
= link_to user_path(@user, :atom, { private_token: current_user.private_token }), class: 'btn btn-gray' do
= icon('rss')
.avatar-holder
= link_to avatar_icon(@user, 400), target: '_blank' do
= image_tag avatar_icon(@user, 90), class: "avatar s90", alt: ''
Loading
Loading
@@ -47,74 +68,56 @@
= icon('map-marker')
= @user.location
 
%ul.nav-links.center
%li.active
= link_to "#activity", 'data-toggle' => 'tab' do
Activity
- if @groups.any?
%li
= link_to "#groups", 'data-toggle' => 'tab' do
Groups
- if @contributed_projects.present?
%li
= link_to "#contributed", 'data-toggle' => 'tab' do
Contributed projects
- if @projects.present?
%li
= link_to "#personal", 'data-toggle' => 'tab' do
Personal projects
 
.cover-controls
- if @user == current_user
= link_to profile_path, class: 'btn btn-gray' do
= icon('pencil')
- elsif current_user
%span.report-abuse
- if @user.abuse_report
%button.btn.btn-danger{ title: 'Already reported for abuse',
data: { toggle: 'tooltip', placement: 'left', container: 'body' }}
= icon('exclamation-circle')
- else
= link_to new_abuse_report_path(user_id: @user.id), class: 'btn btn-gray',
title: 'Report abuse', data: {toggle: 'tooltip', placement: 'left', container: 'body'} do
= icon('exclamation-circle')
- if current_user
 
= link_to user_path(@user, :atom, { private_token: current_user.private_token }), class: 'btn btn-gray' do
= icon('rss')
.gray-content-block.second-block
.user-calendar
%h4.center.light
%i.fa.fa-spinner.fa-spin
.user-calendar-activities
%div{ class: container_class }
.tab-content
.tab-pane.active#activity
.gray-content-block.white.second-block
%div{ class: container_class }
.user-calendar
%h4.center.light
%i.fa.fa-spinner.fa-spin
.user-calendar-activities
 
%ul.center-top-menu.no-top.no-bottom.bottom-border.wide
%li.active
= link_to "#activity", 'data-toggle' => 'tab' do
Activity
- if @groups.any?
%li
= link_to "#groups", 'data-toggle' => 'tab' do
Groups
- if @contributed_projects.present?
%li
= link_to "#contributed", 'data-toggle' => 'tab' do
Contributed projects
- if @projects.present?
%li
= link_to "#personal", 'data-toggle' => 'tab' do
Personal projects
 
.tab-content
.tab-pane.active#activity
.content_list
= spinner
.content_list
= spinner
 
- if @groups.any?
.tab-pane#groups
%ul.content-list
- @groups.each do |group|
= render 'shared/groups/group', group: group
- if @groups.any?
.tab-pane#groups
%ul.content-list
- @groups.each do |group|
= render 'shared/groups/group', group: group
 
- if @contributed_projects.present?
.tab-pane#contributed
.contributed-projects
= render 'shared/projects/list',
projects: @contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 5, stars: true, avatar: true
- if @contributed_projects.present?
.tab-pane#contributed
.contributed-projects
= render 'shared/projects/list',
projects: @contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: true
 
- if @projects.present?
.tab-pane#personal
.personal-projects
= render 'shared/projects/list',
projects: @projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: true
- if @projects.present?
.tab-pane#personal
.personal-projects
= render 'shared/projects/list',
projects: @projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: true
 
:javascript
$(".user-calendar").load("#{user_calendar_path}");
Loading
Loading
@@ -88,6 +88,12 @@ Rails.application.routes.draw do
end
end
 
resources :sent_notifications, only: [], constraints: { id: /\h{32}/ } do
member do
get :unsubscribe
end
end
# Spam reports
resources :abuse_reports, only: [:new, :create]
 
Loading
Loading
@@ -604,9 +610,14 @@ Rails.application.routes.draw do
member do
get :status
post :cancel
get :download
post :retry
end
resource :artifacts, only: [] do
get :download
get :browse, path: 'browse(/*path)', format: false
get :file, path: 'file/*path', format: false
end
end
 
resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do
Loading
Loading
class Gitlab::Seeder::Builds
BUILD_STATUSES = %w(running pending success failed canceled)
def initialize(project)
@project = project
end
def seed!
ci_commits.each do |ci_commit|
build = Ci::Build.new(build_attributes_for(ci_commit))
artifacts_cache_file(artifacts_archive_path) do |file|
build.artifacts_file = file
end
artifacts_cache_file(artifacts_metadata_path) do |file|
build.artifacts_metadata = file
end
begin
build.save!
print '.'
rescue ActiveRecord::RecordInvalid
print 'F'
end
end
end
def ci_commits
commits = @project.repository.commits('master', nil, 5)
commits_sha = commits.map { |commit| commit.raw.id }
commits_sha.map do |sha|
@project.ensure_ci_commit(sha)
end
rescue
[]
end
def build_attributes_for(ci_commit)
{ name: 'test build', commands: "$ build command",
stage: 'test', stage_idx: 1, ref: 'master',
user_id: build_user, gl_project_id: @project.id,
status: build_status, commit_id: ci_commit.id,
created_at: Time.now, updated_at: Time.now }
end
def build_user
@project.team.users.sample
end
def build_status
BUILD_STATUSES.sample
end
def artifacts_archive_path
Rails.root + 'spec/fixtures/ci_build_artifacts.zip'
end
def artifacts_metadata_path
Rails.root + 'spec/fixtures/ci_build_artifacts_metadata.gz'
end
def artifacts_cache_file(file_path)
cache_path = file_path.to_s.gsub('ci_', "p#{@project.id}_")
FileUtils.copy(file_path, cache_path)
File.open(cache_path) do |file|
yield file
end
end
end
Gitlab::Seeder.quiet do
Project.all.sample(10).each do |project|
project_builds = Gitlab::Seeder::Builds.new(project)
project_builds.seed!
end
end
class AddArtifactsMetadataToCiBuild < ActiveRecord::Migration
def change
add_column :ci_builds, :artifacts_metadata, :text
end
end
Loading
Loading
@@ -123,6 +123,7 @@ ActiveRecord::Schema.define(version: 20160113111034) do
t.string "description", limit: 255
t.text "artifacts_file"
t.integer "gl_project_id"
t.text "artifacts_metadata"
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
Loading
Loading
Loading
Loading
@@ -23,6 +23,7 @@
- [Namespaces](namespaces.md)
- [Settings](settings.md)
- [Keys](keys.md)
- [Build Variables](build_variables.md)
 
## Clients
 
Loading
Loading
# Build Variables
## List project variables
Get list of a project's build variables.
```
GET /projects/:id/variables
```
| Attribute | Type | required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a project |
```
curl -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/variables"
```
```json
[
{
"key": "TEST_VARIABLE_1",
"value": "TEST_1"
},
{
"key": "TEST_VARIABLE_2",
"value": "TEST_2"
}
]
```
## Show variable details
Get the details of a project's specific build variable.
```
GET /projects/:id/variables/:key
```
| Attribute | Type | required | Description |
|-----------|---------|----------|-----------------------|
| `id` | integer | yes | The ID of a project |
| `key` | string | yes | The `key` of a variable |
```
curl -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/variables/TEST_VARIABLE_1"
```
```json
{
"key": "TEST_VARIABLE_1",
"value": "TEST_1"
}
```
## Create variable
Create a new build variable.
```
POST /projects/:id/variables
```
| Attribute | Type | required | Description |
|-----------|---------|----------|-----------------------|
| `id` | integer | yes | The ID of a project |
| `key` | string | yes | The `key` of a variable; must have no more than 255 characters; only `A-Z`, `a-z`, `0-9`, and `_` are allowed |
| `value` | string | yes | The `value` of a variable |
```
curl -X POST -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/variables" -F "key=NEW_VARIABLE" -F "value=new value"
```
```json
{
"key": "NEW_VARIABLE",
"value": "new value"
}
```
## Update variable
Update a project's build variable.
```
PUT /projects/:id/variables/:key
```
| Attribute | Type | required | Description |
|-----------|---------|----------|-------------------------|
| `id` | integer | yes | The ID of a project |
| `key` | string | yes | The `key` of a variable |
| `value` | string | yes | The `value` of a variable |
```
curl -X PUT -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/variables/NEW_VARIABLE" -F "value=updated value"
```
```json
{
"key": "NEW_VARIABLE",
"value": "updated value"
}
```
## Remove variable
Remove a project's build variable.
```
DELETE /projects/:id/variables/:key
```
| Attribute | Type | required | Description |
|-----------|---------|----------|-------------------------|
| `id` | integer | yes | The ID of a project |
| `key` | string | yes | The `key` of a variable |
```
curl -X DELETE -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/variables/VARIABLE_1"
```
```json
{
"key": "VARIABLE_1",
"value": "VALUE_1"
}
```
Loading
Loading
@@ -558,7 +558,8 @@ Parameters:
 
- `uid` (required) - id of specified user
 
Will return `200 OK` on success, or `404 User Not Found` is user cannot be found.
Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
`403 Forbidden` when trying to block an already blocked user by LDAP synchronization.
 
## Unblock user
 
Loading
Loading
@@ -572,4 +573,5 @@ Parameters:
 
- `uid` (required) - id of specified user
 
Will return `200 OK` on success, or `404 User Not Found` is user cannot be found.
Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
`403 Forbidden` when trying to unblock a user blocked by LDAP synchronization.
Feature: Project Builds
Background:
Given I sign in as a user
And I own a project
And CI is enabled
And I have recent build for my project
Scenario: I browse build summary page
When I visit recent build summary page
Then I see summary for build
And I see build trace
Scenario: I download build artifacts
Given recent build has artifacts available
When I visit recent build summary page
And I click artifacts download button
Then download of build artifacts archive starts
Scenario: I browse build artifacts
Given recent build has artifacts available
And recent build has artifacts metadata available
When I visit recent build summary page
And I click artifacts browse button
Then I should see content of artifacts archive
Scenario: I browse subdirectory of build artifacts
Given recent build has artifacts available
And recent build has artifacts metadata available
When I visit recent build summary page
And I click artifacts browse button
And I click link to subdirectory within build artifacts
Then I should see content of subdirectory within artifacts archive
Scenario: I browse directory with UTF-8 characters in name
Given recent build has artifacts available
And recent build has artifacts metadata available
And recent build artifacts contain directory with UTF-8 characters
When I visit recent build summary page
And I click artifacts browse button
And I navigate to directory with UTF-8 characters in name
Then I should see content of directory with UTF-8 characters in name
Scenario: I try to browse directory with invalid UTF-8 characters in name
Given recent build has artifacts available
And recent build has artifacts metadata available
And recent build artifacts contain directory with invalid UTF-8 characters
When I visit recent build summary page
And I click artifacts browse button
And I navigate to parent directory of directory with invalid name
Then I should not see directory with invalid name on the list
Scenario: I download a single file from build artifacts
Given recent build has artifacts available
And recent build has artifacts metadata available
When I visit recent build summary page
And I click artifacts browse button
And I click download button for a file within build artifacts
Then download of a file extracted from build artifacts should start
class Spinach::Features::ProjectBuilds < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedBuilds
include RepoHelpers
step 'I see summary for build' do
expect(page).to have_content "Build ##{@build.id}"
end
step 'I see build trace' do
expect(page).to have_css '#build-trace'
end
step 'I click artifacts download button' do
page.within('.artifacts') { click_link 'Download' }
end
step 'download of build artifacts archive starts' do
expect(page.response_headers['Content-Type']).to eq 'application/zip'
expect(page.response_headers['Content-Transfer-Encoding']).to eq 'binary'
end
step 'I click artifacts browse button' do
page.within('.artifacts') { click_link 'Browse' }
end
step 'I should see content of artifacts archive' do
page.within('.tree-table') do
expect(page).to have_no_content '..'
expect(page).to have_content 'other_artifacts_0.1.2'
expect(page).to have_content 'ci_artifacts.txt'
expect(page).to have_content 'rails_sample.jpg'
end
end
step 'I click link to subdirectory within build artifacts' do
page.within('.tree-table') { click_link 'other_artifacts_0.1.2' }
end
step 'I should see content of subdirectory within artifacts archive' do
page.within('.tree-table') do
expect(page).to have_content '..'
expect(page).to have_content 'another-subdirectory'
expect(page).to have_content 'doc_sample.txt'
end
end
step 'recent build artifacts contain directory with UTF-8 characters' do
# metadata fixture contains relevant directory
end
step 'I navigate to directory with UTF-8 characters in name' do
page.within('.tree-table') { click_link 'tests_encoding' }
page.within('.tree-table') { click_link 'utf8 test dir ✓' }
end
step 'I should see content of directory with UTF-8 characters in name' do
page.within('.tree-table') do
expect(page).to have_content '..'
expect(page).to have_content 'regular_file_2'
end
end
step 'recent build artifacts contain directory with invalid UTF-8 characters' do
# metadata fixture contains relevant directory
end
step 'I navigate to parent directory of directory with invalid name' do
page.within('.tree-table') { click_link 'tests_encoding' }
end
step 'I should not see directory with invalid name on the list' do
page.within('.tree-table') do
expect(page).to have_no_content('non-utf8-dir')
end
end
step 'I click download button for a file within build artifacts' do
page.within('.tree-table') { first('.artifact-download').click }
end
step 'download of a file extracted from build artifacts should start' do
# this will be accelerated by Workhorse
response_json = JSON.parse(page.body, symbolize_names: true)
expect(response_json[:archive]).to end_with('build_artifacts.zip')
expect(response_json[:entry]).to eq Base64.encode64('ci_artifacts.txt')
end
end
Loading
Loading
@@ -6,7 +6,7 @@ module SharedActiveTab
end
 
def ensure_active_sub_tab(content)
expect(find('div.content ul.center-top-menu li.active')).to have_content(content)
expect(find('div.content ul.nav-links li.active')).to have_content(content)
end
 
def ensure_active_sub_nav(content)
Loading
Loading
@@ -18,7 +18,7 @@ module SharedActiveTab
end
 
step 'no other sub tabs should be active' do
expect(page).to have_selector('div.content ul.center-top-menu li.active', count: 1)
expect(page).to have_selector('div.content ul.nav-links li.active', count: 1)
end
 
step 'no other sub navs should be active' do
Loading
Loading
module SharedBuilds
include Spinach::DSL
step 'CI is enabled' do
@project.enable_ci
end
step 'I have recent build for my project' do
ci_commit = create :ci_commit, project: @project, sha: sample_commit.id
@build = create :ci_build, commit: ci_commit
end
step 'I visit recent build summary page' do
visit namespace_project_build_path(@project.namespace, @project, @build)
end
step 'recent build has artifacts available' do
artifacts = Rails.root + 'spec/fixtures/ci_build_artifacts.zip'
archive = fixture_file_upload(artifacts, 'application/zip')
@build.update_attributes(artifacts_file: archive)
end
step 'recent build has artifacts metadata available' do
metadata = Rails.root + 'spec/fixtures/ci_build_artifacts_metadata.gz'
gzip = fixture_file_upload(metadata, 'application/x-gzip')
@build.update_attributes(artifacts_metadata: gzip)
end
end
Loading
Loading
@@ -54,5 +54,6 @@ module API
mount Keys
mount Tags
mount Triggers
mount Variables
end
end
Loading
Loading
@@ -366,5 +366,9 @@ module API
class TriggerRequest < Grape::Entity
expose :id, :variables
end
class Variable < Grape::Entity
expose :key, :value
end
end
end
Loading
Loading
@@ -289,12 +289,14 @@ module API
 
# file helpers
 
def uploaded_file!(field, uploads_path)
def uploaded_file(field, uploads_path)
if params[field]
bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename)
return params[field]
end
 
return nil unless params["#{field}.path"] && params["#{field}.name"]
# sanitize file paths
# this requires all paths to exist
required_attributes! %W(#{field}.path)
Loading
Loading
Loading
Loading
@@ -284,10 +284,12 @@ module API
authenticated_as_admin!
user = User.find_by(id: params[:id])
 
if user
if !user
not_found!('User')
elsif !user.ldap_blocked?
user.block
else
not_found!('User')
forbidden!('LDAP blocked users cannot be modified by the API')
end
end
 
Loading
Loading
@@ -299,10 +301,12 @@ module API
authenticated_as_admin!
user = User.find_by(id: params[:id])
 
if user
user.activate
else
if !user
not_found!('User')
elsif user.ldap_blocked?
forbidden!('LDAP blocked users cannot be unblocked by the API')
else
user.activate
end
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment