mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-02 04:03:48 +00:00
Reload repo on hook (#5324)
This commit is contained in:
parent
8fc936356c
commit
5a33134814
4 changed files with 197 additions and 12 deletions
|
@ -398,8 +398,23 @@ func (c *config) PullRequests(ctx context.Context, u *model.User, r *model.Repo,
|
||||||
|
|
||||||
// Hook parses the incoming Bitbucket hook and returns the Repository and
|
// Hook parses the incoming Bitbucket hook and returns the Repository and
|
||||||
// Pipeline details. If the hook is unsupported nil values are returned.
|
// Pipeline details. If the hook is unsupported nil values are returned.
|
||||||
func (c *config) Hook(_ context.Context, req *http.Request) (*model.Repo, *model.Pipeline, error) {
|
func (c *config) Hook(ctx context.Context, req *http.Request) (*model.Repo, *model.Pipeline, error) {
|
||||||
return parseHook(req)
|
repo, pl, err := parseHook(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := common.RepoUserForgeID(ctx, repo.ForgeRemoteID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err = c.Repo(ctx, u, repo.ForgeRemoteID, repo.Owner, repo.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return repo, pl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrgMembership returns if user is member of organization and if user
|
// OrgMembership returns if user is member of organization and if user
|
||||||
|
|
|
@ -23,11 +23,14 @@ import (
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge/bitbucket/fixtures"
|
"go.woodpecker-ci.org/woodpecker/v3/server/forge/bitbucket/fixtures"
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge/bitbucket/internal"
|
"go.woodpecker-ci.org/woodpecker/v3/server/forge/bitbucket/internal"
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge/types"
|
"go.woodpecker-ci.org/woodpecker/v3/server/forge/types"
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v3/server/store"
|
||||||
|
mocks_store "go.woodpecker-ci.org/woodpecker/v3/server/store/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
|
@ -203,9 +206,15 @@ func TestBitbucket(t *testing.T) {
|
||||||
req.Header = http.Header{}
|
req.Header = http.Header{}
|
||||||
req.Header.Set(hookEvent, hookPush)
|
req.Header.Set(hookEvent, hookPush)
|
||||||
|
|
||||||
|
mockStore := mocks_store.NewStore(t)
|
||||||
|
ctx = store.InjectToContext(ctx, mockStore)
|
||||||
|
mockStore.On("GetUser", mock.Anything).Return(fakeUser, nil)
|
||||||
|
mockStore.On("GetRepoForgeID", mock.Anything).Return(fakeRepoFromHook, nil)
|
||||||
|
|
||||||
r, b, err := c.Hook(ctx, req)
|
r, b, err := c.Hook(ctx, req)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "martinherren1984/publictestrepo", r.FullName)
|
assert.Equal(t, "martinherren1984/publictestrepo", r.FullName)
|
||||||
|
assert.Equal(t, "master", r.Branch)
|
||||||
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit)
|
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +278,13 @@ var (
|
||||||
FullName: "test_name/hook_empty",
|
FullName: "test_name/hook_empty",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakeRepoFromHook = &model.Repo{
|
||||||
|
Owner: "martinherren1984",
|
||||||
|
Name: "publictestrepo",
|
||||||
|
FullName: "martinherren1984/publictestrepo",
|
||||||
|
UserID: 1,
|
||||||
|
}
|
||||||
|
|
||||||
fakePipeline = &model.Pipeline{
|
fakePipeline = &model.Pipeline{
|
||||||
Commit: "9ecad50",
|
Commit: "9ecad50",
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ func getRepo(c *gin.Context) {
|
||||||
c.String(http.StatusNotFound, "")
|
c.String(http.StatusNotFound, "")
|
||||||
case "permission_read", "permission_write", "permission_admin":
|
case "permission_read", "permission_write", "permission_admin":
|
||||||
c.String(http.StatusOK, fmt.Sprintf(permissionRepoPayload, c.Param("name")))
|
c.String(http.StatusOK, fmt.Sprintf(permissionRepoPayload, c.Param("name")))
|
||||||
|
case "{898477b2-a080-4089-b385-597a783db392}":
|
||||||
|
c.String(http.StatusOK, repoPayloadFromHook)
|
||||||
default:
|
default:
|
||||||
c.String(http.StatusOK, repoPayload)
|
c.String(http.StatusOK, repoPayload)
|
||||||
}
|
}
|
||||||
|
@ -227,6 +229,137 @@ const permissionRepoPayload = `
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const repoPayloadFromHook = `
|
||||||
|
{
|
||||||
|
"type": "repository",
|
||||||
|
"full_name": "martinherren1984/publictestrepo",
|
||||||
|
"links": {
|
||||||
|
"self": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo"
|
||||||
|
},
|
||||||
|
"html": {
|
||||||
|
"href": "https://bitbucket.org/martinherren1984/publictestrepo"
|
||||||
|
},
|
||||||
|
"avatar": {
|
||||||
|
"href": "https://bytebucket.org/ravatar/%7B898477b2-a080-4089-b385-597a783db392%7D?ts=default"
|
||||||
|
},
|
||||||
|
"pullrequests": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/pullrequests"
|
||||||
|
},
|
||||||
|
"commits": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/commits"
|
||||||
|
},
|
||||||
|
"forks": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/forks"
|
||||||
|
},
|
||||||
|
"watchers": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/watchers"
|
||||||
|
},
|
||||||
|
"branches": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/refs/branches"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/refs/tags"
|
||||||
|
},
|
||||||
|
"downloads": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/downloads"
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/src"
|
||||||
|
},
|
||||||
|
"clone": [
|
||||||
|
{
|
||||||
|
"name": "https",
|
||||||
|
"href": "https://bitbucket.org/martinherren1984/publictestrepo.git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh",
|
||||||
|
"href": "git@bitbucket.org:martinherren1984/publictestrepo.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hooks": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/repositories/martinherren1984/publictestrepo/hooks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "PublicTestRepo",
|
||||||
|
"slug": "publictestrepo",
|
||||||
|
"description": "",
|
||||||
|
"scm": "git",
|
||||||
|
"website": null,
|
||||||
|
"owner": {
|
||||||
|
"display_name": "Martin Herren",
|
||||||
|
"links": {
|
||||||
|
"self": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/users/%7Bc5a0d676-fd27-4bd4-ac69-a7540d7b495b%7D"
|
||||||
|
},
|
||||||
|
"avatar": {
|
||||||
|
"href": "https://secure.gravatar.com/avatar/37de364488b2ec474b5458ca86442bbb?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FMH-2.png"
|
||||||
|
},
|
||||||
|
"html": {
|
||||||
|
"href": "https://bitbucket.org/%7Bc5a0d676-fd27-4bd4-ac69-a7540d7b495b%7D/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "user",
|
||||||
|
"uuid": "{c5a0d676-fd27-4bd4-ac69-a7540d7b495b}",
|
||||||
|
"account_id": "5cf8e3a9678ca90f8e7cc8a8",
|
||||||
|
"nickname": "Martin Herren"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "workspace",
|
||||||
|
"uuid": "{c5a0d676-fd27-4bd4-ac69-a7540d7b495b}",
|
||||||
|
"name": "Martin Herren",
|
||||||
|
"slug": "martinherren1984",
|
||||||
|
"links": {
|
||||||
|
"avatar": {
|
||||||
|
"href": "https://bitbucket.org/workspaces/martinherren1984/avatar/?ts=1658761964"
|
||||||
|
},
|
||||||
|
"html": {
|
||||||
|
"href": "https://bitbucket.org/martinherren1984/"
|
||||||
|
},
|
||||||
|
"self": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/workspaces/martinherren1984"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is_private": false,
|
||||||
|
"project": {
|
||||||
|
"type": "project",
|
||||||
|
"key": "PUB",
|
||||||
|
"uuid": "{2cede481-f59e-49ec-88d0-a85629b7925d}",
|
||||||
|
"name": "PublicTestProject",
|
||||||
|
"links": {
|
||||||
|
"self": {
|
||||||
|
"href": "https://api.bitbucket.org/2.0/workspaces/martinherren1984/projects/PUB"
|
||||||
|
},
|
||||||
|
"html": {
|
||||||
|
"href": "https://bitbucket.org/martinherren1984/workspace/projects/PUB"
|
||||||
|
},
|
||||||
|
"avatar": {
|
||||||
|
"href": "https://bitbucket.org/martinherren1984/workspace/projects/PUB/avatar/32?ts=1658768453"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fork_policy": "allow_forks",
|
||||||
|
"created_on": "2022-07-25T17:01:20.950706+00:00",
|
||||||
|
"updated_on": "2022-09-07T20:19:30.622886+00:00",
|
||||||
|
"size": 85955,
|
||||||
|
"language": "",
|
||||||
|
"uuid": "{898477b2-a080-4089-b385-597a783db392}",
|
||||||
|
"mainbranch": {
|
||||||
|
"name": "master",
|
||||||
|
"type": "branch"
|
||||||
|
},
|
||||||
|
"override_settings": {
|
||||||
|
"default_merge_strategy": true,
|
||||||
|
"branching_model": true
|
||||||
|
},
|
||||||
|
"parent": null,
|
||||||
|
"enforced_signed_commits": null,
|
||||||
|
"has_issues": false,
|
||||||
|
"has_wiki": false
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const repoHookPayload = `
|
const repoHookPayload = `
|
||||||
{
|
{
|
||||||
"pagelen": 10,
|
"pagelen": 10,
|
||||||
|
|
|
@ -16,6 +16,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -49,18 +50,38 @@ func UserToken(ctx context.Context, r *model.Repo, u *model.User) string {
|
||||||
return u.AccessToken
|
return u.AccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
_store, ok := store.TryFromContext(ctx)
|
user, err := RepoUser(ctx, r)
|
||||||
if !ok {
|
|
||||||
log.Error().Msg("could not get store from context")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if r == nil {
|
|
||||||
log.Error().Msg("cannot get user token by empty repo")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
user, err := _store.GetUser(r.UserID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("could not get repo user")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return user.AccessToken
|
return user.AccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RepoUser(ctx context.Context, r *model.Repo) (*model.User, error) {
|
||||||
|
_store, ok := store.TryFromContext(ctx)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("could not get store from context")
|
||||||
|
}
|
||||||
|
if r == nil {
|
||||||
|
log.Error().Msg("cannot get user token by empty repo")
|
||||||
|
return nil, errors.New("cannot get user token by empty repo")
|
||||||
|
}
|
||||||
|
user, err := _store.GetUser(r.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RepoUserForgeID(ctx context.Context, repoForgeID model.ForgeRemoteID) (*model.User, error) {
|
||||||
|
_store, ok := store.TryFromContext(ctx)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("could not get store from context")
|
||||||
|
}
|
||||||
|
r, err := _store.GetRepoForgeID(repoForgeID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return RepoUser(ctx, r)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue