Commit 8a6da07f authored by Stan Hu's avatar Stan Hu

Merge branch 'ce-to-ee-2018-02-16' into 'master'

CE upstream - 2018-02-16 15:23 UTC

Closes gitlab-ce#42939

See merge request gitlab-org/gitlab-ee!4579
parents 7c9872f2 b6bea6c4
import IntegrationSettingsForm from '~/integrations/integration_settings_form';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
export default () => {
const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring');
const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
integrationSettingsForm.init();
if (prometheusSettingsWrapper) {
const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
prometheusMetrics.loadActiveMetrics();
}
};
import PrometheusMetrics from './prometheus_metrics';
$(() => {
const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
prometheusMetrics.loadActiveMetrics();
});
- content_for :page_specific_javascripts do
= webpack_bundle_tag('prometheus_metrics')
.row.prepend-top-default.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring
.col-lg-3
%h4.prepend-top-0
......
---
title: API endpoint for importing a project export
merge_request: 17025
author:
type: added
---
title: Asciidoc now support inter-document cross references between files in repository
merge_request: 17125
author: Turo Soisenniemi
type: changed
......@@ -90,7 +90,6 @@ var config = {
pipelines_details: './pipelines/pipeline_details_bundle.js',
profile: './profile/profile_bundle.js',
project_import_gl: './projects/project_import_gitlab_project.js',
prometheus_metrics: './prometheus_metrics',
protected_branches: './protected_branches',
ee_protected_branches: 'ee/protected_branches',
protected_tags: './protected_tags',
......
......@@ -48,6 +48,7 @@ following locations:
- [Pipeline Schedules](pipeline_schedules.md)
- [Projects](projects.md) including setting Webhooks
- [Project Access Requests](access_requests.md)
- [Project import/export](project_import_export.md)
- [Project Members](members.md)
- [Project Snippets](project_snippets.md)
- [Protected Branches](protected_branches.md)
......
# Project import API
[Introduced][ce-41899] in GitLab 10.6
[See also the project import/export documentation](../user/project/settings/import_export.md)
## Import a file
```http
POST /projects/import
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
| `namespace` | integer/string | no | The ID or path of the namespace that the project will be imported to. Defaults to the current user's namespace |
| `file` | string | yes | The file to be uploaded |
| `path` | string | yes | Name and path for new project |
To upload a file from your filesystem, use the `--form` argument. This causes
cURL to post data using the header `Content-Type: multipart/form-data`.
The `file=` parameter must point to a file on your filesystem and be preceded
by `@`. For example:
```console
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "path=api-project" --form "file=@/path/to/file" https://gitlab.example.com/api/v4/projects/import
```
```json
{
"id": 1,
"description": null,
"name": "api-project",
"name_with_namespace": "Administrator / api-project",
"path": "api-project",
"path_with_namespace": "root/api-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled"
}
```
## Import status
Get the status of an import.
```http
GET /projects/:id/import
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```console
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/import
```
Status can be one of `none`, `scheduled`, `failed`, `started`, or `finished`.
If the status is `failed`, it will include the import error message under `import_error`.
```json
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"import_status": "started"
}
```
[ce-41899]: https://gitlab.com/gitlab-org/gitlab-ce/issues/41899
......@@ -1428,6 +1428,10 @@ DELETE /projects/:id/push_rule
Read more in the [Branches](branches.md) documentation.
## Project Import/Export
Read more in the [Project import/export](project_import_export.md) documentation.
## Project members
Read more in the [Project members](members.md) documentation.
......
......@@ -22,6 +22,7 @@
> in the import side is required to map the users, based on email or username.
> Otherwise, a supplementary comment is left to mention the original author and
> the MRs, notes or issues will be owned by the importer.
> - Control project Import/Export with the [API](../../../api/project_import_export.md).
Existing projects running on any GitLab instance or GitLab.com can be exported
with all their related data and be moved into a new GitLab instance.
......
......@@ -155,6 +155,7 @@ module API
mount ::API::PagesDomains
mount ::API::Pipelines
mount ::API::PipelineSchedules
mount ::API::ProjectImport
mount ::API::ProjectHooks
mount ::API::ProjectPushRule
mount ::API::Projects
......
......@@ -101,6 +101,13 @@ module API
expose :created_at
end
class ProjectImportStatus < ProjectIdentity
expose :import_status
# TODO: Use `expose_nil` once we upgrade the grape-entity gem
expose :import_error, if: lambda { |status, _ops| status.import_error }
end
class BasicProjectDetails < ProjectIdentity
include ::API::ProjectsRelationBuilder
......
module API
class ProjectImport < Grape::API
include PaginationParams
helpers do
def import_params
declared_params(include_missing: false)
end
def file_is_valid?
import_params[:file] && import_params[:file]['tempfile'].respond_to?(:read)
end
def validate_file!
render_api_error!('The file is invalid', 400) unless file_is_valid?
end
end
before do
forbidden! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project')
end
resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
params do
requires :path, type: String, desc: 'The new project path and name'
requires :file, type: File, desc: 'The project export file to be imported'
optional :namespace, type: String, desc: "The ID or name of the namespace that the project will be imported into. Defaults to the current user's namespace."
end
desc 'Create a new project import' do
detail 'This feature was introduced in GitLab 10.6.'
success Entities::ProjectImportStatus
end
post 'import' do
validate_file!
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42437')
namespace = if import_params[:namespace]
find_namespace!(import_params[:namespace])
else
current_user.namespace
end
project_params = {
path: import_params[:path],
namespace_id: namespace.id,
file: import_params[:file]['tempfile']
}
project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute
render_api_error!(project.errors.full_messages&.first, 400) unless project.saved?
present project, with: Entities::ProjectImportStatus
end
params do
requires :id, type: String, desc: 'The ID of a project'
end
desc 'Get a project export status' do
detail 'This feature was introduced in GitLab 10.6.'
success Entities::ProjectImportStatus
end
get ':id/import' do
present user_project, with: Entities::ProjectImportStatus
end
end
end
end
......@@ -8,7 +8,8 @@ module Gitlab
module Asciidoc
DEFAULT_ADOC_ATTRS = [
'showtitle', 'idprefix=user-content-', 'idseparator=-', 'env=gitlab',
'env-gitlab', 'source-highlighter=html-pipeline', 'icons=font'
'env-gitlab', 'source-highlighter=html-pipeline', 'icons=font',
'outfilesuffix=.adoc'
].freeze
# Public: Converts the provided Asciidoc markup into HTML.
......
......@@ -95,6 +95,14 @@ module Gitlab
expect(render(input, context)).to include('<p><code data-math-style="inline" class="code math js-render-math">2+2</code> is 4</p>')
end
end
context 'outfilesuffix' do
it 'defaults to adoc' do
output = render("Inter-document reference <<README.adoc#>>", context)
expect(output).to include("a href=\"README.adoc\"")
end
end
end
def render(*args)
......
require 'spec_helper'
describe API::ProjectImport do
let(:export_path) { "#{Dir.tmpdir}/project_export_spec" }
let(:user) { create(:user) }
let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
let(:namespace) { create(:group) }
before do
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
namespace.add_owner(user)
end
after do
FileUtils.rm_rf(export_path, secure: true)
end
describe 'POST /projects/import' do
it 'schedules an import using a namespace' do
stub_import(namespace)
post api('/projects/import', user), path: 'test-import', file: fixture_file_upload(file), namespace: namespace.id
expect(response).to have_gitlab_http_status(201)
end
it 'schedules an import using the namespace path' do
stub_import(namespace)
post api('/projects/import', user), path: 'test-import', file: fixture_file_upload(file), namespace: namespace.full_path
expect(response).to have_gitlab_http_status(201)
end
it 'schedules an import at the user namespace level' do
stub_import(user.namespace)
post api('/projects/import', user), path: 'test-import2', file: fixture_file_upload(file)
expect(response).to have_gitlab_http_status(201)
end
it 'schedules an import at the user namespace level' do
expect_any_instance_of(Project).not_to receive(:import_schedule)
expect(::Projects::CreateService).not_to receive(:new)
post api('/projects/import', user), namespace: 'nonexistent', path: 'test-import2', file: fixture_file_upload(file)
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Namespace Not Found')
end
it 'does not schedule an import if the user has no permission to the namespace' do
expect_any_instance_of(Project).not_to receive(:import_schedule)
post(api('/projects/import', create(:user)),
path: 'test-import3',
file: fixture_file_upload(file),
namespace: namespace.full_path)
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Namespace Not Found')
end
it 'does not schedule an import if the user uploads no valid file' do
expect_any_instance_of(Project).not_to receive(:import_schedule)
post api('/projects/import', user), path: 'test-import3', file: './random/test'
expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('file is invalid')
end
def stub_import(namespace)
expect_any_instance_of(Project).to receive(:import_schedule)
expect(::Projects::CreateService).to receive(:new).with(user, hash_including(namespace_id: namespace.id)).and_call_original
end
end
describe 'GET /projects/:id/import' do
it 'returns the import status' do
project = create(:project, import_status: 'started')
project.add_master(user)
get api("/projects/#{project.id}/import", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response).to include('import_status' => 'started')
end
it 'returns the import status and the error if failed' do
project = create(:project, import_status: 'failed', import_error: 'error')
project.add_master(user)
get api("/projects/#{project.id}/import", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response).to include('import_status' => 'failed',
'import_error' => 'error')
end
end
end
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