Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auto-create repository on push #2478

Closed
wants to merge 1 commit into from

Conversation

j-keck
Copy link

@j-keck j-keck commented Sep 10, 2017

if the repository doesn't exists at push time,
and the setting 'Repository.Upload.AutoCreate' is 'true'
(default is 'false') create the repository with the given name.

Signed-off-by: Jürgen Keck [email protected]

@lunny lunny added the type/feature Completely new functionality. Can only be merged if feature freeze is not active. label Sep 10, 2017
@lunny lunny added this to the 1.3.0 milestone Sep 10, 2017
@lunny
Copy link
Member

lunny commented Sep 10, 2017

Maybe add some integration tests?

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Sep 10, 2017
@j-keck
Copy link
Author

j-keck commented Sep 10, 2017

@lunny how can i run the integration test local?

if i run it per integration.test i get this exception:

...
2017/09/10 11:00:27 [...ules/context/repo.go:392 func1()] [E] RepoRef Invalid repo /tmp/gitea/user2/repo16.git: no such file or directory
[Macaron] 2017-09-10 11:00:27: Completed /api/v1/repos/user2/repo16/branches/not-signed 500 Internal Server Error in 2.383334ms
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0xe7ec32]

goroutine 3176 [running]:
testing.tRunner.func1(0xc4218aa780)
...

can i setup the test env local?


my code so far in integrations/repo_test.go - but i'm not sure if this is the right way.

func TestAutoCreateRepo(t *testing.T) {
	prepareTestEnv(t)

	session := loginUser(t, "user2")

	setting.Repository.Upload.AutoCreate = false
	req := NewRequest(t, "GET", "/user2/autocreated.git/info/refs?service=git-receive-pack")
	session.MakeRequest(t, req, http.StatusNotFound)

	setting.Repository.Upload.AutoCreate = true
	req = NewRequest(t, "GET", "/user2/autocreated.git/info/refs?service=git-receive-pack")
	resp := session.MakeRequest(t, req, http.StatusOK)

	// cleanup
	var repo api.Repository
	DecodeJSON(t, resp, &repo)
	req = NewRequestWithValues(t, "POST", "/git/admin/repos/delete", map[string]string{
		"_csrf": GetCSRF(t, session, "/git/admin/repos/delete"),
		"id":    string(repo.ID),
	})
	session.MakeRequest(t, req, http.StatusOK)
}

Thanks.

@Morlinest
Copy link
Member

@j-keck First you need pgsql or mysql installed (or use docker) and run make test-mysql or make test-pgsql. If you run with latest changes (#2473), you might need to add mysql or pgsql to hosts file with their real IP.

if the repository doesn't exists at push time,
and the setting 'Repository.Upload.AutoCreate' is 'true'
(default is 'false') create the repository with the given name.

Signed-off-by: Jürgen Keck <[email protected]>
@j-keck j-keck force-pushed the repository-auto-create branch from 19f0768 to 7d5fe39 Compare September 10, 2017 12:23
@j-keck
Copy link
Author

j-keck commented Sep 10, 2017

I have included a test case.

Rebased on 'master' and squash the impl + test in one commit.


//
// if 'AUTO_CREATE = false', the repo should not be created if it doesn't exist
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe don't use empty comment line.

@@ -95,6 +95,13 @@ func HTTP(ctx *context.Context) {
}

repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
if models.IsErrRepoNotExist(err) && setting.Repository.Upload.AutoCreate {
Copy link
Member

@Morlinest Morlinest Sep 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look good to me. You should check err for each function. Later err check block is expecting only GetRepositoryByName error, not CreateRepository error. I think something like this:

	repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
	if err != nil {
		if models.IsErrRepoNotExist(err) {
			if accessMode == models.AccessModeWrite && setting.Repository.Upload.AutoCreate {
				repo, err = models.CreateRepository(repoUser, repoUser, models.CreateRepoOptions{
					Name: reponame,
				})
				if err != nil {
					ctx.Handle(http.StatusInternalServerError, "CreateRepository", err)
					return
				}
			} else {
				ctx.Handle(http.StatusNotFound, "GetRepositoryByName", nil)
				return
			}
		} else {
			ctx.Handle(http.StatusInternalServerError, "GetRepositoryByName", err)
			return
		}
	}

Edit: Updated if condition in example.

Copy link
Member

@Morlinest Morlinest Sep 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you are creating repository on any action, you should check if user is doing push or pull. I think you can use accessMode variable defined few lines above (changing if condition to accessMode == models.AccessModeWrite && setting.Repository.Upload.AutoCreate

Edit: Or use isPull variable.


// if 'CreateRepository' fails, the error are handled in the next 'if err != nil' block
repo, err = models.CreateRepository(repoUser, repoUser, models.CreateRepoOptions{
Name: reponame,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about private/public repo? I think repository should be private by default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it hard-coded private or with an extra bool setting - like 'AutoCreateAsPrivate'?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it should be Auto Create specific but probably more generic like 'NewRepositoryDefaultPrivate` and this setting should be reused to set private check box to this default when creating new repository also in UI

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point - i make a extra pr for this tomorrow

Copy link
Member

@Morlinest Morlinest Sep 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lafriks Actually I think it is more secure to set it private by default. In UI you can tell what you want, but if you autocreate repository, you don't have any option. Also if you use some general variable, you know about it as admin, but not as user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morlinest yes but that does not mean that can't be configurable (as I need myself to to have such option so that I don't have remember to check that check box when creating new repository :) )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can add configurable variable, but we should not mix UI and some kind of auto create function.

}{
Enabled: true,
TempPath: "data/tmp/uploads",
AllowedTypes: []string{},
FileMaxSize: 3,
MaxFiles: 5,
AutoCreate: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool is false by default, don't need to be set.

// if 'AUTO_CREATE = true', the repos should be created
//
setting.Repository.Upload.AutoCreate = true
req = NewRequest(t, "GET", "/user2/autocreated.git/info/refs?service=git-receive-pack")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if logged user is not same user as in url? You should check both options.

//
setting.Repository.Upload.AutoCreate = true
req = NewRequest(t, "GET", "/user2/autocreated.git/info/refs?service=git-receive-pack")
// we don't get a successful response code here, because we don't execute a real 'git push ...'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you do real push? (I don't know how git requests look)

if models.IsErrRepoNotExist(err) && setting.Repository.Upload.AutoCreate {

// if 'CreateRepository' fails, the error are handled in the next 'if err != nil' block
repo, err = models.CreateRepository(repoUser, repoUser, models.CreateRepoOptions{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about access rights? Logged user don't need to be same as repoUser. You need user is logged and if he can create repository under repoUser (e.g. is admin or wants to add repository to his organization or organization he is in owner team).

@j-keck
Copy link
Author

j-keck commented Sep 11, 2017

my changes was only a quick hack for my local setup - not ready for a pull-request.
give me time till the weekend, then i clean it up.

@lunny lunny modified the milestones: 1.3.0, 1.x.x Oct 10, 2017
@stale
Copy link

stale bot commented Jan 5, 2019

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 months. Thank you for your contributions.

@stale stale bot added the issue/stale label Jan 5, 2019
@stale
Copy link

stale bot commented Jan 19, 2019

This pull request has been automatically closed because of inactivity. You can re-open it if needed.

@stale stale bot closed this Jan 19, 2019
@lafriks lafriks removed this from the 1.x.x milestone Jan 21, 2019
@go-gitea go-gitea locked and limited conversation to collaborators Nov 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/stale lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. type/feature Completely new functionality. Can only be merged if feature freeze is not active.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants