Commit 81a584df authored by Imre Farkas's avatar Imre Farkas

Merge branch '263144-commit-to-new-branch' into 'master'

Extend GraphQL API to commit to a new branch in a single operation

See merge request gitlab-org/gitlab!47203
parents 11d0c7c0 5d446e57
......@@ -13,7 +13,11 @@ module Mutations
argument :branch, GraphQL::STRING_TYPE,
required: true,
description: 'Name of the branch'
description: 'Name of the branch to commit into, it can be a new branch'
argument :start_branch, GraphQL::STRING_TYPE,
required: false,
description: 'If on a new branch, name of the original branch'
argument :message,
GraphQL::STRING_TYPE,
......@@ -32,13 +36,13 @@ module Mutations
authorize :push_code
def resolve(project_path:, branch:, message:, actions:)
def resolve(project_path:, branch:, message:, actions:, **args)
project = authorized_find!(full_path: project_path)
attributes = {
commit_message: message,
branch_name: branch,
start_branch: branch,
start_branch: args[:start_branch] || branch,
actions: actions.map { |action| action.to_h }
}
......
---
title: Extend GraphQL API to commit to a new branch in a single operation
merge_request: 47203
author:
type: changed
......@@ -2996,7 +2996,7 @@ input CommitCreateInput {
actions: [CommitAction!]!
"""
Name of the branch
Name of the branch to commit into, it can be a new branch
"""
branch: String!
......@@ -3014,6 +3014,11 @@ input CommitCreateInput {
Project full path the branch is associated with
"""
projectPath: ID!
"""
If on a new branch, name of the original branch
"""
startBranch: String
}
"""
......
......@@ -8114,7 +8114,7 @@
},
{
"name": "branch",
"description": "Name of the branch",
"description": "Name of the branch to commit into, it can be a new branch",
"type": {
"kind": "NON_NULL",
"name": null,
......@@ -8126,6 +8126,16 @@
},
"defaultValue": null
},
{
"name": "startBranch",
"description": "If on a new branch, name of the original branch",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "message",
"description": "Raw commit message",
......@@ -5,8 +5,9 @@ require 'spec_helper'
RSpec.describe Mutations::Commits::Create do
subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
let(:context) do
GraphQL::Query::Context.new(
query: OpenStruct.new(schema: nil),
......@@ -18,9 +19,10 @@ RSpec.describe Mutations::Commits::Create do
specify { expect(described_class).to require_graphql_authorizations(:push_code) }
describe '#resolve' do
subject { mutation.resolve(project_path: project.full_path, branch: branch, message: message, actions: actions) }
subject { mutation.resolve(project_path: project.full_path, branch: branch, start_branch: start_branch, message: message, actions: actions) }
let(:branch) { 'master' }
let(:start_branch) { nil }
let(:message) { 'Commit message' }
let(:actions) do
[
......@@ -142,6 +144,29 @@ RSpec.describe Mutations::Commits::Create do
end
end
context 'when branch does not exist and a start branch is provided' do
let(:branch) { 'my-branch' }
let(:start_branch) { 'master' }
let(:actions) do
[
{
action: 'create',
file_path: 'ANOTHER_FILE.md',
content: 'Bye'
}
]
end
it 'returns a new commit' do
expect(mutated_commit).to have_attributes(message: message, project: project)
expect(subject[:errors]).to be_empty
expect_to_contain_deltas([
a_hash_including(a_mode: '0', b_mode: '100644', new_file: true, new_path: 'ANOTHER_FILE.md')
])
end
end
context 'when message is not set' do
let(:message) { nil }
......
......@@ -23,6 +23,18 @@ RSpec.describe 'Creation of a new commit' do
let(:mutation) { graphql_mutation(:commit_create, input) }
let(:mutation_response) { graphql_mutation_response(:commit_create) }
shared_examples 'a commit is successful' do
it 'creates a new commit' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['commit']).to include(
'title' => message
)
end
end
context 'the user is not allowed to create a commit' do
it_behaves_like 'a mutation that returns a top-level access error'
end
......@@ -32,14 +44,7 @@ RSpec.describe 'Creation of a new commit' do
project.add_developer(current_user)
end
it 'creates a new commit' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['commit']).to include(
'title' => message
)
end
it_behaves_like 'a commit is successful'
context 'when branch is not correct' do
let(:branch) { 'unknown' }
......@@ -47,5 +52,22 @@ RSpec.describe 'Creation of a new commit' do
it_behaves_like 'a mutation that returns errors in the response',
errors: ['You can only create or edit files when you are on a branch']
end
context 'when branch is new, and a start_branch is defined' do
let(:input) { { project_path: project.full_path, branch: branch, start_branch: start_branch, message: message, actions: actions } }
let(:branch) { 'new-branch' }
let(:start_branch) { 'master' }
let(:actions) do
[
{
action: 'CREATE',
filePath: 'ANOTHER_FILE.md',
content: 'Bye'
}
]
end
it_behaves_like 'a commit is successful'
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