Merge branch 'master' into discussions
|
@ -1,3 +1,4 @@
|
||||||
|
language: ruby
|
||||||
env:
|
env:
|
||||||
- DB=postgresql
|
- DB=postgresql
|
||||||
- DB=mysql
|
- DB=mysql
|
||||||
|
@ -8,7 +9,7 @@ branches:
|
||||||
only:
|
only:
|
||||||
- 'master'
|
- 'master'
|
||||||
rvm:
|
rvm:
|
||||||
- 1.9.2
|
- 1.9.3-p327
|
||||||
services:
|
services:
|
||||||
- mysql
|
- mysql
|
||||||
- postgresql
|
- postgresql
|
||||||
|
|
21
CHANGELOG
|
@ -1,3 +1,24 @@
|
||||||
|
v 4.1.0
|
||||||
|
- Project public mode (only admin can set now)
|
||||||
|
- Public area with unauthorized access
|
||||||
|
- Load dashboard events with ajax
|
||||||
|
- remember dashboard filter in cookies
|
||||||
|
- replace resque with sidekiq
|
||||||
|
- fix routing issues
|
||||||
|
- cleanup rake tasks
|
||||||
|
- fix backup/restore
|
||||||
|
- scss cleanup
|
||||||
|
- show preview for note images
|
||||||
|
- improved network-graph
|
||||||
|
- get rid of app/roles/
|
||||||
|
- added new classes Team, Repository
|
||||||
|
- Reduce amount of gitolite calls
|
||||||
|
- Ability to add user in all group projects
|
||||||
|
- remove derecated configs
|
||||||
|
- replaced Korolev font with open font
|
||||||
|
- restyled admin/dashboard page
|
||||||
|
- restyled admin/projects page
|
||||||
|
|
||||||
v 4.0.0
|
v 4.0.0
|
||||||
- Remove project code and path from API. Use id instead
|
- Remove project code and path from API. Use id instead
|
||||||
- Return valid clonable url to repo for web hook
|
- Return valid clonable url to repo for web hook
|
||||||
|
|
3
Gemfile
|
@ -71,7 +71,6 @@ gem "redcarpet", "~> 2.2.2"
|
||||||
gem "github-markup", "~> 0.7.4", require: 'github/markup'
|
gem "github-markup", "~> 0.7.4", require: 'github/markup'
|
||||||
|
|
||||||
# Servers
|
# Servers
|
||||||
gem "thin", '~> 1.5.0'
|
|
||||||
gem "unicorn", "~> 4.4.0"
|
gem "unicorn", "~> 4.4.0"
|
||||||
|
|
||||||
# Issue tags
|
# Issue tags
|
||||||
|
@ -111,7 +110,7 @@ group :assets do
|
||||||
gem "modernizr", "2.6.2"
|
gem "modernizr", "2.6.2"
|
||||||
gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
|
gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
|
||||||
gem 'bootstrap-sass', "2.2.1.1"
|
gem 'bootstrap-sass', "2.2.1.1"
|
||||||
gem "font-awesome-sass-rails", "~> 2.0.0"
|
gem "font-awesome-sass-rails", "~> 3.0.0"
|
||||||
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
12
Gemfile.lock
|
@ -144,7 +144,6 @@ GEM
|
||||||
colorize (0.5.8)
|
colorize (0.5.8)
|
||||||
connection_pool (1.0.0)
|
connection_pool (1.0.0)
|
||||||
crack (0.3.1)
|
crack (0.3.1)
|
||||||
daemons (1.1.9)
|
|
||||||
devise (2.1.2)
|
devise (2.1.2)
|
||||||
bcrypt-ruby (~> 3.0)
|
bcrypt-ruby (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
|
@ -174,7 +173,7 @@ GEM
|
||||||
eventmachine (>= 0.12.0)
|
eventmachine (>= 0.12.0)
|
||||||
ffaker (1.15.0)
|
ffaker (1.15.0)
|
||||||
ffi (1.1.5)
|
ffi (1.1.5)
|
||||||
font-awesome-sass-rails (2.0.0.0)
|
font-awesome-sass-rails (3.0.0.1)
|
||||||
railties (>= 3.1.1)
|
railties (>= 3.1.1)
|
||||||
sass-rails (>= 3.1.1)
|
sass-rails (>= 3.1.1)
|
||||||
foreman (0.60.2)
|
foreman (0.60.2)
|
||||||
|
@ -381,7 +380,7 @@ GEM
|
||||||
rspec-mocks (~> 2.12.0)
|
rspec-mocks (~> 2.12.0)
|
||||||
rubyntlm (0.1.1)
|
rubyntlm (0.1.1)
|
||||||
rubyzip (0.9.9)
|
rubyzip (0.9.9)
|
||||||
sass (3.2.3)
|
sass (3.2.5)
|
||||||
sass-rails (3.2.5)
|
sass-rails (3.2.5)
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
sass (>= 3.1.10)
|
sass (>= 3.1.10)
|
||||||
|
@ -437,10 +436,6 @@ GEM
|
||||||
test_after_commit (0.0.1)
|
test_after_commit (0.0.1)
|
||||||
therubyracer (0.10.2)
|
therubyracer (0.10.2)
|
||||||
libv8 (~> 3.3.10)
|
libv8 (~> 3.3.10)
|
||||||
thin (1.5.0)
|
|
||||||
daemons (>= 1.0.9)
|
|
||||||
eventmachine (>= 0.12.6)
|
|
||||||
rack (>= 1.0.0)
|
|
||||||
thor (0.16.0)
|
thor (0.16.0)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
timers (1.0.2)
|
timers (1.0.2)
|
||||||
|
@ -488,7 +483,7 @@ DEPENDENCIES
|
||||||
email_spec
|
email_spec
|
||||||
factory_girl_rails
|
factory_girl_rails
|
||||||
ffaker
|
ffaker
|
||||||
font-awesome-sass-rails (~> 2.0.0)
|
font-awesome-sass-rails (~> 3.0.0)
|
||||||
foreman
|
foreman
|
||||||
gemoji (~> 1.2.1)
|
gemoji (~> 1.2.1)
|
||||||
git
|
git
|
||||||
|
@ -547,7 +542,6 @@ DEPENDENCIES
|
||||||
stamp
|
stamp
|
||||||
test_after_commit
|
test_after_commit
|
||||||
therubyracer
|
therubyracer
|
||||||
thin (~> 1.5.0)
|
|
||||||
uglifier (~> 1.3.0)
|
uglifier (~> 1.3.0)
|
||||||
unicorn (~> 4.4.0)
|
unicorn (~> 4.4.0)
|
||||||
webmock
|
webmock
|
||||||
|
|
2
Procfile
|
@ -1,2 +1,2 @@
|
||||||
web: bundle exec rails s -p $PORT
|
web: bundle exec unicorn_rails -p $PORT
|
||||||
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,common,default
|
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,common,default
|
||||||
|
|
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 750 B |
Before Width: | Height: | Size: 463 B |
Before Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 463 B |
Before Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 357 B |
|
@ -1,7 +1,4 @@
|
||||||
$ ->
|
window.dashboardPage = ->
|
||||||
dashboardPage()
|
|
||||||
|
|
||||||
dashboardPage = ->
|
|
||||||
Pager.init 20, true
|
Pager.init 20, true
|
||||||
$(".event_filter_link").bind "click", (event) ->
|
$(".event_filter_link").bind "click", (event) ->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
@import "sections/profile.scss";
|
@import "sections/profile.scss";
|
||||||
@import "sections/login.scss";
|
@import "sections/login.scss";
|
||||||
@import "sections/editor.scss";
|
@import "sections/editor.scss";
|
||||||
|
@import "sections/admin.scss";
|
||||||
|
|
||||||
@import "highlight/white.scss";
|
@import "highlight/white.scss";
|
||||||
@import "highlight/dark.scss";
|
@import "highlight/dark.scss";
|
||||||
|
|
|
@ -371,6 +371,7 @@ li.note {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +446,19 @@ li.note {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning_message {
|
||||||
|
border-left: 4px solid #ed9;
|
||||||
|
color: #b90;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
background: #ffffe6;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
&.centered {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.oauth_select_holder {
|
.oauth_select_holder {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
img {
|
img {
|
||||||
|
|
|
@ -37,24 +37,6 @@
|
||||||
background: #fff;
|
background: #fff;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|
||||||
&.wiki {
|
|
||||||
font-size: 13px;
|
|
||||||
code {
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
h1 { font-size: 26px; line-height: 46px; }
|
|
||||||
h2 { font-size: 22px; line-height: 42px; }
|
|
||||||
h3 { font-size: 20px; line-height: 40px; }
|
|
||||||
h4 { font-size: 18px; line-height: 32px; }
|
|
||||||
h5 { font-size: 16px; line-height: 26px; }
|
|
||||||
|
|
||||||
.white .highlight pre {
|
|
||||||
background: #f5f5f5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.image_file {
|
&.image_file {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -64,6 +46,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.wiki {
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
&.blob_file {
|
&.blob_file {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,3 +81,22 @@ a:focus {
|
||||||
.monospace {
|
.monospace {
|
||||||
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
|
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wiki typography
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.wiki {
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
code { padding: 0 4px; }
|
||||||
|
p { font-size: 13px; }
|
||||||
|
h1 { font-size: 32px; line-height: 40px; margin: 10px 0;}
|
||||||
|
h2 { font-size: 26px; line-height: 40px; margin: 10px 0;}
|
||||||
|
h3 { font-size: 22px; line-height: 40px; margin: 10px 0;}
|
||||||
|
h4 { font-size: 18px; line-height: 20px; margin: 10px 0;}
|
||||||
|
h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
|
||||||
|
h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
|
||||||
|
.white .highlight pre { background: #f5f5f5; }
|
||||||
|
ul { margin: 0 0 9px 25px !important; }
|
||||||
|
}
|
||||||
|
|
5
app/assets/stylesheets/sections/admin.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.admin-filter form {
|
||||||
|
label { width: 110px; }
|
||||||
|
.controls { margin-left: 130px; }
|
||||||
|
.form-actions { padding-left: 130px; background: #fff }
|
||||||
|
}
|
|
@ -132,21 +132,25 @@
|
||||||
.event_filter {
|
.event_filter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
margin-left: -50px;
|
margin-left: -55px;
|
||||||
|
|
||||||
.filter_icon {
|
.filter_icon {
|
||||||
float: left;
|
a {
|
||||||
border-left: 3px solid #4bc;
|
text-align:center;
|
||||||
padding: 7px;
|
border-left: 3px solid #29B;
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
img {
|
float: left;
|
||||||
width: 20px;
|
padding: 9px 7px;
|
||||||
|
font-size: 18px;
|
||||||
|
width: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.inactive {
|
&.inactive {
|
||||||
border-left: 3px solid #EEE;
|
a {
|
||||||
opacity: 0.5;
|
color: #DDD;
|
||||||
|
border-left: 3px solid #EEE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,18 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
td.blame-commit {
|
||||||
|
background: #f9f9f9;
|
||||||
|
min-width: 350px;
|
||||||
|
}
|
||||||
|
td.blame-numbers {
|
||||||
|
pre {
|
||||||
|
color: #AAA;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
background: #f1f1f1;
|
||||||
|
border-left: 1px solid #DDD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ class Admin::ProjectsController < AdminController
|
||||||
def index
|
def index
|
||||||
@projects = Project.scoped
|
@projects = Project.scoped
|
||||||
@projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
|
@projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
|
||||||
|
@projects = @projects.where(public: true) if params[:public_only].present?
|
||||||
|
@projects = @projects.with_push if params[:with_push].present?
|
||||||
|
@projects = @projects.abandoned if params[:abandoned].present?
|
||||||
@projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id
|
@projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id
|
||||||
@projects = @projects.search(params[:name]) if params[:name].present?
|
@projects = @projects.search(params[:name]) if params[:name].present?
|
||||||
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
||||||
|
|
12
app/controllers/public/projects_controller.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class Public::ProjectsController < ApplicationController
|
||||||
|
skip_before_filter :authenticate_user!,
|
||||||
|
:reject_blocked, :set_current_user_for_observers,
|
||||||
|
:add_abilities
|
||||||
|
|
||||||
|
layout 'public'
|
||||||
|
|
||||||
|
def index
|
||||||
|
@projects = Project.public
|
||||||
|
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,20 +2,19 @@ class WikisController < ProjectResourceController
|
||||||
before_filter :authorize_read_wiki!
|
before_filter :authorize_read_wiki!
|
||||||
before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
|
before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
|
||||||
before_filter :authorize_admin_wiki!, only: :destroy
|
before_filter :authorize_admin_wiki!, only: :destroy
|
||||||
|
|
||||||
def pages
|
def pages
|
||||||
@wikis = @project.wikis.group(:slug).order("created_at")
|
@wiki_pages = @project.wikis.group(:slug).ordered
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
if params[:old_page_id]
|
@most_recent_wiki = @project.wikis.where(slug: params[:id]).ordered.first
|
||||||
@wiki = @project.wikis.find(params[:old_page_id])
|
if params[:version_id]
|
||||||
|
@wiki = @project.wikis.find(params[:version_id])
|
||||||
else
|
else
|
||||||
@wiki = @project.wikis.where(slug: params[:id]).order("created_at").last
|
@wiki = @most_recent_wiki
|
||||||
end
|
end
|
||||||
|
|
||||||
@note = @project.notes.new(noteable: @wiki)
|
|
||||||
|
|
||||||
if @wiki
|
if @wiki
|
||||||
render 'show'
|
render 'show'
|
||||||
else
|
else
|
||||||
|
@ -29,7 +28,7 @@ class WikisController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@wiki = @project.wikis.where(slug: params[:id]).order("created_at").last
|
@wiki = @project.wikis.where(slug: params[:id]).ordered.first
|
||||||
@wiki = Wiki.regenerate_from @wiki
|
@wiki = Wiki.regenerate_from @wiki
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,9 +46,9 @@ class WikisController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def history
|
def history
|
||||||
@wikis = @project.wikis.where(slug: params[:id]).order("created_at")
|
@wiki_pages = @project.wikis.where(slug: params[:id]).ordered
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@wikis = @project.wikis.where(slug: params[:id]).delete_all
|
@wikis = @project.wikis.where(slug: params[:id]).delete_all
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,17 @@ module EventsHelper
|
||||||
|
|
||||||
content_tag :div, class: "filter_icon #{inactive}" do
|
content_tag :div, class: "filter_icon #{inactive}" do
|
||||||
link_to dashboard_path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
|
link_to dashboard_path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
|
||||||
image_tag "event_filter_#{key}.png"
|
content_tag :i, nil, class: icon_for_event[key]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def icon_for_event
|
||||||
|
{
|
||||||
|
EventFilter.push => "icon-upload-alt",
|
||||||
|
EventFilter.merged => "icon-check",
|
||||||
|
EventFilter.comments => "icon-comments",
|
||||||
|
EventFilter.team => "icon-user",
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,19 +26,17 @@ module ProjectsHelper
|
||||||
# Build avatar image tag
|
# Build avatar image tag
|
||||||
avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av")
|
avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av")
|
||||||
|
|
||||||
# Build name strong tag
|
# Build name span tag
|
||||||
name = content_tag :strong, author.name, class: 'author'
|
name = content_tag :span, author.name, class: 'author'
|
||||||
|
|
||||||
author_html = avatar + name
|
author_html = avatar + name
|
||||||
|
|
||||||
tm = project.team_member_by_id(author)
|
tm = project.team_member_by_id(author)
|
||||||
|
|
||||||
content_tag :span, class: 'member-link' do
|
if tm
|
||||||
if tm
|
link_to author_html, project_team_member_path(project, tm), class: "author_link"
|
||||||
link_to author_html, project_team_member_path(project, tm), class: "author_link"
|
else
|
||||||
else
|
author_html
|
||||||
author_html
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Project < ActiveRecord::Base
|
||||||
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
|
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
|
||||||
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
|
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
|
||||||
|
|
||||||
attr_accessible :namespace_id, :creator_id, as: :admin
|
attr_accessible :namespace_id, :creator_id, :public, as: :admin
|
||||||
|
|
||||||
attr_accessor :error_code
|
attr_accessor :error_code
|
||||||
|
|
||||||
|
@ -81,8 +81,21 @@ class Project < ActiveRecord::Base
|
||||||
scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
|
scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
|
||||||
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
|
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
|
||||||
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
|
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
|
||||||
|
scope :public, where(public: true)
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def abandoned
|
||||||
|
project_ids = Event.select('max(created_at) as latest_date, project_id').
|
||||||
|
group('project_id').
|
||||||
|
having('latest_date < ?', 6.months.ago).map(&:project_id)
|
||||||
|
|
||||||
|
where(id: project_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_push
|
||||||
|
includes(:events).where('events.action = ?', Event::Pushed)
|
||||||
|
end
|
||||||
|
|
||||||
def active
|
def active
|
||||||
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
|
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
|
||||||
end
|
end
|
||||||
|
|
|
@ -151,12 +151,12 @@ class Repository
|
||||||
return nil unless commit
|
return nil unless commit
|
||||||
|
|
||||||
# Build file path
|
# Build file path
|
||||||
file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
|
file_name = self.path_with_namespace + "-" + commit.id.to_s + ".tar.gz"
|
||||||
storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
|
storage_path = Rails.root.join("tmp", "repositories")
|
||||||
file_path = File.join(storage_path, file_name)
|
file_path = File.join(storage_path, file_name)
|
||||||
|
|
||||||
# Put files into a directory before archiving
|
# Put files into a directory before archiving
|
||||||
prefix = self.path + "/"
|
prefix = self.path_with_namespace + "/"
|
||||||
|
|
||||||
# Create file if not exists
|
# Create file if not exists
|
||||||
unless File.exists?(file_path)
|
unless File.exists?(file_path)
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Wiki < ActiveRecord::Base
|
||||||
|
|
||||||
before_update :set_slug
|
before_update :set_slug
|
||||||
|
|
||||||
|
scope :ordered, order("created_at DESC")
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
slug
|
slug
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,17 +25,51 @@
|
||||||
= link_to 'New User', new_admin_user_path, class: "btn small"
|
= link_to 'New User', new_admin_user_path, class: "btn small"
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.span6
|
.span4
|
||||||
%h3 Latest projects
|
%h4 Latest projects
|
||||||
%hr
|
%hr
|
||||||
- @projects.each do |project|
|
- @projects.each do |project|
|
||||||
%p
|
%p
|
||||||
= link_to project.name_with_namespace, [:admin, project]
|
= link_to project.name_with_namespace, [:admin, project]
|
||||||
.span6
|
%span.light.right
|
||||||
%h3 Latest users
|
= time_ago_in_words project.created_at
|
||||||
|
ago
|
||||||
|
|
||||||
|
.span4
|
||||||
|
%h4 Latest users
|
||||||
%hr
|
%hr
|
||||||
- @users.each do |user|
|
- @users.each do |user|
|
||||||
%p
|
%p
|
||||||
= link_to [:admin, user] do
|
= link_to [:admin, user] do
|
||||||
= user.name
|
= user.name
|
||||||
%small= user.email
|
%span.light.right
|
||||||
|
= time_ago_in_words user.created_at
|
||||||
|
ago
|
||||||
|
|
||||||
|
.span4
|
||||||
|
%h4 Stats
|
||||||
|
%hr
|
||||||
|
%p
|
||||||
|
Issues
|
||||||
|
%span.light.right
|
||||||
|
= Issue.count
|
||||||
|
%p
|
||||||
|
Merge Requests
|
||||||
|
%span.light.right
|
||||||
|
= MergeRequest.count
|
||||||
|
%p
|
||||||
|
Notes
|
||||||
|
%span.light.right
|
||||||
|
= Note.count
|
||||||
|
%p
|
||||||
|
Snippets
|
||||||
|
%span.light.right
|
||||||
|
= Snippet.count
|
||||||
|
%p
|
||||||
|
SSH Keys
|
||||||
|
%span.light.right
|
||||||
|
= Key.count
|
||||||
|
%p
|
||||||
|
Milestones
|
||||||
|
%span.light.right
|
||||||
|
= Milestone.count
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
= link_to "application.log", "#application", 'data-toggle' => 'tab'
|
= link_to "application.log", "#application", 'data-toggle' => 'tab'
|
||||||
%li
|
%li
|
||||||
= link_to "production.log", "#production", 'data-toggle' => 'tab'
|
= link_to "production.log", "#production", 'data-toggle' => 'tab'
|
||||||
|
%li
|
||||||
|
= link_to "sidekiq.log", "#sidekiq", 'data-toggle' => 'tab'
|
||||||
|
|
||||||
%p.light To prevent perfomance issues admin logs output the last 2000 lines
|
%p.light To prevent perfomance issues admin logs output the last 2000 lines
|
||||||
.tab-content
|
.tab-content
|
||||||
|
@ -50,3 +52,17 @@
|
||||||
- Gitlab::Logger.read_latest_for('production.log').each do |line|
|
- Gitlab::Logger.read_latest_for('production.log').each do |line|
|
||||||
%li
|
%li
|
||||||
%p= line
|
%p= line
|
||||||
|
.tab-pane#sidekiq
|
||||||
|
.file_holder#README
|
||||||
|
.file_title
|
||||||
|
%i.icon-file
|
||||||
|
sidekiq.log
|
||||||
|
.right
|
||||||
|
= link_to '#', class: 'log-bottom' do
|
||||||
|
%i.icon-arrow-down
|
||||||
|
Scroll down
|
||||||
|
.file_content.logs
|
||||||
|
%ol
|
||||||
|
- Gitlab::Logger.read_latest_for('sidekiq.log').each do |line|
|
||||||
|
%li
|
||||||
|
%p= line
|
||||||
|
|
|
@ -43,6 +43,13 @@
|
||||||
= f.label :wiki_enabled, "Wiki"
|
= f.label :wiki_enabled, "Wiki"
|
||||||
.input= f.check_box :wiki_enabled
|
.input= f.check_box :wiki_enabled
|
||||||
|
|
||||||
|
%fieldset.features
|
||||||
|
%legend Public mode:
|
||||||
|
.clearfix
|
||||||
|
= f.label :public do
|
||||||
|
%span Allow public http clone
|
||||||
|
.input= f.check_box :public
|
||||||
|
|
||||||
%fieldset.features
|
%fieldset.features
|
||||||
%legend Transfer:
|
%legend Transfer:
|
||||||
.control-group
|
.control-group
|
||||||
|
|
|
@ -1,38 +1,61 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Projects (#{Project.count})
|
Projects
|
||||||
= link_to 'New Project', new_project_path, class: "btn small right"
|
= link_to 'New Project', new_project_path, class: "btn small right"
|
||||||
%br
|
|
||||||
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
|
|
||||||
= select_tag :namespace_id, namespaces_options(params[:namespace_id], :all), class: "chosen xlarge", prompt: "Project namespace"
|
|
||||||
= text_field_tag :name, params[:name], class: "xlarge"
|
|
||||||
= submit_tag "Search", class: "btn submit primary"
|
|
||||||
|
|
||||||
%table
|
%hr
|
||||||
%thead
|
|
||||||
%tr
|
|
||||||
%th
|
|
||||||
Name
|
|
||||||
%i.icon-sort-down
|
|
||||||
%th Path
|
|
||||||
%th Team Members
|
|
||||||
%th Owner
|
|
||||||
%th Last Commit
|
|
||||||
%th Edit
|
|
||||||
%th.cred Danger Zone!
|
|
||||||
|
|
||||||
- @projects.each do |project|
|
.row
|
||||||
%tr
|
.span4
|
||||||
%td
|
.admin-filter
|
||||||
= link_to project.name_with_namespace, [:admin, project]
|
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
|
||||||
%td
|
.control-group
|
||||||
%span.monospace= project.path_with_namespace + ".git"
|
= label_tag :name, 'Name:', class: 'control-label'
|
||||||
%td= project.users_projects.count
|
.controls
|
||||||
%td
|
= text_field_tag :name, params[:name], class: "span2"
|
||||||
- if project.owner
|
|
||||||
= link_to project.owner.name, [:admin, project.owner]
|
.control-group
|
||||||
|
= label_tag :namespace_id, 'Namespace:', class: 'control-label'
|
||||||
|
.controls
|
||||||
|
= select_tag :namespace_id, namespaces_options(params[:namespace_id], :all), class: "chosen span2", prompt: "Any"
|
||||||
|
.control-group
|
||||||
|
= label_tag :public_only, 'Public Only', class: 'control-label'
|
||||||
|
.controls
|
||||||
|
= check_box_tag :public_only, 1, params[:public_only]
|
||||||
|
.control-group
|
||||||
|
= label_tag :with_push, 'Not empty', class: 'control-label'
|
||||||
|
.controls
|
||||||
|
= check_box_tag :with_push, 1, params[:with_push]
|
||||||
|
|
||||||
|
%span.light Projects with push events
|
||||||
|
.control-group
|
||||||
|
= label_tag :abandoned, 'Abandoned', class: 'control-label'
|
||||||
|
.controls
|
||||||
|
= check_box_tag :abandoned, 1, params[:abandoned]
|
||||||
|
|
||||||
|
%span.light No activity over 6 month
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.form-actions
|
||||||
|
= submit_tag "Search", class: "btn submit primary"
|
||||||
|
= link_to "Reset", admin_projects_path, class: "btn"
|
||||||
|
.span8
|
||||||
|
.ui-box
|
||||||
|
%h5.title
|
||||||
|
Projects (#{@projects.total_count})
|
||||||
|
%ul.well-list
|
||||||
|
- @projects.each do |project|
|
||||||
|
%li
|
||||||
|
- if project.public
|
||||||
|
%i.icon-unlock.cred
|
||||||
|
- else
|
||||||
|
%i.icon-lock.cgreen
|
||||||
|
= link_to project.name_with_namespace, [:admin, project]
|
||||||
|
.right
|
||||||
|
= link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"
|
||||||
|
= link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"
|
||||||
|
- if @projects.blank?
|
||||||
|
%p.nothing_here_message 0 projects matches
|
||||||
- else
|
- else
|
||||||
(deleted)
|
%li.bottom
|
||||||
%td= last_commit(project)
|
= paginate @projects, theme: "gitlab"
|
||||||
%td= link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"
|
|
||||||
%td.bgred= link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"
|
|
||||||
= paginate @projects, theme: "admin"
|
|
||||||
|
|
|
@ -77,6 +77,13 @@
|
||||||
SSH:
|
SSH:
|
||||||
%td
|
%td
|
||||||
= link_to @project.ssh_url_to_repo
|
= link_to @project.ssh_url_to_repo
|
||||||
|
- if @project.public
|
||||||
|
%tr.bgred
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
Public Read-Only Code access:
|
||||||
|
%td
|
||||||
|
= check_box_tag 'public', nil, @project.public
|
||||||
|
|
||||||
- if @repository
|
- if @repository
|
||||||
%table.zebra-striped
|
%table.zebra-striped
|
||||||
|
|
|
@ -20,16 +20,27 @@
|
||||||
%span.options= render "tree/blob_actions"
|
%span.options= render "tree/blob_actions"
|
||||||
.file_content.blame
|
.file_content.blame
|
||||||
%table
|
%table
|
||||||
|
- current_line = 1
|
||||||
- @blame.each do |commit, lines|
|
- @blame.each do |commit, lines|
|
||||||
- commit = Commit.new(commit)
|
- commit = CommitDecorator.decorate(Commit.new(commit))
|
||||||
- commit = CommitDecorator.decorate(commit)
|
|
||||||
%tr
|
%tr
|
||||||
%td.author= commit.author_link avatar: true, size: 16
|
%td.blame-commit
|
||||||
%td.blame_commit
|
%span.commit
|
||||||
|
= link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
|
||||||
%code= link_to commit.short_id, project_commit_path(@project, commit)
|
|
||||||
= link_to_gfm truncate(commit.title, length: 30), project_commit_path(@project, commit), class: "row_title" rescue "--broken encoding"
|
= commit.author_link avatar: true, size: 16
|
||||||
|
|
||||||
|
= link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title"
|
||||||
|
%td.lines.blame-numbers
|
||||||
|
%pre
|
||||||
|
- if lines.empty?
|
||||||
|
= current_line
|
||||||
|
- current_line += 1
|
||||||
|
- else
|
||||||
|
- lines.each do |line|
|
||||||
|
= current_line
|
||||||
|
- current_line += 1
|
||||||
%td.lines
|
%td.lines
|
||||||
= preserve do
|
%pre
|
||||||
%pre
|
- lines.each do |line|
|
||||||
= lines.join("\n")
|
= line
|
||||||
|
|
|
@ -7,3 +7,6 @@
|
||||||
|
|
||||||
- else
|
- else
|
||||||
= render "zero_authorized_projects"
|
= render "zero_authorized_projects"
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
dashboardPage();
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
- if @issues.any?
|
- if @issues.any?
|
||||||
- @issues.group_by(&:project).each do |group|
|
- @issues.group_by(&:project).each do |group|
|
||||||
%div.ui-box
|
%div.ui-box
|
||||||
- @project = group[0]
|
- project = group[0]
|
||||||
%h5.title
|
%h5.title
|
||||||
= link_to_project @project
|
= link_to_project project
|
||||||
%ul.well-list.issues_table
|
%ul.well-list.issues_table
|
||||||
- group[1].each do |issue|
|
- group[1].each do |issue|
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
= render(partial: 'issues/show', locals: {issue: issue})
|
||||||
|
|
|
@ -8,17 +8,4 @@
|
||||||
.span3
|
.span3
|
||||||
= render 'filter', entity: 'merge_request'
|
= render 'filter', entity: 'merge_request'
|
||||||
.span9
|
.span9
|
||||||
- if @merge_requests.any?
|
= render 'shared/merge_requests'
|
||||||
- @merge_requests.group_by(&:project).each do |group|
|
|
||||||
.ui-box
|
|
||||||
- @project = group[0]
|
|
||||||
%h5.title
|
|
||||||
= link_to_project @project
|
|
||||||
%ul.well-list
|
|
||||||
- group[1].each do |merge_request|
|
|
||||||
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
|
|
||||||
%hr
|
|
||||||
= paginate @merge_requests, theme: "gitlab"
|
|
||||||
|
|
||||||
- else
|
|
||||||
%h3.nothing_here_message Nothing to show here
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
- if show_last_push_widget?(event)
|
- if show_last_push_widget?(event)
|
||||||
.event_lp
|
.event_lp
|
||||||
= image_tag "event_push.png"
|
|
||||||
|
|
||||||
%span You pushed to
|
%span You pushed to
|
||||||
= link_to project_commits_path(event.project, event.ref_name) do
|
= link_to project_commits_path(event.project, event.ref_name) do
|
||||||
%strong= truncate(event.ref_name, length: 28)
|
%strong= truncate(event.ref_name, length: 28)
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
- if @issues.any?
|
- if @issues.any?
|
||||||
- @issues.group_by(&:project).each do |group|
|
- @issues.group_by(&:project).each do |group|
|
||||||
%div.ui-box
|
%div.ui-box
|
||||||
- @project = group[0]
|
- project = group[0]
|
||||||
%h5.title
|
%h5.title
|
||||||
= link_to_project @project
|
= link_to_project project
|
||||||
%ul.well-list.issues_table
|
%ul.well-list.issues_table
|
||||||
- group[1].each do |issue|
|
- group[1].each do |issue|
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
= render(partial: 'issues/show', locals: {issue: issue})
|
||||||
|
|
|
@ -8,17 +8,4 @@
|
||||||
.span3
|
.span3
|
||||||
= render 'filter', entity: 'merge_request'
|
= render 'filter', entity: 'merge_request'
|
||||||
.span9
|
.span9
|
||||||
- if @merge_requests.any?
|
= render 'shared/merge_requests'
|
||||||
- @merge_requests.group_by(&:project).each do |group|
|
|
||||||
.ui-box
|
|
||||||
- @project = group[0]
|
|
||||||
%h5.title
|
|
||||||
= link_to_project @project
|
|
||||||
%ul.well-list
|
|
||||||
- group[1].each do |merge_request|
|
|
||||||
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
|
|
||||||
%hr
|
|
||||||
= paginate @merge_requests, theme: "gitlab"
|
|
||||||
|
|
||||||
- else
|
|
||||||
%h3.nothing_here_message Nothing to show here
|
|
||||||
|
|
|
@ -47,3 +47,5 @@
|
||||||
%li
|
%li
|
||||||
%span= link_to "System Hooks", help_system_hooks_path
|
%span= link_to "System Hooks", help_system_hooks_path
|
||||||
|
|
||||||
|
%li
|
||||||
|
%span= link_to "Public Area", help_public_area_path
|
||||||
|
|
16
app/views/help/public_area.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
%h3.page_title Public Area
|
||||||
|
.back_link
|
||||||
|
= link_to help_path do
|
||||||
|
← to index
|
||||||
|
%hr
|
||||||
|
|
||||||
|
%p
|
||||||
|
Public area - is part of application with public access.
|
||||||
|
%br
|
||||||
|
It used to list all projects with public read-only access.
|
||||||
|
%br
|
||||||
|
If you enable public http access to the project - it will appears there
|
||||||
|
%br
|
||||||
|
|
||||||
|
Follow #{link_to "this link", public_root_path} to visit Public Area
|
||||||
|
|
|
@ -51,8 +51,9 @@
|
||||||
|
|
||||||
- if @issue.description.present?
|
- if @issue.description.present?
|
||||||
.ui-box-bottom
|
.ui-box-bottom
|
||||||
= preserve do
|
.wiki
|
||||||
= markdown @issue.description
|
= preserve do
|
||||||
|
= markdown @issue.description
|
||||||
|
|
||||||
|
|
||||||
.voting_notes#notes= render "notes/notes_with_form"
|
.voting_notes#notes= render "notes/notes_with_form"
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
- if @key.valid?
|
|
||||||
:plain
|
|
||||||
$("#new_key_dialog").dialog("close");
|
|
||||||
$("#keys-table .data").append("#{escape_javascript(render(partial: 'show', locals: {key: @key}))}");
|
|
||||||
$("#no_ssh_key_defined").hide();
|
|
||||||
- else
|
|
||||||
:plain
|
|
||||||
$("#new_key_dialog").empty();
|
|
||||||
$("#new_key_dialog").append("#{escape_javascript(render('form'))}");
|
|
|
@ -1,11 +0,0 @@
|
||||||
:plain
|
|
||||||
var new_key_dialog = $("<div id='new_key_dialog'></div>");
|
|
||||||
new_key_dialog.html("#{escape_javascript(render('form'))}");
|
|
||||||
$(new_key_dialog).dialog({
|
|
||||||
width: 350,
|
|
||||||
resizable: false,
|
|
||||||
draggable: false,
|
|
||||||
title: "Add new public key",
|
|
||||||
close: function(event, ui) { $("#new_key_dialog").remove();},
|
|
||||||
modal: true
|
|
||||||
});
|
|
|
@ -6,12 +6,14 @@
|
||||||
= favicon_link_tag 'favicon.ico'
|
= favicon_link_tag 'favicon.ico'
|
||||||
= stylesheet_link_tag "application"
|
= stylesheet_link_tag "application"
|
||||||
= javascript_include_tag "application"
|
= javascript_include_tag "application"
|
||||||
-# Atom feed
|
|
||||||
- if controller_name == 'projects' && action_name == 'index'
|
|
||||||
= auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"
|
|
||||||
- if @project && !@project.new_record?
|
|
||||||
- if current_controller?(:tree, :commits)
|
|
||||||
= auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
|
|
||||||
- if current_controller?(:issues)
|
|
||||||
= auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
|
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
|
|
||||||
|
-# Atom feed
|
||||||
|
- if current_user
|
||||||
|
- if controller_name == 'projects' && action_name == 'index'
|
||||||
|
= auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"
|
||||||
|
- if @project && !@project.new_record?
|
||||||
|
- if current_controller?(:tree, :commits)
|
||||||
|
= auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
|
||||||
|
- if current_controller?(:issues)
|
||||||
|
= auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
%span.count= current_user.cared_merge_requests.opened.count
|
%span.count= current_user.cared_merge_requests.opened.count
|
||||||
= nav_link(path: 'search#show') do
|
= nav_link(path: 'search#show') do
|
||||||
= link_to "Search", search_path
|
= link_to "Search", search_path
|
||||||
= nav_link(path: 'help#index') do
|
= nav_link(controller: :help) do
|
||||||
= link_to "Help", help_path
|
= link_to "Help", help_path
|
||||||
|
|
||||||
.content= yield
|
.content= yield
|
||||||
|
|
17
app/views/layouts/public.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
!!! 5
|
||||||
|
%html{ lang: "en"}
|
||||||
|
= render "layouts/head", title: "Public Area"
|
||||||
|
%body{class: "#{app_theme} application"}
|
||||||
|
%header.navbar.navbar-static-top.navbar-gitlab
|
||||||
|
.navbar-inner
|
||||||
|
.container
|
||||||
|
%div.app_logo
|
||||||
|
%span.separator
|
||||||
|
= link_to root_path, class: "home" do
|
||||||
|
%h1 GITLAB
|
||||||
|
%span.separator
|
||||||
|
%h1.project_name Public Area
|
||||||
|
.container
|
||||||
|
.content
|
||||||
|
.prepend-top-20
|
||||||
|
= yield
|
17
app/views/public/projects/index.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
%h3.page_title
|
||||||
|
Projects
|
||||||
|
%small Read-Only Access
|
||||||
|
%hr
|
||||||
|
|
||||||
|
%ul.unstyled
|
||||||
|
- @projects.each do |project|
|
||||||
|
%li.clearfix
|
||||||
|
%h5
|
||||||
|
%i.icon-star.cgreen
|
||||||
|
= project.name_with_namespace
|
||||||
|
.right
|
||||||
|
%span.monospace.tiny
|
||||||
|
git clone #{project.http_url_to_repo}
|
||||||
|
|
||||||
|
|
||||||
|
= paginate @projects, theme: "admin"
|
|
@ -1,4 +1,5 @@
|
||||||
.input-prepend.project_clone_holder
|
.input-prepend.project_clone_holder
|
||||||
%button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
|
%button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
|
||||||
%button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
|
%button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
|
||||||
|
|
||||||
= text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
|
= text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
|
||||||
|
|
14
app/views/shared/_merge_requests.html.haml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
- if @merge_requests.any?
|
||||||
|
- @merge_requests.group_by(&:project).each do |group|
|
||||||
|
.ui-box
|
||||||
|
- project = group[0]
|
||||||
|
%h5.title
|
||||||
|
= link_to_project project
|
||||||
|
%ul.well-list
|
||||||
|
- group[1].each do |merge_request|
|
||||||
|
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
|
||||||
|
%hr
|
||||||
|
= paginate @merge_requests, theme: "gitlab"
|
||||||
|
|
||||||
|
- else
|
||||||
|
%h3.nothing_here_message Nothing to show here
|
|
@ -1,3 +1,8 @@
|
||||||
%h3.page_title Editing page
|
%h3.page_title Editing page
|
||||||
%hr
|
%hr
|
||||||
= render 'form'
|
= render 'form'
|
||||||
|
|
||||||
|
.right
|
||||||
|
- if can? current_user, :admin_wiki, @project
|
||||||
|
= link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn small danger" do
|
||||||
|
Delete this page
|
|
@ -1,4 +1,4 @@
|
||||||
%h3.page_title Empty page
|
%h3.page_title Empty page
|
||||||
%hr
|
%hr
|
||||||
.alert-message.block-message.warning
|
.error_message
|
||||||
%span You are not allowed to create wiki pages
|
You are not allowed to create wiki pages
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
%span.cgray History for
|
%span.cgray History for
|
||||||
= @wikis.last.title
|
= @wiki_pages.first.title
|
||||||
%br
|
%br
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th #
|
%th Page version
|
||||||
%th last edit
|
%th Last updated
|
||||||
%th created by
|
%th Updated by
|
||||||
%tbody
|
%tbody
|
||||||
- @wikis.each_with_index do |wiki_page, i|
|
- @wiki_pages.each_with_index do |wiki_page, i|
|
||||||
%tr
|
%tr
|
||||||
%td= i + 1
|
|
||||||
%td
|
%td
|
||||||
= link_to wiki_page.created_at.to_s(:short), project_wiki_path(@project, wiki_page, old_page_id: wiki_page.id)
|
%strong
|
||||||
|
= link_to project_wiki_path(@project, wiki_page, version_id: wiki_page.id) do
|
||||||
|
Version
|
||||||
|
= @wiki_pages.count - i
|
||||||
|
%td
|
||||||
|
= wiki_page.created_at.to_s(:short)
|
||||||
(#{time_ago_in_words(wiki_page.created_at)}
|
(#{time_ago_in_words(wiki_page.created_at)}
|
||||||
ago)
|
ago)
|
||||||
%td= wiki_page.user.name
|
%td= link_to_member(@project, wiki_page.user)
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,17 @@
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th Title
|
%th Title
|
||||||
%th slug
|
%th Slug
|
||||||
%th created by
|
%th Last updated
|
||||||
|
%th Updated by
|
||||||
%tbody
|
%tbody
|
||||||
- @wikis.each_with_index do |wiki_page, i|
|
- @wiki_pages.each do |wiki_page|
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= link_to wiki_page.title, project_wiki_path(@project, wiki_page, old_page_id: wiki_page.id)
|
%strong= link_to wiki_page.title, project_wiki_path(@project, wiki_page)
|
||||||
(#{time_ago_in_words(wiki_page.created_at)}
|
|
||||||
ago)
|
|
||||||
%td= wiki_page.slug
|
%td= wiki_page.slug
|
||||||
%td= wiki_page.user.name
|
%td
|
||||||
|
= wiki_page.created_at.to_s(:short) do
|
||||||
|
(#{time_ago_in_words(wiki_page.created_at)}
|
||||||
|
ago)
|
||||||
|
%td= link_to_member(@project, wiki_page.user)
|
||||||
|
|
|
@ -10,12 +10,14 @@
|
||||||
%i.icon-edit
|
%i.icon-edit
|
||||||
Edit
|
Edit
|
||||||
%br
|
%br
|
||||||
|
- if @wiki != @most_recent_wiki
|
||||||
|
.warning_message
|
||||||
|
This is an old version of this page.
|
||||||
|
You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}.
|
||||||
|
|
||||||
.file_holder
|
.file_holder
|
||||||
.file_content.wiki
|
.file_content.wiki
|
||||||
= preserve do
|
= preserve do
|
||||||
= markdown @wiki.content
|
= markdown @wiki.content
|
||||||
|
|
||||||
%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago
|
%p.time Last edited by #{link_to_member @project, @wiki.user}, #{time_ago_in_words @wiki.created_at} ago
|
||||||
- if can? current_user, :admin_wiki, @project
|
|
||||||
= link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete do
|
|
||||||
Delete this page
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
if defined?(PhusionPassenger)
|
|
||||||
|
|
||||||
# When you're using Passenger with smart-lv2 (default) or smart spawn method,
|
|
||||||
# Resque doesn't recognize that it has been forked and should re-establish
|
|
||||||
# Redis connection. You can see this error message in log:
|
|
||||||
# Redis::InheritedError, Tried to use a connection from a child process
|
|
||||||
# without reconnecting. You need to reconnect to Redis after forking.
|
|
||||||
#
|
|
||||||
# This solution is based on
|
|
||||||
# https://github.com/redis/redis-rb/wiki/redis-rb-on-Phusion-Passenger
|
|
||||||
#
|
|
||||||
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
|
||||||
# if we're in smart spawning mode, reconnect to Redis
|
|
||||||
Resque.redis.client.reconnect if forked
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -35,6 +35,15 @@ Gitlab::Application.routes.draw do
|
||||||
get 'help/markdown' => 'help#markdown'
|
get 'help/markdown' => 'help#markdown'
|
||||||
get 'help/ssh' => 'help#ssh'
|
get 'help/ssh' => 'help#ssh'
|
||||||
get 'help/raketasks' => 'help#raketasks'
|
get 'help/raketasks' => 'help#raketasks'
|
||||||
|
get 'help/public_area' => 'help#public_area'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Public namespace
|
||||||
|
#
|
||||||
|
namespace :public do
|
||||||
|
resources :projects, only: [:index]
|
||||||
|
root to: "projects#index"
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Admin Area
|
# Admin Area
|
||||||
|
|
5
db/migrate/20130110172407_add_public_to_project.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPublicToProject < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :projects, :public, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
17
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20130102143055) do
|
ActiveRecord::Schema.define(:version => 20130110172407) do
|
||||||
|
|
||||||
create_table "events", :force => true do |t|
|
create_table "events", :force => true do |t|
|
||||||
t.string "target_type"
|
t.string "target_type"
|
||||||
|
@ -145,16 +145,17 @@ ActiveRecord::Schema.define(:version => 20130102143055) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "path"
|
t.string "path"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.boolean "private_flag", :default => true, :null => false
|
t.boolean "private_flag", :default => true, :null => false
|
||||||
t.integer "creator_id"
|
t.integer "creator_id"
|
||||||
t.string "default_branch"
|
t.string "default_branch"
|
||||||
t.boolean "issues_enabled", :default => true, :null => false
|
t.boolean "issues_enabled", :default => true, :null => false
|
||||||
t.boolean "wall_enabled", :default => true, :null => false
|
t.boolean "wall_enabled", :default => true, :null => false
|
||||||
t.boolean "merge_requests_enabled", :default => true, :null => false
|
t.boolean "merge_requests_enabled", :default => true, :null => false
|
||||||
t.boolean "wiki_enabled", :default => true, :null => false
|
t.boolean "wiki_enabled", :default => true, :null => false
|
||||||
t.integer "namespace_id"
|
t.integer "namespace_id"
|
||||||
|
t.boolean "public", :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
|
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
|
||||||
|
|
|
@ -270,20 +270,6 @@ used for the `email.from` setting in `config/gitlab.yml`)
|
||||||
sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production
|
sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production
|
||||||
|
|
||||||
|
|
||||||
## Check Application Status
|
|
||||||
|
|
||||||
Check if GitLab and its environment is configured correctly:
|
|
||||||
|
|
||||||
sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production
|
|
||||||
|
|
||||||
To make sure you didn't miss anything run a more thorough check with:
|
|
||||||
|
|
||||||
sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
|
|
||||||
|
|
||||||
If you are all green: congratulations, you successfully installed GitLab!
|
|
||||||
Although this is the case, there are still a few steps to go.
|
|
||||||
|
|
||||||
|
|
||||||
## Install Init Script
|
## Install Init Script
|
||||||
|
|
||||||
Download the init script (will be /etc/init.d/gitlab):
|
Download the init script (will be /etc/init.d/gitlab):
|
||||||
|
@ -296,7 +282,20 @@ Make GitLab start on boot:
|
||||||
sudo update-rc.d gitlab defaults 21
|
sudo update-rc.d gitlab defaults 21
|
||||||
|
|
||||||
|
|
||||||
Start your GitLab instance:
|
## Check Application Status
|
||||||
|
|
||||||
|
Check if GitLab and its environment is configured correctly:
|
||||||
|
|
||||||
|
sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production
|
||||||
|
|
||||||
|
To make sure you didn't miss anything run a more thorough check with:
|
||||||
|
|
||||||
|
sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
|
||||||
|
|
||||||
|
If all items are green, then congratulations on successfully installing GitLab!
|
||||||
|
However there are still a few steps left.
|
||||||
|
|
||||||
|
## Start Your GitLab Instance
|
||||||
|
|
||||||
sudo service gitlab start
|
sudo service gitlab start
|
||||||
# or
|
# or
|
||||||
|
|
|
@ -2,25 +2,41 @@ module Grack
|
||||||
class Auth < Rack::Auth::Basic
|
class Auth < Rack::Auth::Basic
|
||||||
attr_accessor :user, :project
|
attr_accessor :user, :project
|
||||||
|
|
||||||
def valid?
|
def call(env)
|
||||||
# Authentication with username and password
|
@env = env
|
||||||
login, password = @auth.credentials
|
@request = Rack::Request.new(env)
|
||||||
|
@auth = Request.new(env)
|
||||||
|
|
||||||
self.user = User.find_by_email(login) || User.find_by_username(login)
|
|
||||||
|
|
||||||
return false unless user.try(:valid_password?, password)
|
|
||||||
|
|
||||||
email = user.email
|
|
||||||
|
|
||||||
# Set GL_USER env variable
|
|
||||||
ENV['GL_USER'] = email
|
|
||||||
# Pass Gitolite update hook
|
# Pass Gitolite update hook
|
||||||
ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
|
ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
|
||||||
|
|
||||||
# Find project by PATH_INFO from env
|
# Need this patch due to the rails mount
|
||||||
if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
|
@env['PATH_INFO'] = @request.path
|
||||||
self.project = Project.find_with_namespace(m.last)
|
@env['SCRIPT_NAME'] = ""
|
||||||
return false unless project
|
|
||||||
|
return render_not_found unless project
|
||||||
|
return unauthorized unless project.public || @auth.provided?
|
||||||
|
return bad_request if @auth.provided? && !@auth.basic?
|
||||||
|
|
||||||
|
if valid?
|
||||||
|
if @auth.provided?
|
||||||
|
@env['REMOTE_USER'] = @auth.username
|
||||||
|
end
|
||||||
|
return @app.call(env)
|
||||||
|
else
|
||||||
|
unauthorized
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
if @auth.provided?
|
||||||
|
# Authentication with username and password
|
||||||
|
login, password = @auth.credentials
|
||||||
|
self.user = User.find_by_email(login) || User.find_by_username(login)
|
||||||
|
return false unless user.try(:valid_password?, password)
|
||||||
|
|
||||||
|
# Set GL_USER env variable
|
||||||
|
ENV['GL_USER'] = user.email
|
||||||
end
|
end
|
||||||
|
|
||||||
# Git upload and receive
|
# Git upload and receive
|
||||||
|
@ -34,12 +50,12 @@ module Grack
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_get_request
|
def validate_get_request
|
||||||
can?(user, :download_code, project)
|
project.public || can?(user, :download_code, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_post_request
|
def validate_post_request
|
||||||
if @request.path_info.end_with?('git-upload-pack')
|
if @request.path_info.end_with?('git-upload-pack')
|
||||||
can?(user, :download_code, project)
|
project.public || can?(user, :download_code, project)
|
||||||
elsif @request.path_info.end_with?('git-receive-pack')
|
elsif @request.path_info.end_with?('git-receive-pack')
|
||||||
action = if project.protected_branch?(current_ref)
|
action = if project.protected_branch?(current_ref)
|
||||||
:push_code_to_protected_branches
|
:push_code_to_protected_branches
|
||||||
|
@ -68,6 +84,22 @@ module Grack
|
||||||
/refs\/heads\/([\w\.-]+)/.match(input).to_a.first
|
/refs\/heads\/([\w\.-]+)/.match(input).to_a.first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
unless instance_variable_defined? :@project
|
||||||
|
# Find project by PATH_INFO from env
|
||||||
|
if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
|
||||||
|
@project = Project.find_with_namespace(m.last)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return @project
|
||||||
|
end
|
||||||
|
|
||||||
|
PLAIN_TYPE = {"Content-Type" => "text/plain"}
|
||||||
|
|
||||||
|
def render_not_found
|
||||||
|
[404, PLAIN_TYPE, ["Not Found"]]
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def abilities
|
def abilities
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace :gitlab do
|
||||||
desc "GITLAB | Check the configuration of GitLab and its environment"
|
desc "GITLAB | Check the configuration of GitLab and its environment"
|
||||||
task check: %w{gitlab:env:check
|
task check: %w{gitlab:env:check
|
||||||
gitlab:gitolite:check
|
gitlab:gitolite:check
|
||||||
gitlab:resque:check
|
gitlab:sidekiq:check
|
||||||
gitlab:app:check}
|
gitlab:app:check}
|
||||||
|
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ namespace :gitlab do
|
||||||
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
|
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
|
||||||
print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
|
print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
|
||||||
|
|
||||||
profile_file = File.join(gitolite_home, ".profile")
|
profile_file = File.join(gitolite_user_home, ".profile")
|
||||||
|
|
||||||
unless File.read(profile_file) =~ /^-e PATH/
|
unless File.read(profile_file) =~ /^-e PATH/
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
|
@ -475,7 +475,7 @@ namespace :gitlab do
|
||||||
def check_dot_gitolite_exists
|
def check_dot_gitolite_exists
|
||||||
print "Config directory exists? ... "
|
print "Config directory exists? ... "
|
||||||
|
|
||||||
gitolite_config_path = File.join(gitolite_home, ".gitolite")
|
gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
|
||||||
|
|
||||||
if File.directory?(gitolite_config_path)
|
if File.directory?(gitolite_config_path)
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
|
@ -496,13 +496,13 @@ namespace :gitlab do
|
||||||
def check_dot_gitolite_permissions
|
def check_dot_gitolite_permissions
|
||||||
print "Config directory access is drwxr-x---? ... "
|
print "Config directory access is drwxr-x---? ... "
|
||||||
|
|
||||||
gitolite_config_path = File.join(gitolite_home, ".gitolite")
|
gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
|
||||||
unless File.exists?(gitolite_config_path)
|
unless File.exists?(gitolite_config_path)
|
||||||
puts "can't check because of previous errors".magenta
|
puts "can't check because of previous errors".magenta
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if `stat --printf %a #{gitolite_config_path}` == "750"
|
if File.stat(gitolite_config_path).mode.to_s(8).ends_with?("750")
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
else
|
else
|
||||||
puts "no".red
|
puts "no".red
|
||||||
|
@ -520,18 +520,17 @@ namespace :gitlab do
|
||||||
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
|
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
|
||||||
print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
|
print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
|
||||||
|
|
||||||
gitolite_config_path = File.join(gitolite_home, ".gitolite")
|
gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
|
||||||
unless File.exists?(gitolite_config_path)
|
unless File.exists?(gitolite_config_path)
|
||||||
puts "can't check because of previous errors".magenta
|
puts "can't check because of previous errors".magenta
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user
|
if File.stat(gitolite_config_path).uid == uid_for(gitolite_ssh_user) &&
|
||||||
`stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group
|
File.stat(gitolite_config_path).gid == gid_for(gitolite_ssh_user)
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
else
|
else
|
||||||
puts "no".red
|
puts "no".red
|
||||||
puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red
|
|
||||||
try_fixing_it(
|
try_fixing_it(
|
||||||
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
|
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
|
||||||
)
|
)
|
||||||
|
@ -559,7 +558,7 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_gitoliterc_git_config_keys
|
def check_gitoliterc_git_config_keys
|
||||||
gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
|
gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc")
|
||||||
|
|
||||||
print "Allow all Git config keys in .gitolite.rc ... "
|
print "Allow all Git config keys in .gitolite.rc ... "
|
||||||
option_name = if has_gitolite3?
|
option_name = if has_gitolite3?
|
||||||
|
@ -588,7 +587,7 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_gitoliterc_repo_umask
|
def check_gitoliterc_repo_umask
|
||||||
gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
|
gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc")
|
||||||
|
|
||||||
print "Repo umask is 0007 in .gitolite.rc? ... "
|
print "Repo umask is 0007 in .gitolite.rc? ... "
|
||||||
option_name = if has_gitolite3?
|
option_name = if has_gitolite3?
|
||||||
|
@ -722,11 +721,10 @@ namespace :gitlab do
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if `stat --printf %a #{repo_base_path}` == "6770"
|
if File.stat(repo_base_path).mode.to_s(8).ends_with?("6770")
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
else
|
else
|
||||||
puts "no".red
|
puts "no".red
|
||||||
puts "#{repo_base_path} is not writable".red
|
|
||||||
try_fixing_it(
|
try_fixing_it(
|
||||||
"sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
|
"sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
|
||||||
)
|
)
|
||||||
|
@ -747,12 +745,11 @@ namespace :gitlab do
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user
|
if File.stat(repo_base_path).uid == uid_for(gitolite_ssh_user) &&
|
||||||
`stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group
|
File.stat(repo_base_path).gid == gid_for(gitolite_ssh_user)
|
||||||
puts "yes".green
|
puts "yes".green
|
||||||
else
|
else
|
||||||
puts "no".red
|
puts "no".red
|
||||||
puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red
|
|
||||||
try_fixing_it(
|
try_fixing_it(
|
||||||
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
|
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
|
||||||
)
|
)
|
||||||
|
@ -833,7 +830,8 @@ namespace :gitlab do
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/)
|
if File.lstat(project_hook_file).symlink? &&
|
||||||
|
File.realpath(project_hook_file) == File.realpath(gitolite_hook_file)
|
||||||
puts "ok".green
|
puts "ok".green
|
||||||
else
|
else
|
||||||
puts "not a link to Gitolite's hook".red
|
puts "not a link to Gitolite's hook".red
|
||||||
|
@ -852,12 +850,12 @@ namespace :gitlab do
|
||||||
# Helper methods
|
# Helper methods
|
||||||
########################
|
########################
|
||||||
|
|
||||||
def gitolite_home
|
def gitolite_user_home
|
||||||
File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
|
File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def gitolite_version
|
def gitolite_version
|
||||||
gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION"
|
gitolite_version_file = "#{gitolite_user_home}/gitolite/src/VERSION"
|
||||||
if File.readable?(gitolite_version_file)
|
if File.readable?(gitolite_version_file)
|
||||||
File.read(gitolite_version_file)
|
File.read(gitolite_version_file)
|
||||||
end
|
end
|
||||||
|
@ -870,22 +868,22 @@ namespace :gitlab do
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace :resque do
|
namespace :sidekiq do
|
||||||
desc "GITLAB | Check the configuration of Sidekiq"
|
desc "GITLAB | Check the configuration of Sidekiq"
|
||||||
task check: :environment do
|
task check: :environment do
|
||||||
warn_user_is_not_gitlab
|
warn_user_is_not_gitlab
|
||||||
start_checking "Resque"
|
start_checking "Sidekiq"
|
||||||
|
|
||||||
check_resque_running
|
check_sidekiq_running
|
||||||
|
|
||||||
finished_checking "Resque"
|
finished_checking "Sidekiq"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Checks
|
# Checks
|
||||||
########################
|
########################
|
||||||
|
|
||||||
def check_resque_running
|
def check_sidekiq_running
|
||||||
print "Running? ... "
|
print "Running? ... "
|
||||||
|
|
||||||
if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
|
if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
|
||||||
|
@ -893,9 +891,7 @@ namespace :gitlab do
|
||||||
else
|
else
|
||||||
puts "no".red
|
puts "no".red
|
||||||
try_fixing_it(
|
try_fixing_it(
|
||||||
"sudo service gitlab restart",
|
"sudo -u gitlab -H bundle exec rake sidekiq:start"
|
||||||
"or",
|
|
||||||
"sudo /etc/init.d/gitlab restart"
|
|
||||||
)
|
)
|
||||||
for_more_information(
|
for_more_information(
|
||||||
see_installation_guide_section("Install Init Script"),
|
see_installation_guide_section("Install Init Script"),
|
||||||
|
|
|
@ -3,20 +3,6 @@ namespace :gitlab do
|
||||||
desc "GITLAB | Show information about GitLab and its environment"
|
desc "GITLAB | Show information about GitLab and its environment"
|
||||||
task info: :environment do
|
task info: :environment do
|
||||||
|
|
||||||
# check which OS is running
|
|
||||||
os_name = run("lsb_release -irs")
|
|
||||||
os_name ||= if File.readable?('/etc/system-release')
|
|
||||||
File.read('/etc/system-release')
|
|
||||||
end
|
|
||||||
os_name ||= if File.readable?('/etc/debian_version')
|
|
||||||
debian_version = File.read('/etc/debian_version')
|
|
||||||
"Debian #{debian_version}"
|
|
||||||
end
|
|
||||||
os_name ||= if File.readable?('/etc/SuSE-release')
|
|
||||||
File.read('/etc/SuSE-release')
|
|
||||||
end
|
|
||||||
os_name.try(:squish!)
|
|
||||||
|
|
||||||
# check if there is an RVM environment
|
# check if there is an RVM environment
|
||||||
rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s)
|
rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s)
|
||||||
# check Ruby version
|
# check Ruby version
|
||||||
|
|
|
@ -1,5 +1,27 @@
|
||||||
namespace :gitlab do
|
namespace :gitlab do
|
||||||
|
|
||||||
|
# Check which OS is running
|
||||||
|
#
|
||||||
|
# It will primarily use lsb_relase to determine the OS.
|
||||||
|
# It has fallbacks to Debian, SuSE and OS X.
|
||||||
|
def os_name
|
||||||
|
os_name = run("lsb_release -irs")
|
||||||
|
os_name ||= if File.readable?('/etc/system-release')
|
||||||
|
File.read('/etc/system-release')
|
||||||
|
end
|
||||||
|
os_name ||= if File.readable?('/etc/debian_version')
|
||||||
|
debian_version = File.read('/etc/debian_version')
|
||||||
|
"Debian #{debian_version}"
|
||||||
|
end
|
||||||
|
os_name ||= if File.readable?('/etc/SuSE-release')
|
||||||
|
File.read('/etc/SuSE-release')
|
||||||
|
end
|
||||||
|
os_name ||= if os_x_version = run("sw_vers -productVersion")
|
||||||
|
"Mac OS X #{os_x_version}"
|
||||||
|
end
|
||||||
|
os_name.try(:squish!)
|
||||||
|
end
|
||||||
|
|
||||||
# Runs the given command and matches the output agains the given pattern
|
# Runs the given command and matches the output agains the given pattern
|
||||||
#
|
#
|
||||||
# Returns nil if nothing matched
|
# Returns nil if nothing matched
|
||||||
|
@ -23,6 +45,15 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def uid_for(user_name)
|
||||||
|
run("id -u #{user_name}").chomp.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def gid_for(group_name)
|
||||||
|
group_line = File.read("/etc/group").lines.select{|l| l.start_with?("#{group_name}:")}.first
|
||||||
|
group_line.split(":")[2].to_i
|
||||||
|
end
|
||||||
|
|
||||||
def warn_user_is_not_gitlab
|
def warn_user_is_not_gitlab
|
||||||
unless @warned_user_not_gitlab
|
unless @warned_user_not_gitlab
|
||||||
current_user = run("whoami").chomp
|
current_user = run("whoami").chomp
|
||||||
|
|
|
@ -6,18 +6,10 @@ namespace :sidekiq do
|
||||||
|
|
||||||
desc "GITLAB | Start sidekiq"
|
desc "GITLAB | Start sidekiq"
|
||||||
task :start do
|
task :start do
|
||||||
run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,common,default -e #{rails_env} -P #{pidfile} >> #{root_path}/log/sidekiq.log 2>&1 &"
|
run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
|
||||||
end
|
|
||||||
|
|
||||||
def root_path
|
|
||||||
@root_path ||= File.join(File.expand_path(File.dirname(__FILE__)), "../..")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pidfile
|
def pidfile
|
||||||
"#{root_path}/tmp/pids/sidekiq.pid"
|
Rails.root.join("tmp", "pids", "sidekiq.pid")
|
||||||
end
|
|
||||||
|
|
||||||
def rails_env
|
|
||||||
ENV['RAILS_ENV'] || "production"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|